From 9f1d4b2e5227d96ab0fde146a7c987952c44d7ca Mon Sep 17 00:00:00 2001 From: Axel Spoerl Date: Tue, 29 Nov 2022 16:37:11 +0100 Subject: [PATCH] Stabilize tst_QWidgetRepaintManager on XCB platforms When a widget's palette has different brushes in Active / Inactive color groups, or it is pixmap based, multiple paint events are triggered. This leads to unpredictable, double entries in QWidgetRepaintManager::dirtyWidgetList(). This patch overrides event() of all test widgets and ignores activation / deactivation events in order to make the entries of QWidgetRepaintManager::dirtyWidgetList() predictable. Change-Id: I164d7ab4148551590ac3c50fcc3b9f98c5ac0535 Reviewed-by: Volker Hilsheimer (cherry picked from commit 58b1984efc99d96a56f97bb9156a8c0f245b71ca) Reviewed-by: Qt Cherry-pick Bot --- .../tst_qwidgetrepaintmanager.cpp | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp b/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp index fb959821bc0..5b839cbde5b 100644 --- a/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp +++ b/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp @@ -51,6 +51,14 @@ public: } QRegion paintedRegions; + bool event(QEvent *event) override + { + const auto type = event->type(); + if (type == QEvent::WindowActivate || type == QEvent::WindowDeactivate) + return true; + return QWidget::event(event); + } + protected: void paintEvent(QPaintEvent *event) override { @@ -71,6 +79,14 @@ public: setAttribute(Qt::WA_OpaquePaintEvent); } + bool event(QEvent *event) override + { + const auto type = event->type(); + if (type == QEvent::WindowActivate || type == QEvent::WindowDeactivate) + return true; + return QWidget::event(event); + } + protected: void paintEvent(QPaintEvent *e) override { @@ -186,6 +202,14 @@ public: QSize sizeHint() const override { return QSize(400, 400); } + bool event(QEvent *event) override + { + const auto type = event->type(); + if (type == QEvent::WindowActivate || type == QEvent::WindowDeactivate) + return true; + return QWidget::event(event); + } + protected: void resizeEvent(QResizeEvent *) override { @@ -226,13 +250,14 @@ protected: */ bool compareWidget(QWidget *w) { + QBackingStore *backingStore = w->window()->backingStore(); + Q_ASSERT(backingStore && backingStore->handle()); + QPlatformBackingStore *platformBackingStore = backingStore->handle(); + if (!waitForFlush(w)) { qWarning() << "Widget" << w << "failed to flush"; return false; } - QBackingStore *backingStore = w->window()->backingStore(); - Q_ASSERT(backingStore && backingStore->handle()); - QPlatformBackingStore *platformBackingStore = backingStore->handle(); QImage backingstoreContent = platformBackingStore->toImage(); if (!w->isWindow()) { @@ -259,7 +284,14 @@ protected: } bool waitForFlush(QWidget *widget) const { + if (!widget) + return true; + auto *repaintManager = QWidgetPrivate::get(widget->window())->maybeRepaintManager(); + + if (!repaintManager) + return true; + return QTest::qWaitFor([repaintManager]{ return !repaintManager->isDirty(); } ); }; #endif // QT_BUILD_INTERNAL @@ -282,7 +314,7 @@ void tst_QWidgetRepaintManager::initTestCase() QVERIFY(QTest::qWaitForWindowExposed(&widget)); m_implementsScroll = widget.backingStore()->handle()->scroll(QRegion(widget.rect()), 1, 1); - qDebug() << QGuiApplication::platformName() << "QPA backend implements scroll:" << m_implementsScroll; + qInfo() << QGuiApplication::platformName() << "QPA backend implements scroll:" << m_implementsScroll; } void tst_QWidgetRepaintManager::cleanup() @@ -594,6 +626,7 @@ void tst_QWidgetRepaintManager::fastMove() QCOMPARE(dirtyRegion(scene.yellowChild), QRect(0, 0, 100, 100)); } QCOMPARE(dirtyRegion(&scene), QRect(0, 0, 25, 100)); + QTRY_VERIFY(dirtyRegion(&scene).isEmpty()); QVERIFY(compareWidget(&scene)); }