From 6ab321a38c40933ec57b87ff4dc3300e05e679f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 16 Sep 2023 13:08:40 +0200 Subject: [PATCH] Platform: query DPI scaling values every time instead of saving them. This makes them consistent with window and framebuffer size queries, that are also not cached but queried every time. It fixes a case where a global UI scaling change in the OS triggered a viewport event but the event didn't actually have the DPI scaling value updated. It doesn't however handle actual explicit DPI change events yet, that's another nightmare altogether. --- doc/changelog.dox | 10 +++ src/Magnum/Platform/EmscriptenApplication.cpp | 56 ++++++++++------ src/Magnum/Platform/EmscriptenApplication.h | 12 ++-- src/Magnum/Platform/GlfwApplication.cpp | 45 ++++++++----- src/Magnum/Platform/GlfwApplication.h | 12 ++-- src/Magnum/Platform/Sdl2Application.cpp | 65 ++++++++++++------- src/Magnum/Platform/Sdl2Application.h | 13 ++-- 7 files changed, 137 insertions(+), 76 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 86b4d494f..609ff086b 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -711,6 +711,16 @@ See also: - @ref Platform::GlfwApplication now overrides GLFW's default behavior that changes current working directory to `Resources/` in the app bundle on Apple platforms. +- @ref Platform::EmscriptenApplication, @ref Platform::GlfwApplication and + @ref Platform::Sdl2Application now explicitly query DPI scaling values each + time they're accessed, either directly or via the viewport event, instead + of always returning the initially queried / calculated value. This makes + the behavior consistent with framebuffer and window sizes that are also + queried every time, and fixes a case where changing global UI scaling + would trigger a viewport event but the event would still have the previous + UI scale. However note that this does not yet properly handle DPI change + events themselves, which happen for example when moving windows across + displays with different DPI. @subsubsection changelog-latest-changes-scenegraph SceneGraph library diff --git a/src/Magnum/Platform/EmscriptenApplication.cpp b/src/Magnum/Platform/EmscriptenApplication.cpp index f95fba8ab..a24650f2b 100644 --- a/src/Magnum/Platform/EmscriptenApplication.cpp +++ b/src/Magnum/Platform/EmscriptenApplication.cpp @@ -268,6 +268,10 @@ void EmscriptenApplication::create(const Configuration& configuration, const GLC #endif Vector2 EmscriptenApplication::dpiScaling(const Configuration& configuration) const { + return dpiScalingInternal(configuration.dpiScaling()); +} + +Vector2 EmscriptenApplication::dpiScalingInternal(const Vector2& configurationDpiScaling) const { std::ostream* verbose = _verboseLog ? Debug::output() : nullptr; /* Use values from the configuration only if not overridden on command line. @@ -275,9 +279,9 @@ Vector2 EmscriptenApplication::dpiScaling(const Configuration& configuration) co if(!_commandLineDpiScaling.isZero()) { Debug{verbose} << "Platform::EmscriptenApplication: user-defined DPI scaling" << _commandLineDpiScaling; return _commandLineDpiScaling; - } else if(!configuration.dpiScaling().isZero()) { - Debug{verbose} << "Platform::EmscriptenApplication: app-defined DPI scaling" << configuration.dpiScaling(); - return configuration.dpiScaling(); + } else if(!configurationDpiScaling.isZero()) { + Debug{verbose} << "Platform::EmscriptenApplication: app-defined DPI scaling" << configurationDpiScaling; + return configurationDpiScaling; } /* Unlike Sdl2Application, not taking device pixel ratio into account @@ -299,12 +303,6 @@ bool EmscriptenApplication::tryCreate(const Configuration& configuration) { std::ostream* verbose = _verboseLog ? Debug::output() : nullptr; - /* Fetch device pixel ratio. Together with DPI scaling (which is 1.0 by - default) this will define framebuffer size. See class docs for why is it - done like that. */ - _devicePixelRatio = Vector2{Float(emscripten_get_device_pixel_ratio())}; - Debug{verbose} << "Platform::EmscriptenApplication: device pixel ratio" << _devicePixelRatio.x(); - _canvasTarget = canvasId(); /* Get CSS canvas size and cache it. This is used later to detect canvas @@ -327,8 +325,14 @@ bool EmscriptenApplication::tryCreate(const Configuration& configuration) { canvasSize = _lastKnownCanvasSize; Debug{verbose} << "Platform::EmscriptenApplication::tryCreate(): autodetected canvas size" << canvasSize; } - _dpiScaling = dpiScaling(configuration); - const Vector2i scaledCanvasSize = canvasSize*_dpiScaling*_devicePixelRatio; + + /* Save DPI scaling value from configuration for future use. Device pixel + ratio together with DPI scaling (which is 1.0 by default) defines + framebuffer size. See class docs for why it's done like that. */ + _configurationDpiScaling = configuration.dpiScaling(); + const Vector2 devicePixelRatio = this->devicePixelRatio(); + Debug{verbose} << "Platform::EmscriptenApplication: device pixel ratio" << devicePixelRatio.x(); + const Vector2i scaledCanvasSize = canvasSize*dpiScaling(configuration)*devicePixelRatio; emscripten_set_canvas_element_size(_canvasTarget.data(), scaledCanvasSize.x(), scaledCanvasSize.y()); setupCallbacks(!!(configuration.windowFlags() & Configuration::WindowFlag::Resizable)); @@ -376,12 +380,6 @@ bool EmscriptenApplication::tryCreate(const Configuration& configuration, const std::ostream* verbose = _verboseLog ? Debug::output() : nullptr; - /* Fetch device pixel ratio. Together with DPI scaling (which is 1.0 by - default) this will define framebuffer size. See class docs for why is it - done like that. */ - _devicePixelRatio = Vector2{Float(emscripten_get_device_pixel_ratio())}; - Debug{verbose} << "Platform::EmscriptenApplication: device pixel ratio" << _devicePixelRatio.x(); - /* Get the canvas ID from Module.canvas, either set by EmscriptenApplication.js or overridden/manually set by the user. */ _canvasTarget = canvasId(); @@ -406,8 +404,14 @@ bool EmscriptenApplication::tryCreate(const Configuration& configuration, const canvasSize = _lastKnownCanvasSize; Debug{verbose} << "Platform::EmscriptenApplication::tryCreate(): autodetected canvas size" << canvasSize; } - _dpiScaling = dpiScaling(configuration); - const Vector2i scaledCanvasSize = canvasSize*_dpiScaling*_devicePixelRatio; + + /* Save DPI scaling value from configuration for future use. Device pixel + ratio together with DPI scaling (which is 1.0 by default) defines + framebuffer size. See class docs for why it's done like that. */ + _configurationDpiScaling = configuration.dpiScaling(); + const Vector2 devicePixelRatio = this->devicePixelRatio(); + Debug{verbose} << "Platform::EmscriptenApplication: device pixel ratio" << devicePixelRatio.x(); + const Vector2i scaledCanvasSize = canvasSize*dpiScaling(configuration)*devicePixelRatio; emscripten_set_canvas_element_size(_canvasTarget.data(), scaledCanvasSize.x(), scaledCanvasSize.y()); /* Create WebGL context */ @@ -445,6 +449,14 @@ Vector2i EmscriptenApplication::framebufferSize() const { } #endif +Vector2 EmscriptenApplication::dpiScaling() const { + return dpiScalingInternal(_configurationDpiScaling); +} + +Vector2 EmscriptenApplication::devicePixelRatio() const { + return Vector2{Float(emscripten_get_device_pixel_ratio())}; +} + void EmscriptenApplication::setWindowTitle(const Containers::StringView title) { magnumPlatformSetWindowTitle(title.data(), title.size()); } @@ -467,13 +479,15 @@ void EmscriptenApplication::handleCanvasResize(const EmscriptenUiEvent* event) { const Vector2i canvasSize{windowSize()}; if(canvasSize != _lastKnownCanvasSize) { _lastKnownCanvasSize = canvasSize; - const Vector2i size = canvasSize*_dpiScaling*_devicePixelRatio; + const Vector2 dpiScaling = this->dpiScaling(); + const Vector2 devicePixelRatio = this->devicePixelRatio(); + const Vector2i size = canvasSize*dpiScaling*devicePixelRatio; emscripten_set_canvas_element_size(_canvasTarget.data(), size.x(), size.y()); ViewportEvent e{event, canvasSize, #ifdef MAGNUM_TARGET_GL framebufferSize(), #endif - _dpiScaling, _devicePixelRatio}; + dpiScaling, devicePixelRatio}; viewportEvent(e); /* Can't say just _flags | Flag::Redraw because in case the diff --git a/src/Magnum/Platform/EmscriptenApplication.h b/src/Magnum/Platform/EmscriptenApplication.h index 4e4ff5c47..c7e335d17 100644 --- a/src/Magnum/Platform/EmscriptenApplication.h +++ b/src/Magnum/Platform/EmscriptenApplication.h @@ -497,7 +497,7 @@ class EmscriptenApplication { * more information. * @see @ref framebufferSize(), @ref devicePixelRatio() */ - Vector2 dpiScaling() const { return _dpiScaling; } + Vector2 dpiScaling() const; /** * @brief DPI scaling for given configuration @@ -518,7 +518,7 @@ class EmscriptenApplication { * and @ref framebufferSize() values. * @see @ref dpiScaling() */ - Vector2 devicePixelRatio() const { return _devicePixelRatio; } + Vector2 devicePixelRatio() const; /** * @brief Set window title @@ -890,12 +890,13 @@ class EmscriptenApplication { typedef Containers::EnumSet Flags; CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) + Vector2 dpiScalingInternal(const Vector2& configurationDpiScaling) const; + void handleCanvasResize(const EmscriptenUiEvent* event); /* Sorry, but can't use Configuration::WindowFlags here :( */ void setupCallbacks(bool resizable); void setupAnimationFrame(bool ForceAnimationFrame); - Vector2 _devicePixelRatio, _dpiScaling; Vector2i _lastKnownCanvasSize, _previousMouseMovePosition{-1}; Flags _flags; @@ -911,9 +912,10 @@ class EmscriptenApplication { Containers::Optional _context; #endif - /* These are saved from command-line arguments */ + /* These are saved from command-line arguments, and from configuration + to be reused in dpiScaling() and viewportEvent() later */ bool _verboseLog{}; - Vector2 _commandLineDpiScaling; + Vector2 _commandLineDpiScaling, _configurationDpiScaling; /* Animation frame callback */ int (*_callback)(void*); diff --git a/src/Magnum/Platform/GlfwApplication.cpp b/src/Magnum/Platform/GlfwApplication.cpp index fb4d49af0..1f97ff697 100644 --- a/src/Magnum/Platform/GlfwApplication.cpp +++ b/src/Magnum/Platform/GlfwApplication.cpp @@ -141,8 +141,6 @@ void GlfwApplication::create(const Configuration& configuration, const GLConfigu #endif Vector2 GlfwApplication::dpiScaling(const Configuration& configuration) { - std::ostream* verbose = _verboseLog ? Debug::output() : nullptr; - /* Print a helpful warning in case some extra steps are needed for HiDPI support */ #ifdef CORRADE_TARGET_APPLE @@ -151,9 +149,16 @@ Vector2 GlfwApplication::dpiScaling(const Configuration& configuration) { _flags |= Flag::HiDpiWarningPrinted; } #elif defined(CORRADE_TARGET_WINDOWS) - /** @todo */ + /* Handled in dpiScalingInternal(), warning printed only when using virtual + DPI scaling (and thus not setting the HiDpiWarningPrinted flag) */ #endif + return dpiScalingInternal(configuration.dpiScalingPolicy(), configuration.dpiScaling()); +} + +Vector2 GlfwApplication::dpiScalingInternal(const Implementation::GlfwDpiScalingPolicy configurationDpiScalingPolicy, const Vector2& configurationDpiScaling) const { + std::ostream* verbose = _verboseLog ? Debug::output() : nullptr; + /* Use values from the configuration only if not overridden on command line to something non-default. In any case explicit scaling has a precedence before the policy. */ @@ -163,11 +168,11 @@ Vector2 GlfwApplication::dpiScaling(const Configuration& configuration) { return _commandLineDpiScaling; } else if(_commandLineDpiScalingPolicy != Implementation::GlfwDpiScalingPolicy::Default) { dpiScalingPolicy = _commandLineDpiScalingPolicy; - } else if(!configuration.dpiScaling().isZero()) { - Debug{verbose} << "Platform::GlfwApplication: app-defined DPI scaling" << configuration.dpiScaling(); - return configuration.dpiScaling(); + } else if(!configurationDpiScaling.isZero()) { + Debug{verbose} << "Platform::GlfwApplication: app-defined DPI scaling" << configurationDpiScaling; + return configurationDpiScaling; } else { - dpiScalingPolicy = configuration.dpiScalingPolicy(); + dpiScalingPolicy = configurationDpiScalingPolicy; } /* There's no choice on Apple, it's all controlled by the plist file. So @@ -328,9 +333,11 @@ bool GlfwApplication::tryCreate(const Configuration& configuration) { CORRADE_ASSERT(!_window, "Platform::GlfwApplication::tryCreate(): window already created", false); - /* Scale window based on DPI */ - _dpiScaling = dpiScaling(configuration); - const Vector2i scaledWindowSize = configuration.size()*_dpiScaling; + /* Save DPI scaling values from configuration for future use, scale window + based on those */ + _configurationDpiScalingPolicy = configuration.dpiScalingPolicy(); + _configurationDpiScaling = configuration.dpiScaling(); + const Vector2i scaledWindowSize = configuration.size()*dpiScaling(configuration); /* Window flags */ GLFWmonitor* monitor = nullptr; /* Needed for setting fullscreen */ @@ -405,9 +412,11 @@ GlfwApplication::InputEvent::Modifiers currentGlfwModifiers(GLFWwindow* window) bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration) { CORRADE_ASSERT(!_window && _context->version() == GL::Version::None, "Platform::GlfwApplication::tryCreate(): window with OpenGL context already created", false); - /* Scale window based on DPI */ - _dpiScaling = dpiScaling(configuration); - const Vector2i scaledWindowSize = configuration.size()*_dpiScaling; + /* Save DPI scaling values from configuration for future use, scale window + based on those */ + _configurationDpiScalingPolicy = configuration.dpiScalingPolicy(); + _configurationDpiScaling = configuration.dpiScaling(); + const Vector2i scaledWindowSize = configuration.size()*dpiScaling(configuration); /* Window flags */ GLFWmonitor* monitor = nullptr; /* Needed for setting fullscreen */ @@ -690,7 +699,7 @@ Vector2i GlfwApplication::windowSize() const { void GlfwApplication::setWindowSize(const Vector2i& size) { CORRADE_ASSERT(_window, "Platform::GlfwApplication::setWindowSize(): no window opened", ); - const Vector2i newSize = _dpiScaling*size; + const Vector2i newSize = dpiScaling()*size; glfwSetWindowSize(_window, newSize.x(), newSize.y()); } @@ -698,7 +707,7 @@ void GlfwApplication::setWindowSize(const Vector2i& size) { void GlfwApplication::setMinWindowSize(const Vector2i& size) { CORRADE_ASSERT(_window, "Platform::GlfwApplication::setMinWindowSize(): no window opened", ); - const Vector2i newSize = _dpiScaling*size; + const Vector2i newSize = dpiScaling()*size; glfwSetWindowSizeLimits(_window, newSize.x(), newSize.y(), _maxWindowSize.x(), _maxWindowSize.y()); _minWindowSize = newSize; } @@ -706,7 +715,7 @@ void GlfwApplication::setMinWindowSize(const Vector2i& size) { void GlfwApplication::setMaxWindowSize(const Vector2i& size) { CORRADE_ASSERT(_window, "Platform::GlfwApplication::setMaxWindowSize(): no window opened", ); - const Vector2i newSize = _dpiScaling*size; + const Vector2i newSize = dpiScaling()*size; glfwSetWindowSizeLimits(_window, _minWindowSize.x(), _minWindowSize.y(), newSize.x(), newSize.y()); _maxWindowSize = newSize; } @@ -722,6 +731,10 @@ Vector2i GlfwApplication::framebufferSize() const { } #endif +Vector2 GlfwApplication::dpiScaling() const { + return dpiScalingInternal(_configurationDpiScalingPolicy, _configurationDpiScaling); +} + void GlfwApplication::setSwapInterval(const Int interval) { glfwSwapInterval(interval); } diff --git a/src/Magnum/Platform/GlfwApplication.h b/src/Magnum/Platform/GlfwApplication.h index a75f6ceb6..f788d8881 100644 --- a/src/Magnum/Platform/GlfwApplication.h +++ b/src/Magnum/Platform/GlfwApplication.h @@ -460,7 +460,7 @@ class GlfwApplication { * for more information. * @see @ref framebufferSize() */ - Vector2 dpiScaling() const { return _dpiScaling; } + Vector2 dpiScaling() const; /** * @brief DPI scaling for given configuration @@ -747,6 +747,8 @@ class GlfwApplication { typedef Containers::EnumSet Flags; CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) + Vector2 dpiScalingInternal(Implementation::GlfwDpiScalingPolicy configurationDpiScalingPolicy, const Vector2& configurationDpiScaling) const; + void setupCallbacks(); /* Corresponds to size of the Cursor enum, the two Hidden cursors are @@ -760,12 +762,12 @@ class GlfwApplication { ]{}; Cursor _cursor = Cursor::Arrow; - /* These are saved from command-line arguments */ + /* These are saved from command-line arguments, and from configuration + to be reused in dpiScaling() and viewportEvent() later */ bool _verboseLog{}; - Implementation::GlfwDpiScalingPolicy _commandLineDpiScalingPolicy{}; - Vector2 _commandLineDpiScaling; + Implementation::GlfwDpiScalingPolicy _commandLineDpiScalingPolicy{}, _configurationDpiScalingPolicy{}; + Vector2 _commandLineDpiScaling, _configurationDpiScaling; - Vector2 _dpiScaling; GLFWwindow* _window{nullptr}; Flags _flags; #ifdef MAGNUM_TARGET_GL diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp index d8dcdcbfe..86b9d6e2b 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -216,8 +216,6 @@ void Sdl2Application::create(const Configuration& configuration, const GLConfigu #endif Vector2 Sdl2Application::dpiScaling(const Configuration& configuration) { - std::ostream* verbose = _verboseLog ? Debug::output() : nullptr; - /* Print a helpful warning in case some extra steps are needed for HiDPI support */ #ifdef CORRADE_TARGET_APPLE @@ -226,9 +224,16 @@ Vector2 Sdl2Application::dpiScaling(const Configuration& configuration) { _flags |= Flag::HiDpiWarningPrinted; } #elif defined(CORRADE_TARGET_WINDOWS) - /* Handled below, warning printed only when using virtual DPI scaling */ + /* Handled in dpiScalingInternal(), warning printed only when using virtual + DPI scaling (and thus not setting the HiDpiWarningPrinted flag) */ #endif + return dpiScalingInternal(configuration.dpiScalingPolicy(), configuration.dpiScaling()); +} + +Vector2 Sdl2Application::dpiScalingInternal(const Implementation::Sdl2DpiScalingPolicy configurationDpiScalingPolicy, const Vector2& configurationDpiScaling) const { + std::ostream* verbose = _verboseLog ? Debug::output() : nullptr; + /* Use values from the configuration only if not overridden on command line to something non-default. In any case explicit scaling has a precedence before the policy. */ @@ -238,11 +243,11 @@ Vector2 Sdl2Application::dpiScaling(const Configuration& configuration) { return _commandLineDpiScaling; } else if(_commandLineDpiScalingPolicy != Implementation::Sdl2DpiScalingPolicy::Default) { dpiScalingPolicy = _commandLineDpiScalingPolicy; - } else if(!configuration.dpiScaling().isZero()) { - Debug{verbose} << "Platform::Sdl2Application: app-defined DPI scaling" << configuration.dpiScaling(); - return configuration.dpiScaling(); + } else if(!configurationDpiScaling.isZero()) { + Debug{verbose} << "Platform::Sdl2Application: app-defined DPI scaling" << configurationDpiScaling; + return configurationDpiScaling; } else { - dpiScalingPolicy = configuration.dpiScalingPolicy(); + dpiScalingPolicy = configurationDpiScalingPolicy; } /* There's no choice on Apple, it's all controlled by the plist file. So @@ -395,9 +400,11 @@ bool Sdl2Application::tryCreate(const Configuration& configuration) { #endif #ifndef CORRADE_TARGET_EMSCRIPTEN - /* Scale window based on DPI */ - _dpiScaling = dpiScaling(configuration); - const Vector2i scaledWindowSize = configuration.size()*_dpiScaling; + /* Save DPI scaling values from configuration for future use, scale window + based on those */ + _configurationDpiScalingPolicy = configuration.dpiScalingPolicy(); + _configurationDpiScaling = configuration.dpiScaling(); + const Vector2i scaledWindowSize = configuration.size()*dpiScaling(configuration); /* Create window */ if(!(_window = SDL_CreateWindow( @@ -440,8 +447,11 @@ bool Sdl2Application::tryCreate(const Configuration& configuration) { windowSize = _lastKnownCanvasSize; Debug{_verboseLog ? Debug::output() : nullptr} << "Platform::Sdl2Application::tryCreate(): autodetected canvas size" << windowSize; } - _dpiScaling = dpiScaling(configuration); - const Vector2i scaledWindowSize = windowSize*_dpiScaling; + /* Save DPI scaling values from configuration for future use, scale window + based on those */ + _configurationDpiScalingPolicy = configuration.dpiScalingPolicy(); + _configurationDpiScaling = configuration.dpiScaling(); + const Vector2i scaledWindowSize = windowSize*dpiScaling(configuration); Uint32 flags = SDL_OPENGL|SDL_HWSURFACE|SDL_DOUBLEBUF; if(configuration.windowFlags() & Configuration::WindowFlag::Resizable) { @@ -483,9 +493,11 @@ bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConf #endif #ifndef CORRADE_TARGET_EMSCRIPTEN - /* Scale window based on DPI */ - _dpiScaling = dpiScaling(configuration); - const Vector2i scaledWindowSize = configuration.size()*_dpiScaling; + /* Save DPI scaling values from configuration for future use, scale window + based on those */ + _configurationDpiScalingPolicy = configuration.dpiScalingPolicy(); + _configurationDpiScaling = configuration.dpiScaling(); + const Vector2i scaledWindowSize = configuration.size()*dpiScaling(configuration); /* Request debug context if GpuValidation is enabled either via the configuration or via command-line */ @@ -668,8 +680,11 @@ bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConf windowSize = _lastKnownCanvasSize; Debug{_verboseLog ? Debug::output() : nullptr} << "Platform::Sdl2Application::tryCreate(): autodetected canvas size" << windowSize; } - _dpiScaling = dpiScaling(configuration); - const Vector2i scaledWindowSize = windowSize*_dpiScaling; + /* Save DPI scaling values from configuration for future use, scale window + based on those */ + _configurationDpiScalingPolicy = configuration.dpiScalingPolicy(); + _configurationDpiScaling = configuration.dpiScaling(); + const Vector2i scaledWindowSize = windowSize*dpiScaling(); Uint32 flags = SDL_OPENGL|SDL_HWSURFACE|SDL_DOUBLEBUF; if(configuration.windowFlags() & Configuration::WindowFlag::Resizable) { @@ -724,21 +739,21 @@ Vector2i Sdl2Application::windowSize() const { void Sdl2Application::setWindowSize(const Vector2i& size) { CORRADE_ASSERT(_window, "Platform::Sdl2Application::setWindowSize(): no window opened", ); - const Vector2i newSize = _dpiScaling*size; + const Vector2i newSize = dpiScaling()*size; SDL_SetWindowSize(_window, newSize.x(), newSize.y()); } void Sdl2Application::setMinWindowSize(const Vector2i& size) { CORRADE_ASSERT(_window, "Platform::Sdl2Application::setMinWindowSize(): no window opened", ); - const Vector2i newSize = _dpiScaling*size; + const Vector2i newSize = dpiScaling()*size; SDL_SetWindowMinimumSize(_window, newSize.x(), newSize.y()); } void Sdl2Application::setMaxWindowSize(const Vector2i& size) { CORRADE_ASSERT(_window, "Platform::Sdl2Application::setMaxWindowSize(): no window opened", ); - const Vector2i newSize = _dpiScaling*size; + const Vector2i newSize = dpiScaling()*size; SDL_SetWindowMaximumSize(_window, newSize.x(), newSize.y()); } #endif @@ -757,6 +772,10 @@ Vector2i Sdl2Application::framebufferSize() const { } #endif +Vector2 Sdl2Application::dpiScaling() const { + return dpiScalingInternal(_configurationDpiScalingPolicy, _configurationDpiScaling); +} + #ifdef CORRADE_TARGET_EMSCRIPTEN void Sdl2Application::setContainerCssClass(const Containers::StringView cssClass) { magnumPlatformSetContainerCssClass(cssClass.data(), cssClass.size()); @@ -876,13 +895,13 @@ bool Sdl2Application::mainLoopIteration() { const Vector2i canvasSizei{canvasSize}; if(canvasSizei != _lastKnownCanvasSize) { _lastKnownCanvasSize = canvasSizei; - const Vector2i size = _dpiScaling*canvasSizei; + const Vector2i size = dpiScaling()*canvasSizei; emscripten_set_canvas_element_size("#canvas", size.x(), size.y()); ViewportEvent e{ #ifdef MAGNUM_TARGET_GL size, #endif - size, _dpiScaling}; + size, dpiScaling()}; viewportEvent(e); _flags |= Flag::Redraw; } @@ -912,7 +931,7 @@ bool Sdl2Application::mainLoopIteration() { #ifdef MAGNUM_TARGET_GL framebufferSize(), #endif - _dpiScaling}; + dpiScaling()}; /** @todo handle also WM_DPICHANGED events when a window is moved between displays with different DPI */ viewportEvent(e); _flags |= Flag::Redraw; diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index 68835eef8..bc1a95c61 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -805,7 +805,7 @@ class Sdl2Application { * for more information. * @see @ref framebufferSize() */ - Vector2 dpiScaling() const { return _dpiScaling; } + Vector2 dpiScaling() const; /** * @brief DPI scaling for given configuration @@ -1240,18 +1240,19 @@ class Sdl2Application { typedef Containers::EnumSet Flags; CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) + Vector2 dpiScalingInternal(Implementation::Sdl2DpiScalingPolicy configurationDpiScalingPolicy, const Vector2& configurationDpiScaling) const; + #ifndef CORRADE_TARGET_EMSCRIPTEN SDL_Cursor* _cursors[12]{}; #else Cursor _cursor; #endif - /* These are saved from command-line arguments */ + /* These are saved from command-line arguments, and from configuration + to be reused in dpiScaling() and viewportEvent() later */ bool _verboseLog{}; - Implementation::Sdl2DpiScalingPolicy _commandLineDpiScalingPolicy{}; - Vector2 _commandLineDpiScaling; - - Vector2 _dpiScaling; + Implementation::Sdl2DpiScalingPolicy _commandLineDpiScalingPolicy{}, _configurationDpiScalingPolicy{}; + Vector2 _commandLineDpiScaling, _configurationDpiScaling; #ifndef CORRADE_TARGET_EMSCRIPTEN SDL_Window* _window{};