tests/auto/qwswindowsystem/tst_qwswindowsystem.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #ifdef Q_WS_QWS
       
    46 
       
    47 //TESTED_CLASS=
       
    48 //TESTED_FILES=gui/embedded/qwindowsystem_qws.h gui/embedded/qwindowsystem_qws.cpp
       
    49 
       
    50 #include <qwindowsystem_qws.h>
       
    51 #include <qpainter.h>
       
    52 #include <qdesktopwidget.h>
       
    53 #include <qdirectpainter_qws.h>
       
    54 #include <qscreen_qws.h>
       
    55 #include <private/qwindowsurface_qws_p.h>
       
    56 
       
    57 class tst_QWSWindowSystem : public QObject
       
    58 {
       
    59     Q_OBJECT
       
    60 
       
    61 public:
       
    62     tst_QWSWindowSystem() {}
       
    63     ~tst_QWSWindowSystem() {}
       
    64 
       
    65 private slots:
       
    66     void initTestCase();
       
    67     void showHideWindow();
       
    68     void raiseLowerWindow();
       
    69     void windowOpacity();
       
    70     void directPainter();
       
    71     void setMaxWindowRect();
       
    72     void initialGeometry();
       
    73     void WA_PaintOnScreen();
       
    74     void toplevelMove();
       
    75     void dontFlushUnitializedWindowSurfaces();
       
    76     void task188025_data();
       
    77     void task188025();
       
    78 
       
    79 private:
       
    80     QWSWindow* getWindow(int windId);
       
    81     QColor bgColor;
       
    82 };
       
    83 
       
    84 class ColorWidget : public QWidget
       
    85 {
       
    86 public:
       
    87     ColorWidget(const QColor &color = QColor(Qt::red), Qt::WindowFlags f = 0)
       
    88         : QWidget(0, f | Qt::FramelessWindowHint), c(color) {}
       
    89 
       
    90     QColor color() { return c; }
       
    91 
       
    92 protected:
       
    93     void paintEvent(QPaintEvent*) {
       
    94         QPainter p(this);
       
    95         p.fillRect(rect(), QBrush(c));
       
    96     }
       
    97 
       
    98 private:
       
    99     QColor c;
       
   100 };
       
   101 
       
   102 void tst_QWSWindowSystem::initTestCase()
       
   103 {
       
   104     bgColor = QColor(Qt::green);
       
   105 
       
   106     QWSServer *server = QWSServer::instance();
       
   107     server->setBackground(bgColor);
       
   108 }
       
   109 
       
   110 QWSWindow* tst_QWSWindowSystem::getWindow(int winId)
       
   111 {
       
   112     QWSServer *server = QWSServer::instance();
       
   113     foreach (QWSWindow *w, server->clientWindows()) {
       
   114         if (w->winId() == winId)
       
   115             return w;
       
   116     }
       
   117     return 0;
       
   118 }
       
   119 
       
   120 #define VERIFY_COLOR(rect, color) {                                     \
       
   121     const QPixmap pixmap = QPixmap::grabWindow(QDesktopWidget().winId(), \
       
   122                                                rect.left(), rect.top(), \
       
   123                                                rect.width(), rect.height()); \
       
   124     QCOMPARE(pixmap.size(), rect.size());                               \
       
   125     QPixmap expectedPixmap(pixmap); /* ensure equal formats */          \
       
   126     expectedPixmap.fill(color);                                         \
       
   127     QCOMPARE(pixmap, expectedPixmap);                                   \
       
   128 }
       
   129 
       
   130 void tst_QWSWindowSystem::showHideWindow()
       
   131 {
       
   132     ColorWidget w;
       
   133 
       
   134     const QRect rect(100, 100, 100, 100);
       
   135 
       
   136     w.setGeometry(rect);
       
   137     QApplication::processEvents();
       
   138 
       
   139     QWSWindow *win = getWindow(w.winId());
       
   140     QVERIFY(win);
       
   141     QCOMPARE(win->requestedRegion(), QRegion());
       
   142     QCOMPARE(win->allocatedRegion(), QRegion());
       
   143     VERIFY_COLOR(rect, bgColor);
       
   144 
       
   145     w.show();
       
   146     QApplication::processEvents();
       
   147     QApplication::sendPostedEvents(); // glib event loop workaround
       
   148     QCOMPARE(win->requestedRegion(), QRegion(rect));
       
   149     QCOMPARE(win->allocatedRegion(), QRegion(rect));
       
   150     VERIFY_COLOR(rect, w.color());
       
   151 
       
   152     w.hide();
       
   153     QApplication::processEvents();
       
   154     QCOMPARE(win->requestedRegion(), QRegion());
       
   155     QCOMPARE(win->allocatedRegion(), QRegion());
       
   156     VERIFY_COLOR(rect, bgColor);
       
   157 }
       
   158 
       
   159 void tst_QWSWindowSystem::raiseLowerWindow()
       
   160 {
       
   161     const QRect rect(100, 100, 100, 100);
       
   162 
       
   163     ColorWidget w1(Qt::red);
       
   164     w1.setGeometry(rect);
       
   165     w1.show();
       
   166     QApplication::processEvents();
       
   167 
       
   168     ColorWidget w2(Qt::blue);
       
   169     w2.setGeometry(rect);
       
   170     w2.show();
       
   171 
       
   172     QWSWindow *win1 = getWindow(w1.winId());
       
   173     QWSWindow *win2 = getWindow(w2.winId());
       
   174 
       
   175     QApplication::processEvents();
       
   176     QApplication::sendPostedEvents(); // glib event loop workaround
       
   177     QCOMPARE(win1->requestedRegion(), QRegion(rect));
       
   178     QCOMPARE(win2->requestedRegion(), QRegion(rect));
       
   179     QCOMPARE(win1->allocatedRegion(), QRegion());
       
   180     QCOMPARE(win2->allocatedRegion(), QRegion(rect));
       
   181     VERIFY_COLOR(rect, w2.color());
       
   182 
       
   183     w1.raise();
       
   184     QApplication::processEvents();
       
   185     QCOMPARE(win1->requestedRegion(), QRegion(rect));
       
   186     QCOMPARE(win2->requestedRegion(), QRegion(rect));
       
   187     QCOMPARE(win1->allocatedRegion(), QRegion(rect));
       
   188     QCOMPARE(win2->allocatedRegion(), QRegion());
       
   189     VERIFY_COLOR(rect, w1.color());
       
   190 
       
   191     w1.lower();
       
   192     QApplication::processEvents();
       
   193     QCOMPARE(win1->requestedRegion(), QRegion(rect));
       
   194     QCOMPARE(win2->requestedRegion(), QRegion(rect));
       
   195     QCOMPARE(win1->allocatedRegion(), QRegion());
       
   196     QCOMPARE(win2->allocatedRegion(), QRegion(rect));
       
   197     VERIFY_COLOR(rect, w2.color());
       
   198 }
       
   199 
       
   200 void tst_QWSWindowSystem::windowOpacity()
       
   201 {
       
   202     const QRect rect(100, 100, 100, 100);
       
   203 
       
   204     ColorWidget w1(Qt::red);
       
   205     w1.setGeometry(rect);
       
   206     w1.show();
       
   207 
       
   208     QWidget w2(0, Qt::FramelessWindowHint);
       
   209     w2.setGeometry(rect);
       
   210     w2.show();
       
   211     w2.raise();
       
   212 
       
   213     QWSWindow *win1 = getWindow(w1.winId());
       
   214     QWSWindow *win2 = getWindow(w2.winId());
       
   215 
       
   216     QApplication::processEvents();
       
   217     QApplication::sendPostedEvents(); // glib event loop workaround
       
   218     QCOMPARE(win1->allocatedRegion(), QRegion());
       
   219     QCOMPARE(win2->allocatedRegion(), QRegion(rect));
       
   220     VERIFY_COLOR(rect, w2.palette().color(w2.backgroundRole()));
       
   221 
       
   222     // Make w2 transparent so both widgets are shown.
       
   223 
       
   224     w2.setWindowOpacity(0.0);
       
   225     QApplication::processEvents();
       
   226     QCOMPARE(win1->allocatedRegion(), QRegion(rect));
       
   227     QCOMPARE(win2->allocatedRegion(), QRegion(rect));
       
   228     VERIFY_COLOR(rect, w1.color());
       
   229 
       
   230     w2.setWindowOpacity(1.0);
       
   231     QApplication::processEvents();
       
   232     QCOMPARE(win1->allocatedRegion(), QRegion());
       
   233     QCOMPARE(win2->allocatedRegion(), QRegion(rect));
       
   234     VERIFY_COLOR(rect, w2.palette().color(w2.backgroundRole()));
       
   235 
       
   236     // Use the palette to make w2 transparent
       
   237     QPalette palette = w2.palette();
       
   238     palette.setBrush(QPalette::All, QPalette::Background,
       
   239                      QColor(255, 255, 255, 0));
       
   240     w2.setPalette(palette);
       
   241     QApplication::processEvents();
       
   242     QApplication::processEvents();
       
   243     QCOMPARE(win1->allocatedRegion(), QRegion(rect));
       
   244     QCOMPARE(win2->allocatedRegion(), QRegion(rect));
       
   245     VERIFY_COLOR(rect, w1.color());
       
   246 
       
   247     palette.setBrush(QPalette::All, QPalette::Background,
       
   248                      QColor(255, 255, 255, 255));
       
   249     w2.setPalette(palette);
       
   250     QApplication::processEvents();
       
   251     QApplication::processEvents();
       
   252     QApplication::processEvents();
       
   253     QApplication::sendPostedEvents(); // glib event loop workaround
       
   254     QCOMPARE(win1->allocatedRegion(), QRegion());
       
   255     QCOMPARE(win2->allocatedRegion(), QRegion(rect));
       
   256     VERIFY_COLOR(rect, QColor(255, 255, 255, 255));
       
   257 }
       
   258 
       
   259 void tst_QWSWindowSystem::directPainter()
       
   260 {
       
   261     const QRect rect(100, 100, 100, 100);
       
   262 
       
   263     ColorWidget w(Qt::red);
       
   264     w.setGeometry(rect);
       
   265     w.show();
       
   266 
       
   267     QWSWindow *win = getWindow(w.winId());
       
   268 
       
   269     QApplication::processEvents();
       
   270     QCOMPARE(win->allocatedRegion(), QRegion(rect));
       
   271 
       
   272     // reserve screen area using the static functions
       
   273 
       
   274     QDirectPainter::reserveRegion(QRegion(rect));
       
   275     QApplication::processEvents();
       
   276     QCOMPARE(win->allocatedRegion(), QRegion());
       
   277     QCOMPARE(QDirectPainter::reservedRegion(), QRegion(rect));
       
   278 
       
   279     QDirectPainter::reserveRegion(QRegion());
       
   280     QApplication::processEvents();
       
   281     QCOMPARE(win->allocatedRegion(), QRegion(rect));
       
   282     QCOMPARE(QDirectPainter::reservedRegion(), QRegion());
       
   283 
       
   284     // reserve screen area using a QDirectPainter object
       
   285     {
       
   286         QDirectPainter dp;
       
   287         dp.setRegion(QRegion(rect));
       
   288         dp.lower();
       
   289 
       
   290         QWSWindow *dpWin = getWindow(dp.winId());
       
   291 
       
   292         QApplication::processEvents();
       
   293         QCOMPARE(win->allocatedRegion(), QRegion(rect));
       
   294         QCOMPARE(dpWin->allocatedRegion(), QRegion());
       
   295 
       
   296         w.lower();
       
   297         QApplication::processEvents();
       
   298         QCOMPARE(win->allocatedRegion(), QRegion());
       
   299         QCOMPARE(dpWin->allocatedRegion(), QRegion(rect));
       
   300     }
       
   301 
       
   302     QApplication::processEvents();
       
   303     QCOMPARE(win->allocatedRegion(), QRegion(rect));
       
   304     VERIFY_COLOR(rect, w.color());
       
   305 }
       
   306 
       
   307 void tst_QWSWindowSystem::setMaxWindowRect()
       
   308 {
       
   309     QDesktopWidget *desktop = QApplication::desktop();
       
   310     QSignalSpy spy(desktop, SIGNAL(workAreaResized(int)));
       
   311 
       
   312     const QRect screenRect = desktop->screenGeometry();
       
   313 
       
   314     QWidget w;
       
   315     w.showMaximized();
       
   316     QWidget w2;
       
   317     QApplication::processEvents();
       
   318 
       
   319     QCOMPARE(spy.count(), 0);
       
   320     QCOMPARE(w.frameGeometry(), screenRect);
       
   321 
       
   322     QRect available = QRect(screenRect.left(), screenRect.top(),
       
   323                             screenRect.right() + 1, screenRect.bottom() - 20 + 1);
       
   324     QWSServer::setMaxWindowRect(available);
       
   325     QApplication::processEvents();
       
   326 
       
   327     QCOMPARE(spy.count(), 1);
       
   328     QCOMPARE(desktop->availableGeometry(), available);
       
   329     QCOMPARE(w.frameGeometry(), desktop->availableGeometry());
       
   330 
       
   331     w.hide();
       
   332     QApplication::processEvents();
       
   333 
       
   334     QWSServer::setMaxWindowRect(screenRect);
       
   335     QCOMPARE(spy.count(), 2);
       
   336     w.show();
       
   337     QVERIFY(w.isMaximized());
       
   338     QCOMPARE(desktop->availableGeometry(), screenRect);
       
   339     QCOMPARE(w.frameGeometry(), desktop->availableGeometry());
       
   340 }
       
   341 
       
   342 void tst_QWSWindowSystem::initialGeometry()
       
   343 {
       
   344     ColorWidget w(Qt::red);
       
   345     w.setGeometry(100, 0, 50, 50);
       
   346     w.show();
       
   347 
       
   348     const QRect rect(10, 200, 100, 100);
       
   349     w.setGeometry(rect);
       
   350 
       
   351     QApplication::processEvents();
       
   352     QApplication::sendPostedEvents(); // glib event loop workaround
       
   353 
       
   354     QCOMPARE(w.frameGeometry(), rect);
       
   355     VERIFY_COLOR(rect, QColor(Qt::red));
       
   356 }
       
   357 
       
   358 void tst_QWSWindowSystem::WA_PaintOnScreen()
       
   359 {
       
   360     ColorWidget w(Qt::red);
       
   361     w.setAttribute(Qt::WA_PaintOnScreen);
       
   362 
       
   363     QRect rect;
       
   364 
       
   365     QVERIFY(w.testAttribute(Qt::WA_PaintOnScreen));
       
   366     rect = QRect(10, 0, 50, 50);
       
   367     w.setGeometry(rect);
       
   368     w.show();
       
   369 
       
   370     QApplication::processEvents();
       
   371     QApplication::sendPostedEvents(); // glib event loop workaround
       
   372     QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(w.windowSurface());
       
   373     QCOMPARE(surface->key(), QLatin1String("OnScreen"));
       
   374     QVERIFY(w.testAttribute(Qt::WA_PaintOnScreen));
       
   375     VERIFY_COLOR(rect, QColor(Qt::red));
       
   376 
       
   377     // move
       
   378     rect = QRect(10, 100, 50, 50);
       
   379     w.setGeometry(rect);
       
   380     QApplication::processEvents();
       
   381     QApplication::sendPostedEvents(); // glib event loop workaround
       
   382     VERIFY_COLOR(rect, QColor(Qt::red));
       
   383 
       
   384     // resize
       
   385     rect = QRect(10, 100, 60, 60);
       
   386     w.setGeometry(rect);
       
   387     QApplication::processEvents();
       
   388     QApplication::sendPostedEvents(); // glib event loop workaround
       
   389     VERIFY_COLOR(rect, QColor(Qt::red));
       
   390 }
       
   391 
       
   392 class DummyMoveSurface : public QWSSharedMemSurface
       
   393 {
       
   394 public:
       
   395     DummyMoveSurface(QWidget *w) : QWSSharedMemSurface(w) {}
       
   396     DummyMoveSurface() : QWSSharedMemSurface() {}
       
   397 
       
   398     // doesn't do any move
       
   399     QRegion move(const QPoint &, const QRegion &) {
       
   400         return QRegion();
       
   401     }
       
   402 
       
   403     QString key() const { return QLatin1String("dummy"); }
       
   404 };
       
   405 
       
   406 class DummyScreen : public QScreen
       
   407 {
       
   408 private:
       
   409     QScreen *s;
       
   410 
       
   411 public:
       
   412 
       
   413     DummyScreen() : QScreen(0), s(qt_screen) {
       
   414         qt_screen = this;
       
   415         w = s->width();
       
   416         h = s->height();
       
   417         dw = s->deviceWidth();
       
   418         dh = s->deviceHeight();
       
   419         d = s->depth();
       
   420         data = s->base();
       
   421         lstep = s->linestep();
       
   422         physWidth = s->physicalWidth();
       
   423         physHeight = s->physicalHeight();
       
   424         setPixelFormat(s->pixelFormat());
       
   425     }
       
   426 
       
   427     ~DummyScreen() {
       
   428         qt_screen = s;
       
   429     }
       
   430 
       
   431     bool initDevice() { return s->initDevice(); }
       
   432     bool connect(const QString &displaySpec) {
       
   433         return s->connect(displaySpec);
       
   434     }
       
   435     void disconnect() { s->disconnect(); }
       
   436     void setMode(int w, int h, int d) { s->setMode(w, h, d); }
       
   437     void exposeRegion(QRegion r, int changing) {
       
   438         s->exposeRegion(r, changing);
       
   439     }
       
   440     void blit(const QImage &img, const QPoint &topLeft, const QRegion &r) {
       
   441         s->blit(img, topLeft, r);
       
   442     }
       
   443     void solidFill(const QColor &color, const QRegion &region) {
       
   444         s->solidFill(color, region);
       
   445     }
       
   446     QWSWindowSurface* createSurface(const QString &key) const {
       
   447         if (key == QLatin1String("dummy"))
       
   448             return new DummyMoveSurface;
       
   449         return s->createSurface(key);
       
   450     }
       
   451 };
       
   452 
       
   453 void tst_QWSWindowSystem::toplevelMove()
       
   454 {
       
   455     { // default move implementation, opaque window
       
   456         ColorWidget w(Qt::red);
       
   457         w.show();
       
   458 
       
   459         w.setGeometry(50, 50, 50, 50);
       
   460         QApplication::processEvents();
       
   461         QApplication::sendPostedEvents(); // glib event loop workaround
       
   462         VERIFY_COLOR(QRect(50, 50, 50, 50), w.color());
       
   463         VERIFY_COLOR(QRect(100, 100, 50, 50), bgColor);
       
   464 
       
   465         w.move(100, 100);
       
   466         QApplication::processEvents();
       
   467 
       
   468         VERIFY_COLOR(QRect(100, 100, 50, 50), w.color());
       
   469         VERIFY_COLOR(QRect(50, 50, 50, 50), bgColor);
       
   470     }
       
   471 
       
   472     { // default move implementation, non-opaque window
       
   473         ColorWidget w(Qt::red);
       
   474         w.setWindowOpacity(0.5);
       
   475         w.show();
       
   476 
       
   477         w.setGeometry(50, 50, 50, 50);
       
   478         QApplication::processEvents();
       
   479 //        VERIFY_COLOR(QRect(50, 50, 50, 50), w.color());
       
   480         VERIFY_COLOR(QRect(100, 100, 50, 50), bgColor);
       
   481 
       
   482         w.move(100, 100);
       
   483         QApplication::processEvents();
       
   484 
       
   485 //        VERIFY_COLOR(QRect(100, 100, 50, 50), w.color());
       
   486         VERIFY_COLOR(QRect(50, 50, 50, 50), bgColor);
       
   487     }
       
   488 
       
   489     DummyScreen *screen = new DummyScreen;
       
   490     { // dummy accelerated move
       
   491 
       
   492         ColorWidget w(Qt::red);
       
   493         w.setWindowSurface(new DummyMoveSurface(&w));
       
   494         w.show();
       
   495 
       
   496         w.setGeometry(50, 50, 50, 50);
       
   497         QApplication::processEvents();
       
   498         QApplication::sendPostedEvents(); // glib event loop workaround
       
   499         VERIFY_COLOR(QRect(50, 50, 50, 50), w.color());
       
   500         VERIFY_COLOR(QRect(100, 100, 50, 50), bgColor);
       
   501 
       
   502         w.move(100, 100);
       
   503         QApplication::processEvents();
       
   504         // QEXPECT_FAIL("", "Task 169976", Continue);
       
   505         //VERIFY_COLOR(QRect(50, 50, 50, 50), w.color()); // unchanged
       
   506         VERIFY_COLOR(QRect(100, 100, 50, 50), bgColor); // unchanged
       
   507     }
       
   508     delete screen;
       
   509 }
       
   510 
       
   511 static void fillWindowSurface(QWidget *w, const QColor &color)
       
   512 {
       
   513     QWindowSurface *s = w->windowSurface();
       
   514     const QRect rect = s->rect(w);
       
   515     s->beginPaint(rect);
       
   516     QImage *img = s->buffer(w);
       
   517     QPainter p(img);
       
   518     p.fillRect(rect, color);
       
   519     s->endPaint(rect);
       
   520 }
       
   521 
       
   522 void tst_QWSWindowSystem::dontFlushUnitializedWindowSurfaces()
       
   523 {
       
   524     QApplication::processEvents();
       
   525 
       
   526     const QRect r(50, 50, 50, 50);
       
   527     QDirectPainter p(0, QDirectPainter::ReservedSynchronous);
       
   528     p.setRegion(r);
       
   529     QCOMPARE(p.allocatedRegion(), QRegion(r));
       
   530 
       
   531     { // Opaque widget, tests the blitting path in QScreen::compose()
       
   532         ColorWidget w(Qt::red);
       
   533         w.setGeometry(r);
       
   534         w.show();
       
   535         QCOMPARE(w.visibleRegion(), QRegion());
       
   536 
       
   537         // At this point w has a windowsurface but it's completely covered by
       
   538         // the directpainter so nothing will be painted here and the
       
   539         // windowsurface contains unitialized data.
       
   540 
       
   541         QApplication::processEvents();
       
   542         QCOMPARE(p.allocatedRegion(), QRegion(r));
       
   543         QCOMPARE(w.visibleRegion(), QRegion());
       
   544         fillWindowSurface(&w, Qt::black); // fill with "unitialized" data
       
   545 
       
   546         p.setRegion(QRegion());
       
   547 
       
   548         QCOMPARE(w.visibleRegion(), QRegion());
       
   549         VERIFY_COLOR(r, bgColor); // don't blit uninitialized data
       
   550         QTest::qWait(100);
       
   551 
       
   552         QApplication::processEvents(); // get new clip region
       
   553         QCOMPARE(w.visibleRegion().translated(w.geometry().topLeft()),
       
   554                  QRegion(r));
       
   555 
       
   556         QApplication::processEvents(); // do paint
       
   557         VERIFY_COLOR(r, w.color());
       
   558     }
       
   559 
       
   560     p.setRegion(r);
       
   561 
       
   562     { // Semi-transparent widget, tests the blending path in QScreen::compose()
       
   563         ColorWidget w(Qt::red);
       
   564         w.setGeometry(r);
       
   565         w.setWindowOpacity(0.44);
       
   566         w.show();
       
   567         QCOMPARE(w.visibleRegion(), QRegion());
       
   568 
       
   569         QApplication::processEvents();
       
   570         QCOMPARE(p.allocatedRegion(), QRegion(r));
       
   571         QCOMPARE(w.visibleRegion(), QRegion());
       
   572         fillWindowSurface(&w, Qt::black); // fill with "unitialized" data
       
   573 
       
   574         p.setRegion(QRegion());
       
   575 
       
   576         QCOMPARE(w.visibleRegion(), QRegion());
       
   577         VERIFY_COLOR(r, bgColor);
       
   578         QTest::qWait(100);
       
   579 
       
   580         QApplication::processEvents();
       
   581         QCOMPARE(w.visibleRegion().translated(w.geometry().topLeft()),
       
   582                  QRegion(r));
       
   583 
       
   584         QApplication::processEvents();
       
   585 
       
   586         // compose expected color
       
   587         QImage::Format screenFormat = QScreen::instance()->pixelFormat();
       
   588         if (screenFormat == QImage::Format_Invalid)
       
   589             screenFormat = QImage::Format_ARGB32_Premultiplied;
       
   590 
       
   591         QImage img(1, 1, screenFormat);
       
   592         {
       
   593             QPainter p(&img);
       
   594             p.fillRect(QRect(0, 0, 1, 1), bgColor);
       
   595             p.setOpacity(w.windowOpacity());
       
   596 #if 1
       
   597             QImage colorImage(1,1, screenFormat);
       
   598             {
       
   599                 QPainter urk(&colorImage);
       
   600                 urk.fillRect(QRect(0, 0, 1, 1), w.color());
       
   601             }
       
   602             p.drawImage(0,0,colorImage);
       
   603 #else
       
   604             p.fillRect(QRect(0, 0, 1, 1), w.color());
       
   605 #endif
       
   606         }
       
   607         VERIFY_COLOR(r, img.pixel(0, 0));
       
   608     }
       
   609 }
       
   610 
       
   611 void tst_QWSWindowSystem::task188025_data()
       
   612 {
       
   613     QTest::addColumn<int>("windowFlags");
       
   614 
       
   615     QTest::newRow("normal") << 0;
       
   616     QTest::newRow("paintonscreen") << int(Qt::WA_PaintOnScreen | Qt::Window);
       
   617 }
       
   618 
       
   619 void tst_QWSWindowSystem::task188025()
       
   620 {
       
   621     QFETCH(int, windowFlags);
       
   622     QRect r(-25, 50, 50, 50);
       
   623 
       
   624     ColorWidget w(Qt::red, Qt::WindowFlags(windowFlags));
       
   625     w.setGeometry(r);
       
   626     w.show();
       
   627     QApplication::processEvents();
       
   628     QApplication::sendPostedEvents(); // glib event loop workaround
       
   629 
       
   630     const QRect visible(0, 50, 25, 50);
       
   631     const QPoint topLeft = w.frameGeometry().topLeft();
       
   632     QCOMPARE(w.visibleRegion(), QRegion(visible.translated(-topLeft)));
       
   633     VERIFY_COLOR(visible, Qt::red);
       
   634 
       
   635     w.setMask(QRect(25, 0, 25, 50));
       
   636     QApplication::processEvents();
       
   637     QCOMPARE(w.visibleRegion(), QRegion(visible.translated(-topLeft)));
       
   638     VERIFY_COLOR(visible, Qt::red);
       
   639 
       
   640     // extend widget to the right (mask prevents new geometry to be exposed)
       
   641     r = r.adjusted(0, 0, 25, 0);
       
   642     w.setGeometry(r);
       
   643     QApplication::processEvents();
       
   644     QCOMPARE(w.visibleRegion(), QRegion(visible.translated(-topLeft)));
       
   645     VERIFY_COLOR(visible, Qt::red);
       
   646 }
       
   647 
       
   648 QTEST_MAIN(tst_QWSWindowSystem)
       
   649 
       
   650 #include "tst_qwswindowsystem.moc"
       
   651 
       
   652 #else // Q_WS_QWS
       
   653 QTEST_NOOP_MAIN
       
   654 #endif