summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/kernel
diff options
context:
space:
mode:
authorJan Arve Saether <jan-arve.saether@digia.com>2014-01-28 16:20:13 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-07 23:52:49 +0100
commitde1b98e9c16afd1f428652e800cbeb35414b2b4f (patch)
tree8ebfa0ecbde1f231ccd4118d967e8bcf26054c1f /tests/auto/widgets/kernel
parent29804462f4f7205ba941973e209642dfc81a5f14 (diff)
Fallback to QWidget::grab() if QScreen::grabWindow() fails.
QScreen::grabWindow() is not always reliable because it grabs from the framebuffer. (The window might then be covered by other windows, e.g. "Stays on top"-Windows, popups etc). If QScreen::grabWindow() fails we therefore fallback to QWidget::grab(). This will not grab from the frame buffer, but it will ask the widget to render itself (with its current state) to a pixmap and return it. QWidget::grab() should usually return the expected pixmap, and the pixmap it gives is not subject to the state of the window manager. This means that both QScreen::grabWindow() *and* QWidget::grab() must produce an unexpected pixmap in order for the test to fail. Change-Id: I276554155bb1e5b510d2a2d43628d91669464fe2 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
Diffstat (limited to 'tests/auto/widgets/kernel')
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp119
1 files changed, 57 insertions, 62 deletions
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 38b629cad7..ecbe774f22 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -4816,73 +4816,68 @@ static inline QByteArray msgRgbMismatch(unsigned actual, unsigned expected)
QByteArrayLiteral(" != 0x") + QByteArray::number(expected, 16);
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
-QT_BEGIN_NAMESPACE
-extern Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0);
-QT_END_NAMESPACE
-
-// grabs the window *without including any overlapping windows*
-static QPixmap grabWindow(QWindow *window, int x, int y, int width, int height)
-{
- const HWND hwnd = (HWND)window->winId();
-
- // Create and setup bitmap
- const HDC displayDc = ::GetDC(0);
- const HDC bitmapDc = ::CreateCompatibleDC(displayDc);
- const HBITMAP bitmap = ::CreateCompatibleBitmap(displayDc, width, height);
- const HGDIOBJ oldBitmap = ::SelectObject(bitmapDc, bitmap);
-
- // copy data
- const HDC windowDc = ::GetDC(hwnd);
- ::BitBlt(bitmapDc, 0, 0, width, height, windowDc, x, y, SRCCOPY);
-
- // clean up all but bitmap
- ::ReleaseDC(hwnd, windowDc);
- ::SelectObject(bitmapDc, oldBitmap);
- ::DeleteDC(bitmapDc);
-
- const QPixmap pixmap = qt_pixmapFromWinHBITMAP(bitmap);
-
- ::DeleteObject(bitmap);
- ::ReleaseDC(0, displayDc);
-
- return pixmap;
-}
-#else
-// fallback for other platforms.
static QPixmap grabWindow(QWindow *window, int x, int y, int width, int height)
{
QScreen *screen = window->screen();
return screen ? screen->grabWindow(window->winId(), x, y, width, height) : QPixmap();
}
-#endif //defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
-
-#define VERIFY_COLOR(child, region, color) do { \
- const QRegion r = QRegion(region); \
- QWindow *window = child.window()->windowHandle(); \
- Q_ASSERT(window); \
- const QPoint offset = child.mapTo(child.window(), QPoint(0,0)); \
- for (int i = 0; i < r.rects().size(); ++i) { \
- const QRect rect = r.rects().at(i).translated(offset); \
- for (int t = 0; t < 5; t++) { \
- const QPixmap pixmap = grabWindow(window, \
- rect.left(), rect.top(), \
- rect.width(), rect.height()); \
- QCOMPARE(pixmap.size(), rect.size()); \
- QPixmap expectedPixmap(pixmap); /* ensure equal formats */ \
- expectedPixmap.detach(); \
- expectedPixmap.fill(color); \
- QImage image = pixmap.toImage(); \
- uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0; \
- uint firstPixel = image.pixel(0,0) | alphaCorrection; \
- if ( firstPixel != QColor(color).rgb() && t < 4 ) \
- { QTest::qWait(200); continue; } \
- QVERIFY2(firstPixel == QColor(color).rgb(), msgRgbMismatch(firstPixel, QColor(color).rgb())); \
- QCOMPARE(pixmap, expectedPixmap); \
- break; \
- } \
- } \
-} while (0)
+
+#define VERIFY_COLOR(child, region, color) verifyColor(child, region, color, __LINE__)
+
+bool verifyColor(QWidget &child, const QRegion &region, const QColor &color, unsigned int callerLine)
+{
+ const QRegion r = QRegion(region);
+ QWindow *window = child.window()->windowHandle();
+ Q_ASSERT(window);
+ const QPoint offset = child.mapTo(child.window(), QPoint(0,0));
+ bool grabBackingStore = false;
+ for (int i = 0; i < r.rects().size(); ++i) {
+ QRect rect = r.rects().at(i).translated(offset);
+ for (int t = 0; t < 6; t++) {
+ const QPixmap pixmap = grabBackingStore
+ ? child.grab(rect)
+ : grabWindow(window, rect.left(), rect.top(), rect.width(), rect.height());
+ if (!QTest::qCompare(pixmap.size(), rect.size(), "pixmap.size()", "rect.size()", __FILE__, callerLine))
+ return false;
+ QPixmap expectedPixmap(pixmap); /* ensure equal formats */
+ expectedPixmap.detach();
+ expectedPixmap.fill(color);
+ QImage image = pixmap.toImage();
+ uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0;
+ uint firstPixel = image.pixel(0,0) | alphaCorrection;
+ if (t < 5) {
+ /* Normal run.
+ If it succeeds: return success
+ If it fails: do not return, but wait a bit and reiterate (retry)
+ */
+ if (firstPixel == QColor(color).rgb()
+ && image == expectedPixmap.toImage()) {
+ return true;
+ } else {
+ if (t == 4) {
+ grabBackingStore = true;
+ rect = r.rects().at(i);
+ } else {
+ QTest::qWait(200);
+ }
+ }
+ } else {
+ // Last run, report failure if it still fails
+ if (!QTest::qVerify(firstPixel == QColor(color).rgb(),
+ "firstPixel == QColor(color).rgb()",
+ qPrintable(msgRgbMismatch(firstPixel, QColor(color).rgb())),
+ __FILE__, callerLine))
+ return false;
+ if (!QTest::qVerify(image == expectedPixmap.toImage(),
+ "image == expectedPixmap.toImage()",
+ "grabbed pixmap differs from expected pixmap",
+ __FILE__, callerLine))
+ return false;
+ }
+ }
+ }
+ return true;
+}
void tst_QWidget::popupEnterLeave()
{