diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2022-06-16 14:55:14 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2022-06-30 00:28:35 +0200 |
commit | 97665c9615ff399e9a074b94926ab06e0c9619e5 (patch) | |
tree | 0244ffed8663ea8fd0211fb478a8972ce596dcec /src | |
parent | 54f328f0e8205480749a6d8d2ebe0e58cb1cdb67 (diff) |
Windows: Don't rely on top level QWindow to scale children on DPI change
The native size of a QWindow on Windows is the logical size of the window
times the window's device pixel ratio. We manage this relationship
for top level windows via the WM_GETDPISCALEDSIZE message, and during
WM_DPICHANGED we then applied the same scale to child windows.
This is problematic in the case where a child window does not have
a QWindow parent, so instead of scaling all children when the parent
gets a WM_DPICHANGED message, we scale each individual child in the
child's WM_DPICHANGED_AFTERPARENT message.
Task-number: QTBUG-103383
Pick-to: 6.4
Change-Id: Ia0845aa19a3bb97b7bc9e7d9554ac02b95ca65a5
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 93519dc730..76060f45ee 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1966,7 +1966,6 @@ void QWindowsWindow::handleDpiScaledSize(WPARAM wParam, LPARAM lParam, LRESULT * void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam) { const UINT dpi = HIWORD(wParam); - const qreal scale = qreal(dpi) / qreal(savedDpi()); setSavedDpi(dpi); // Send screen change first, so that the new screen is set during any following resize @@ -1995,24 +1994,21 @@ void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam) prcNewWindow->right - prcNewWindow->left, prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE); } - - // Scale child QPlatformWindow size. Windows sends WM_DPICHANGE to top-level windows only. - for (QWindow *childWindow : window()->findChildren<QWindow *>()) { - QWindowsWindow *platformChildWindow = static_cast<QWindowsWindow *>(childWindow->handle()); - if (!platformChildWindow) - continue; - QRect currentGeometry = platformChildWindow->geometry(); - QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale); - platformChildWindow->setGeometry(scaledGeometry); - } } void QWindowsWindow::handleDpiChangedAfterParent(HWND hwnd) { - // FIXME: refactor, do we really need this? - setSavedDpi(GetDpiForWindow(hwnd)); + const UINT dpi = GetDpiForWindow(hwnd); + const qreal scale = qreal(dpi) / qreal(savedDpi()); + setSavedDpi(dpi); checkForScreenChanged(QWindowsWindow::FromDpiChange); + + // Child windows do not get WM_GETDPISCALEDSIZE messages to inform + // Windows about the new size, so we need to manually scale them. + QRect currentGeometry = geometry(); + QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale); + setGeometry(scaledGeometry); } static QRect normalFrameGeometry(HWND hwnd) |