Skip to content

Commit

Permalink
Platform: implement virtual DPI scaling in GlfwApp on Windows.
Browse files Browse the repository at this point in the history
Until now, both physical and virtual returned the physical DPI scaling.
  • Loading branch information
mosra committed Feb 15, 2020
1 parent a78cdc2 commit 444b925
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 19 deletions.
2 changes: 2 additions & 0 deletions doc/changelog.dox
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ See also:
enabled by default on macOS 10.15+ and iOS 13+. Applications running on
these platforms no longer need to supply a custom `Info.plist` in order to
enable HiDPI. See @ref platforms-macos-hidpi for more information.
- Implemented virtual DPI scaling in @ref Platform::GlfwApplication (was
behaving like physical before) (see [mosra/magnum#243](https://github.com/mosra/magnum/issues/243))

@subsubsection changelog-latest-changes-trade Trade library

Expand Down
37 changes: 18 additions & 19 deletions src/Magnum/Platform/GlfwApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,20 +169,23 @@ Vector2 GlfwApplication::dpiScaling(const Configuration& configuration) {
/* Otherwise there's a choice between virtual and physical DPI scaling */
#else
/* Try to get virtual DPI scaling first, if supported and requested */
/** @todo Revisit this for GLFW 3.3 -- https://github.com/glfw/glfw/issues/677 */
if(dpiScalingPolicy == Implementation::GlfwDpiScalingPolicy::Virtual) {
/* Use Xft.dpi on X11 */
/* Use Xft.dpi on X11. This could probably be dropped for GLFW 3.3+
as glfwGetMonitorContentScale() does the same, but I'd still need to
keep it for 2.2 and below, plus the same code needs to be used for
SDL anyway. So keeping it to reduce the chance for unexpected minor
differences across app implementations. */
#ifdef _MAGNUM_PLATFORM_USE_X11
const Vector2 dpiScaling{Implementation::x11DpiScaling()};
if(!dpiScaling.isZero()) {
Debug{verbose} << "Platform::GlfwApplication: virtual DPI scaling" << dpiScaling.x();
return dpiScaling;
}

/* Check for DPI awareness on non-RT Windows and then ask for DPI. GLFW
is advertising the application to be DPI-aware on its own even
without supplying an explicit manifest --
https://github.com/glfw/glfw/blob/089ea9af227fdffdf872348923e1c12682e63029/src/win32_init.c#L564-L569
/* Check for DPI awareness on non-RT Windows and then ask for content
scale (available since GLFW 3.3). GLFW is advertising the
application to be DPI-aware on its own even without supplying an
explicit manifest -- https://github.com/glfw/glfw/blob/089ea9af227fdffdf872348923e1c12682e63029/src/win32_init.c#L564-L569
If, for some reason, the app is still not DPI-aware, tell that to
the user explicitly and don't even attempt to query the value if the
app is not DPI aware. If it's desired to get the DPI value
Expand All @@ -192,18 +195,15 @@ Vector2 GlfwApplication::dpiScaling(const Configuration& configuration) {
Warning{verbose} << "Platform::GlfwApplication: your application is not set as DPI-aware, DPI scaling won't be used";
return Vector2{1.0f};
}
#if GLFW_VERSION_MAJOR*100 + GLFW_VERSION_MINOR >= 303
GLFWmonitor* const monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* const mode = glfwGetVideoMode(monitor);
Vector2i monitorSize;
glfwGetMonitorPhysicalSize(monitor, &monitorSize.x(), &monitorSize.y());
if(monitorSize.isZero()) {
Warning{verbose} << "Platform::GlfwApplication: the physical monitor size is zero? DPI scaling won't be used";
return Vector2{1.0f};
}
auto dpi = Vector2{Vector2i{mode->width, mode->height}*25.4f/Vector2{monitorSize}};
const Vector2 dpiScaling{dpi/96.0f};
Vector2 dpiScaling;
glfwGetMonitorContentScale(monitor, &dpiScaling.x(), &dpiScaling.y());
Debug{verbose} << "Platform::GlfwApplication: virtual DPI scaling" << dpiScaling;
return dpiScaling;
#else
Debug{verbose} << "Platform::GlfwApplication: sorry, virtual DPI scaling only available on GLFW 3.3+, falling back to physical DPI scaling";
#endif

/* Otherwise ¯\_(ツ)_/¯ */
#else
Expand All @@ -215,10 +215,9 @@ Vector2 GlfwApplication::dpiScaling(const Configuration& configuration) {
scaling is requested */
CORRADE_INTERNAL_ASSERT(dpiScalingPolicy == Implementation::GlfwDpiScalingPolicy::Virtual || dpiScalingPolicy == Implementation::GlfwDpiScalingPolicy::Physical);

/* Take display DPI elsewhere. Enable only on Linux (where it gets the
usually very-off value from X11) and on non-RT Windows (where it takes
the UI scale value like with virtual DPI scaling, but without checking
for DPI awareness first). */
/* Physical DPI scaling. Enable only on Linux (where it gets the usually
very-off value from X11) and on non-RT Windows (where it calculates it
from actual monitor dimensions). */
#if defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT))
GLFWmonitor* const monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* const mode = glfwGetVideoMode(monitor);
Expand Down

0 comments on commit 444b925

Please sign in to comment.