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 Change-Id: I26dd5b89dc62b313db066a285f6ad7d4d92baaf2 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 4096667d6601dcbc5e713e6b0fd5b5218453c4cb) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
7b0fc393a0
commit
f20f1c6b7c
@ -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
|
|
@ -262,6 +262,8 @@ private slots:
|
|||||||
void moveInOutOverlapped();
|
void moveInOutOverlapped();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool m_xcb = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This helper compares the widget as rendered into the backingstore with the widget
|
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,
|
as rendered via QWidget::grab. The latter always produces a fully rendered image,
|
||||||
@ -279,14 +281,44 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
QImage backingstoreContent = platformBackingStore->toImage();
|
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()) {
|
if (!w->isWindow()) {
|
||||||
const qreal dpr = w->devicePixelRatioF();
|
const qreal dpr = w->devicePixelRatioF();
|
||||||
const QPointF offset = w->mapTo(w->window(), QPointF(0, 0)) * dpr;
|
const QPointF offset = w->mapTo(w->window(), QPointF(0, 0)) * dpr;
|
||||||
backingstoreContent = backingstoreContent.copy(offset.x(), offset.y(), w->width() * dpr, w->height() * dpr);
|
backingstoreContent = backingstoreContent.copy(offset.x(), offset.y(), w->width() * dpr, w->height() * dpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QImage widgetRender = w->grab().toImage().convertToFormat(backingstoreContent.format());
|
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
|
#ifdef MANUAL_DEBUG
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@ -334,6 +366,10 @@ void tst_QWidgetRepaintManager::initTestCase()
|
|||||||
|
|
||||||
m_implementsScroll = widget.backingStore()->handle()->scroll(QRegion(widget.rect()), 1, 1);
|
m_implementsScroll = widget.backingStore()->handle()->scroll(QRegion(widget.rect()), 1, 1);
|
||||||
qInfo() << QGuiApplication::platformName() << "QPA backend implements scroll:" << m_implementsScroll;
|
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()
|
void tst_QWidgetRepaintManager::cleanup()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user