diff options
author | Viktor Arvidsson <viktor.arvidss@gmail.com> | 2022-01-31 19:14:04 +0100 |
---|---|---|
committer | Viktor Arvidsson <viktor.arvidss@gmail.com> | 2022-02-22 18:03:11 +0000 |
commit | cfe421cee2d4f56180280ecd9da8c3da6a980b84 (patch) | |
tree | 4853169b28b53cacba419153d52483fff509633e /src/plugins/platforms/windows/qwindowswindow.cpp | |
parent | d48609a9c41643d6fdb0a964fa3209fe1a175a11 (diff) |
Windows QPA: Calculate window frame for frameless windows the same for all code paths
When we add the WS_THICKFRAME/WS_CAPTION window flags to a
frameless window the return value of AdjustWindowRectEx is no
longer 0. This works fine when creating the window since the version
of QWindowsGeometryHint::frame used during creation checks the
FramelessWindowHint, however later when the window changes
screen, the screen change code checks the fullFrameMargins which
uses a version of QWindowsGeometryHint::frame that does not
early out, causing a missmatch in the geometries of the backing
store and platform window.
This fixes aero snapping shortcuts for frameless windows on multi
monitor setups.
Fixes: QTBUG-84466
Pick-to: 6.2 6.3
Change-Id: I2357ea32669e4676645549996a3ac6073f3df15c
Reviewed-by: André de la Rocha <andre.rocha@qt.io>
Diffstat (limited to 'src/plugins/platforms/windows/qwindowswindow.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 6db4eb3d5b..43297b6aeb 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -978,8 +978,10 @@ static QSize toNativeSizeConstrained(QSize dip, const QScreen *s) \internal */ -QMargins QWindowsGeometryHint::frameOnPrimaryScreen(DWORD style, DWORD exStyle) +QMargins QWindowsGeometryHint::frameOnPrimaryScreen(const QWindow *w, DWORD style, DWORD exStyle) { + if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint)) + return {}; RECT rect = {0,0,0,0}; style &= ~DWORD(WS_OVERLAPPED); // Not permitted, see docs. if (AdjustWindowRectEx(&rect, style, FALSE, exStyle) == FALSE) @@ -992,14 +994,16 @@ QMargins QWindowsGeometryHint::frameOnPrimaryScreen(DWORD style, DWORD exStyle) return result; } -QMargins QWindowsGeometryHint::frameOnPrimaryScreen(HWND hwnd) +QMargins QWindowsGeometryHint::frameOnPrimaryScreen(const QWindow *w, HWND hwnd) { - return frameOnPrimaryScreen(DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)), + return frameOnPrimaryScreen(w, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)), DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE))); } -QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle, qreal dpi) +QMargins QWindowsGeometryHint::frame(const QWindow *w, DWORD style, DWORD exStyle, qreal dpi) { + if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint)) + return {}; RECT rect = {0,0,0,0}; style &= ~DWORD(WS_OVERLAPPED); // Not permitted, see docs. if (AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, unsigned(qRound(dpi))) == FALSE) { @@ -1014,16 +1018,18 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle, qreal dpi) return result; } -QMargins QWindowsGeometryHint::frame(HWND hwnd, DWORD style, DWORD exStyle) +QMargins QWindowsGeometryHint::frame(const QWindow *w, HWND hwnd, DWORD style, DWORD exStyle) { + if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint)) + return {}; if (QWindowsScreenManager::isSingleScreen()) - return frameOnPrimaryScreen(style, exStyle); + return frameOnPrimaryScreen(w, style, exStyle); auto screenManager = QWindowsContext::instance()->screenManager(); auto screen = screenManager.screenForHwnd(hwnd); if (!screen) screen = screenManager.screens().value(0); const auto dpi = screen ? screen->logicalDpi().first : qreal(96); - return frame(style, exStyle, dpi); + return frame(w, style, exStyle, dpi); } // For newly created windows. @@ -1034,7 +1040,7 @@ QMargins QWindowsGeometryHint::frame(const QWindow *w, const QRect &geometry, return {}; if (QWindowsScreenManager::isSingleScreen() || !QWindowsContext::shouldHaveNonClientDpiScaling(w)) { - return frameOnPrimaryScreen(style, exStyle); + return frameOnPrimaryScreen(w, style, exStyle); } qreal dpi = 96; auto screenManager = QWindowsContext::instance()->screenManager(); @@ -1043,7 +1049,7 @@ QMargins QWindowsGeometryHint::frame(const QWindow *w, const QRect &geometry, screen = screenManager.screens().value(0); if (screen) dpi = screen->logicalDpi().first; - return QWindowsGeometryHint::frame(style, exStyle, dpi); + return QWindowsGeometryHint::frame(w, style, exStyle, dpi); } bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, const MSG &msg, LRESULT *result) @@ -1181,7 +1187,7 @@ QRect QWindowsBaseWindow::geometry_sys() const QMargins QWindowsBaseWindow::frameMargins_sys() const { - return QWindowsGeometryHint::frame(handle(), style(), exStyle()); + return QWindowsGeometryHint::frame(window(), handle(), style(), exStyle()); } std::optional<QWindowsBaseWindow::TouchWindowTouchTypes> @@ -1906,7 +1912,7 @@ void QWindowsWindow::handleDpiScaledSize(WPARAM wParam, LPARAM lParam, LRESULT * const int dpi = int(wParam); const qreal scale = QHighDpiScaling::roundScaleFactor(qreal(dpi) / QWindowsScreen::baseDpi) / QHighDpiScaling::roundScaleFactor(qreal(savedDpi()) / QWindowsScreen::baseDpi); - const QMargins margins = QWindowsGeometryHint::frame(style(), exStyle(), dpi); + const QMargins margins = QWindowsGeometryHint::frame(window(), style(), exStyle(), dpi); const QSize windowSize = (geometry().size() * scale).grownBy(margins); SIZE *size = reinterpret_cast<SIZE *>(lParam); size->cx = windowSize.width(); @@ -1976,7 +1982,7 @@ QRect QWindowsWindow::normalGeometry() const m_savedFrameGeometry.isValid() && (window()->windowStates() & Qt::WindowFullScreen); const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd); const QMargins margins = fakeFullScreen - ? QWindowsGeometryHint::frame(handle(), m_savedStyle, 0) + ? QWindowsGeometryHint::frame(window(), handle(), m_savedStyle, 0) : fullFrameMargins(); return frame.isValid() ? frame.marginsRemoved(margins) : frame; } @@ -2611,7 +2617,7 @@ void QWindowsWindow::calculateFullFrameMargins() // Normally obtained from WM_NCCALCSIZE. This calculation only works // when no native menu is present. const auto systemMargins = testFlag(DisableNonClientScaling) - ? QWindowsGeometryHint::frameOnPrimaryScreen(m_data.hwnd) + ? QWindowsGeometryHint::frameOnPrimaryScreen(window(), m_data.hwnd) : frameMargins_sys(); setFullFrameMargins(systemMargins + m_data.customMargins); } |