summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYansheng Zhu <[email protected]>2023-12-21 12:27:49 +0800
committerQt Cherry-pick Bot <[email protected]>2023-12-22 03:27:25 +0000
commit27c8d61e9da3e2299bddb7cc3c4190477b12f4d2 (patch)
tree6ddff7cc3dcc2fa6fac3472c3241c0bb977d3375
parent640518d3448abb0d06647274041bc95c8e4af4b7 (diff)
Fix Maximized frameless window painting wrong with WS_THICKFRAME
In Qt versions greater than 6.4.2, when using Qt:FramelessWindowHint and WS_THICKFRAME simultaneously, and handling the WM_NCCALCSIZE message to draw a frameless window, the right and bottom sides may extend beyond the drawable boundaries. This is because in the previous commits, the calculation for margins was skipped for windows with Qt:FramelessWindowHint set. This is correct for non-maximized windows. However, when a window is maximized on Windows, its actual size is slightly larger than the drawable area to avoid users from dragging the border to resize the window. When window was maximized , the code for calculating geometry should remove the margins instead of skipping its calculation. The fixed code determines whether to skip the calculation of margins and frame by checking whether the window is maximized during the calculation [ChangeLog][QPA][Windows] Adding a check for the maximized state of the window during the calculation of margins. Margins calculation will not be skipped for maximized windows. Task-number: QTBUG-120196 Change-Id: I63c8dbc8f65ff28cc581be261acfd3f675b027c4 Reviewed-by: Oliver Wolff <[email protected]> (cherry picked from commit 5f7b4c045f4347b9e47849d15d5932df45626c51) Reviewed-by: Qt Cherry-pick Bot <[email protected]> (cherry picked from commit 2b18f6c7b837202c72bfc9346d1e8a4477388255) (cherry picked from commit 19a473137a38372e7563ba339c957e07903ec596)
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 654fb0edf68..77803d076d0 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1021,6 +1021,21 @@ static QSize toNativeSizeConstrained(QSize dip, const QScreen *s)
return dip;
}
+// Helper for checking if frame adjustment needs to be skipped
+// NOTE: Unmaximized frameless windows will skip margins calculation
+static bool shouldOmitFrameAdjustment(const Qt::WindowFlags flags, DWORD style)
+{
+ return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
+}
+
+// Helper for checking if frame adjustment needs to be skipped
+// NOTE: Unmaximized frameless windows will skip margins calculation
+static bool shouldOmitFrameAdjustment(const Qt::WindowFlags flags, HWND hwnd)
+{
+ DWORD style = hwnd != nullptr ? DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)) : 0;
+ return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
+}
+
/*!
\class QWindowsGeometryHint
\brief Stores geometry constraints and provides utility functions.
@@ -1033,7 +1048,7 @@ static QSize toNativeSizeConstrained(QSize dip, const QScreen *s)
QMargins QWindowsGeometryHint::frameOnPrimaryScreen(const QWindow *w, DWORD style, DWORD exStyle)
{
- if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
+ if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
return {};
RECT rect = {0,0,0,0};
style &= ~DWORD(WS_OVERLAPPED); // Not permitted, see docs.
@@ -1049,15 +1064,13 @@ QMargins QWindowsGeometryHint::frameOnPrimaryScreen(const QWindow *w, DWORD styl
QMargins QWindowsGeometryHint::frameOnPrimaryScreen(const QWindow *w, HWND hwnd)
{
- if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
- return {};
return frameOnPrimaryScreen(w, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
}
QMargins QWindowsGeometryHint::frame(const QWindow *w, DWORD style, DWORD exStyle, qreal dpi)
{
- if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
+ if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
return {};
RECT rect = {0,0,0,0};
style &= ~DWORD(WS_OVERLAPPED); // Not permitted, see docs.
@@ -1075,7 +1088,7 @@ QMargins QWindowsGeometryHint::frame(const QWindow *w, DWORD style, DWORD exStyl
QMargins QWindowsGeometryHint::frame(const QWindow *w, HWND hwnd, DWORD style, DWORD exStyle)
{
- if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
+ if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
return {};
if (QWindowsScreenManager::isSingleScreen())
return frameOnPrimaryScreen(w, style, exStyle);
@@ -1089,8 +1102,6 @@ QMargins QWindowsGeometryHint::frame(const QWindow *w, HWND hwnd, DWORD style, D
QMargins QWindowsGeometryHint::frame(const QWindow *w, HWND hwnd)
{
- if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
- return {};
return frame(w, hwnd, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
}
@@ -1099,7 +1110,7 @@ QMargins QWindowsGeometryHint::frame(const QWindow *w, HWND hwnd)
QMargins QWindowsGeometryHint::frame(const QWindow *w, const QRect &geometry,
DWORD style, DWORD exStyle)
{
- if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
+ if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
return {};
if (QWindowsScreenManager::isSingleScreen()
|| !QWindowsContext::shouldHaveNonClientDpiScaling(w)) {
@@ -2036,7 +2047,7 @@ void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
// If the window does not have a frame, WM_MOVE and WM_SIZE won't be
// called which prevents the content from being scaled appropriately
// after a DPI change.
- if (m_data.flags & Qt::FramelessWindowHint)
+ if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
handleGeometryChange();
}
@@ -2752,7 +2763,7 @@ bool QWindowsWindow::handleGeometryChanging(MSG *message) const
void QWindowsWindow::setFullFrameMargins(const QMargins &newMargins)
{
- if (m_data.flags & Qt::FramelessWindowHint)
+ if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
return;
if (m_data.fullFrameMargins != newMargins) {
qCDebug(lcQpaWindow) << __FUNCTION__ << window() << m_data.fullFrameMargins << "->" << newMargins;
@@ -2771,7 +2782,7 @@ void QWindowsWindow::updateFullFrameMargins()
void QWindowsWindow::calculateFullFrameMargins()
{
- if (m_data.flags & Qt::FramelessWindowHint)
+ if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
return;
// Normally obtained from WM_NCCALCSIZE. This calculation only works
// when no native menu is present.
@@ -2813,7 +2824,7 @@ QMargins QWindowsWindow::frameMargins() const
QMargins QWindowsWindow::fullFrameMargins() const
{
- if (m_data.flags & Qt::FramelessWindowHint)
+ if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
return {};
return m_data.fullFrameMargins;
}