diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 5aae1aafc50f62c69a1fdd65be74eb4d35d1984d..cac8ec5ecca04d3e693761f4156b9db8538b9f28 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1720,7 +1720,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) if (!m_savedStyle) { m_savedStyle = style(); #ifndef Q_OS_WINCE - if (oldState == Qt::WindowMinimized) { + if (oldState == Qt::WindowMinimized || oldState == Qt::WindowMaximized) { const QRect nf = normalFrameGeometry(m_data.hwnd); if (nf.isValid()) m_savedFrameGeometry = nf; @@ -1771,7 +1771,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) // preserve maximized state if (visible) { setFlag(WithinMaximize); - ShowWindow(m_data.hwnd, (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE); + ShowWindow(m_data.hwnd, (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA); clearFlag(WithinMaximize); } m_savedStyle = 0; diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 2219306b814690a10e752f5dd28423ad36d0b9d2..a89f0da4d27c01a345a475ebf7fcaffb83d797c3 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -95,6 +95,8 @@ private slots: void windowsTransientChildren(); void requestUpdate(); void initTestCase(); + void stateChange_data(); + void stateChange(); void cleanup(); private: @@ -272,6 +274,18 @@ static inline bool qFuzzyCompareWindowPosition(const QPoint &p1, const QPoint p2 return (p1 - p2).manhattanLength() <= fuzz; } +static inline bool qFuzzyCompareWindowSize(const QSize &s1, const QSize &s2, int fuzz) +{ + const int manhattanLength = qAbs(s1.width() - s2.width()) + qAbs(s1.height() - s2.height()); + return manhattanLength <= fuzz; +} + +static inline bool qFuzzyCompareWindowGeometry(const QRect &r1, const QRect &r2, int fuzz) +{ + return qFuzzyCompareWindowPosition(r1.topLeft(), r2.topLeft(), fuzz) + && qFuzzyCompareWindowSize(r1.size(), r2.size(), fuzz); +} + static QString msgPointMismatch(const QPoint &p1, const QPoint p2) { QString result; @@ -279,6 +293,13 @@ static QString msgPointMismatch(const QPoint &p1, const QPoint p2) return result; } +static QString msgRectMismatch(const QRect &r1, const QRect &r2) +{ + QString result; + QDebug(&result) << r1 << "!=" << r2; + return result; +} + void tst_QWindow::positioning() { if (!QGuiApplicationPrivate::platformIntegration()->hasCapability( @@ -394,6 +415,52 @@ void tst_QWindow::positioningDuringMinimized() QTRY_COMPARE(window.geometry(), newGeometry); } +// QTBUG-49709: Verify that the normal geometry is correctly restored +// when executing a sequence of window state changes. So far, Windows +// only where state changes have immediate effect. + +typedef QList<Qt::WindowState> WindowStateList; + +Q_DECLARE_METATYPE(WindowStateList) + +void tst_QWindow::stateChange_data() +{ + QTest::addColumn<WindowStateList>("stateSequence"); + + QTest::newRow("normal->min->normal") << + (WindowStateList() << Qt::WindowMinimized << Qt::WindowNoState); + QTest::newRow("normal->maximized->normal") << + (WindowStateList() << Qt::WindowMaximized << Qt::WindowNoState); + QTest::newRow("normal->fullscreen->normal") << + (WindowStateList() << Qt::WindowFullScreen << Qt::WindowNoState); + QTest::newRow("normal->maximized->fullscreen->normal") << + (WindowStateList() << Qt::WindowMaximized << Qt::WindowFullScreen << Qt::WindowNoState); +} + +void tst_QWindow::stateChange() +{ + QFETCH(WindowStateList, stateSequence); + + if (QGuiApplication::platformName().compare(QLatin1String("windows"), Qt::CaseInsensitive)) + QSKIP("Windows-only test"); + + Window window; + window.setTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag())); + const QRect normalGeometry(m_availableTopLeft + QPoint(40, 40), m_testWindowSize); + window.setGeometry(normalGeometry); + // explicitly use non-fullscreen show. show() can be fullscreen on some platforms + window.showNormal(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + foreach (Qt::WindowState state, stateSequence) { + window.setWindowState(state); + QCoreApplication::processEvents(); + } + const QRect geometry = window.geometry(); + const int fuzz = int(QHighDpiScaling::factor(&window)); + QVERIFY2(qFuzzyCompareWindowGeometry(geometry, normalGeometry, fuzz), + qPrintable(msgRectMismatch(geometry, normalGeometry))); +} + class PlatformWindowFilter : public QObject { Q_OBJECT