Stabilize tst_QWidget::optimizedResizeMove and optimizedResize_topLevel
The test functions tst_QWidget::optimizedResizeMove and tst_QWidget::optimizedResize_topLevel use a custom widget to record paint events in a boolean. Using QTRY_* or qWait() to wait for the boolean to become true stops event processing upon consumption of the first paint event. In case of multiple paint events, the next paint event will be recorded in the next check and may lead to a wrong result. This leads to flakiness on platforms generating multiple paint events, openSuSE Leap 15.4 / XCB being one of them. This patch replaces the boolean with a counter. It adds a waitForPaintEvents method to the custom class, which processes events, until the counter stops increasing. It returns true when paint events have been recorded and false otherwise. It resets the counter after each call. It also removes the QSKIP on wayland, as the failure results from the same reason. Fixes: QTBUG-109093 Change-Id: I59ee8bb4efeaf5417d5749d21e384bee89301ae0 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 2ec7a6322f465ad7cce3c48096d8912903196ab2) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
d95b21706f
commit
761bd30d7d
@ -4490,22 +4490,20 @@ class StaticWidget : public QWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
bool partial = false;
|
||||
bool gotPaintEvent = false;
|
||||
QRegion paintedRegion;
|
||||
|
||||
explicit StaticWidget(QWidget *parent = nullptr) : QWidget(parent)
|
||||
explicit StaticWidget(const QPalette &palette, QWidget *parent = nullptr) : QWidget(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_StaticContents);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
setPalette(Qt::red); // Make sure we have an opaque palette.
|
||||
setPalette(palette);
|
||||
setAutoFillBackground(true);
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent *e) override
|
||||
{
|
||||
paintedRegion += e->region();
|
||||
gotPaintEvent = true;
|
||||
// qDebug() << "paint" << e->region();
|
||||
++paintEvents;
|
||||
// Look for a full update, set partial to false if found.
|
||||
for (QRect r : e->region()) {
|
||||
partial = (r != rect());
|
||||
@ -4513,6 +4511,28 @@ public:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait timeout ms until at least one paint event has been consumed
|
||||
// and the counter is no longer increasing.
|
||||
// => making sure to consume multiple paint events relating to one operation
|
||||
// before returning true.
|
||||
bool waitForPaintEvent(int timeout = 100)
|
||||
{
|
||||
QDeadlineTimer deadline(timeout);
|
||||
int count = -1;
|
||||
while (!deadline.hasExpired() && count != paintEvents) {
|
||||
count = paintEvents;
|
||||
QCoreApplication::processEvents();
|
||||
if (count == paintEvents && count > 0) {
|
||||
paintEvents = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
paintEvents = 0;
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
int paintEvents = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -4521,102 +4541,75 @@ public:
|
||||
*/
|
||||
void tst_QWidget::optimizedResizeMove()
|
||||
{
|
||||
if (m_platform == QStringLiteral("wayland"))
|
||||
QSKIP("Wayland: This fails. Figure out why.");
|
||||
QWidget parent;
|
||||
parent.setPalette(simplePalette());
|
||||
parent.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
parent.setWindowTitle(QTest::currentTestFunction());
|
||||
parent.resize(400, 400);
|
||||
|
||||
StaticWidget staticWidget(&parent);
|
||||
staticWidget.setPalette(simplePalette());
|
||||
staticWidget.gotPaintEvent = false;
|
||||
StaticWidget staticWidget(simplePalette(), &parent);
|
||||
staticWidget.move(150, 150);
|
||||
staticWidget.resize(150, 150);
|
||||
parent.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&parent));
|
||||
QTRY_VERIFY(staticWidget.gotPaintEvent);
|
||||
QVERIFY(staticWidget.waitForPaintEvent());
|
||||
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.move(staticWidget.pos() + QPoint(10, 10));
|
||||
QTest::qWait(20);
|
||||
QCOMPARE(staticWidget.gotPaintEvent, false);
|
||||
QVERIFY(!staticWidget.waitForPaintEvent());
|
||||
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.move(staticWidget.pos() + QPoint(-10, -10));
|
||||
QTest::qWait(20);
|
||||
QCOMPARE(staticWidget.gotPaintEvent, false);
|
||||
QVERIFY(!staticWidget.waitForPaintEvent());
|
||||
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.move(staticWidget.pos() + QPoint(-10, 10));
|
||||
QTest::qWait(20);
|
||||
QCOMPARE(staticWidget.gotPaintEvent, false);
|
||||
QVERIFY(!staticWidget.waitForPaintEvent());
|
||||
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.resize(staticWidget.size() + QSize(10, 10));
|
||||
QTRY_VERIFY(staticWidget.gotPaintEvent);
|
||||
QVERIFY(staticWidget.waitForPaintEvent());
|
||||
QCOMPARE(staticWidget.partial, true);
|
||||
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.resize(staticWidget.size() + QSize(-10, -10));
|
||||
QTest::qWait(20);
|
||||
QCOMPARE(staticWidget.gotPaintEvent, false);
|
||||
QVERIFY(!staticWidget.waitForPaintEvent());
|
||||
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.resize(staticWidget.size() + QSize(10, -10));
|
||||
QTRY_VERIFY(staticWidget.gotPaintEvent);
|
||||
QVERIFY(staticWidget.waitForPaintEvent());
|
||||
QCOMPARE(staticWidget.partial, true);
|
||||
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.move(staticWidget.pos() + QPoint(10, 10));
|
||||
staticWidget.resize(staticWidget.size() + QSize(-10, -10));
|
||||
QTest::qWait(20);
|
||||
QCOMPARE(staticWidget.gotPaintEvent, false);
|
||||
QVERIFY(!staticWidget.waitForPaintEvent());
|
||||
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.move(staticWidget.pos() + QPoint(10, 10));
|
||||
staticWidget.resize(staticWidget.size() + QSize(10, 10));
|
||||
QTRY_VERIFY(staticWidget.gotPaintEvent);
|
||||
QVERIFY(staticWidget.waitForPaintEvent());
|
||||
QCOMPARE(staticWidget.partial, true);
|
||||
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.move(staticWidget.pos() + QPoint(-10, -10));
|
||||
staticWidget.resize(staticWidget.size() + QSize(-10, -10));
|
||||
QTest::qWait(20);
|
||||
QCOMPARE(staticWidget.gotPaintEvent, false);
|
||||
QVERIFY(!staticWidget.waitForPaintEvent());
|
||||
|
||||
staticWidget.setAttribute(Qt::WA_StaticContents, false);
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.move(staticWidget.pos() + QPoint(-10, -10));
|
||||
staticWidget.resize(staticWidget.size() + QSize(-10, -10));
|
||||
QTRY_VERIFY(staticWidget.gotPaintEvent);
|
||||
QVERIFY(staticWidget.waitForPaintEvent());
|
||||
QCOMPARE(staticWidget.partial, false);
|
||||
staticWidget.setAttribute(Qt::WA_StaticContents, true);
|
||||
|
||||
staticWidget.setAttribute(Qt::WA_StaticContents, false);
|
||||
staticWidget.gotPaintEvent = false;
|
||||
staticWidget.move(staticWidget.pos() + QPoint(10, 10));
|
||||
QTest::qWait(20);
|
||||
QCOMPARE(staticWidget.gotPaintEvent, false);
|
||||
QVERIFY(!staticWidget.waitForPaintEvent());
|
||||
staticWidget.setAttribute(Qt::WA_StaticContents, true);
|
||||
}
|
||||
|
||||
void tst_QWidget::optimizedResize_topLevel()
|
||||
{
|
||||
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
|
||||
QSKIP("Wayland: This fails. Figure out why.");
|
||||
|
||||
if (QHighDpiScaling::isActive())
|
||||
QSKIP("Skip due to rounding errors in the regions.");
|
||||
StaticWidget topLevel;
|
||||
StaticWidget topLevel(simplePalette());
|
||||
topLevel.setPalette(simplePalette());
|
||||
topLevel.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
|
||||
topLevel.gotPaintEvent = false;
|
||||
topLevel.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
|
||||
QTRY_VERIFY(topLevel.gotPaintEvent);
|
||||
QVERIFY(topLevel.waitForPaintEvent());
|
||||
|
||||
topLevel.gotPaintEvent = false;
|
||||
topLevel.partial = false;
|
||||
topLevel.paintedRegion = QRegion();
|
||||
|
||||
@ -4641,7 +4634,7 @@ void tst_QWidget::optimizedResize_topLevel()
|
||||
QRegion expectedUpdateRegion(topLevel.rect());
|
||||
expectedUpdateRegion -= QRect(QPoint(), topLevel.size() - QSize(10, 10));
|
||||
|
||||
QTRY_VERIFY(topLevel.gotPaintEvent);
|
||||
QVERIFY(topLevel.waitForPaintEvent());
|
||||
if (m_platform == QStringLiteral("xcb") || m_platform == QStringLiteral("offscreen"))
|
||||
QSKIP("QTBUG-26424");
|
||||
QCOMPARE(topLevel.partial, true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user