From 59d77a0162d92a9993b7bb4c593e88cbb8f8d9c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 9 Apr 2025 11:37:13 +0200 Subject: [PATCH] Disable {position,resize}Automatic on QPlatformWindow creation Once the platform window has been created it has had its chance to set a default position and size, which is reflected back to the QWindow. Destroying and recreating the window after that should keep the position and size, even when those have been changed by the end user via the system's window manager. We were effectively doing this for size already, as initialGeomery only applied a default size if the size was 0x0, but we were failing to preserve the position. We now handle both cases explicitly. [ChangeLog][QtGui] A destroyed and recreated QWindow will now maintain its position and size, instead of allowing the platform window another chance at setting a default position and size. Users of QWindow and its consumers that reuses a single window for many "logical" windows need to explicitly position and size the window for each "use". Change-Id: Ib9a395295e6dfdc6db908e2c96be60046f462c30 Reviewed-by: Liang Qi --- src/gui/kernel/qwindow.cpp | 6 ++++ tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 8b7cfd231bc..b389cee4b35 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -584,6 +584,12 @@ void QWindowPrivate::create(bool recursive) platformWindow->initialize(); + // Now that the window is created and initialized the platform has had + // a chance to position and size it automatically. From this point on + // we want the window to keep its geometry, even when recreated. + positionAutomatic = false; + resizeAutomatic = false; + QObjectList childObjects = q->children(); for (int i = 0; i < childObjects.size(); i ++) { QObject *object = childObjects.at(i); diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 4c826a1db9e..3e9538b1130 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -48,6 +48,7 @@ private slots: void framePositioning(); void framePositioning_data(); void framePositioningStableAfterDestroy(); + void geometryAfterWmUpdateAndDestroyCreate(); void positioningDuringMinimized(); void childWindowPositioning_data(); void childWindowPositioning(); @@ -692,6 +693,33 @@ void tst_QWindow::framePositioningStableAfterDestroy() QTRY_COMPARE(window.framePosition(), stableFramePosition); } +void tst_QWindow::geometryAfterWmUpdateAndDestroyCreate() +{ + QWindow window; + window.setFlag(Qt::FramelessWindowHint); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + if (window.windowState() != Qt::WindowNoState) + QSKIP("Default window state is not Qt::WindowNoState"); + + const QRect geometryAfterShow = window.geometry(); + + // Check that the geometry is retained for create/destroy/create, + // if the user has moved and resized the window via the window-manager + // (i.e. no explicit setGeometry calls from user code). + QRect modifiedGeometry = geometryAfterShow.translated(42, 42); + modifiedGeometry.setSize(modifiedGeometry.size() + QSize(42, 42)); + QWindowSystemInterface::handleGeometryChange( + &window, modifiedGeometry); + + window.destroy(); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QTRY_COMPARE(window.geometry(), modifiedGeometry); +} + void tst_QWindow::positioningDuringMinimized() { // QTBUG-39544, setting a geometry in minimized state should work as well.