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 Pick-to: 6.5 Change-Id: I63c8dbc8f65ff28cc581be261acfd3f675b027c4 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> (cherry picked from commit 5f7b4c045f4347b9e47849d15d5932df45626c51) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit 2b18f6c7b837202c72bfc9346d1e8a4477388255)
This commit is contained in:
parent
57f02a814a
commit
19a473137a
@ -1014,6 +1014,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.
|
||||
@ -1026,7 +1041,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.
|
||||
@ -1042,15 +1057,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.
|
||||
@ -1068,7 +1081,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);
|
||||
@ -1082,8 +1095,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)));
|
||||
}
|
||||
@ -1092,7 +1103,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)) {
|
||||
@ -2029,7 +2040,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();
|
||||
}
|
||||
|
||||
@ -2745,7 +2756,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;
|
||||
@ -2764,7 +2775,7 @@ void QWindowsWindow::updateFullFrameMargins()
|
||||
|
||||
void QWindowsWindow::calculateFullFrameMargins()
|
||||
{
|
||||
if (m_data.flags & Qt::FramelessWindowHint)
|
||||
if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
|
||||
return;
|
||||
|
||||
// QTBUG-113736: systemMargins depends on AdjustWindowRectExForDpi. This doesn't take into
|
||||
@ -2815,7 +2826,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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user