diff options
author | Axel Spoerl <axel.spoerl@qt.io> | 2023-01-09 14:33:23 +0100 |
---|---|---|
committer | Axel Spoerl <axel.spoerl@qt.io> | 2023-01-10 05:45:02 +0000 |
commit | 4096667d6601dcbc5e713e6b0fd5b5218453c4cb (patch) | |
tree | cf1a18831d19e32e5994fcc927665fa98eacb592 /tests/auto/widgets | |
parent | f6b026eed1a4a3441ba9b1b92a9eaf2c17d69253 (diff) |
Fix tst_QWidgetRepaintManager on XCB
Due to an XCB library change, QXcbBackingStore::toImage() cannot be
safely assumed to return an image identical to QWidget::grab().
The test functions fastMove(), moveAccross() and moveInOutOverlapped()
relied on QXcbBackingStore::toImage() and failed.
They were backlisted on Linux/XCB.
This patch obtains a screen shot instead of an image from the backing
store on XCB platforms. It processes events until the screen shot
matches QWidget::grab(). It makes the test fail only if the comparison
times out.
The patch also removes the BLACKLIST file, containing only the test
functions mentioned above.
Fixes: QTBUG-109036
Pick-to: 6.5 6.4
Change-Id: I26dd5b89dc62b313db066a285f6ad7d4d92baaf2
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'tests/auto/widgets')
-rw-r--r-- | tests/auto/widgets/kernel/qwidgetrepaintmanager/BLACKLIST | 11 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp | 38 |
2 files changed, 37 insertions, 12 deletions
diff --git a/tests/auto/widgets/kernel/qwidgetrepaintmanager/BLACKLIST b/tests/auto/widgets/kernel/qwidgetrepaintmanager/BLACKLIST deleted file mode 100644 index 94692ee20a..0000000000 --- a/tests/auto/widgets/kernel/qwidgetrepaintmanager/BLACKLIST +++ /dev/null @@ -1,11 +0,0 @@ -# Temporary for QTBUG-109036 -[fastMove] -opensuse-leap - -# Temporary for QTBUG-109036 -[moveAccross] -opensuse-leap - -# Temporary for QTBUG-109036 -[moveInOutOverlapped] -opensuse-leap diff --git a/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp b/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp index f53d5aeb05..feb8a99131 100644 --- a/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp +++ b/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp @@ -262,6 +262,8 @@ private slots: void moveInOutOverlapped(); protected: + bool m_xcb = false; + /* This helper compares the widget as rendered into the backingstore with the widget as rendered via QWidget::grab. The latter always produces a fully rendered image, @@ -279,14 +281,44 @@ protected: } QImage backingstoreContent = platformBackingStore->toImage(); + + // QXcbBackingStore::toImage() is not reliable. Take a screenshot instead. + // X11 draws the screen in a thread, which is not a QThread. + // The first screenshot is therefore unlikely to contain the correct image. + // It is taken just to obtain size and format. + QWidget *window = nullptr; + if (m_xcb) { + + // Widget must be shown to be caught on a screen shot + if (!w->isWindow()) { + qWarning() << "Hidden widget" << w << "cannot be compared on XCB"; + return false; + } + + window = w->window(); + Q_ASSERT(window); + + backingstoreContent = window->screen()->grabWindow(window->winId()).toImage(); + } + if (!w->isWindow()) { const qreal dpr = w->devicePixelRatioF(); const QPointF offset = w->mapTo(w->window(), QPointF(0, 0)) * dpr; backingstoreContent = backingstoreContent.copy(offset.x(), offset.y(), w->width() * dpr, w->height() * dpr); } + const QImage widgetRender = w->grab().toImage().convertToFormat(backingstoreContent.format()); - const bool result = backingstoreContent == widgetRender; + // XCB: Process events, until screenshot equals widgetRender or timeout kicks in. + if (m_xcb) { + // Unuse result to hit MANUAL_DEBUG code path + Q_UNUSED(QTest::qWaitFor([&](){ + backingstoreContent = window->screen()->grabWindow(window->winId()).toImage(); + return widgetRender == backingstoreContent; + })); + } + + const bool result = widgetRender == backingstoreContent; #ifdef MANUAL_DEBUG if (!result) { @@ -334,6 +366,10 @@ void tst_QWidgetRepaintManager::initTestCase() m_implementsScroll = widget.backingStore()->handle()->scroll(QRegion(widget.rect()), 1, 1); qInfo() << QGuiApplication::platformName() << "QPA backend implements scroll:" << m_implementsScroll; + +#if defined(QT_BUILD_INTERNAL) + m_xcb = QGuiApplication::platformName().contains("xcb", Qt::CaseInsensitive); +#endif } void tst_QWidgetRepaintManager::cleanup() |