diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index fe29627c5a..2364f465b6 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -127,6 +127,18 @@ QRect QPlatformWindow::geometry() const return d->rect; } +/*! + Returns the geometry of a window in 'normal' state + (neither maximized, fullscreen nor minimized) for saving geometries to + application settings. + + \since 5.3 +*/ +QRect QPlatformWindow::normalGeometry() const +{ + return QRect(); +} + QMargins QPlatformWindow::frameMargins() const { return QMargins(); diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 7dfbae036f..0adeb223f1 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -84,6 +84,7 @@ public: virtual void setGeometry(const QRect &rect); virtual QRect geometry() const; + virtual QRect normalGeometry() const; virtual QMargins frameMargins() const; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 5b6fced031..e9ab902966 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1234,6 +1234,28 @@ void QWindowsWindow::handleCompositionSettingsChanged() applyBlurBehindWindow(handle()); } +static QRect normalFrameGeometry(HWND hwnd) +{ +#ifndef Q_OS_WINCE + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + if (GetWindowPlacement(hwnd, &wp)) + return qrectFromRECT(wp.rcNormalPosition); +#else + Q_UNUSED(hwnd) +#endif + return QRect(); +} + +QRect QWindowsWindow::normalGeometry() const +{ + // Check for fake 'fullscreen' mode. + const bool fakeFullScreen = m_savedFrameGeometry.isValid() && window()->windowState() == Qt::WindowFullScreen; + const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd); + const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMargins(); + return frame.isValid() ? frame.marginsRemoved(margins) : frame; +} + void QWindowsWindow::setGeometry(const QRect &rectIn) { QRect rect = rectIn; @@ -1593,10 +1615,9 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) m_savedStyle = style(); #ifndef Q_OS_WINCE if (oldState == Qt::WindowMinimized) { - WINDOWPLACEMENT wp; - wp.length = sizeof(WINDOWPLACEMENT); - if (GetWindowPlacement(m_data.hwnd, &wp)) - m_savedFrameGeometry = qrectFromRECT(wp.rcNormalPosition); + const QRect nf = normalFrameGeometry(m_data.hwnd); + if (nf.isValid()) + m_savedFrameGeometry = nf; } else { #endif m_savedFrameGeometry = frameGeometry_sys(); diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 3a9516e0e5..99c5761a65 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -162,6 +162,7 @@ public: virtual QSurfaceFormat format() const { return m_format; } virtual void setGeometry(const QRect &rect); virtual QRect geometry() const { return m_data.geometry; } + QRect normalGeometry() const Q_DECL_OVERRIDE; virtual void setVisible(bool visible); bool isVisible() const; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index c7f8e18118..672c4156cd 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -547,6 +548,24 @@ void QWidgetWindow::updateGeometry() m_widget->data->fstrut_dirty = false; } +Qt::WindowState effectiveState(Qt::WindowStates state); + +// Store normal geometry used for saving application settings. +void QWidgetWindow::updateNormalGeometry() +{ + QTLWExtra *tle = m_widget->d_func()->maybeTopData(); + if (!tle) + return; + // Ask platform window, default to widget geometry. + QRect normalGeometry; + if (const QPlatformWindow *pw = handle()) + normalGeometry = pw->normalGeometry(); + if (!normalGeometry.isValid() && effectiveState(m_widget->windowState()) == Qt::WindowNoState) + normalGeometry = m_widget->geometry(); + if (normalGeometry.isValid()) + tle->normalGeometry = normalGeometry; +} + void QWidgetWindow::handleMoveEvent(QMoveEvent *event) { updateGeometry(); @@ -692,8 +711,6 @@ void QWidgetWindow::handleExposeEvent(QExposeEvent *event) } } -Qt::WindowState effectiveState(Qt::WindowStates state); - void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event) { // QWindow does currently not know 'active'. @@ -712,16 +729,12 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event widgetState |= Qt::WindowMinimized; break; case Qt::WindowMaximized: - if (effectiveState(widgetState) == Qt::WindowNoState) - if (QTLWExtra *tle = m_widget->d_func()->maybeTopData()) - tle->normalGeometry = m_widget->geometry(); + updateNormalGeometry(); widgetState |= Qt::WindowMaximized; widgetState &= ~(Qt::WindowMinimized | Qt::WindowFullScreen); break; case Qt::WindowFullScreen: - if (effectiveState(widgetState) == Qt::WindowNoState) - if (QTLWExtra *tle = m_widget->d_func()->maybeTopData()) - tle->normalGeometry = m_widget->geometry(); + updateNormalGeometry(); widgetState |= Qt::WindowFullScreen; widgetState &= ~(Qt::WindowMinimized); break; diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h index ffde44dd27..8d6f14a669 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa_p.h +++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h @@ -104,6 +104,7 @@ private slots: private: void updateGeometry(); + void updateNormalGeometry(); enum FocusWidgets { FirstFocusWidget,