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.

Pick-to: 6.4
Change-Id: I164d7ab4148551590ac3c50fcc3b9f98c5ac0535
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Axel Spoerl 2022-11-29 16:37:11 +01:00
parent 8071e3c2af
commit 58b1984efc

View File

@ -70,6 +70,14 @@ public:
} }
QRegion paintedRegions; 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: protected:
void paintEvent(QPaintEvent *event) override void paintEvent(QPaintEvent *event) override
{ {
@ -90,6 +98,14 @@ public:
setAttribute(Qt::WA_OpaquePaintEvent); 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: protected:
void paintEvent(QPaintEvent *e) override void paintEvent(QPaintEvent *e) override
{ {
@ -205,6 +221,14 @@ public:
QSize sizeHint() const override { return QSize(400, 400); } 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: protected:
void resizeEvent(QResizeEvent *) override void resizeEvent(QResizeEvent *) override
{ {
@ -245,13 +269,14 @@ protected:
*/ */
bool compareWidget(QWidget *w) bool compareWidget(QWidget *w)
{ {
QBackingStore *backingStore = w->window()->backingStore();
Q_ASSERT(backingStore && backingStore->handle());
QPlatformBackingStore *platformBackingStore = backingStore->handle();
if (!waitForFlush(w)) { if (!waitForFlush(w)) {
qWarning() << "Widget" << w << "failed to flush"; qWarning() << "Widget" << w << "failed to flush";
return false; return false;
} }
QBackingStore *backingStore = w->window()->backingStore();
Q_ASSERT(backingStore && backingStore->handle());
QPlatformBackingStore *platformBackingStore = backingStore->handle();
QImage backingstoreContent = platformBackingStore->toImage(); QImage backingstoreContent = platformBackingStore->toImage();
if (!w->isWindow()) { if (!w->isWindow()) {
@ -278,7 +303,14 @@ protected:
} }
bool waitForFlush(QWidget *widget) const bool waitForFlush(QWidget *widget) const
{ {
if (!widget)
return true;
auto *repaintManager = QWidgetPrivate::get(widget->window())->maybeRepaintManager(); auto *repaintManager = QWidgetPrivate::get(widget->window())->maybeRepaintManager();
if (!repaintManager)
return true;
return QTest::qWaitFor([repaintManager]{ return !repaintManager->isDirty(); } ); return QTest::qWaitFor([repaintManager]{ return !repaintManager->isDirty(); } );
}; };
#endif // QT_BUILD_INTERNAL #endif // QT_BUILD_INTERNAL
@ -301,7 +333,7 @@ void tst_QWidgetRepaintManager::initTestCase()
QVERIFY(QTest::qWaitForWindowExposed(&widget)); QVERIFY(QTest::qWaitForWindowExposed(&widget));
m_implementsScroll = widget.backingStore()->handle()->scroll(QRegion(widget.rect()), 1, 1); 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() void tst_QWidgetRepaintManager::cleanup()
@ -614,6 +646,7 @@ void tst_QWidgetRepaintManager::fastMove()
QCOMPARE(dirtyRegion(scene.yellowChild), QRect(0, 0, 100, 100)); QCOMPARE(dirtyRegion(scene.yellowChild), QRect(0, 0, 100, 100));
} }
QCOMPARE(dirtyRegion(&scene), QRect(0, 0, 25, 100)); QCOMPARE(dirtyRegion(&scene), QRect(0, 0, 25, 100));
QTRY_VERIFY(dirtyRegion(&scene).isEmpty());
QVERIFY(compareWidget(&scene)); QVERIFY(compareWidget(&scene));
} }