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 <volker.hilsheimer@qt.io>
(cherry picked from commit 58b1984efc99d96a56f97bb9156a8c0f245b71ca)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Axel Spoerl 2022-11-29 16:37:11 +01:00 committed by Qt Cherry-pick Bot
parent 150b94d4d2
commit 9f1d4b2e52

View File

@ -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));
}