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 <liang.qi@qt.io>
This commit is contained in:
Tor Arne Vestbø 2025-04-09 11:37:13 +02:00
parent 2471115715
commit 59d77a0162
2 changed files with 34 additions and 0 deletions

View File

@ -584,6 +584,12 @@ void QWindowPrivate::create(bool recursive)
platformWindow->initialize(); 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(); QObjectList childObjects = q->children();
for (int i = 0; i < childObjects.size(); i ++) { for (int i = 0; i < childObjects.size(); i ++) {
QObject *object = childObjects.at(i); QObject *object = childObjects.at(i);

View File

@ -48,6 +48,7 @@ private slots:
void framePositioning(); void framePositioning();
void framePositioning_data(); void framePositioning_data();
void framePositioningStableAfterDestroy(); void framePositioningStableAfterDestroy();
void geometryAfterWmUpdateAndDestroyCreate();
void positioningDuringMinimized(); void positioningDuringMinimized();
void childWindowPositioning_data(); void childWindowPositioning_data();
void childWindowPositioning(); void childWindowPositioning();
@ -692,6 +693,33 @@ void tst_QWindow::framePositioningStableAfterDestroy()
QTRY_COMPARE(window.framePosition(), stableFramePosition); 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<QWindowSystemInterface::SynchronousDelivery>(
&window, modifiedGeometry);
window.destroy();
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
QTRY_COMPARE(window.geometry(), modifiedGeometry);
}
void tst_QWindow::positioningDuringMinimized() void tst_QWindow::positioningDuringMinimized()
{ {
// QTBUG-39544, setting a geometry in minimized state should work as well. // QTBUG-39544, setting a geometry in minimized state should work as well.