From f9883865606b7b31396f673fd07a163d911c61f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 25 Jun 2021 13:14:13 +0200 Subject: [PATCH] Track current window DPI The WM_DPICHANGED event gives us the new DPI, but we also need the current DPI in order to determine the scale factor corresponding to the DPI change. Pick-to: 6.2 Change-Id: Ia61388415f57aa739397d3125b8751952e8fd392 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscontext.cpp | 5 +++++ src/plugins/platforms/windows/qwindowscontext.h | 4 ++++ src/plugins/platforms/windows/qwindowswindow.cpp | 2 ++ src/plugins/platforms/windows/qwindowswindow.h | 4 ++++ 4 files changed, 15 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 983fc9d47b..f24ab02b87 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -218,6 +218,7 @@ void QWindowsUser32DLL::init() getWindowDpiAwarenessContext = (GetWindowDpiAwarenessContext)library.resolve("GetWindowDpiAwarenessContext"); getAwarenessFromDpiAwarenessContext = (GetAwarenessFromDpiAwarenessContext)library.resolve("GetAwarenessFromDpiAwarenessContext"); systemParametersInfoForDpi = (SystemParametersInfoForDpi)library.resolve("SystemParametersInfoForDpi"); + getDpiForWindow = (GetDpiForWindow)library.resolve("GetDpiForWindow"); } } @@ -1474,6 +1475,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, #endif } break; case QtWindows::DpiChangedEvent: { + + const UINT dpi = HIWORD(wParam); + platformWindow->setSavedDpi(dpi); + // Try to apply the suggested size first and then notify ScreenChanged // so that the resize event sent from QGuiApplication incorporates it // WM_DPICHANGED is sent with a size that avoids resize loops (by diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 99b4bb6c77..04328a0369 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -108,6 +108,7 @@ struct QWindowsUser32DLL typedef int (WINAPI *GetWindowDpiAwarenessContext)(HWND); typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(int); typedef BOOL (WINAPI *SystemParametersInfoForDpi)(UINT, UINT, PVOID, UINT, UINT); + typedef int (WINAPI *GetDpiForWindow)(HWND); // Windows pointer functions (Windows 8 or later). EnableMouseInPointer enableMouseInPointer = nullptr; @@ -124,6 +125,9 @@ struct QWindowsUser32DLL // Windows Vista onwards SetProcessDPIAware setProcessDPIAware = nullptr; + // Windows 10 version 1607 onwards + GetDpiForWindow getDpiForWindow = nullptr; + // Windows 10 version 1703 onwards SetProcessDpiAwarenessContext setProcessDpiAwarenessContext = nullptr; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 3e291f310d..e16b3e7b5a 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1419,6 +1419,8 @@ void QWindowsWindow::initialize() if (obtainedScreen && screen() != obtainedScreen) QWindowSystemInterface::handleWindowScreenChanged(w, obtainedScreen->screen()); } + QWindowsWindow::setSavedDpi(QWindowsContext::user32dll.getDpiForWindow ? + QWindowsContext::user32dll.getDpiForWindow(handle()) : 96); } QSurfaceFormat QWindowsWindow::format() const diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index b0f58b09a9..73b3b81f7f 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -372,6 +372,9 @@ public: static const char *embeddedNativeParentHandleProperty; static const char *hasBorderInFullScreenProperty; + void setSavedDpi(int dpi) { m_savedDpi = dpi; } + int savedDpi() const { return m_savedDpi; } + private: inline void show_sys() const; inline QWindowsWindowData setWindowFlags_sys(Qt::WindowFlags wt, unsigned flags = 0) const; @@ -405,6 +408,7 @@ private: HICON m_iconSmall = nullptr; HICON m_iconBig = nullptr; void *m_surface = nullptr; + int m_savedDpi = 96; static bool m_screenForGLInitialized;