Revert "Update window state in QWindowsWindow and QXcbWindow geometry setters"

This reverts commit 99c8ffb9f259760e45618f0988bbd79237d6d291. It fixed
QTBUG-104201, which in essence pointed out a state mismatch between
widgets and platform windows on Linux (X11 and wayland). Mismatches
occurred in the margins between calls to QWidget and async screen
rendering: While the widget layer reported the expected size, the
platform layer did so only after the rendering thread had finished.

As mentioned in the comments of QTBUG-104201, the state mismatch is
predictable, temporary and consistent.

By bridging the time gab, an async operation was made to look
synchronous. That gave more comfort to application developers. By
oversight, it broke code that relied on the platform window state
reflecting physical rendering. This has caused QTBUG-126479 as a
regression.

Both purposes can't be served at the same time: The platform window
state either reflects rendering, or the expected state. It's therefore
justified to revert.

Reason for revert: <Causes QTBUG-126479>

Pick-to: 6.7 6.5
Fixes: QTBUG-126479
Task-number: QTBUG-104201
Change-Id: I22380a6a463822a1cb4be90a44d2775954c7ca82
Reviewed-by: Liang Qi <liang.qi@qt.io>
(cherry picked from commit 7d7be38d95eb82ef3e0be5250440072d8b5bc4b2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Axel Spoerl 2024-07-10 12:10:39 +00:00 committed by Qt Cherry-pick Bot
parent 35562e8e0a
commit 678dccb7ac
3 changed files with 0 additions and 120 deletions

View File

@ -2152,12 +2152,8 @@ void QWindowsWindow::setGeometry(const QRect &rectIn)
const QMargins margins = frameMargins();
rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top()));
}
if (m_windowState & Qt::WindowMinimized)
m_data.geometry = rect; // Otherwise set by handleGeometryChange() triggered by event.
else
setWindowState(Qt::WindowNoState);// Update window state to WindowNoState unless minimized
if (m_data.hwnd) {
// A ResizeEvent with resulting geometry will be sent. If we cannot
// achieve that size (for example, window title minimal constraint),

View File

@ -573,8 +573,6 @@ void QXcbWindow::destroy()
void QXcbWindow::setGeometry(const QRect &rect)
{
setWindowState(Qt::WindowNoState);
QPlatformWindow::setGeometry(rect);
propagateSizeHints();

View File

@ -216,7 +216,6 @@ private slots:
void reparent();
void setScreen();
void windowState();
void resizePropagation();
void showMaximized();
void showFullScreen();
void showMinimized();
@ -3172,119 +3171,6 @@ void tst_QWidget::windowState()
QTRY_COMPARE(widget1.size(), size);
}
// Test propagation of size and state from platform window to QWidget
// Windows and linux/XCB only
void tst_QWidget::resizePropagation()
{
#if !defined(Q_OS_LINUX) && !defined(Q_OS_WIN)
QSKIP("resizePropagation test is designed for Linux/XCB and Windows only");
#endif
const bool xcb = (m_platform == QStringLiteral("xcb"));
#ifdef Q_OS_LINUX
if (!xcb)
QSKIP("resizePropagation test is designed for XCB only");
#endif
// Windows:
// When a widget is maximized after it has been resized, the widget retains its original size,
// while the window shows maximum size.
// windowStateChanged signal gets fired on a no-op change from/to WindowNoState
// Initialize widget and signal spy for window handle
QWidget widget;
widget.showMaximized();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
QWindow *window = widget.windowHandle();
QTRY_VERIFY(window);
QSignalSpy spy(window, &QWindow::windowStateChanged);
int count = 0;
const QSize screenSize = QGuiApplication::primaryScreen()->size();
const QSize size1 = QSize(screenSize.width() * 0.5, screenSize.height() * 0.5);
const QSize size2 = QSize(screenSize.width() * 0.625, screenSize.height() * 0.833);
enum CountIncrementCheck {Equal, Greater};
enum TargetSizeCheck {Fail, Warn};
auto verifyResize = [&](const QSize &size, Qt::WindowState windowState,
CountIncrementCheck checkCountIncrement,
TargetSizeCheck checkTargetSize)
{
// Capture count of latest async signals
if (checkCountIncrement == Equal)
count = spy.count();
// Resize if required
if (size.isValid())
widget.resize(size);
// Wait for the widget anyway
QVERIFY(QTest::qWaitForWindowExposed(&widget));
// Check signal count and qDebug output for fail analysis
switch (checkCountIncrement) {
case Greater: {
auto logger = qScopeGuard([&](){
qDebug() << "spy count:" << spy.count() << "previous count:" << count;
});
QTRY_VERIFY(spy.count() > count);
logger.dismiss();
count = spy.count();
}
break;
case Equal: {
auto logger = qScopeGuard([&](){
qDebug() << spy << widget.windowState() << window->windowState();
});
QCOMPARE(spy.count(), count);
logger.dismiss();
}
break;
}
// QTRY necessary because state changes are propagated async
QTRY_COMPARE(widget.windowState(), windowState);
QTRY_COMPARE(window->windowState(), windowState);
// Check target size with fail or warning
switch (checkTargetSize) {
case Fail:
QCOMPARE(widget.size(), window->size());
break;
case Warn:
if (widget.size() != window->size()) {
qWarning() << m_platform << "size mismtach tolerated. Widget:"
<< widget.size() << "Window:" << window->size();
}
break;
}
};
// test state and size consistency of maximized window
verifyResize(QSize(), Qt::WindowMaximized, Equal, Fail);
if (QTest::currentTestFailed())
return;
// test state transition, state and size consistency after resize
verifyResize(size1, Qt::WindowNoState, Greater, xcb ? Warn : Fail );
if (QTest::currentTestFailed())
return;
// test unchanged state, state and size consistency after resize
verifyResize(size2, Qt::WindowNoState, Equal, xcb ? Warn : Fail);
if (QTest::currentTestFailed())
return;
// test state transition, state and size consistency after maximize
widget.showMaximized();
verifyResize(QSize(), Qt::WindowMaximized, Greater, xcb ? Fail : Warn);
if (QTest::currentTestFailed())
return;
#ifdef Q_OS_WIN
QCOMPARE(widget.size(), size2);
#endif
}
void tst_QWidget::showMaximized()
{
QWidget plain;