diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowswindow.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 132 |
1 files changed, 74 insertions, 58 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index b5522c1f90..04db975360 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -114,6 +114,35 @@ static QByteArray debugWinExStyle(DWORD exStyle) return rc; } +static QByteArray debugWinSwpPos(UINT flags) +{ + QByteArray rc = "0x"; + rc += QByteArray::number(flags, 16); + if (flags & SWP_FRAMECHANGED) + rc += " SWP_FRAMECHANGED"; + if (flags & SWP_HIDEWINDOW) + rc += " SWP_HIDEWINDOW"; + if (flags & SWP_NOACTIVATE) + rc += " SWP_NOACTIVATE"; + if (flags & SWP_NOCOPYBITS) + rc += " SWP_NOCOPYBITS"; + if (flags & SWP_NOMOVE) + rc += " SWP_NOMOVE"; + if (flags & SWP_NOOWNERZORDER) + rc += " SWP_NOOWNERZORDER"; + if (flags & SWP_NOREDRAW) + rc += " SWP_NOREDRAW"; + if (flags & SWP_NOSENDCHANGING) + rc += " SWP_NOSENDCHANGING"; + if (flags & SWP_NOSIZE) + rc += " SWP_NOSIZE"; + if (flags & SWP_NOZORDER) + rc += " SWP_NOZORDER"; + if (flags & SWP_SHOWWINDOW) + rc += " SWP_SHOWWINDOW"; + return rc; +} + static inline QSize qSizeOfRect(const RECT &rect) { return QSize(rect.right -rect.left, rect.bottom - rect.top); @@ -137,8 +166,9 @@ QDebug operator<<(QDebug d, const RECT &r) { QDebugStateSaver saver(d); d.nospace(); - d << "RECT: left/top=" << r.left << ',' << r.top - << " right/bottom=" << r.right << ',' << r.bottom; + d << "RECT(left=" << r.left << ", top=" << r.top + << ", right=" << r.right << ", bottom=" << r.bottom + << " (" << r.right - r.left << 'x' << r.bottom - r.top << "))"; return d; } @@ -148,12 +178,23 @@ QDebug operator<<(QDebug d, const POINT &p) return d; } +QDebug operator<<(QDebug d, const WINDOWPOS &wp) +{ + QDebugStateSaver saver(d); + d.nospace(); + d.noquote(); + d << "WINDOWPOS(flags=" << debugWinSwpPos(wp.flags) << ", hwnd=" + << wp.hwnd << ", hwndInsertAfter=" << wp.hwndInsertAfter << ", x=" << wp.x + << ", y=" << wp.y << ", cx=" << wp.cx << ", cy=" << wp.cy << ')'; + return d; +} + QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p) { QDebugStateSaver saver(d); d.nospace(); - d << "NCCALCSIZE_PARAMS " << qrectFromRECT(p.rgrc[0]) - << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' << qrectFromRECT(p.rgrc[2]); + d << "NCCALCSIZE_PARAMS(rgrc=[" << p.rgrc[0] << ' ' << p.rgrc[1] << ' ' + << p.rgrc[2] << "], lppos=" << *p.lppos << ')'; return d; } @@ -173,6 +214,7 @@ QDebug operator<<(QDebug d, const WINDOWPLACEMENT &wp) { QDebugStateSaver saver(d); d.nospace(); + d.noquote(); d << "WINDOWPLACEMENT(flags=0x" << hex << wp.flags << dec << ", showCmd=" << wp.showCmd << ", ptMinPosition=" << wp.ptMinPosition << ", ptMaxPosition=" << wp.ptMaxPosition << ", rcNormalPosition=" << wp.rcNormalPosition; @@ -935,9 +977,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, DWORD style_, DWORD exStyle_) : geometryHint(w, cm), window(w), style(style_), exStyle(exStyle_), requestedGeometry(geometry), obtainedGeometry(geometry), - margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm), - frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT), - frameWidth(CW_USEDEFAULT), frameHeight(CW_USEDEFAULT) + margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm) { // Geometry of toplevels does not consider window frames. // TODO: No concept of WA_wasMoved yet that would indicate a @@ -990,17 +1030,8 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) : QWindowsBaseWindow(aWindow), m_data(data), - m_flags(WithinCreate), - m_hdc(0), - m_windowState(Qt::WindowNoState), - m_opacity(1.0), m_cursor(new CursorHandle), - m_dropTarget(0), - m_savedStyle(0), - m_format(aWindow->requestedFormat()), - m_iconSmall(0), - m_iconBig(0), - m_surface(0) + m_format(aWindow->requestedFormat()) { // Clear the creation context as the window can be found in QWindowsContext's map. QWindowsContext::instance()->setWindowCreationContext(QSharedPointer<QWindowCreationContext>()); @@ -1212,18 +1243,14 @@ bool QWindowsWindow::isActive() const return false; } -bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const +bool QWindowsWindow::isAncestorOf(const QPlatformWindow *child) const { - if (parentWindow) { - const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(parentWindow); - const HWND hwnd = ww->handle(); - if (!IsChild(hwnd, m_data.hwnd)) - return false; - } - - if (!m_data.embedded && parent()) - return parent()->isEmbedded(); + const QWindowsWindow *childWindow = static_cast<const QWindowsWindow *>(child); + return IsChild(m_data.hwnd, childWindow->handle()); +} +bool QWindowsWindow::isEmbedded() const +{ return m_data.embedded; } @@ -1467,18 +1494,22 @@ void QWindowsWindow::handleResized(int wParam) case SIZE_MAXHIDE: // Some other window affected. case SIZE_MAXSHOW: return; - case SIZE_MINIMIZED: - handleWindowStateChange(Qt::WindowMinimized); + case SIZE_MINIMIZED: // QTBUG-53577, prevent state change events during programmatic state change + if (!testFlag(WithinSetStyle)) + handleWindowStateChange(Qt::WindowMinimized); return; case SIZE_MAXIMIZED: - handleWindowStateChange(Qt::WindowMaximized); + if (!testFlag(WithinSetStyle)) + handleWindowStateChange(Qt::WindowMaximized); handleGeometryChange(); break; case SIZE_RESTORED: - if (isFullScreen_sys()) - handleWindowStateChange(Qt::WindowFullScreen); - else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen)) - handleWindowStateChange(Qt::WindowNoState); + if (!testFlag(WithinSetStyle)) { + if (isFullScreen_sys()) + handleWindowStateChange(Qt::WindowFullScreen); + else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen)) + handleWindowStateChange(Qt::WindowNoState); + } handleGeometryChange(); break; } @@ -1486,9 +1517,6 @@ void QWindowsWindow::handleResized(int wParam) void QWindowsWindow::handleGeometryChange() { - //Prevent recursive resizes for Windows CE - if (testFlag(WithinSetStyle)) - return; const QRect previousGeometry = m_data.geometry; m_data.geometry = geometry_sys(); QPlatformWindow::setGeometry(m_data.geometry); @@ -1655,7 +1683,6 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt, QWindowsWindowData result = m_data; result.flags = creationData.flags; result.embedded = creationData.embedded; - setFlag(FrameDirty); return result; } @@ -1663,7 +1690,6 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) { qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << "\n from " << m_windowState << " to " << state; - setFlag(FrameDirty); m_windowState = state; QWindowSystemInterface::handleWindowStateChanged(window(), state); switch (state) { @@ -1740,8 +1766,6 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) const bool visible = isVisible(); - setFlag(FrameDirty); - if ((oldState == Qt::WindowFullScreen) != (newState == Qt::WindowFullScreen)) { if (newState == Qt::WindowFullScreen) { #ifndef Q_FLATTEN_EXPOSE @@ -1835,7 +1859,6 @@ void QWindowsWindow::setStyle(unsigned s) const { qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << debugWinStyle(s); setFlag(WithinSetStyle); - setFlag(FrameDirty); SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s); clearFlag(WithinSetStyle); } @@ -1844,7 +1867,6 @@ void QWindowsWindow::setExStyle(unsigned s) const { qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << this << ' ' << window() << " 0x" << QByteArray::number(s, 16); - setFlag(FrameDirty); SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s); } @@ -1900,22 +1922,17 @@ bool QWindowsWindow::handleGeometryChanging(MSG *message) const return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins); } -QMargins QWindowsWindow::frameMargins() const +void QWindowsWindow::setFrameMargins(const QMargins &newMargins) { - // Frames are invalidated by style changes (window state, flags). - // As they are also required for geometry calculations in resize - // event sequences, introduce a dirty flag mechanism to be able - // to cache results. - if (testFlag(FrameDirty)) { - // Always skip calculating style-dependent margins for windows claimed to be frameless. - // This allows users to remove the margins by handling WM_NCCALCSIZE with WS_THICKFRAME set - // to ensure Areo snap still works (QTBUG-40578). - m_data.frame = m_data.flags & Qt::FramelessWindowHint - ? QMargins(0, 0, 0, 0) - : QWindowsGeometryHint::frame(style(), exStyle()); - clearFlag(FrameDirty); + if (m_data.frame != newMargins) { + qCDebug(lcQpaWindows) << __FUNCTION__ << window() << m_data.frame << "->" << newMargins; + m_data.frame = newMargins; } - return m_data.frame + m_data.customMargins; +} + +QMargins QWindowsWindow::frameMargins() const +{ + return m_data.frame; } void QWindowsWindow::setOpacity(qreal level) @@ -2331,7 +2348,6 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins) const QPoint topLeft = currentFrameGeometry.topLeft(); QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins; newFrame.moveTo(topLeft); - setFlag(FrameDirty); qCDebug(lcQpaWindows) << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins << currentFrameGeometry << "->" << newFrame; SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED); |