tests/auto/qwidget/tst_qwidget.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
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 #if defined(QT3_SUPPORT)
       
    44 #include <q3hbox.h>
       
    45 #include <q3textedit.h>
       
    46 #endif
       
    47 #include <qboxlayout.h>
       
    48 #include <qapplication.h>
       
    49 #include <qbitmap.h>
       
    50 #include <qdebug.h>
       
    51 #include <qeventloop.h>
       
    52 #include <qlabel.h>
       
    53 #include <qlayout.h>
       
    54 #include <qlineedit.h>
       
    55 #include <qlistview.h>
       
    56 #include <qmessagebox.h>
       
    57 #include <qpainter.h>
       
    58 #include <qpoint.h>
       
    59 #include <qpushbutton.h>
       
    60 #include <qstyle.h>
       
    61 #include <qwidget.h>
       
    62 #include <qwindowsstyle.h>
       
    63 #include <qinputcontext.h>
       
    64 #include <qdesktopwidget.h>
       
    65 #include <private/qwidget_p.h>
       
    66 #include <private/qapplication_p.h>
       
    67 #include <qcalendarwidget.h>
       
    68 #include <qmainwindow.h>
       
    69 #include <QtGui/qpaintengine.h>
       
    70 #include <private/qbackingstore_p.h>
       
    71 
       
    72 #include <QtGui/QGraphicsView>
       
    73 #include <QtGui/QGraphicsProxyWidget>
       
    74 
       
    75 #include "../../shared/util.h"
       
    76 
       
    77 
       
    78 #ifdef Q_WS_S60
       
    79 #include <avkon.hrh>                // EEikStatusPaneUidTitle
       
    80 #include <akntitle.h>               // CAknTitlePane
       
    81 #include <akncontext.h>             // CAknContextPane
       
    82 #include <eikspane.h>               // CEikStatusPane
       
    83 #include <eikbtgpc.h>               // CEikButtonGroupContainer
       
    84 #endif
       
    85 
       
    86 #ifdef Q_WS_QWS
       
    87 # include <qscreen_qws.h>
       
    88 #endif
       
    89 
       
    90 // I *MUST* have QtTest afterwards or this test won't work with newer headers
       
    91 #if defined(Q_WS_MAC)
       
    92 # include <private/qt_mac_p.h>
       
    93 #undef verify
       
    94 #include "tst_qwidget_mac_helpers.h"  // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile.
       
    95 #endif
       
    96 
       
    97 #include <QtTest/QtTest>
       
    98 
       
    99 #if defined(Q_WS_WIN)
       
   100 #  include <qt_windows.h>
       
   101 #  if !defined(Q_OS_WINCE)
       
   102 #define Q_CHECK_PAINTEVENTS \
       
   103     if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
       
   104         QSKIP("desktop is not visible, this test would fail", SkipSingle);
       
   105 #  else
       
   106 #    define Q_CHECK_PAINTEVENTS
       
   107 #  endif
       
   108 #elif defined(Q_WS_X11)
       
   109 #  include <private/qt_x11_p.h>
       
   110 #  include <qx11info_x11.h>
       
   111 #elif defined(Q_WS_QWS)
       
   112 # include <qwindowsystem_qws.h>
       
   113 #endif
       
   114 
       
   115 #if !defined(Q_WS_WIN)
       
   116 #define Q_CHECK_PAINTEVENTS
       
   117 #endif
       
   118 
       
   119 #if defined(Q_OS_WINCE_WM)
       
   120 #include <qguifunctions_wince.h>
       
   121 // taken from qguifunctions_wce.cpp
       
   122 #define SPI_GETPLATFORMTYPE 257
       
   123 bool qt_wince_is_platform(const QString &platformString) {
       
   124     wchar_t tszPlatform[64];
       
   125     if (SystemParametersInfo(SPI_GETPLATFORMTYPE,
       
   126                              sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0))
       
   127       if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform))
       
   128             return true;
       
   129     return false;
       
   130 }
       
   131 bool qt_wince_is_smartphone() {
       
   132        return qt_wince_is_platform(QString::fromLatin1("Smartphone"));
       
   133 }
       
   134 #endif
       
   135 
       
   136 #ifdef Q_WS_MAC
       
   137 #include <Security/AuthSession.h>
       
   138 bool macHasAccessToWindowsServer()
       
   139 {
       
   140     SecuritySessionId mySession;
       
   141     SessionAttributeBits sessionInfo;
       
   142     SessionGetInfo(callerSecuritySession, &mySession, &sessionInfo);
       
   143     return (sessionInfo & sessionHasGraphicAccess);
       
   144 }
       
   145 #endif
       
   146 
       
   147 
       
   148 #if defined(Bool)
       
   149 #undef Bool
       
   150 #endif
       
   151 
       
   152 // Will try to wait for the condition while allowing event processing
       
   153 // for a maximum of 2 seconds.
       
   154 #define WAIT_FOR_CONDITION(expr, expected) \
       
   155     do { \
       
   156         const int step = 100; \
       
   157         for (int i = 0; i < 2000 && expr != expected; i+=step) { \
       
   158             QTest::qWait(step); \
       
   159         } \
       
   160     } while(0)
       
   161 
       
   162 //TESTED_CLASS=
       
   163 //TESTED_FILES=
       
   164 
       
   165 class tst_QWidget : public QObject
       
   166 {
       
   167     Q_OBJECT
       
   168 
       
   169 public:
       
   170     tst_QWidget();
       
   171     virtual ~tst_QWidget();
       
   172 
       
   173 
       
   174 public slots:
       
   175     void initTestCase();
       
   176     void cleanupTestCase();
       
   177     void init();
       
   178     void cleanup();
       
   179 private slots:
       
   180     void getSetCheck();
       
   181     void fontPropagation();
       
   182     void fontPropagation2();
       
   183     void palettePropagation();
       
   184     void palettePropagation2();
       
   185     void enabledPropagation();
       
   186     void acceptDropsPropagation();
       
   187     void isEnabledTo();
       
   188     void visible();
       
   189     void visible_setWindowOpacity();
       
   190     void isVisibleTo();
       
   191     void isHidden();
       
   192     void fonts();
       
   193     void mapToGlobal();
       
   194     void mapFromAndTo_data();
       
   195     void mapFromAndTo();
       
   196     void checkFocus();
       
   197     void focusChainOnHide();
       
   198     void focusChainOnReparent();
       
   199     void setTabOrder();
       
   200     void activation();
       
   201     void reparent();
       
   202     void windowState();
       
   203     void showMaximized();
       
   204     void showFullScreen();
       
   205     void showMinimized();
       
   206     void showMinimizedKeepsFocus();
       
   207     void icon();
       
   208     void hideWhenFocusWidgetIsChild();
       
   209     void normalGeometry();
       
   210     void setGeometry();
       
   211     void windowOpacity();
       
   212     void raise();
       
   213     void lower();
       
   214     void stackUnder();
       
   215     void testContentsPropagation();
       
   216     void saveRestoreGeometry();
       
   217 
       
   218     void restoreVersion1Geometry_data();
       
   219     void restoreVersion1Geometry();
       
   220 
       
   221     void windowTitle();
       
   222     void windowModified();
       
   223     void windowIconText();
       
   224 
       
   225     void widgetAt();
       
   226 #ifdef Q_WS_MAC
       
   227     void retainHIView();
       
   228     void sheetOpacity();
       
   229     void setMask();
       
   230 #endif
       
   231     void optimizedResizeMove();
       
   232     void optimizedResize_topLevel();
       
   233     void resizeEvent();
       
   234     void task110173();
       
   235 
       
   236     void testDeletionInEventHandlers();
       
   237 
       
   238     void childDeletesItsSibling();
       
   239 
       
   240     void setMinimumSize();
       
   241     void setMaximumSize();
       
   242     void setFixedSize();
       
   243 
       
   244     void ensureCreated();
       
   245     void winIdChangeEvent();
       
   246 #ifdef Q_OS_SYMBIAN
       
   247     void reparentCausesChildWinIdChange();
       
   248 #else
       
   249     void persistentWinId();
       
   250 #endif
       
   251     void qobject_castInDestroyedSlot();
       
   252 
       
   253     void showHideEvent_data();
       
   254     void showHideEvent();
       
   255 
       
   256     void lostUpdatesOnHide();
       
   257 
       
   258     void update();
       
   259     void isOpaque();
       
   260 
       
   261 #ifndef Q_WS_MAC
       
   262     void scroll();
       
   263 #endif
       
   264 
       
   265     // tests QWidget::setGeometry() on windows only
       
   266     void setWindowGeometry_data();
       
   267     void setWindowGeometry();
       
   268 
       
   269     // tests QWidget::move() and resize() on windows only
       
   270     void windowMoveResize_data();
       
   271     void windowMoveResize();
       
   272 
       
   273     void moveChild_data();
       
   274     void moveChild();
       
   275     void showAndMoveChild();
       
   276 
       
   277     void subtractOpaqueSiblings();
       
   278 
       
   279 #ifdef Q_WS_WIN
       
   280     void getDC();
       
   281 #ifndef Q_OS_WINCE
       
   282     void setGeometry_win();
       
   283 #endif
       
   284 #endif
       
   285 
       
   286     void setLocale();
       
   287     void deleteStyle();
       
   288     void multipleToplevelFocusCheck();
       
   289     void setFocus();
       
   290     void setCursor();
       
   291     void setToolTip();
       
   292     void testWindowIconChangeEventPropagation();
       
   293 #ifdef Q_WS_X11
       
   294     void minAndMaxSizeWithX11BypassWindowManagerHint();
       
   295     void showHideShow();
       
   296     void clean_qt_x11_enforce_cursor();
       
   297 #endif
       
   298 
       
   299     void compatibilityChildInsertedEvents();
       
   300     void render();
       
   301     void renderInvisible();
       
   302     void renderWithPainter();
       
   303     void render_task188133();
       
   304     void render_task211796();
       
   305     void render_task217815();
       
   306     void render_windowOpacity();
       
   307     void render_systemClip();
       
   308     void render_systemClip2_data();
       
   309     void render_systemClip2();
       
   310     void render_systemClip3_data();
       
   311     void render_systemClip3();
       
   312     void render_task252837();
       
   313     void render_worldTransform();
       
   314 
       
   315     void setContentsMargins();
       
   316 
       
   317     void moveWindowInShowEvent_data();
       
   318     void moveWindowInShowEvent();
       
   319 
       
   320     void repaintWhenChildDeleted();
       
   321     void hideOpaqueChildWhileHidden();
       
   322     void updateWhileMinimized();
       
   323 #if defined(Q_WS_WIN) || defined(Q_WS_X11)
       
   324     void alienWidgets();
       
   325 #endif
       
   326     void adjustSize();
       
   327     void adjustSize_data();
       
   328     void updateGeometry();
       
   329     void updateGeometry_data();
       
   330     void sendUpdateRequestImmediately();
       
   331     void painterRedirection();
       
   332     void doubleRepaint();
       
   333 #ifndef Q_WS_MAC
       
   334     void resizeInPaintEvent();
       
   335 #endif
       
   336 
       
   337     void setMaskInResizeEvent();
       
   338     void moveInResizeEvent();
       
   339 
       
   340 #if defined(Q_WS_WIN) || defined(Q_WS_X11)
       
   341     // We don't support immediate repaint right after show on
       
   342     // other platforms. Must be compatible with Qt 4.3.
       
   343     void immediateRepaintAfterShow();
       
   344     void immediateRepaintAfterInvalidateBuffer();
       
   345 #endif
       
   346     void effectiveWinId();
       
   347     void customDpi();
       
   348     void customDpiProperty();
       
   349 
       
   350     void quitOnCloseAttribute();
       
   351     void moveRect();
       
   352 
       
   353 #if defined (Q_WS_WIN)
       
   354     void gdiPainting();
       
   355     void paintOnScreenPossible();
       
   356 #endif
       
   357     void reparentStaticWidget();
       
   358 #ifdef Q_WS_QWS
       
   359     void updateOutsideSurfaceClip();
       
   360 #endif
       
   361     void translucentWidget();
       
   362 
       
   363     void setClearAndResizeMask();
       
   364     void maskedUpdate();
       
   365 #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS)
       
   366     void syntheticEnterLeave();
       
   367     void taskQTBUG_4055_sendSyntheticEnterLeave();
       
   368 #endif
       
   369     void windowFlags();
       
   370     void initialPosForDontShowOnScreenWidgets();
       
   371 #ifdef Q_WS_X11
       
   372     void paintOutsidePaintEvent();
       
   373 #endif
       
   374     void updateOnDestroyedSignal();
       
   375     void toplevelLineEditFocus();
       
   376     void inputFocus_task257832();
       
   377 
       
   378     void focusWidget_task254563();
       
   379     void rectOutsideCoordinatesLimit_task144779();
       
   380     void setGraphicsEffect();
       
   381 
       
   382     void destroyBackingStore();
       
   383 
       
   384     void activateWindow();
       
   385 
       
   386 #ifdef Q_OS_SYMBIAN
       
   387     void cbaVisibility();
       
   388 #endif
       
   389 
       
   390 private:
       
   391     bool ensureScreenSize(int width, int height);
       
   392     QWidget *testWidget;
       
   393 };
       
   394 
       
   395 bool tst_QWidget::ensureScreenSize(int width, int height)
       
   396 {
       
   397     QSize available;
       
   398 #ifdef Q_WS_QWS
       
   399     available = QDesktopWidget().availableGeometry().size();
       
   400     if (available.width() < width || available.height() < height) {
       
   401         QScreen *screen = QScreen::instance();
       
   402         if (!screen)
       
   403             return false;
       
   404         screen->setMode(width, height, screen->depth());
       
   405     }
       
   406 #endif // Q_WS_QWS
       
   407 
       
   408     available = QDesktopWidget().availableGeometry().size();
       
   409     return (available.width() >= width && available.height() >= height);
       
   410 }
       
   411 
       
   412 class MyInputContext : public QInputContext
       
   413 {
       
   414 public:
       
   415     MyInputContext() : QInputContext() {}
       
   416     QString identifierName() { return QString("NoName"); }
       
   417     QString language() { return QString("NoLanguage"); }
       
   418     void reset() {}
       
   419     bool isComposing() const { return false; }
       
   420 };
       
   421 
       
   422 // Testing get/set functions
       
   423 void tst_QWidget::getSetCheck()
       
   424 {
       
   425     QWidget obj1;
       
   426     QWidget child1(&obj1);
       
   427     // QStyle * QWidget::style()
       
   428     // void QWidget::setStyle(QStyle *)
       
   429     QWindowsStyle *var1 = new QWindowsStyle;
       
   430     obj1.setStyle(var1);
       
   431     QCOMPARE(static_cast<QStyle *>(var1), obj1.style());
       
   432     obj1.setStyle((QStyle *)0);
       
   433     QVERIFY(var1 != obj1.style());
       
   434     QVERIFY(0 != obj1.style()); // style can never be 0 for a widget
       
   435 
       
   436     // int QWidget::minimumWidth()
       
   437     // void QWidget::setMinimumWidth(int)
       
   438     obj1.setMinimumWidth(0);
       
   439     QCOMPARE(obj1.minimumWidth(), 0);
       
   440     obj1.setMinimumWidth(INT_MIN);
       
   441     QCOMPARE(obj1.minimumWidth(), 0); // A widgets width can never be less than 0
       
   442     obj1.setMinimumWidth(INT_MAX);
       
   443 #ifndef Q_WS_QWS  //QWS doesn't allow toplevels to be bigger than the screen
       
   444 #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
       
   445     QCOMPARE((long)obj1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
       
   446 #else
       
   447     QCOMPARE(obj1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
       
   448 #endif
       
   449 #endif
       
   450 
       
   451     child1.setMinimumWidth(0);
       
   452     QCOMPARE(child1.minimumWidth(), 0);
       
   453     child1.setMinimumWidth(INT_MIN);
       
   454     QCOMPARE(child1.minimumWidth(), 0); // A widgets width can never be less than 0
       
   455     child1.setMinimumWidth(INT_MAX);
       
   456 #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
       
   457     QCOMPARE((long)child1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
       
   458 #else
       
   459     QCOMPARE(child1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
       
   460 #endif
       
   461 
       
   462     // int QWidget::minimumHeight()
       
   463     // void QWidget::setMinimumHeight(int)
       
   464     obj1.setMinimumHeight(0);
       
   465     QCOMPARE(obj1.minimumHeight(), 0);
       
   466     obj1.setMinimumHeight(INT_MIN);
       
   467     QCOMPARE(obj1.minimumHeight(), 0); // A widgets height can never be less than 0
       
   468     obj1.setMinimumHeight(INT_MAX);
       
   469 #ifndef Q_WS_QWS    //QWS doesn't allow toplevels to be bigger than the screen
       
   470 #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
       
   471     QCOMPARE((long)obj1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
       
   472 #else
       
   473     QCOMPARE(obj1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
       
   474 #endif
       
   475 #endif
       
   476 
       
   477     child1.setMinimumHeight(0);
       
   478     QCOMPARE(child1.minimumHeight(), 0);
       
   479     child1.setMinimumHeight(INT_MIN);
       
   480     QCOMPARE(child1.minimumHeight(), 0); // A widgets height can never be less than 0
       
   481     child1.setMinimumHeight(INT_MAX);
       
   482 #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
       
   483     QCOMPARE((long)child1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
       
   484 #else
       
   485     QCOMPARE(child1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
       
   486 #endif
       
   487 
       
   488 
       
   489 
       
   490 // int QWidget::maximumWidth()
       
   491     // void QWidget::setMaximumWidth(int)
       
   492     obj1.setMaximumWidth(0);
       
   493     QCOMPARE(obj1.maximumWidth(), 0);
       
   494     obj1.setMaximumWidth(INT_MIN);
       
   495     QCOMPARE(obj1.maximumWidth(), 0); // A widgets width can never be less than 0
       
   496     obj1.setMaximumWidth(INT_MAX);
       
   497 #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
       
   498     QCOMPARE((long)obj1.maximumWidth(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
       
   499 #else
       
   500     QCOMPARE(obj1.maximumWidth(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
       
   501 #endif
       
   502 
       
   503     // int QWidget::maximumHeight()
       
   504     // void QWidget::setMaximumHeight(int)
       
   505     obj1.setMaximumHeight(0);
       
   506     QCOMPARE(obj1.maximumHeight(), 0);
       
   507     obj1.setMaximumHeight(INT_MIN);
       
   508     QCOMPARE(obj1.maximumHeight(), 0); // A widgets height can never be less than 0
       
   509     obj1.setMaximumHeight(INT_MAX);
       
   510 #if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
       
   511     QCOMPARE((long)obj1.maximumHeight(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
       
   512 #else
       
   513     QCOMPARE(obj1.maximumHeight(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
       
   514 #endif
       
   515 
       
   516     // back to normal
       
   517     obj1.setMinimumWidth(0);
       
   518     obj1.setMinimumHeight(0);
       
   519     obj1.setMaximumWidth(QWIDGETSIZE_MAX);
       
   520     obj1.setMaximumHeight(QWIDGETSIZE_MAX);
       
   521 
       
   522     // const QPalette & QWidget::palette()
       
   523     // void QWidget::setPalette(const QPalette &)
       
   524     QPalette var6;
       
   525     obj1.setPalette(var6);
       
   526     QCOMPARE(var6, obj1.palette());
       
   527     obj1.setPalette(QPalette());
       
   528     QCOMPARE(QPalette(), obj1.palette());
       
   529 
       
   530     // const QFont & QWidget::font()
       
   531     // void QWidget::setFont(const QFont &)
       
   532     QFont var7;
       
   533     obj1.setFont(var7);
       
   534     QCOMPARE(var7, obj1.font());
       
   535     obj1.setFont(QFont());
       
   536     QCOMPARE(QFont(), obj1.font());
       
   537 
       
   538     // qreal QWidget::windowOpacity()
       
   539     // void QWidget::setWindowOpacity(qreal)
       
   540     obj1.setWindowOpacity(0.0);
       
   541     QCOMPARE(0.0, obj1.windowOpacity());
       
   542     obj1.setWindowOpacity(1.1f);
       
   543     QCOMPARE(1.0, obj1.windowOpacity()); // 1.0 is the fullest opacity possible
       
   544 
       
   545     // QWidget * QWidget::focusProxy()
       
   546     // void QWidget::setFocusProxy(QWidget *)
       
   547     QWidget *var9 = new QWidget();
       
   548     obj1.setFocusProxy(var9);
       
   549     QCOMPARE(var9, obj1.focusProxy());
       
   550     obj1.setFocusProxy((QWidget *)0);
       
   551     QCOMPARE((QWidget *)0, obj1.focusProxy());
       
   552     delete var9;
       
   553 
       
   554     // const QRect & QWidget::geometry()
       
   555     // void QWidget::setGeometry(const QRect &)
       
   556     qApp->processEvents();
       
   557     QRect var10(10, 10, 100, 100);
       
   558     obj1.setGeometry(var10);
       
   559     qApp->processEvents();
       
   560     qDebug() << obj1.geometry();
       
   561     QCOMPARE(var10, obj1.geometry());
       
   562     obj1.setGeometry(QRect(0,0,0,0));
       
   563     qDebug() << obj1.geometry();
       
   564     QCOMPARE(QRect(0,0,0,0), obj1.geometry());
       
   565 
       
   566     // QLayout * QWidget::layout()
       
   567     // void QWidget::setLayout(QLayout *)
       
   568     QBoxLayout *var11 = new QBoxLayout(QBoxLayout::LeftToRight);
       
   569     obj1.setLayout(var11);
       
   570     QCOMPARE(static_cast<QLayout *>(var11), obj1.layout());
       
   571     obj1.setLayout((QLayout *)0);
       
   572     QCOMPARE(static_cast<QLayout *>(var11), obj1.layout()); // You cannot set a 0-pointer layout, that keeps the current
       
   573     delete var11; // This will remove the layout from the widget
       
   574     QCOMPARE((QLayout *)0, obj1.layout());
       
   575 
       
   576     // bool QWidget::acceptDrops()
       
   577     // void QWidget::setAcceptDrops(bool)
       
   578     obj1.setAcceptDrops(false);
       
   579     QCOMPARE(false, obj1.acceptDrops());
       
   580     obj1.setAcceptDrops(true);
       
   581     QCOMPARE(true, obj1.acceptDrops());
       
   582 
       
   583     // QInputContext * QWidget::inputContext()
       
   584     // void QWidget::setInputContext(QInputContext *)
       
   585     MyInputContext *var13 = new MyInputContext;
       
   586     obj1.setInputContext(var13);
       
   587     QCOMPARE((QInputContext *)0, obj1.inputContext()); // The widget by default doesn't have the WA_InputMethodEnabled attribute
       
   588     obj1.setAttribute(Qt::WA_InputMethodEnabled);
       
   589     obj1.setInputContext(var13);
       
   590     QCOMPARE(static_cast<QInputContext *>(var13), obj1.inputContext());
       
   591     obj1.setInputContext((QInputContext *)0);
       
   592     QCOMPARE(qApp->inputContext(), obj1.inputContext());
       
   593     QVERIFY(qApp->inputContext() != var13);
       
   594     //delete var13; // No delete, since QWidget takes ownership
       
   595 
       
   596     // bool QWidget::autoFillBackground()
       
   597     // void QWidget::setAutoFillBackground(bool)
       
   598     obj1.setAutoFillBackground(false);
       
   599     QCOMPARE(false, obj1.autoFillBackground());
       
   600     obj1.setAutoFillBackground(true);
       
   601     QCOMPARE(true, obj1.autoFillBackground());
       
   602 
       
   603     delete var1;
       
   604 #if defined (Q_WS_WIN) && !defined(Q_OS_WINCE)
       
   605     obj1.setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
       
   606     HWND handle = obj1.winId();
       
   607     long flags = GetWindowLong(handle, GWL_STYLE);
       
   608     QVERIFY(flags & WS_POPUP);
       
   609 #endif
       
   610 }
       
   611 
       
   612 tst_QWidget::tst_QWidget()
       
   613 {
       
   614     QFont font;
       
   615     font.setBold(true);
       
   616     font.setPointSize(42);
       
   617     qApp->setFont(font, "QPropagationTestWidget");
       
   618 
       
   619     QPalette palette;
       
   620     palette.setColor(QPalette::ToolTipBase, QColor(12, 13, 14));
       
   621     palette.setColor(QPalette::Text, QColor(21, 22, 23));
       
   622     qApp->setPalette(palette, "QPropagationTestWidget");
       
   623 
       
   624     testWidget = 0;
       
   625 }
       
   626 
       
   627 tst_QWidget::~tst_QWidget()
       
   628 {
       
   629 }
       
   630 
       
   631 class BezierViewer : public QWidget {
       
   632 public:
       
   633     BezierViewer( QWidget* parent=0, const char* name=0 );
       
   634     void paintEvent( QPaintEvent* );
       
   635     void setPoints( const QPolygonF& poly );
       
   636 private:
       
   637     QPolygonF points;
       
   638 
       
   639 };
       
   640 
       
   641 void tst_QWidget::initTestCase()
       
   642 {
       
   643 #ifdef Q_OS_WINCE //disable magic for WindowsCE
       
   644     qApp->setAutoMaximizeThreshold(-1);
       
   645 #endif
       
   646   // Create the test class
       
   647     testWidget = new BezierViewer( 0, "testObject");
       
   648     testWidget->resize(200,200);
       
   649 #ifdef QT3_SUPPORT
       
   650     qApp->setMainWidget(testWidget);
       
   651 #endif
       
   652     testWidget->show();
       
   653     QTest::qWaitForWindowShown(testWidget);
       
   654     QTest::qWait(50);
       
   655 }
       
   656 
       
   657 void tst_QWidget::cleanupTestCase()
       
   658 {
       
   659     delete testWidget;
       
   660     testWidget = 0;
       
   661 }
       
   662 
       
   663 void tst_QWidget::init()
       
   664 {
       
   665 // TODO: Add initialization code here.
       
   666 // This will be executed immediately before each test is run.
       
   667     testWidget->setFont(QFont());
       
   668     testWidget->setPalette(QPalette());
       
   669 }
       
   670 
       
   671 void tst_QWidget::cleanup()
       
   672 {
       
   673 }
       
   674 
       
   675 // Helper class...
       
   676 
       
   677 BezierViewer::BezierViewer( QWidget* parent, const char* name )
       
   678 	: QWidget( parent )
       
   679 {
       
   680     setObjectName(name);
       
   681     QPalette pal;
       
   682     pal.setColor(backgroundRole(), Qt::white);
       
   683     setPalette(pal);
       
   684 }
       
   685 
       
   686 
       
   687 void BezierViewer::setPoints( const QPolygonF& a )
       
   688 {
       
   689     points = a;
       
   690 }
       
   691 
       
   692 #include "private/qbezier_p.h"
       
   693 void BezierViewer::paintEvent( QPaintEvent* )
       
   694 {
       
   695     if ( points.size() != 4 ) {
       
   696 #if defined(QT_CHECK_RANGE)
       
   697 	qWarning( "QPolygon::bezier: The array must have 4 control points" );
       
   698 #endif
       
   699 	return;
       
   700     }
       
   701 
       
   702     /* Calculate Bezier curve */
       
   703     QPolygonF bezier = QBezier::fromPoints(points.at(0),points.at(1),points.at(2),points.at(3)).toPolygon();
       
   704 
       
   705     QPainter painter( this );
       
   706 
       
   707     /* Calculate scale to fit in window */
       
   708     QRectF br = bezier.boundingRect() | points.boundingRect();
       
   709     QRectF pr = rect();
       
   710     int scl = qMax( qMin(pr.width()/br.width(), pr.height()/br.height()), qreal(1.) );
       
   711     int border = scl-1;
       
   712 
       
   713     /* Scale Bezier curve vertices */
       
   714     for ( QPolygonF::Iterator it = bezier.begin(); it != bezier.end(); ++it ) {
       
   715 	it->setX( (it->x()-br.x()) * scl + border );
       
   716 	it->setY( (it->y()-br.y()) * scl + border );
       
   717     }
       
   718 
       
   719     /* Draw grid */
       
   720     painter.setPen( Qt::lightGray );
       
   721 	int i;
       
   722 	for ( i = border; i <= pr.width(); i += scl ) {
       
   723 		painter.drawLine( i, 0, i, pr.height() );
       
   724     }
       
   725     for ( int j = border; j <= pr.height(); j += scl ) {
       
   726 	painter.drawLine( 0, j, pr.width(), j );
       
   727     }
       
   728 
       
   729     /* Write number of vertices */
       
   730     painter.setPen( Qt::red );
       
   731     painter.setFont( QFont("Helvetica", 14, QFont::DemiBold, TRUE ) );
       
   732     QString caption;
       
   733     caption.setNum( bezier.size() );
       
   734     caption += QString::fromLatin1( " vertices" );
       
   735     painter.drawText( 10, pr.height()-10, caption );
       
   736 
       
   737     /* Draw Bezier curve */
       
   738     painter.setPen( Qt::black );
       
   739     painter.drawPolyline( bezier );
       
   740 
       
   741     /* Scale and draw control points */
       
   742     painter.setPen( Qt::darkGreen );
       
   743     for ( QPolygonF::Iterator p1 = points.begin(); p1 != points.end(); ++p1 ) {
       
   744 	int x = (p1->x()-br.x()) * scl + border;
       
   745 	int y = (p1->y()-br.y()) * scl + border;
       
   746 	painter.drawLine( x-4, y-4, x+4, y+4 );
       
   747 	painter.drawLine( x+4, y-4, x-4, y+4 );
       
   748     }
       
   749 
       
   750     /* Draw vertices */
       
   751     painter.setPen( Qt::red );
       
   752     painter.setBrush( Qt::red );
       
   753     for ( QPolygonF::Iterator p2 = bezier.begin(); p2 != bezier.end(); ++p2 )
       
   754 	painter.drawEllipse( p2->x()-1, p2->y()-1, 3, 3 );
       
   755 }
       
   756 
       
   757 void tst_QWidget::fontPropagation()
       
   758 {
       
   759     QFont font = testWidget->font();
       
   760     QWidget* childWidget = new QWidget( testWidget );
       
   761     childWidget->show();
       
   762     QCOMPARE( font, childWidget->font() );
       
   763 
       
   764     font.setBold( TRUE );
       
   765     testWidget->setFont( font );
       
   766     QCOMPARE( font, testWidget->font() );
       
   767     QCOMPARE( font, childWidget->font() );
       
   768 
       
   769     QFont newFont = font;
       
   770     newFont.setItalic( TRUE );
       
   771     childWidget->setFont( newFont );
       
   772     QWidget* grandChildWidget = new QWidget( childWidget );
       
   773     QCOMPARE( font, testWidget->font() );
       
   774     QCOMPARE( newFont, grandChildWidget->font() );
       
   775 
       
   776     font.setUnderline( TRUE );
       
   777     testWidget->setFont( font );
       
   778 
       
   779     // the child and grand child should now have merged bold and
       
   780     // underline
       
   781     newFont.setUnderline( TRUE );
       
   782 
       
   783     QCOMPARE( newFont, childWidget->font() );
       
   784     QCOMPARE( newFont, grandChildWidget->font() );
       
   785 
       
   786     // make sure font propagation continues working after reparenting
       
   787     font = testWidget->font();
       
   788     font.setPointSize(font.pointSize() + 2);
       
   789     testWidget->setFont(font);
       
   790 
       
   791     QWidget *one   = new QWidget(testWidget);
       
   792     QWidget *two   = new QWidget(one);
       
   793     QWidget *three = new QWidget(two);
       
   794     QWidget *four  = new QWidget(two);
       
   795 
       
   796     four->setParent(three);
       
   797     four->move(QPoint(0,0));
       
   798 
       
   799     font.setPointSize(font.pointSize() + 2);
       
   800     testWidget->setFont(font);
       
   801 
       
   802     QCOMPARE(testWidget->font(), one->font());
       
   803     QCOMPARE(one->font(), two->font());
       
   804     QCOMPARE(two->font(), three->font());
       
   805     QCOMPARE(three->font(), four->font());
       
   806 
       
   807     QVERIFY(testWidget->testAttribute(Qt::WA_SetFont));
       
   808     QVERIFY(! one->testAttribute(Qt::WA_SetFont));
       
   809     QVERIFY(! two->testAttribute(Qt::WA_SetFont));
       
   810     QVERIFY(! three->testAttribute(Qt::WA_SetFont));
       
   811     QVERIFY(! four->testAttribute(Qt::WA_SetFont));
       
   812 
       
   813     font.setPointSize(font.pointSize() + 2);
       
   814     one->setFont(font);
       
   815 
       
   816     QCOMPARE(one->font(), two->font());
       
   817     QCOMPARE(two->font(), three->font());
       
   818     QCOMPARE(three->font(), four->font());
       
   819 
       
   820     QVERIFY(one->testAttribute(Qt::WA_SetFont));
       
   821     QVERIFY(! two->testAttribute(Qt::WA_SetFont));
       
   822     QVERIFY(! three->testAttribute(Qt::WA_SetFont));
       
   823     QVERIFY(! four->testAttribute(Qt::WA_SetFont));
       
   824 
       
   825     font.setPointSize(font.pointSize() + 2);
       
   826     two->setFont(font);
       
   827 
       
   828     QCOMPARE(two->font(), three->font());
       
   829     QCOMPARE(three->font(), four->font());
       
   830 
       
   831     QVERIFY(two->testAttribute(Qt::WA_SetFont));
       
   832     QVERIFY(! three->testAttribute(Qt::WA_SetFont));
       
   833     QVERIFY(! four->testAttribute(Qt::WA_SetFont));
       
   834 
       
   835     font.setPointSize(font.pointSize() + 2);
       
   836     three->setFont(font);
       
   837 
       
   838     QCOMPARE(three->font(), four->font());
       
   839 
       
   840     QVERIFY(three->testAttribute(Qt::WA_SetFont));
       
   841     QVERIFY(! four->testAttribute(Qt::WA_SetFont));
       
   842 
       
   843     font.setPointSize(font.pointSize() + 2);
       
   844     four->setFont(font);
       
   845 
       
   846     QVERIFY(four->testAttribute(Qt::WA_SetFont));
       
   847 }
       
   848 
       
   849 class QPropagationTestWidget : public QWidget
       
   850 {
       
   851     Q_OBJECT
       
   852 public:
       
   853     QPropagationTestWidget(QWidget *parent = 0)
       
   854         : QWidget(parent)
       
   855     { }
       
   856 };
       
   857 
       
   858 void tst_QWidget::fontPropagation2()
       
   859 {
       
   860     // ! Note, the code below is executed in tst_QWidget's constructor.
       
   861     // QFont font;
       
   862     // font.setBold(true);
       
   863     // font.setPointSize(42);
       
   864     // qApp->setFont(font, "QPropagationTestWidget");
       
   865 
       
   866     QWidget *root = new QWidget;
       
   867     QWidget *child0 = new QWidget(root);
       
   868     QWidget *child1 = new QWidget(child0);
       
   869     QWidget *child2 = new QPropagationTestWidget(child1);
       
   870     QWidget *child3 = new QWidget(child2);
       
   871     QWidget *child4 = new QWidget(child3);
       
   872     QWidget *child5 = new QWidget(child4);
       
   873     root->show();
       
   874 
       
   875     // Check that only the application fonts apply.
       
   876     QCOMPARE(root->font(), QApplication::font());
       
   877     QCOMPARE(child0->font(), QApplication::font());
       
   878     QCOMPARE(child1->font(), QApplication::font());
       
   879     QCOMPARE(child2->font().pointSize(), 42);
       
   880     QVERIFY(child2->font().bold());
       
   881     QCOMPARE(child3->font().pointSize(), 42);
       
   882     QVERIFY(child3->font().bold());
       
   883     QCOMPARE(child4->font().pointSize(), 42);
       
   884     QVERIFY(child4->font().bold());
       
   885     QCOMPARE(child5->font().pointSize(), 42);
       
   886     QVERIFY(child5->font().bold());
       
   887 
       
   888     // Set child0's font size to 15, and remove bold on child4.
       
   889     QFont font;
       
   890     font.setPointSize(15);
       
   891     child0->setFont(font);
       
   892     QFont unboldFont;
       
   893     unboldFont.setBold(false);
       
   894     child4->setFont(unboldFont);
       
   895 
       
   896     // Check that the above settings propagate correctly.
       
   897     QCOMPARE(root->font(), QApplication::font());
       
   898     QCOMPARE(child0->font().pointSize(), 15);
       
   899     QVERIFY(!child0->font().bold());
       
   900     QCOMPARE(child1->font().pointSize(), 15);
       
   901     QVERIFY(!child1->font().bold());
       
   902     QCOMPARE(child2->font().pointSize(), 15);
       
   903     QVERIFY(child2->font().bold());
       
   904     QCOMPARE(child3->font().pointSize(), 15);
       
   905     QVERIFY(child3->font().bold());
       
   906     QCOMPARE(child4->font().pointSize(), 15);
       
   907     QVERIFY(!child4->font().bold());
       
   908     QCOMPARE(child5->font().pointSize(), 15);
       
   909     QVERIFY(!child5->font().bold());
       
   910 
       
   911     // Replace the app font for child2. Italic should propagate
       
   912     // but the size should still be ignored. The previous bold
       
   913     // setting is gone.
       
   914     QFont italicSizeFont;
       
   915     italicSizeFont.setItalic(true);
       
   916     italicSizeFont.setPointSize(33);
       
   917     qApp->setFont(italicSizeFont, "QPropagationTestWidget");
       
   918 
       
   919     // Check that this propagates correctly.
       
   920     QCOMPARE(root->font(), QApplication::font());
       
   921     QCOMPARE(child0->font().pointSize(), 15);
       
   922     QVERIFY(!child0->font().bold());
       
   923     QVERIFY(!child0->font().italic());
       
   924     QCOMPARE(child1->font().pointSize(), 15);
       
   925     QVERIFY(!child1->font().bold());
       
   926     QVERIFY(!child1->font().italic());
       
   927     QCOMPARE(child2->font().pointSize(), 15);
       
   928     QVERIFY(!child2->font().bold());
       
   929     QVERIFY(child2->font().italic());
       
   930     QCOMPARE(child3->font().pointSize(), 15);
       
   931     QVERIFY(!child3->font().bold());
       
   932     QVERIFY(child3->font().italic());
       
   933     QCOMPARE(child4->font().pointSize(), 15);
       
   934     QVERIFY(!child4->font().bold());
       
   935     QVERIFY(child4->font().italic());
       
   936     QCOMPARE(child5->font().pointSize(), 15);
       
   937     QVERIFY(!child5->font().bold());
       
   938     QVERIFY(child5->font().italic());
       
   939 }
       
   940 
       
   941 void tst_QWidget::palettePropagation()
       
   942 {
       
   943     QPalette palette = testWidget->palette();
       
   944     QWidget* childWidget = new QWidget( testWidget );
       
   945     childWidget->show();
       
   946     QCOMPARE( palette, childWidget->palette() );
       
   947 
       
   948     palette.setColor( QPalette::Base, Qt::red );
       
   949     testWidget->setPalette( palette );
       
   950     QCOMPARE( palette, testWidget->palette() );
       
   951     QCOMPARE( palette, childWidget->palette() );
       
   952 
       
   953     QPalette newPalette = palette;
       
   954     newPalette.setColor( QPalette::Highlight, Qt::green );
       
   955     childWidget->setPalette( newPalette );
       
   956     QWidget* grandChildWidget = new QWidget( childWidget );
       
   957     QCOMPARE( palette, testWidget->palette() );
       
   958     QCOMPARE( newPalette, grandChildWidget->palette() );
       
   959 
       
   960     palette.setColor( QPalette::Text, Qt::blue );
       
   961     testWidget->setPalette( palette );
       
   962 
       
   963     // the child and grand child should now have merged green
       
   964     // highlight and blue text
       
   965     newPalette.setColor( QPalette::Text, Qt::blue);
       
   966 
       
   967     QCOMPARE( newPalette, childWidget->palette() );
       
   968     QCOMPARE( newPalette, grandChildWidget->palette() );
       
   969 }
       
   970 
       
   971 void tst_QWidget::palettePropagation2()
       
   972 {
       
   973     // ! Note, the code below is executed in tst_QWidget's constructor.
       
   974     // QPalette palette;
       
   975     // font.setColor(QPalette::ToolTipBase, QColor(12, 13, 14));
       
   976     // font.setColor(QPalette::Text, QColor(21, 22, 23));
       
   977     // qApp->setPalette(palette, "QPropagationTestWidget");
       
   978 
       
   979     QWidget *root = new QWidget;
       
   980     QWidget *child0 = new QWidget(root);
       
   981     QWidget *child1 = new QWidget(child0);
       
   982     QWidget *child2 = new QPropagationTestWidget(child1);
       
   983     QWidget *child3 = new QWidget(child2);
       
   984     QWidget *child4 = new QWidget(child3);
       
   985     QWidget *child5 = new QWidget(child4);
       
   986     root->show();
       
   987     QTest::qWait(100);
       
   988 
       
   989     // These colors are unlikely to be imposed on the default palette of
       
   990     // QWidget ;-).
       
   991     QColor sysPalText(21, 22, 23);
       
   992     QColor sysPalToolTipBase(12, 13, 14);
       
   993     QColor overridePalText(42, 43, 44);
       
   994     QColor overridePalToolTipBase(45, 46, 47);
       
   995     QColor sysPalButton(99, 98, 97);
       
   996 
       
   997     // Check that only the application fonts apply.
       
   998     QPalette appPal = QApplication::palette();
       
   999     QCOMPARE(root->palette(), appPal);
       
  1000     QCOMPARE(child0->palette(), appPal);
       
  1001     QCOMPARE(child1->palette(), appPal);
       
  1002     QCOMPARE(child2->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
       
  1003     QCOMPARE(child2->palette().color(QPalette::Text), sysPalText);
       
  1004     QCOMPARE(child2->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1005     QCOMPARE(child3->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
       
  1006     QCOMPARE(child3->palette().color(QPalette::Text), sysPalText);
       
  1007     QCOMPARE(child3->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1008     QCOMPARE(child4->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
       
  1009     QCOMPARE(child4->palette().color(QPalette::Text), sysPalText);
       
  1010     QCOMPARE(child4->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1011     QCOMPARE(child5->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
       
  1012     QCOMPARE(child5->palette().color(QPalette::Text), sysPalText);
       
  1013     QCOMPARE(child5->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1014 
       
  1015     // Set child0's Text, and set ToolTipBase on child4.
       
  1016     QPalette textPalette;
       
  1017     textPalette.setColor(QPalette::Text, overridePalText);
       
  1018     child0->setPalette(textPalette);
       
  1019     QPalette toolTipPalette;
       
  1020     toolTipPalette.setColor(QPalette::ToolTipBase, overridePalToolTipBase);
       
  1021     child4->setPalette(toolTipPalette);
       
  1022 
       
  1023     // Check that the above settings propagate correctly.
       
  1024     QCOMPARE(root->palette(), appPal);
       
  1025     QCOMPARE(child0->palette().color(QPalette::Text), overridePalText);
       
  1026     QCOMPARE(child0->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
  1027     QCOMPARE(child0->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1028     QCOMPARE(child1->palette().color(QPalette::Text), overridePalText);
       
  1029     QCOMPARE(child1->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
  1030     QCOMPARE(child1->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1031     QCOMPARE(child2->palette().color(QPalette::Text), overridePalText);
       
  1032     QCOMPARE(child2->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
       
  1033     QCOMPARE(child2->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1034     QCOMPARE(child3->palette().color(QPalette::Text), overridePalText);
       
  1035     QCOMPARE(child3->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
       
  1036     QCOMPARE(child3->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1037     QCOMPARE(child4->palette().color(QPalette::Text), overridePalText);
       
  1038     QCOMPARE(child4->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
       
  1039     QCOMPARE(child4->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1040     QCOMPARE(child5->palette().color(QPalette::Text), overridePalText);
       
  1041     QCOMPARE(child5->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
       
  1042     QCOMPARE(child5->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1043 
       
  1044     // Replace the app palette for child2. Button should propagate but Text
       
  1045     // should still be ignored. The previous ToolTipBase setting is gone.
       
  1046     QPalette buttonPalette;
       
  1047     buttonPalette.setColor(QPalette::ToolTipText, sysPalButton);
       
  1048     qApp->setPalette(buttonPalette, "QPropagationTestWidget");
       
  1049 
       
  1050     // Check that the above settings propagate correctly.
       
  1051     QCOMPARE(root->palette(), appPal);
       
  1052     QCOMPARE(child0->palette().color(QPalette::Text), overridePalText);
       
  1053     QCOMPARE(child0->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
  1054     QCOMPARE(child0->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1055     QCOMPARE(child1->palette().color(QPalette::Text), overridePalText);
       
  1056     QCOMPARE(child1->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
  1057     QCOMPARE(child1->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
       
  1058     QCOMPARE(child2->palette().color(QPalette::Text), overridePalText);
       
  1059     QCOMPARE(child2->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
  1060     QCOMPARE(child2->palette().color(QPalette::ToolTipText), sysPalButton);
       
  1061     QCOMPARE(child3->palette().color(QPalette::Text), overridePalText);
       
  1062     QCOMPARE(child3->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
  1063     QCOMPARE(child3->palette().color(QPalette::ToolTipText), sysPalButton);
       
  1064     QCOMPARE(child4->palette().color(QPalette::Text), overridePalText);
       
  1065     QCOMPARE(child4->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
       
  1066     QCOMPARE(child4->palette().color(QPalette::ToolTipText), sysPalButton);
       
  1067     QCOMPARE(child5->palette().color(QPalette::Text), overridePalText);
       
  1068     QCOMPARE(child5->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
       
  1069     QCOMPARE(child5->palette().color(QPalette::ToolTipText), sysPalButton);
       
  1070 }
       
  1071 
       
  1072 void tst_QWidget::enabledPropagation()
       
  1073 {
       
  1074     QWidget* childWidget = new QWidget( testWidget );
       
  1075     childWidget->show();
       
  1076     QVERIFY( testWidget->isEnabled() );
       
  1077     QVERIFY( childWidget->isEnabled() );
       
  1078 
       
  1079     testWidget->setEnabled( FALSE );
       
  1080     QVERIFY( !testWidget->isEnabled() );
       
  1081     QVERIFY( !childWidget->isEnabled() );
       
  1082 
       
  1083     testWidget->setDisabled( FALSE );
       
  1084     QVERIFY( testWidget->isEnabled() );
       
  1085     QVERIFY( childWidget->isEnabled() );
       
  1086 
       
  1087     QWidget* grandChildWidget = new QWidget( childWidget );
       
  1088     QVERIFY( grandChildWidget->isEnabled() );
       
  1089 
       
  1090     testWidget->setDisabled( TRUE );
       
  1091     QVERIFY( !testWidget->isEnabled() );
       
  1092     QVERIFY( !childWidget->isEnabled() );
       
  1093     QVERIFY( !grandChildWidget->isEnabled() );
       
  1094 
       
  1095     grandChildWidget->setEnabled( FALSE );
       
  1096     testWidget->setEnabled( TRUE );
       
  1097     QVERIFY( testWidget->isEnabled() );
       
  1098     QVERIFY( childWidget->isEnabled() );
       
  1099     QVERIFY( !grandChildWidget->isEnabled() );
       
  1100 
       
  1101     grandChildWidget->setEnabled( TRUE );
       
  1102     testWidget->setEnabled( FALSE );
       
  1103     childWidget->setDisabled( TRUE );
       
  1104     testWidget->setEnabled( TRUE );
       
  1105     QVERIFY( testWidget->isEnabled() );
       
  1106     QVERIFY( !childWidget->isEnabled() );
       
  1107     QVERIFY( !grandChildWidget->isEnabled() );
       
  1108 }
       
  1109 
       
  1110 void tst_QWidget::acceptDropsPropagation()
       
  1111 {
       
  1112 #ifdef QT_NO_DRAGANDDROP
       
  1113     QSKIP("Drag'n drop disabled in this build", SkipAll);
       
  1114 #else
       
  1115     QWidget *childWidget = new QWidget(testWidget);
       
  1116     childWidget->show();
       
  1117     QVERIFY(!testWidget->acceptDrops());
       
  1118     QVERIFY(!childWidget->acceptDrops());
       
  1119 
       
  1120     testWidget->setAcceptDrops(true);
       
  1121     QVERIFY(testWidget->acceptDrops());
       
  1122     QVERIFY(!childWidget->acceptDrops());
       
  1123     QVERIFY(childWidget->testAttribute(Qt::WA_DropSiteRegistered));
       
  1124 
       
  1125     testWidget->setAcceptDrops(false);
       
  1126     QVERIFY(!testWidget->acceptDrops());
       
  1127     QVERIFY(!childWidget->acceptDrops());
       
  1128     QVERIFY(!childWidget->testAttribute(Qt::WA_DropSiteRegistered));
       
  1129 
       
  1130     QWidget *grandChildWidget = new QWidget(childWidget);
       
  1131     QVERIFY(!grandChildWidget->acceptDrops());
       
  1132     QVERIFY(!grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
       
  1133 
       
  1134     testWidget->setAcceptDrops(true);
       
  1135     QVERIFY(testWidget->acceptDrops());
       
  1136     QVERIFY(!childWidget->acceptDrops());
       
  1137     QVERIFY(childWidget->testAttribute(Qt::WA_DropSiteRegistered));
       
  1138     QVERIFY(!grandChildWidget->acceptDrops());
       
  1139     QVERIFY(grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
       
  1140 
       
  1141     grandChildWidget->setAcceptDrops(true);
       
  1142     testWidget->setAcceptDrops(false);
       
  1143     QVERIFY(!testWidget->acceptDrops());
       
  1144     QVERIFY(!childWidget->acceptDrops());
       
  1145     QVERIFY(grandChildWidget->acceptDrops());
       
  1146     QVERIFY(grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
       
  1147 
       
  1148 
       
  1149     grandChildWidget->setAcceptDrops(false);
       
  1150     QVERIFY(!grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
       
  1151     testWidget->setAcceptDrops(true);
       
  1152     childWidget->setAcceptDrops(true);
       
  1153     testWidget->setAcceptDrops(false);
       
  1154     QVERIFY(!testWidget->acceptDrops());
       
  1155     QVERIFY(childWidget->acceptDrops());
       
  1156     QVERIFY(!grandChildWidget->acceptDrops());
       
  1157     QVERIFY(grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
       
  1158 #endif
       
  1159 }
       
  1160 
       
  1161 void tst_QWidget::isEnabledTo()
       
  1162 {
       
  1163     QWidget* childWidget = new QWidget( testWidget );
       
  1164     QWidget* grandChildWidget = new QWidget( childWidget );
       
  1165 
       
  1166     QVERIFY( childWidget->isEnabledTo( testWidget ) );
       
  1167     QVERIFY( grandChildWidget->isEnabledTo( testWidget ) );
       
  1168 
       
  1169     childWidget->setEnabled( FALSE );
       
  1170     QVERIFY( !childWidget->isEnabledTo( testWidget ) );
       
  1171     QVERIFY( grandChildWidget->isEnabledTo( childWidget ) );
       
  1172     QVERIFY( !grandChildWidget->isEnabledTo( testWidget ) );
       
  1173 }
       
  1174 
       
  1175 void tst_QWidget::visible()
       
  1176 {
       
  1177     // Ensure that the testWidget is hidden for this test at the
       
  1178     // start
       
  1179 
       
  1180     testWidget->hide();
       
  1181     QVERIFY( !testWidget->isVisible() );
       
  1182     QWidget* childWidget = new QWidget( testWidget );
       
  1183     QVERIFY( !childWidget->isVisible() );
       
  1184 
       
  1185     testWidget->show();
       
  1186     QVERIFY( testWidget->isVisible() );
       
  1187     QVERIFY( childWidget->isVisible() );
       
  1188 
       
  1189     QWidget* grandChildWidget = new QWidget( childWidget );
       
  1190     QVERIFY( !grandChildWidget->isVisible() );
       
  1191     grandChildWidget->show();
       
  1192     QVERIFY( grandChildWidget->isVisible() );
       
  1193 
       
  1194     grandChildWidget->hide();
       
  1195     testWidget->hide();
       
  1196     testWidget->show();
       
  1197     QVERIFY( !grandChildWidget->isVisible() );
       
  1198     QVERIFY( testWidget->isVisible() );
       
  1199     QVERIFY( childWidget->isVisible() );
       
  1200 
       
  1201     grandChildWidget->show();
       
  1202     childWidget->hide();
       
  1203     testWidget->hide();
       
  1204     testWidget->show();
       
  1205     QVERIFY( testWidget->isVisible() );
       
  1206     QVERIFY( !childWidget->isVisible() );
       
  1207     QVERIFY( !grandChildWidget->isVisible() );
       
  1208 
       
  1209     grandChildWidget->show();
       
  1210     QVERIFY( !grandChildWidget->isVisible() );
       
  1211 }
       
  1212 
       
  1213 void tst_QWidget::setLocale()
       
  1214 {
       
  1215     QWidget w;
       
  1216     QCOMPARE(w.locale(), QLocale());
       
  1217 
       
  1218     w.setLocale(QLocale::Italian);
       
  1219     QCOMPARE(w.locale(), QLocale(QLocale::Italian));
       
  1220 
       
  1221     QWidget child1(&w);
       
  1222     QCOMPARE(child1.locale(), QLocale(QLocale::Italian));
       
  1223 
       
  1224     w.unsetLocale();
       
  1225     QCOMPARE(w.locale(), QLocale());
       
  1226     QCOMPARE(child1.locale(), QLocale());
       
  1227 
       
  1228     w.setLocale(QLocale::French);
       
  1229     QCOMPARE(w.locale(), QLocale(QLocale::French));
       
  1230     QCOMPARE(child1.locale(), QLocale(QLocale::French));
       
  1231 
       
  1232     child1.setLocale(QLocale::Italian);
       
  1233     QCOMPARE(w.locale(), QLocale(QLocale::French));
       
  1234     QCOMPARE(child1.locale(), QLocale(QLocale::Italian));
       
  1235 
       
  1236     child1.unsetLocale();
       
  1237     QCOMPARE(w.locale(), QLocale(QLocale::French));
       
  1238     QCOMPARE(child1.locale(), QLocale(QLocale::French));
       
  1239 
       
  1240     QWidget child2;
       
  1241     QCOMPARE(child2.locale(), QLocale());
       
  1242     child2.setParent(&w);
       
  1243     QCOMPARE(child2.locale(), QLocale(QLocale::French));
       
  1244 }
       
  1245 
       
  1246 void tst_QWidget::visible_setWindowOpacity()
       
  1247 {
       
  1248     testWidget->hide();
       
  1249     QVERIFY( !testWidget->isVisible() );
       
  1250     testWidget->setWindowOpacity(0.5);
       
  1251 #ifdef Q_OS_WIN
       
  1252     QVERIFY(::IsWindowVisible(testWidget->winId()) ==  FALSE);
       
  1253 #endif
       
  1254     testWidget->setWindowOpacity(1.0);
       
  1255 }
       
  1256 
       
  1257 void tst_QWidget::isVisibleTo()
       
  1258 {
       
  1259     // Ensure that the testWidget is hidden for this test at the
       
  1260     // start
       
  1261 
       
  1262     testWidget->hide();
       
  1263     QWidget* childWidget = new QWidget( testWidget );
       
  1264     QVERIFY( childWidget->isVisibleTo( testWidget ) );
       
  1265     childWidget->hide();
       
  1266     QVERIFY( !childWidget->isVisibleTo( testWidget ) );
       
  1267 
       
  1268     QWidget* grandChildWidget = new QWidget( childWidget );
       
  1269     QVERIFY( !grandChildWidget->isVisibleTo( testWidget ) );
       
  1270     QVERIFY( grandChildWidget->isVisibleTo( childWidget ) );
       
  1271 
       
  1272     testWidget->show();
       
  1273     childWidget->show();
       
  1274 
       
  1275     QVERIFY( childWidget->isVisibleTo( testWidget ) );
       
  1276     grandChildWidget->hide();
       
  1277     QVERIFY( !grandChildWidget->isVisibleTo( childWidget ) );
       
  1278     QVERIFY( !grandChildWidget->isVisibleTo( testWidget ) );
       
  1279 
       
  1280 }
       
  1281 
       
  1282 void tst_QWidget::isHidden()
       
  1283 {
       
  1284     // Ensure that the testWidget is hidden for this test at the
       
  1285     // start
       
  1286 
       
  1287     testWidget->hide();
       
  1288     QVERIFY( testWidget->isHidden() );
       
  1289     QWidget* childWidget = new QWidget( testWidget );
       
  1290     QVERIFY( !childWidget->isHidden() );
       
  1291 
       
  1292     testWidget->show();
       
  1293     QVERIFY( !testWidget->isHidden() );
       
  1294     QVERIFY( !childWidget->isHidden() );
       
  1295 
       
  1296     QWidget* grandChildWidget = new QWidget( childWidget );
       
  1297     QVERIFY( grandChildWidget->isHidden() );
       
  1298     grandChildWidget->show();
       
  1299     QVERIFY( !grandChildWidget->isHidden() );
       
  1300 
       
  1301     grandChildWidget->hide();
       
  1302     testWidget->hide();
       
  1303     testWidget->show();
       
  1304     QVERIFY( grandChildWidget->isHidden() );
       
  1305     QVERIFY( !testWidget->isHidden() );
       
  1306     QVERIFY( !childWidget->isHidden() );
       
  1307 
       
  1308     grandChildWidget->show();
       
  1309     childWidget->hide();
       
  1310     testWidget->hide();
       
  1311     testWidget->show();
       
  1312     QVERIFY( !testWidget->isHidden() );
       
  1313     QVERIFY( childWidget->isHidden() );
       
  1314     QVERIFY( !grandChildWidget->isHidden() );
       
  1315 
       
  1316     grandChildWidget->show();
       
  1317     QVERIFY( !grandChildWidget->isHidden() );
       
  1318 }
       
  1319 
       
  1320 void tst_QWidget::fonts()
       
  1321 {
       
  1322     // Tests setFont(), ownFont() and unsetFont()
       
  1323     QWidget* cleanTestWidget = new QWidget( testWidget );
       
  1324     QFont originalFont = cleanTestWidget->font();
       
  1325 
       
  1326     QVERIFY( !cleanTestWidget->testAttribute(Qt::WA_SetFont) );
       
  1327     cleanTestWidget->setFont(QFont());
       
  1328     QVERIFY( !cleanTestWidget->testAttribute(Qt::WA_SetFont) );
       
  1329 
       
  1330     QFont newFont( "times", 18 );
       
  1331     cleanTestWidget->setFont( newFont );
       
  1332     newFont = newFont.resolve( testWidget->font() );
       
  1333 
       
  1334     QVERIFY( cleanTestWidget->testAttribute(Qt::WA_SetFont) );
       
  1335     QVERIFY( cleanTestWidget->font() == newFont );
       
  1336 
       
  1337     cleanTestWidget->setFont(QFont());
       
  1338     QVERIFY( !cleanTestWidget->testAttribute(Qt::WA_SetFont) );
       
  1339     QVERIFY( cleanTestWidget->font() == originalFont );
       
  1340 }
       
  1341 
       
  1342 void tst_QWidget::mapToGlobal()
       
  1343 {
       
  1344 #if !defined(QT3_SUPPORT)
       
  1345     QSKIP("No Qt3 Support", SkipAll);
       
  1346 #else
       
  1347     QPoint vis = testWidget->mapToGlobal(QPoint(0,0));
       
  1348     testWidget->hide();
       
  1349     QCOMPARE(testWidget->mapToGlobal(QPoint(0,0)), vis);
       
  1350     testWidget->show();
       
  1351 
       
  1352     // test in a layout and witha move
       
  1353     Q3HBox * qhb = new Q3HBox(testWidget);
       
  1354     QWidget * qw = new QWidget(qhb);
       
  1355     qw->move(6,12);
       
  1356     QPoint wVis = qw->mapToGlobal(QPoint(0,0));
       
  1357     qw->hide();
       
  1358     QCOMPARE(qw->mapToGlobal(QPoint(0,0)), wVis);
       
  1359     delete qhb;
       
  1360 #endif // QT3_SUPPORT
       
  1361 }
       
  1362 
       
  1363 void tst_QWidget::mapFromAndTo_data()
       
  1364 {
       
  1365     QTest::addColumn<bool>("windowHidden");
       
  1366     QTest::addColumn<bool>("subWindow1Hidden");
       
  1367     QTest::addColumn<bool>("subWindow2Hidden");
       
  1368     QTest::addColumn<bool>("subSubWindowHidden");
       
  1369     QTest::addColumn<bool>("windowMinimized");
       
  1370     QTest::addColumn<bool>("subWindow1Minimized");
       
  1371 
       
  1372     QTest::newRow("window 1 sub1 1 sub2 1 subsub 1") << false << false << false << false << false << false;
       
  1373     QTest::newRow("window 0 sub1 1 sub2 1 subsub 1") << true << false << false << false << false << false;
       
  1374     QTest::newRow("window 1 sub1 0 sub2 1 subsub 1") << false << true << false << false << false << false;
       
  1375     QTest::newRow("window 0 sub1 0 sub2 1 subsub 1") << true << true << false << false << false << false;
       
  1376     QTest::newRow("window 1 sub1 1 sub2 0 subsub 1") << false << false << true << false << false << false;
       
  1377     QTest::newRow("window 0 sub1 1 sub2 0 subsub 1") << true << false << true << false << false << false;
       
  1378     QTest::newRow("window 1 sub1 0 sub2 0 subsub 1") << false << true << true << false << false << false;
       
  1379     QTest::newRow("window 0 sub1 0 sub2 0 subsub 1") << true << true << true << false << false << false;
       
  1380     QTest::newRow("window 1 sub1 1 sub2 1 subsub 0") << false << false << false << true << false << false;
       
  1381     QTest::newRow("window 0 sub1 1 sub2 1 subsub 0") << true << false << false << true << false << false;
       
  1382     QTest::newRow("window 1 sub1 0 sub2 1 subsub 0") << false << true << false << true << false << false;
       
  1383     QTest::newRow("window 0 sub1 0 sub2 1 subsub 0") << true << true << false << true << false << false;
       
  1384     QTest::newRow("window 1 sub1 1 sub2 0 subsub 0") << false << false << true << true << false << false;
       
  1385     QTest::newRow("window 0 sub1 1 sub2 0 subsub 0") << true << false << true << true << false << false;
       
  1386     QTest::newRow("window 1 sub1 0 sub2 0 subsub 0") << false << true << true << true << false << false;
       
  1387     QTest::newRow("window 0 sub1 0 sub2 0 subsub 0") << true << true << true << true << false << false;
       
  1388     QTest::newRow("window 1 sub1 1 sub2 1 subsub 1 windowMinimized") << false << false << false << false << true << false;
       
  1389     QTest::newRow("window 0 sub1 1 sub2 1 subsub 1 windowMinimized") << true << false << false << false << true << false;
       
  1390     QTest::newRow("window 1 sub1 0 sub2 1 subsub 1 windowMinimized") << false << true << false << false << true << false;
       
  1391     QTest::newRow("window 0 sub1 0 sub2 1 subsub 1 windowMinimized") << true << true << false << false << true << false;
       
  1392     QTest::newRow("window 1 sub1 1 sub2 0 subsub 1 windowMinimized") << false << false << true << false << true << false;
       
  1393     QTest::newRow("window 0 sub1 1 sub2 0 subsub 1 windowMinimized") << true << false << true << false << true << false;
       
  1394     QTest::newRow("window 1 sub1 0 sub2 0 subsub 1 windowMinimized") << false << true << true << false << true << false;
       
  1395     QTest::newRow("window 0 sub1 0 sub2 0 subsub 1 windowMinimized") << true << true << true << false << true << false;
       
  1396     QTest::newRow("window 1 sub1 1 sub2 1 subsub 0 windowMinimized") << false << false << false << true << true << false;
       
  1397     QTest::newRow("window 0 sub1 1 sub2 1 subsub 0 windowMinimized") << true << false << false << true << true << false;
       
  1398     QTest::newRow("window 1 sub1 0 sub2 1 subsub 0 windowMinimized") << false << true << false << true << true << false;
       
  1399     QTest::newRow("window 0 sub1 0 sub2 1 subsub 0 windowMinimized") << true << true << false << true << true << false;
       
  1400     QTest::newRow("window 1 sub1 1 sub2 0 subsub 0 windowMinimized") << false << false << true << true << true << false;
       
  1401     QTest::newRow("window 0 sub1 1 sub2 0 subsub 0 windowMinimized") << true << false << true << true << true << false;
       
  1402     QTest::newRow("window 1 sub1 0 sub2 0 subsub 0 windowMinimized") << false << true << true << true << true << false;
       
  1403     QTest::newRow("window 0 sub1 0 sub2 0 subsub 0 windowMinimized") << true << true << true << true << true << false;
       
  1404     QTest::newRow("window 1 sub1 1 sub2 1 subsub 1 subWindow1Minimized") << false << false << false << false << false << true;
       
  1405     QTest::newRow("window 0 sub1 1 sub2 1 subsub 1 subWindow1Minimized") << true << false << false << false << false << true;
       
  1406     QTest::newRow("window 1 sub1 0 sub2 1 subsub 1 subWindow1Minimized") << false << true << false << false << false << true;
       
  1407     QTest::newRow("window 0 sub1 0 sub2 1 subsub 1 subWindow1Minimized") << true << true << false << false << false << true;
       
  1408     QTest::newRow("window 1 sub1 1 sub2 0 subsub 1 subWindow1Minimized") << false << false << true << false << false << true;
       
  1409     QTest::newRow("window 0 sub1 1 sub2 0 subsub 1 subWindow1Minimized") << true << false << true << false << false << true;
       
  1410     QTest::newRow("window 1 sub1 0 sub2 0 subsub 1 subWindow1Minimized") << false << true << true << false << false << true;
       
  1411     QTest::newRow("window 0 sub1 0 sub2 0 subsub 1 subWindow1Minimized") << true << true << true << false << false << true;
       
  1412     QTest::newRow("window 1 sub1 1 sub2 1 subsub 0 subWindow1Minimized") << false << false << false << true << false << true;
       
  1413     QTest::newRow("window 0 sub1 1 sub2 1 subsub 0 subWindow1Minimized") << true << false << false << true << false << true;
       
  1414     QTest::newRow("window 1 sub1 0 sub2 1 subsub 0 subWindow1Minimized") << false << true << false << true << false << true;
       
  1415     QTest::newRow("window 0 sub1 0 sub2 1 subsub 0 subWindow1Minimized") << true << true << false << true << false << true;
       
  1416     QTest::newRow("window 1 sub1 1 sub2 0 subsub 0 subWindow1Minimized") << false << false << true << true << false << true;
       
  1417     QTest::newRow("window 0 sub1 1 sub2 0 subsub 0 subWindow1Minimized") << true << false << true << true << false << true;
       
  1418     QTest::newRow("window 1 sub1 0 sub2 0 subsub 0 subWindow1Minimized") << false << true << true << true << false << true;
       
  1419     QTest::newRow("window 0 sub1 0 sub2 0 subsub 0 subWindow1Minimized") << true << true << true << true << false << true;
       
  1420 
       
  1421 
       
  1422 }
       
  1423 
       
  1424 void tst_QWidget::mapFromAndTo()
       
  1425 {
       
  1426     QFETCH(bool, windowHidden);
       
  1427     QFETCH(bool, subWindow1Hidden);
       
  1428     QFETCH(bool, subWindow2Hidden);
       
  1429     QFETCH(bool, subSubWindowHidden);
       
  1430     QFETCH(bool, windowMinimized);
       
  1431     QFETCH(bool, subWindow1Minimized);
       
  1432 
       
  1433     // create a toplevel and two overlapping siblings
       
  1434     QWidget window;
       
  1435     window.setWindowFlags(window.windowFlags() | Qt::X11BypassWindowManagerHint);
       
  1436     QWidget *subWindow1 = new QWidget(&window);
       
  1437     QWidget *subWindow2 = new QWidget(&window);
       
  1438     QWidget *subSubWindow = new QWidget(subWindow1);
       
  1439 
       
  1440     // set their geometries
       
  1441     window.setGeometry(100, 100, 100, 100);
       
  1442     subWindow1->setGeometry(50, 50, 100, 100);
       
  1443     subWindow2->setGeometry(75, 75, 100, 100);
       
  1444     subSubWindow->setGeometry(10, 10, 10, 10);
       
  1445 
       
  1446 #if !defined (Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) //still no proper minimizing
       
  1447     //update visibility
       
  1448     if (windowMinimized) {
       
  1449         if (!windowHidden) {
       
  1450             window.showMinimized();
       
  1451             QVERIFY(window.isMinimized());
       
  1452         }
       
  1453     } else {
       
  1454         window.setVisible(!windowHidden);
       
  1455     }
       
  1456     if (subWindow1Minimized) {
       
  1457         subWindow1->hide();
       
  1458         subWindow1->showMinimized();
       
  1459         QVERIFY(subWindow1->isMinimized());
       
  1460     } else {
       
  1461         subWindow1->setVisible(!subWindow1Hidden);
       
  1462     }
       
  1463 #else
       
  1464     Q_UNUSED(windowHidden);
       
  1465     Q_UNUSED(subWindow1Hidden);
       
  1466     Q_UNUSED(windowMinimized);
       
  1467     Q_UNUSED(subWindow1Minimized);
       
  1468 #endif
       
  1469 
       
  1470     subWindow2->setVisible(!subWindow2Hidden);
       
  1471     subSubWindow->setVisible(!subSubWindowHidden);
       
  1472 
       
  1473     // window
       
  1474     QCOMPARE(window.mapToGlobal(QPoint(0, 0)), QPoint(100, 100));
       
  1475     QCOMPARE(window.mapToGlobal(QPoint(10, 0)), QPoint(110, 100));
       
  1476     QCOMPARE(window.mapToGlobal(QPoint(0, 10)), QPoint(100, 110));
       
  1477     QCOMPARE(window.mapToGlobal(QPoint(-10, 0)), QPoint(90, 100));
       
  1478     QCOMPARE(window.mapToGlobal(QPoint(0, -10)), QPoint(100, 90));
       
  1479     QCOMPARE(window.mapToGlobal(QPoint(100, 100)), QPoint(200, 200));
       
  1480     QCOMPARE(window.mapToGlobal(QPoint(110, 100)), QPoint(210, 200));
       
  1481     QCOMPARE(window.mapToGlobal(QPoint(100, 110)), QPoint(200, 210));
       
  1482     QCOMPARE(window.mapFromGlobal(QPoint(100, 100)), QPoint(0, 0));
       
  1483     QCOMPARE(window.mapFromGlobal(QPoint(110, 100)), QPoint(10, 0));
       
  1484     QCOMPARE(window.mapFromGlobal(QPoint(100, 110)), QPoint(0, 10));
       
  1485     QCOMPARE(window.mapFromGlobal(QPoint(90, 100)), QPoint(-10, 0));
       
  1486     QCOMPARE(window.mapFromGlobal(QPoint(100, 90)), QPoint(0, -10));
       
  1487     QCOMPARE(window.mapFromGlobal(QPoint(200, 200)), QPoint(100, 100));
       
  1488     QCOMPARE(window.mapFromGlobal(QPoint(210, 200)), QPoint(110, 100));
       
  1489     QCOMPARE(window.mapFromGlobal(QPoint(200, 210)), QPoint(100, 110));
       
  1490     QCOMPARE(window.mapToParent(QPoint(0, 0)), QPoint(100, 100));
       
  1491     QCOMPARE(window.mapToParent(QPoint(10, 0)), QPoint(110, 100));
       
  1492     QCOMPARE(window.mapToParent(QPoint(0, 10)), QPoint(100, 110));
       
  1493     QCOMPARE(window.mapToParent(QPoint(-10, 0)), QPoint(90, 100));
       
  1494     QCOMPARE(window.mapToParent(QPoint(0, -10)), QPoint(100, 90));
       
  1495     QCOMPARE(window.mapToParent(QPoint(100, 100)), QPoint(200, 200));
       
  1496     QCOMPARE(window.mapToParent(QPoint(110, 100)), QPoint(210, 200));
       
  1497     QCOMPARE(window.mapToParent(QPoint(100, 110)), QPoint(200, 210));
       
  1498     QCOMPARE(window.mapFromParent(QPoint(100, 100)), QPoint(0, 0));
       
  1499     QCOMPARE(window.mapFromParent(QPoint(110, 100)), QPoint(10, 0));
       
  1500     QCOMPARE(window.mapFromParent(QPoint(100, 110)), QPoint(0, 10));
       
  1501     QCOMPARE(window.mapFromParent(QPoint(90, 100)), QPoint(-10, 0));
       
  1502     QCOMPARE(window.mapFromParent(QPoint(100, 90)), QPoint(0, -10));
       
  1503     QCOMPARE(window.mapFromParent(QPoint(200, 200)), QPoint(100, 100));
       
  1504     QCOMPARE(window.mapFromParent(QPoint(210, 200)), QPoint(110, 100));
       
  1505     QCOMPARE(window.mapFromParent(QPoint(200, 210)), QPoint(100, 110));
       
  1506 
       
  1507     // first subwindow
       
  1508     QCOMPARE(subWindow1->mapToGlobal(QPoint(0, 0)), QPoint(150, 150));
       
  1509     QCOMPARE(subWindow1->mapToGlobal(QPoint(10, 0)), QPoint(160, 150));
       
  1510     QCOMPARE(subWindow1->mapToGlobal(QPoint(0, 10)), QPoint(150, 160));
       
  1511     QCOMPARE(subWindow1->mapToGlobal(QPoint(-10, 0)), QPoint(140, 150));
       
  1512     QCOMPARE(subWindow1->mapToGlobal(QPoint(0, -10)), QPoint(150, 140));
       
  1513     QCOMPARE(subWindow1->mapToGlobal(QPoint(100, 100)), QPoint(250, 250));
       
  1514     QCOMPARE(subWindow1->mapToGlobal(QPoint(110, 100)), QPoint(260, 250));
       
  1515     QCOMPARE(subWindow1->mapToGlobal(QPoint(100, 110)), QPoint(250, 260));
       
  1516     QCOMPARE(subWindow1->mapFromGlobal(QPoint(150, 150)), QPoint(0, 0));
       
  1517     QCOMPARE(subWindow1->mapFromGlobal(QPoint(160, 150)), QPoint(10, 0));
       
  1518     QCOMPARE(subWindow1->mapFromGlobal(QPoint(150, 160)), QPoint(0, 10));
       
  1519     QCOMPARE(subWindow1->mapFromGlobal(QPoint(140, 150)), QPoint(-10, 0));
       
  1520     QCOMPARE(subWindow1->mapFromGlobal(QPoint(150, 140)), QPoint(0, -10));
       
  1521     QCOMPARE(subWindow1->mapFromGlobal(QPoint(250, 250)), QPoint(100, 100));
       
  1522     QCOMPARE(subWindow1->mapFromGlobal(QPoint(260, 250)), QPoint(110, 100));
       
  1523     QCOMPARE(subWindow1->mapFromGlobal(QPoint(250, 260)), QPoint(100, 110));
       
  1524     QCOMPARE(subWindow1->mapToParent(QPoint(0, 0)), QPoint(50, 50));
       
  1525     QCOMPARE(subWindow1->mapToParent(QPoint(10, 0)), QPoint(60, 50));
       
  1526     QCOMPARE(subWindow1->mapToParent(QPoint(0, 10)), QPoint(50, 60));
       
  1527     QCOMPARE(subWindow1->mapToParent(QPoint(-10, 0)), QPoint(40, 50));
       
  1528     QCOMPARE(subWindow1->mapToParent(QPoint(0, -10)), QPoint(50, 40));
       
  1529     QCOMPARE(subWindow1->mapToParent(QPoint(100, 100)), QPoint(150, 150));
       
  1530     QCOMPARE(subWindow1->mapToParent(QPoint(110, 100)), QPoint(160, 150));
       
  1531     QCOMPARE(subWindow1->mapToParent(QPoint(100, 110)), QPoint(150, 160));
       
  1532     QCOMPARE(subWindow1->mapFromParent(QPoint(50, 50)), QPoint(0, 0));
       
  1533     QCOMPARE(subWindow1->mapFromParent(QPoint(60, 50)), QPoint(10, 0));
       
  1534     QCOMPARE(subWindow1->mapFromParent(QPoint(50, 60)), QPoint(0, 10));
       
  1535     QCOMPARE(subWindow1->mapFromParent(QPoint(40, 50)), QPoint(-10, 0));
       
  1536     QCOMPARE(subWindow1->mapFromParent(QPoint(50, 40)), QPoint(0, -10));
       
  1537     QCOMPARE(subWindow1->mapFromParent(QPoint(150, 150)), QPoint(100, 100));
       
  1538     QCOMPARE(subWindow1->mapFromParent(QPoint(160, 150)), QPoint(110, 100));
       
  1539     QCOMPARE(subWindow1->mapFromParent(QPoint(150, 160)), QPoint(100, 110));
       
  1540 
       
  1541     // subsubwindow
       
  1542     QCOMPARE(subSubWindow->mapToGlobal(QPoint(0, 0)), QPoint(160, 160));
       
  1543     QCOMPARE(subSubWindow->mapToGlobal(QPoint(10, 0)), QPoint(170, 160));
       
  1544     QCOMPARE(subSubWindow->mapToGlobal(QPoint(0, 10)), QPoint(160, 170));
       
  1545     QCOMPARE(subSubWindow->mapToGlobal(QPoint(-10, 0)), QPoint(150, 160));
       
  1546     QCOMPARE(subSubWindow->mapToGlobal(QPoint(0, -10)), QPoint(160, 150));
       
  1547     QCOMPARE(subSubWindow->mapToGlobal(QPoint(100, 100)), QPoint(260, 260));
       
  1548     QCOMPARE(subSubWindow->mapToGlobal(QPoint(110, 100)), QPoint(270, 260));
       
  1549     QCOMPARE(subSubWindow->mapToGlobal(QPoint(100, 110)), QPoint(260, 270));
       
  1550     QCOMPARE(subSubWindow->mapFromGlobal(QPoint(160, 160)), QPoint(0, 0));
       
  1551     QCOMPARE(subSubWindow->mapFromGlobal(QPoint(170, 160)), QPoint(10, 0));
       
  1552     QCOMPARE(subSubWindow->mapFromGlobal(QPoint(160, 170)), QPoint(0, 10));
       
  1553     QCOMPARE(subSubWindow->mapFromGlobal(QPoint(150, 160)), QPoint(-10, 0));
       
  1554     QCOMPARE(subSubWindow->mapFromGlobal(QPoint(160, 150)), QPoint(0, -10));
       
  1555     QCOMPARE(subSubWindow->mapFromGlobal(QPoint(260, 260)), QPoint(100, 100));
       
  1556     QCOMPARE(subSubWindow->mapFromGlobal(QPoint(270, 260)), QPoint(110, 100));
       
  1557     QCOMPARE(subSubWindow->mapFromGlobal(QPoint(260, 270)), QPoint(100, 110));
       
  1558     QCOMPARE(subSubWindow->mapToParent(QPoint(0, 0)), QPoint(10, 10));
       
  1559     QCOMPARE(subSubWindow->mapToParent(QPoint(10, 0)), QPoint(20, 10));
       
  1560     QCOMPARE(subSubWindow->mapToParent(QPoint(0, 10)), QPoint(10, 20));
       
  1561     QCOMPARE(subSubWindow->mapToParent(QPoint(-10, 0)), QPoint(0, 10));
       
  1562     QCOMPARE(subSubWindow->mapToParent(QPoint(0, -10)), QPoint(10, 0));
       
  1563     QCOMPARE(subSubWindow->mapToParent(QPoint(100, 100)), QPoint(110, 110));
       
  1564     QCOMPARE(subSubWindow->mapToParent(QPoint(110, 100)), QPoint(120, 110));
       
  1565     QCOMPARE(subSubWindow->mapToParent(QPoint(100, 110)), QPoint(110, 120));
       
  1566     QCOMPARE(subSubWindow->mapFromParent(QPoint(10, 10)), QPoint(0, 0));
       
  1567     QCOMPARE(subSubWindow->mapFromParent(QPoint(20, 10)), QPoint(10, 0));
       
  1568     QCOMPARE(subSubWindow->mapFromParent(QPoint(10, 20)), QPoint(0, 10));
       
  1569     QCOMPARE(subSubWindow->mapFromParent(QPoint(0, 10)), QPoint(-10, 0));
       
  1570     QCOMPARE(subSubWindow->mapFromParent(QPoint(10, 0)), QPoint(0, -10));
       
  1571     QCOMPARE(subSubWindow->mapFromParent(QPoint(110, 110)), QPoint(100, 100));
       
  1572     QCOMPARE(subSubWindow->mapFromParent(QPoint(120, 110)), QPoint(110, 100));
       
  1573     QCOMPARE(subSubWindow->mapFromParent(QPoint(110, 120)), QPoint(100, 110));
       
  1574 }
       
  1575 
       
  1576 void tst_QWidget::focusChainOnReparent()
       
  1577 {
       
  1578     QWidget window;
       
  1579     QWidget *child1 = new QWidget(&window);
       
  1580     QWidget *child2 = new QWidget(&window);
       
  1581     QWidget *child3 = new QWidget(&window);
       
  1582     QWidget *child21 = new QWidget(child2);
       
  1583     QWidget *child22 = new QWidget(child2);
       
  1584     QWidget *child4 = new QWidget(&window);
       
  1585 
       
  1586     QWidget *expectedOriginalChain[8] = {&window, child1,  child2,  child3,  child21, child22, child4, &window};
       
  1587     QWidget *w = &window;
       
  1588     for (int i = 0; i <8; ++i) {
       
  1589         QCOMPARE(w, expectedOriginalChain[i]);
       
  1590         w = w->nextInFocusChain();
       
  1591     }
       
  1592     for (int i = 7; i >= 0; --i) {
       
  1593         w = w->previousInFocusChain();
       
  1594         QCOMPARE(w, expectedOriginalChain[i]);
       
  1595     }
       
  1596 
       
  1597     QWidget window2;
       
  1598     child2->setParent(&window2);
       
  1599 
       
  1600     QWidget *expectedNewChain[5] = {&window2, child2,  child21, child22, &window2};
       
  1601     w = &window2;
       
  1602     for (int i = 0; i <5; ++i) {
       
  1603         QCOMPARE(w, expectedNewChain[i]);
       
  1604         w = w->nextInFocusChain();
       
  1605     }
       
  1606     for (int i = 4; i >= 0; --i) {
       
  1607         w = w->previousInFocusChain();
       
  1608         QCOMPARE(w, expectedNewChain[i]);
       
  1609     }
       
  1610 
       
  1611     QWidget *expectedOldChain[5] = {&window, child1,  child3, child4, &window};
       
  1612     w = &window;
       
  1613     for (int i = 0; i <5; ++i) {
       
  1614         QCOMPARE(w, expectedOldChain[i]);
       
  1615         w = w->nextInFocusChain();
       
  1616     }
       
  1617     for (int i = 4; i >= 0; --i) {
       
  1618         w = w->previousInFocusChain();
       
  1619         QCOMPARE(w, expectedOldChain[i]);
       
  1620     }
       
  1621 }
       
  1622 
       
  1623 
       
  1624 void tst_QWidget::focusChainOnHide()
       
  1625 {
       
  1626     testWidget->hide(); // We do not want to get disturbed by other widgets
       
  1627     // focus should move to the next widget in the focus chain when we hide it.
       
  1628     QWidget *parent = new QWidget();
       
  1629     parent->setObjectName(QLatin1String("Parent"));
       
  1630     parent->setFocusPolicy(Qt::StrongFocus);
       
  1631     QWidget *child = new QWidget(parent);
       
  1632     child->setObjectName(QLatin1String("child"));
       
  1633     child->setFocusPolicy(Qt::StrongFocus);
       
  1634     QWidget::setTabOrder(child, parent);
       
  1635 
       
  1636     parent->show();
       
  1637     qApp->setActiveWindow(parent->window());
       
  1638     child->activateWindow();
       
  1639     child->setFocus();
       
  1640     qApp->processEvents();
       
  1641 
       
  1642     WAIT_FOR_CONDITION(child->hasFocus(), true);
       
  1643     QCOMPARE(child->hasFocus(), true);
       
  1644     child->hide();
       
  1645     qApp->processEvents();
       
  1646 
       
  1647     WAIT_FOR_CONDITION(parent->hasFocus(), true);
       
  1648     QCOMPARE(parent->hasFocus(), true);
       
  1649     QCOMPARE(parent, qApp->focusWidget());
       
  1650 
       
  1651     delete parent;
       
  1652     testWidget->show(); //don't disturb later tests
       
  1653 }
       
  1654 
       
  1655 void tst_QWidget::checkFocus()
       
  1656 {
       
  1657 #if !defined(QT3_SUPPORT)
       
  1658     QSKIP("No Qt3 Support", SkipAll);
       
  1659 #else
       
  1660     // This is a very specific test for a specific bug, the bug was
       
  1661     // that when setEnabled(FALSE) then setEnabled(TRUE) was called on
       
  1662     // the parent of a child widget which had focus while hidden, then
       
  1663     // when the widget was shown, the focus would be in the wrong place.
       
  1664 
       
  1665     Q3HBox widget;
       
  1666     QLineEdit *focusWidget = new QLineEdit( &widget );
       
  1667     new QLineEdit( &widget );
       
  1668     new QPushButton( &widget );
       
  1669     focusWidget->setFocus();
       
  1670     widget.setEnabled( FALSE );
       
  1671     widget.setEnabled( TRUE );
       
  1672     widget.show();
       
  1673 #ifdef Q_WS_X11
       
  1674     qt_x11_wait_for_window_manager(&widget);
       
  1675 #endif
       
  1676     QTest::qWait( 100 );
       
  1677     widget.activateWindow();
       
  1678     // next call is necessary since the window manager may not give the focus to the widget when
       
  1679     // it is shown, which causes the QVERIFY to fail
       
  1680     QApplication::setActiveWindow(&widget);
       
  1681     QVERIFY( qApp->focusWidget() == focusWidget );
       
  1682 #endif // QT3_SUPPORT
       
  1683 }
       
  1684 
       
  1685 class Container : public QWidget
       
  1686 {
       
  1687 public:
       
  1688     QVBoxLayout* box;
       
  1689 
       
  1690     Container()
       
  1691     {
       
  1692         box = new QVBoxLayout(this);
       
  1693 	//(new QVBoxLayout(this))->setAutoAdd(true);
       
  1694     }
       
  1695 
       
  1696     void tab()
       
  1697     {
       
  1698 	focusNextPrevChild(TRUE);
       
  1699     }
       
  1700 
       
  1701     void backTab()
       
  1702     {
       
  1703 	focusNextPrevChild(FALSE);
       
  1704     }
       
  1705 };
       
  1706 
       
  1707 class Composite : public QFrame
       
  1708 {
       
  1709 public:
       
  1710     Composite(QWidget* parent = 0, const char* name = 0)
       
  1711         : QFrame(parent)
       
  1712     {
       
  1713         setObjectName(name);
       
  1714         //QHBoxLayout* hbox = new QHBoxLayout(this, 2, 0);
       
  1715         //hbox->setAutoAdd(true);
       
  1716         QHBoxLayout* hbox = new QHBoxLayout(this);
       
  1717 
       
  1718         lineEdit = new QLineEdit(this);
       
  1719         hbox->addWidget(lineEdit);
       
  1720 
       
  1721         button = new QPushButton(this);
       
  1722         hbox->addWidget(button);
       
  1723         button->setFocusPolicy( Qt::NoFocus );
       
  1724 
       
  1725         setFocusProxy( lineEdit );
       
  1726         setFocusPolicy( Qt::StrongFocus );
       
  1727 
       
  1728 	setTabOrder(lineEdit, button);
       
  1729     }
       
  1730 
       
  1731 private:
       
  1732     QLineEdit* lineEdit;
       
  1733     QPushButton* button;
       
  1734 };
       
  1735 
       
  1736 #define NUM_WIDGETS 4
       
  1737 
       
  1738 void tst_QWidget::setTabOrder()
       
  1739 {
       
  1740     QTest::qWait(100);
       
  1741 
       
  1742     Container container;
       
  1743 
       
  1744     Composite* comp[NUM_WIDGETS];
       
  1745 
       
  1746     QLineEdit *firstEdit = new QLineEdit(&container);
       
  1747     container.box->addWidget(firstEdit);
       
  1748 
       
  1749     int i = 0;
       
  1750     for(i = 0; i < NUM_WIDGETS; i++) {
       
  1751         comp[i] = new Composite(&container);
       
  1752         container.box->addWidget(comp[i]);
       
  1753     }
       
  1754 
       
  1755     QLineEdit *lastEdit = new QLineEdit(&container);
       
  1756     container.box->addWidget(lastEdit);
       
  1757 
       
  1758     container.setTabOrder(lastEdit, comp[NUM_WIDGETS-1]);
       
  1759     for(i = NUM_WIDGETS-1; i > 0; i--) {
       
  1760         container.setTabOrder(comp[i], comp[i-1]);
       
  1761     }
       
  1762     container.setTabOrder(comp[0], firstEdit);
       
  1763 
       
  1764     int current = NUM_WIDGETS-1;
       
  1765     lastEdit->setFocus();
       
  1766 
       
  1767     container.show();
       
  1768     container.activateWindow();
       
  1769     qApp->setActiveWindow(&container);
       
  1770 #ifdef Q_WS_X11
       
  1771     QTest::qWaitForWindowShown(&container);
       
  1772     QTest::qWait(50);
       
  1773 #endif
       
  1774 
       
  1775     QTest::qWait(100);
       
  1776 
       
  1777     QTRY_VERIFY(lastEdit->hasFocus());
       
  1778     container.tab();
       
  1779     do {
       
  1780 	QVERIFY(comp[current]->focusProxy()->hasFocus());
       
  1781 	container.tab();
       
  1782 	current--;
       
  1783     } while (current >= 0);
       
  1784 
       
  1785     QVERIFY(firstEdit->hasFocus());
       
  1786 }
       
  1787 
       
  1788 void tst_QWidget::activation()
       
  1789 {
       
  1790 #if !defined(Q_WS_WIN)
       
  1791     QSKIP("This test is Windows-only.", SkipAll);
       
  1792 #endif
       
  1793     Q_CHECK_PAINTEVENTS
       
  1794 
       
  1795 #if defined(Q_OS_WINCE)
       
  1796     int waitTime = 1000;
       
  1797 #else
       
  1798     int waitTime = 100;
       
  1799 #endif
       
  1800 
       
  1801 #ifdef Q_OS_WINCE
       
  1802     qApp->processEvents();
       
  1803 #endif
       
  1804     QWidget widget1;
       
  1805     widget1.setWindowTitle("Widget1");
       
  1806 
       
  1807     QWidget widget2;
       
  1808     widget2.setWindowTitle("Widget2");
       
  1809 
       
  1810     widget1.show();
       
  1811     widget2.show();
       
  1812 
       
  1813     QTest::qWait(waitTime);
       
  1814     QVERIFY(qApp->activeWindow() == &widget2);
       
  1815     widget2.showMinimized();
       
  1816     QTest::qWait(waitTime);
       
  1817 
       
  1818     QVERIFY(qApp->activeWindow() == &widget1);
       
  1819     widget2.showMaximized();
       
  1820     QTest::qWait(waitTime);
       
  1821     QVERIFY(qApp->activeWindow() == &widget2);
       
  1822     widget2.showMinimized();
       
  1823     QTest::qWait(waitTime);
       
  1824     QVERIFY(qApp->activeWindow() == &widget1);
       
  1825     widget2.showNormal();
       
  1826     QTest::qWait(waitTime);
       
  1827 #if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
       
  1828     if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
       
  1829         QEXPECT_FAIL("", "MS introduced new behavior after XP", Continue);
       
  1830 #endif
       
  1831     QTest::qWait(waitTime);
       
  1832     QVERIFY(qApp->activeWindow() == &widget2);
       
  1833     widget2.hide();
       
  1834     QTest::qWait(waitTime);
       
  1835     QVERIFY(qApp->activeWindow() == &widget1);
       
  1836 }
       
  1837 
       
  1838 void tst_QWidget::windowState()
       
  1839 {
       
  1840 #ifdef Q_WS_X11
       
  1841     QSKIP("Many window managers do not support window state properly, which causes this "
       
  1842          "test to fail.", SkipAll);
       
  1843 #else
       
  1844 #ifdef Q_OS_WINCE_WM
       
  1845     QPoint pos(500, 500);
       
  1846     QSize size(200, 200);
       
  1847     if (qt_wince_is_smartphone()) { //small screen
       
  1848         pos = QPoint(10,10);
       
  1849         size = QSize(100,100);
       
  1850     }
       
  1851 #elif defined(Q_WS_S60)
       
  1852     QPoint pos = QPoint(10,10);
       
  1853     QSize size = QSize(100,100);
       
  1854 #else
       
  1855     const QPoint pos(500, 500);
       
  1856     const QSize size(200, 200);
       
  1857 #endif
       
  1858 
       
  1859     QWidget widget1;
       
  1860     widget1.move(pos);
       
  1861     widget1.resize(size);
       
  1862     QCOMPARE(widget1.pos(), pos);
       
  1863     QCOMPARE(widget1.size(), size);
       
  1864     QTest::qWait(100);
       
  1865     widget1.setWindowTitle("Widget1");
       
  1866     QCOMPARE(widget1.pos(), pos);
       
  1867     QCOMPARE(widget1.size(), size);
       
  1868 
       
  1869 #define VERIFY_STATE(s) QCOMPARE(int(widget1.windowState() & stateMask), int(s))
       
  1870 
       
  1871     const int stateMask = Qt::WindowMaximized|Qt::WindowMinimized|Qt::WindowFullScreen;
       
  1872 
       
  1873     widget1.setWindowState(Qt::WindowMaximized);
       
  1874     QTest::qWait(100);
       
  1875     VERIFY_STATE(Qt::WindowMaximized);
       
  1876 
       
  1877     widget1.show();
       
  1878     QTest::qWait(100);
       
  1879     VERIFY_STATE(Qt::WindowMaximized);
       
  1880 
       
  1881     widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
       
  1882     QTest::qWait(100);
       
  1883     QVERIFY(!(widget1.windowState() & Qt::WindowMaximized));
       
  1884     QCOMPARE(widget1.pos(), pos);
       
  1885 
       
  1886     widget1.setWindowState(Qt::WindowMinimized);
       
  1887     QTest::qWait(100);
       
  1888     VERIFY_STATE(Qt::WindowMinimized);
       
  1889 
       
  1890     widget1.setWindowState(widget1.windowState() | Qt::WindowMaximized);
       
  1891     QTest::qWait(100);
       
  1892     VERIFY_STATE((Qt::WindowMinimized|Qt::WindowMaximized));
       
  1893 
       
  1894     widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
       
  1895     QTest::qWait(100);
       
  1896     VERIFY_STATE(Qt::WindowMaximized);
       
  1897 
       
  1898     widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
       
  1899     QTest::qWait(100);
       
  1900     QVERIFY(!(widget1.windowState() & (Qt::WindowMinimized|Qt::WindowMaximized)));
       
  1901     QCOMPARE(widget1.pos(), pos);
       
  1902 
       
  1903     widget1.setWindowState(Qt::WindowFullScreen);
       
  1904     QTest::qWait(100);
       
  1905     VERIFY_STATE(Qt::WindowFullScreen);
       
  1906 
       
  1907     widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
       
  1908     QTest::qWait(100);
       
  1909     VERIFY_STATE((Qt::WindowFullScreen|Qt::WindowMinimized));
       
  1910 
       
  1911     widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
       
  1912     QTest::qWait(100);
       
  1913     VERIFY_STATE(Qt::WindowFullScreen);
       
  1914 
       
  1915     widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
       
  1916     QTest::qWait(100);
       
  1917     VERIFY_STATE((Qt::WindowFullScreen|Qt::WindowMaximized));
       
  1918 
       
  1919     widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
       
  1920     QTest::qWait(100);
       
  1921     VERIFY_STATE((Qt::WindowFullScreen|Qt::WindowMaximized|Qt::WindowMinimized));
       
  1922 
       
  1923     widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
       
  1924     QTest::qWait(100);
       
  1925     VERIFY_STATE((Qt::WindowFullScreen|Qt::WindowMaximized));
       
  1926 
       
  1927     widget1.setWindowState(widget1.windowState() ^ Qt::WindowFullScreen);
       
  1928     QTest::qWait(100);
       
  1929     VERIFY_STATE(Qt::WindowMaximized);
       
  1930 
       
  1931     widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
       
  1932     QTest::qWait(100);
       
  1933     QVERIFY(!(widget1.windowState() & stateMask));
       
  1934 
       
  1935     QCOMPARE(widget1.pos(), pos);
       
  1936     QCOMPARE(widget1.size(), size);
       
  1937 #endif
       
  1938 }
       
  1939 
       
  1940 void tst_QWidget::showMaximized()
       
  1941 {
       
  1942     QWidget plain;
       
  1943     QHBoxLayout *layout;
       
  1944     layout = new QHBoxLayout;
       
  1945     QWidget layouted;
       
  1946     QLineEdit le;
       
  1947     QLineEdit le2;
       
  1948     QLineEdit le3;
       
  1949 
       
  1950     layout->addWidget(&le);
       
  1951     layout->addWidget(&le2);
       
  1952     layout->addWidget(&le3);
       
  1953 
       
  1954     layouted.setLayout(layout);
       
  1955 
       
  1956     plain.showMaximized();
       
  1957     QVERIFY(plain.windowState() & Qt::WindowMaximized);
       
  1958 
       
  1959     plain.showNormal();
       
  1960     QVERIFY(!(plain.windowState() & Qt::WindowMaximized));
       
  1961 
       
  1962     layouted.showMaximized();
       
  1963     QVERIFY(layouted.windowState() & Qt::WindowMaximized);
       
  1964 
       
  1965     layouted.showNormal();
       
  1966     QVERIFY(!(layouted.windowState() & Qt::WindowMaximized));
       
  1967 
       
  1968 #if !defined(Q_WS_QWS) && !defined(Q_OS_WINCE) && !defined(Q_WS_S60)
       
  1969 //embedded may choose a different size to fit on the screen.
       
  1970     QCOMPARE(layouted.size(), layouted.sizeHint());
       
  1971 #endif
       
  1972     layouted.showMaximized();
       
  1973     QVERIFY(layouted.isMaximized());
       
  1974     QVERIFY(layouted.isVisible());
       
  1975 
       
  1976     layouted.hide();
       
  1977     QVERIFY(layouted.isMaximized());
       
  1978     QVERIFY(!layouted.isVisible());
       
  1979 
       
  1980     layouted.showMaximized();
       
  1981     QVERIFY(layouted.isMaximized());
       
  1982     QVERIFY(layouted.isVisible());
       
  1983 
       
  1984     layouted.showMinimized();
       
  1985     QVERIFY(layouted.isMinimized());
       
  1986     QVERIFY(layouted.isMaximized());
       
  1987 
       
  1988     layouted.showMaximized();
       
  1989     QVERIFY(!layouted.isMinimized());
       
  1990     QVERIFY(layouted.isMaximized());
       
  1991     QVERIFY(layouted.isVisible());
       
  1992 
       
  1993     layouted.showMinimized();
       
  1994     QVERIFY(layouted.isMinimized());
       
  1995     QVERIFY(layouted.isMaximized());
       
  1996 
       
  1997     layouted.showMaximized();
       
  1998     QVERIFY(!layouted.isMinimized());
       
  1999     QVERIFY(layouted.isMaximized());
       
  2000     QVERIFY(layouted.isVisible());
       
  2001 
       
  2002     {
       
  2003         QWidget frame;
       
  2004         QWidget widget(&frame);
       
  2005         widget.showMaximized();
       
  2006         QVERIFY(widget.isMaximized());
       
  2007     }
       
  2008 
       
  2009     {
       
  2010         QWidget widget;
       
  2011         widget.setGeometry(0, 0, 10, 10);
       
  2012         widget.showMaximized();
       
  2013         QTRY_VERIFY(widget.size().width() > 20 && widget.size().height() > 20);
       
  2014     }
       
  2015 
       
  2016 #ifdef QT3_SUPPORT
       
  2017 #if !defined(Q_WS_QWS)
       
  2018 //embedded respects max/min sizes by design -- maybe wrong design, but that's the way it is now.
       
  2019     {
       
  2020         Q3HBox box;
       
  2021         QWidget widget(&box);
       
  2022         widget.setMinimumSize(500, 500);
       
  2023         box.showMaximized();
       
  2024         QVERIFY(box.isMaximized());
       
  2025     }
       
  2026 
       
  2027     {
       
  2028         Q3HBox box;
       
  2029         QWidget widget(&box);
       
  2030         widget.setMaximumSize(500, 500);
       
  2031 
       
  2032         box.showMaximized();
       
  2033         QVERIFY(box.isMaximized());
       
  2034     }
       
  2035 #endif
       
  2036 #endif // QT3_SUPPORT
       
  2037 }
       
  2038 
       
  2039 void tst_QWidget::showFullScreen()
       
  2040 {
       
  2041     QWidget plain;
       
  2042     QHBoxLayout *layout;
       
  2043     QWidget layouted;
       
  2044     QLineEdit le;
       
  2045     QLineEdit le2;
       
  2046     QLineEdit le3;
       
  2047     layout = new QHBoxLayout;
       
  2048 
       
  2049     layout->addWidget(&le);
       
  2050     layout->addWidget(&le2);
       
  2051     layout->addWidget(&le3);
       
  2052 
       
  2053     layouted.setLayout(layout);
       
  2054 
       
  2055     plain.showFullScreen();
       
  2056     QVERIFY(plain.windowState() & Qt::WindowFullScreen);
       
  2057 
       
  2058     plain.showNormal();
       
  2059     QVERIFY(!(plain.windowState() & Qt::WindowFullScreen));
       
  2060 
       
  2061     layouted.showFullScreen();
       
  2062     QVERIFY(layouted.windowState() & Qt::WindowFullScreen);
       
  2063 
       
  2064     layouted.showNormal();
       
  2065     QVERIFY(!(layouted.windowState() & Qt::WindowFullScreen));
       
  2066 
       
  2067 #if !defined(Q_WS_QWS) && !defined(Q_OS_WINCE) && !defined (Q_WS_S60)
       
  2068 //embedded may choose a different size to fit on the screen.
       
  2069     QCOMPARE(layouted.size(), layouted.sizeHint());
       
  2070 #endif
       
  2071 
       
  2072     layouted.showFullScreen();
       
  2073     QVERIFY(layouted.isFullScreen());
       
  2074     QVERIFY(layouted.isVisible());
       
  2075 
       
  2076     layouted.hide();
       
  2077     QVERIFY(layouted.isFullScreen());
       
  2078     QVERIFY(!layouted.isVisible());
       
  2079 
       
  2080     layouted.showFullScreen();
       
  2081     QVERIFY(layouted.isFullScreen());
       
  2082     QVERIFY(layouted.isVisible());
       
  2083 
       
  2084     layouted.showMinimized();
       
  2085     QVERIFY(layouted.isMinimized());
       
  2086     QVERIFY(layouted.isFullScreen());
       
  2087 
       
  2088     layouted.showFullScreen();
       
  2089     QVERIFY(!layouted.isMinimized());
       
  2090     QVERIFY(layouted.isFullScreen());
       
  2091     QVERIFY(layouted.isVisible());
       
  2092 
       
  2093     layouted.showMinimized();
       
  2094     QVERIFY(layouted.isMinimized());
       
  2095     QVERIFY(layouted.isFullScreen());
       
  2096 
       
  2097     layouted.showFullScreen();
       
  2098     QVERIFY(!layouted.isMinimized());
       
  2099     QVERIFY(layouted.isFullScreen());
       
  2100     QVERIFY(layouted.isVisible());
       
  2101 
       
  2102     {
       
  2103         QWidget frame;
       
  2104         QWidget widget(&frame);
       
  2105         widget.showFullScreen();
       
  2106         QVERIFY(widget.isFullScreen());
       
  2107     }
       
  2108 
       
  2109 #ifdef QT3_SUPPORT
       
  2110 #if !defined(Q_WS_QWS)
       
  2111 //embedded respects max/min sizes by design -- maybe wrong design, but that's the way it is now.
       
  2112     {
       
  2113         Q3HBox box;
       
  2114         QWidget widget(&box);
       
  2115         widget.setMinimumSize(500, 500);
       
  2116         box.showFullScreen();
       
  2117         QVERIFY(box.isFullScreen());
       
  2118     }
       
  2119 
       
  2120     {
       
  2121         Q3HBox box;
       
  2122         QWidget widget(&box);
       
  2123         widget.setMaximumSize(500, 500);
       
  2124 
       
  2125         box.showFullScreen();
       
  2126         QVERIFY(box.isFullScreen());
       
  2127     }
       
  2128 #endif
       
  2129 #endif // QT3_SUPPORT
       
  2130 }
       
  2131 
       
  2132 class ResizeWidget : public QWidget {
       
  2133 public:
       
  2134     ResizeWidget(QWidget *p = 0) : QWidget(p)
       
  2135     {
       
  2136         m_resizeEventCount = 0;
       
  2137     }
       
  2138 protected:
       
  2139     void resizeEvent(QResizeEvent *e){
       
  2140         QCOMPARE(size(), e->size());
       
  2141         ++m_resizeEventCount;
       
  2142     }
       
  2143 
       
  2144 public:
       
  2145     int m_resizeEventCount;
       
  2146 };
       
  2147 
       
  2148 void tst_QWidget::resizeEvent()
       
  2149 {
       
  2150     {
       
  2151         QWidget wParent;
       
  2152         ResizeWidget wChild(&wParent);
       
  2153         wParent.show();
       
  2154         QCOMPARE (wChild.m_resizeEventCount, 1); // initial resize event before paint
       
  2155         wParent.hide();
       
  2156         wChild.resize(QSize(640,480));
       
  2157         QCOMPARE (wChild.m_resizeEventCount, 1);
       
  2158         wParent.show();
       
  2159         QCOMPARE (wChild.m_resizeEventCount, 2);
       
  2160     }
       
  2161 
       
  2162     {
       
  2163         ResizeWidget wTopLevel;
       
  2164         wTopLevel.show();
       
  2165         QCOMPARE (wTopLevel.m_resizeEventCount, 1); // initial resize event before paint for toplevels
       
  2166         wTopLevel.hide();
       
  2167         wTopLevel.resize(QSize(640,480));
       
  2168         QCOMPARE (wTopLevel.m_resizeEventCount, 1);
       
  2169         wTopLevel.show();
       
  2170         QCOMPARE (wTopLevel.m_resizeEventCount, 2);
       
  2171     }
       
  2172 }
       
  2173 
       
  2174 void tst_QWidget::showMinimized()
       
  2175 {
       
  2176     QWidget plain;
       
  2177     plain.move(100, 100);
       
  2178     plain.resize(200, 200);
       
  2179     QPoint pos = plain.pos();
       
  2180 
       
  2181     plain.showMinimized();
       
  2182     QVERIFY(plain.isMinimized());
       
  2183     QVERIFY(plain.isVisible());
       
  2184     QCOMPARE(plain.pos(), pos);
       
  2185 
       
  2186     plain.showNormal();
       
  2187     QVERIFY(!plain.isMinimized());
       
  2188     QVERIFY(plain.isVisible());
       
  2189     QCOMPARE(plain.pos(), pos);
       
  2190 
       
  2191     plain.showMinimized();
       
  2192     QVERIFY(plain.isMinimized());
       
  2193     QVERIFY(plain.isVisible());
       
  2194     QCOMPARE(plain.pos(), pos);
       
  2195 
       
  2196     plain.hide();
       
  2197     QVERIFY(plain.isMinimized());
       
  2198     QVERIFY(!plain.isVisible());
       
  2199 
       
  2200     plain.showMinimized();
       
  2201     QVERIFY(plain.isMinimized());
       
  2202     QVERIFY(plain.isVisible());
       
  2203 
       
  2204     plain.setGeometry(200, 200, 300, 300);
       
  2205     plain.showNormal();
       
  2206     QCOMPARE(plain.geometry(), QRect(200, 200, 300, 300));
       
  2207 
       
  2208     {
       
  2209         QWidget frame;
       
  2210         QWidget widget(&frame);
       
  2211         widget.showMinimized();
       
  2212         QVERIFY(widget.isMinimized());
       
  2213     }
       
  2214 }
       
  2215 
       
  2216 void tst_QWidget::showMinimizedKeepsFocus()
       
  2217 {
       
  2218     //here we test that minimizing a widget and restoring it doesn't change the focus inside of it
       
  2219     {
       
  2220         QWidget window;
       
  2221         QWidget child1(&window), child2(&window);
       
  2222         child1.setFocusPolicy(Qt::StrongFocus);
       
  2223         child2.setFocusPolicy(Qt::StrongFocus);
       
  2224         window.show();
       
  2225         qApp->setActiveWindow(&window);
       
  2226         QTest::qWaitForWindowShown(&window);
       
  2227         child2.setFocus();
       
  2228         QTest::qWait(50);
       
  2229 
       
  2230         QTRY_COMPARE(window.focusWidget(), &child2);
       
  2231         QTRY_COMPARE(qApp->focusWidget(), &child2);
       
  2232 
       
  2233         window.showMinimized();
       
  2234         QTest::qWait(10);
       
  2235         QTRY_VERIFY(window.isMinimized());
       
  2236         QTRY_COMPARE(window.focusWidget(), &child2);
       
  2237 
       
  2238         window.showNormal();
       
  2239         QTest::qWait(10);
       
  2240         QTRY_COMPARE(window.focusWidget(), &child2);
       
  2241     }
       
  2242 
       
  2243     //testing deletion of the focusWidget
       
  2244     {
       
  2245         QWidget window;
       
  2246         QWidget *child = new QWidget(&window);
       
  2247         child->setFocusPolicy(Qt::StrongFocus);
       
  2248         window.show();
       
  2249         qApp->setActiveWindow(&window);
       
  2250         QTest::qWaitForWindowShown(&window);
       
  2251         child->setFocus();
       
  2252         QTest::qWait(50);
       
  2253         QTRY_COMPARE(window.focusWidget(), child);
       
  2254         QTRY_COMPARE(qApp->focusWidget(), child);
       
  2255 
       
  2256         delete child;
       
  2257         QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
       
  2258         QCOMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
       
  2259     }
       
  2260 
       
  2261     //testing reparenting the focus widget
       
  2262     {
       
  2263         QWidget window;
       
  2264         QWidget *child = new QWidget(&window);
       
  2265         child->setFocusPolicy(Qt::StrongFocus);
       
  2266         window.show();
       
  2267         qApp->setActiveWindow(&window);
       
  2268         QTest::qWaitForWindowShown(&window);
       
  2269         child->setFocus();
       
  2270         QTest::qWait(50);
       
  2271         QTRY_COMPARE(window.focusWidget(), child);
       
  2272         QTRY_COMPARE(qApp->focusWidget(), child);
       
  2273 
       
  2274         child->setParent(0);
       
  2275         QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
       
  2276         QCOMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
       
  2277     }
       
  2278 
       
  2279     //testing setEnabled(false)
       
  2280     {
       
  2281         QWidget window;
       
  2282         QWidget *child = new QWidget(&window);
       
  2283         child->setFocusPolicy(Qt::StrongFocus);
       
  2284         window.show();
       
  2285         qApp->setActiveWindow(&window);
       
  2286         QTest::qWaitForWindowShown(&window);
       
  2287         child->setFocus();
       
  2288         QTest::qWait(10);
       
  2289         QTRY_COMPARE(window.focusWidget(), child);
       
  2290         QTRY_COMPARE(qApp->focusWidget(), child);
       
  2291 
       
  2292         child->setEnabled(false);
       
  2293         QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
       
  2294         QCOMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
       
  2295     }
       
  2296 
       
  2297     //testing clearFocus
       
  2298     {
       
  2299         QWidget window;
       
  2300         QWidget *firstchild = new QWidget(&window);
       
  2301         firstchild->setFocusPolicy(Qt::StrongFocus);
       
  2302         QWidget *child = new QWidget(&window);
       
  2303         child->setFocusPolicy(Qt::StrongFocus);
       
  2304         window.show();
       
  2305         qApp->setActiveWindow(&window);
       
  2306         QTest::qWaitForWindowShown(&window);
       
  2307         child->setFocus();
       
  2308         QTest::qWait(10);
       
  2309         QTRY_COMPARE(window.focusWidget(), child);
       
  2310         QTRY_COMPARE(qApp->focusWidget(), child);
       
  2311 
       
  2312         child->clearFocus();
       
  2313         QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
       
  2314         QCOMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
       
  2315 
       
  2316         window.showMinimized();
       
  2317         QTest::qWait(30);
       
  2318         QTRY_VERIFY(window.isMinimized());
       
  2319 #ifdef Q_WS_QWS
       
  2320         QEXPECT_FAIL("", "QWS does not implement showMinimized()", Continue);
       
  2321 #endif
       
  2322         QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
       
  2323 #ifdef Q_WS_QWS
       
  2324         QEXPECT_FAIL("", "QWS does not implement showMinimized()", Continue);
       
  2325 #endif
       
  2326         QTRY_COMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
       
  2327 
       
  2328         window.showNormal();
       
  2329         qApp->setActiveWindow(&window);
       
  2330         QTest::qWaitForWindowShown(&window);
       
  2331         QTest::qWait(30);
       
  2332 #ifdef Q_WS_MAC
       
  2333         if (!macHasAccessToWindowsServer())
       
  2334             QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
       
  2335 #endif
       
  2336         QTRY_COMPARE(window.focusWidget(), firstchild);
       
  2337 #ifdef Q_WS_MAC
       
  2338         if (!macHasAccessToWindowsServer())
       
  2339             QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
       
  2340 #endif
       
  2341         QTRY_COMPARE(qApp->focusWidget(), firstchild);
       
  2342     }
       
  2343 }
       
  2344 
       
  2345 
       
  2346 void tst_QWidget::reparent()
       
  2347 {
       
  2348     QWidget parent;
       
  2349     parent.setWindowTitle("Toplevel");
       
  2350     parent.setGeometry(300, 300, 200, 150);
       
  2351 
       
  2352     QWidget child(0);
       
  2353     child.setObjectName("child");
       
  2354     child.setGeometry(10, 10, 180, 130);
       
  2355     QPalette pal1;
       
  2356     pal1.setColor(child.backgroundRole(), Qt::white);
       
  2357     child.setPalette(pal1);
       
  2358 
       
  2359     QWidget childTLW(&child, Qt::Window);
       
  2360     childTLW.setObjectName("childTLW");
       
  2361     childTLW.setGeometry(100, 100, 50, 50);
       
  2362     QPalette pal2;
       
  2363     pal2.setColor(childTLW.backgroundRole(), Qt::yellow);
       
  2364     childTLW.setPalette(pal2);
       
  2365 
       
  2366     parent.show();
       
  2367     childTLW.show();
       
  2368     QTest::qWaitForWindowShown(&parent);
       
  2369 
       
  2370 #ifdef Q_OS_WINCE
       
  2371     parent.move(50, 50);
       
  2372 #else
       
  2373     parent.move(300, 300);
       
  2374 #endif
       
  2375 
       
  2376     QPoint childPos = parent.mapToGlobal(child.pos());
       
  2377     QPoint tlwPos = childTLW.pos();
       
  2378 
       
  2379     child.setParent(0, child.windowFlags() & ~Qt::WindowType_Mask);
       
  2380     child.setGeometry(childPos.x(), childPos.y(), child.width(), child.height());
       
  2381     child.show();
       
  2382 
       
  2383 #ifdef Q_WS_X11
       
  2384     // On X11, the window manager will apply NorthWestGravity rules to 'child', which
       
  2385     // means the top-left corner of the window frame will be placed at 'childPos',
       
  2386     // causing this test to fail
       
  2387 #else
       
  2388     QCOMPARE(child.geometry().topLeft(), childPos);
       
  2389 #endif
       
  2390     QTRY_COMPARE(childTLW.pos(), tlwPos);
       
  2391 
       
  2392 #ifdef Q_WS_WIN
       
  2393     QWidget childTLWChild(&childTLW);
       
  2394     childTLWChild.setObjectName("childTLWChild");
       
  2395 
       
  2396     QWidget grandChild(&child);
       
  2397     grandChild.setObjectName("grandChild");
       
  2398     grandChild.setGeometry(10, 10, 160, 110);
       
  2399     QPalette pal3;
       
  2400     pal3.setColor(grandChild.backgroundRole(), Qt::red);
       
  2401     grandChild.setPalette(pal3);
       
  2402     //grandChild.setPaletteBackgroundColor(Qt::red);
       
  2403 
       
  2404     QWidget grandChildTLW(&grandChild, Qt::Window);
       
  2405     grandChildTLW.setObjectName("grandChildTLW");
       
  2406     grandChildTLW.setGeometry(200, 200, 50, 50);
       
  2407     QPalette pal4;
       
  2408     pal4.setColor(grandChildTLW.backgroundRole(), Qt::yellow);
       
  2409     grandChildTLW.setPalette(pal4);
       
  2410     //grandChildTLW.setPaletteBackgroundColor(Qt::yellow);
       
  2411 
       
  2412     QWidget grandChildTLWChild(&grandChildTLW);
       
  2413     grandChildTLWChild.setObjectName("grandChildTLWChild");
       
  2414 
       
  2415     QVERIFY(IsWindow(childTLW.winId()));
       
  2416     QVERIFY(IsWindow(childTLWChild.winId()));
       
  2417     QVERIFY(IsWindow(grandChildTLW.winId()));
       
  2418     QVERIFY(IsWindow(grandChildTLWChild.winId()));
       
  2419 
       
  2420     parent.show();
       
  2421 
       
  2422     QVERIFY(IsWindow(childTLW.winId()));
       
  2423     QVERIFY(IsWindow(childTLWChild.winId()));
       
  2424     QVERIFY(IsWindow(grandChildTLW.winId()));
       
  2425     QVERIFY(IsWindow(grandChildTLWChild.winId()));
       
  2426 
       
  2427     child.setParent(&parent);
       
  2428     child.move(10,10);
       
  2429     child.show();
       
  2430 
       
  2431     // this appears to stabelize results
       
  2432     qApp->processEvents();
       
  2433 
       
  2434     QVERIFY(IsWindow(childTLW.winId()));
       
  2435     QVERIFY(IsWindow(childTLWChild.winId()));
       
  2436 
       
  2437     QVERIFY(IsWindow(grandChildTLW.winId()));
       
  2438     QVERIFY(IsWindow(grandChildTLWChild.winId()));
       
  2439 #else
       
  2440     QSKIP("This test makes only sense on Windows", SkipAll);
       
  2441 #endif
       
  2442 }
       
  2443 
       
  2444 void tst_QWidget::icon()
       
  2445 {
       
  2446 #if defined(Q_WS_QWS)
       
  2447     QSKIP("Qt/Embedded does it differently", SkipAll);
       
  2448 #else
       
  2449     QPixmap p(20,20);
       
  2450     p.fill(Qt::red);
       
  2451     testWidget->setWindowIcon(p);
       
  2452 
       
  2453     QVERIFY(!testWidget->windowIcon().isNull());
       
  2454     testWidget->show();
       
  2455     QVERIFY(!testWidget->windowIcon().isNull());
       
  2456     testWidget->showFullScreen();
       
  2457     QVERIFY(!testWidget->windowIcon().isNull());
       
  2458     testWidget->showNormal();
       
  2459     QVERIFY(!testWidget->windowIcon().isNull());
       
  2460 #endif
       
  2461 }
       
  2462 
       
  2463 void tst_QWidget::hideWhenFocusWidgetIsChild()
       
  2464 {
       
  2465     testWidget->activateWindow();
       
  2466     QWidget *parentWidget = new QWidget(testWidget);
       
  2467     parentWidget->setObjectName("parentWidget");
       
  2468     parentWidget->setGeometry(0, 0, 100, 100);
       
  2469     QLineEdit *edit = new QLineEdit(parentWidget);
       
  2470     edit->setObjectName("edit1");
       
  2471     QLineEdit *edit3 = new QLineEdit(parentWidget);
       
  2472     edit3->setObjectName("edit3");
       
  2473     edit3->move(0,50);
       
  2474     parentWidget->show();
       
  2475     QLineEdit *edit2 = new QLineEdit(testWidget);
       
  2476     edit2->setObjectName("edit2");
       
  2477     edit2->show();
       
  2478     edit2->move(110, 100);
       
  2479     edit->setFocus();
       
  2480     qApp->processEvents();
       
  2481     QString actualFocusWidget, expectedFocusWidget;
       
  2482 #ifdef Q_WS_X11
       
  2483     if (!qApp->focusWidget())
       
  2484         QSKIP("Your window manager is too broken for this test", SkipAll);
       
  2485 #endif
       
  2486     QVERIFY(qApp->focusWidget());
       
  2487     actualFocusWidget.sprintf("%p %s %s", qApp->focusWidget(), qApp->focusWidget()->objectName().toLatin1().constData(), qApp->focusWidget()->metaObject()->className());
       
  2488     expectedFocusWidget.sprintf("%p %s %s", edit, edit->objectName().toLatin1().constData(), edit->metaObject()->className());
       
  2489     QCOMPARE(actualFocusWidget, expectedFocusWidget);
       
  2490 
       
  2491     parentWidget->hide();
       
  2492     qApp->processEvents();
       
  2493     actualFocusWidget.sprintf("%p %s %s", qApp->focusWidget(), qApp->focusWidget()->objectName().toLatin1().constData(), qApp->focusWidget()->metaObject()->className());
       
  2494     expectedFocusWidget.sprintf("%p %s %s", edit2, edit2->objectName().toLatin1().constData(), edit2->metaObject()->className());
       
  2495     QCOMPARE(actualFocusWidget, expectedFocusWidget);
       
  2496 
       
  2497     delete edit2;
       
  2498     delete parentWidget;
       
  2499 }
       
  2500 
       
  2501 void tst_QWidget::normalGeometry()
       
  2502 {
       
  2503 #ifdef Q_OS_IRIX
       
  2504     QSKIP("4DWM issues on IRIX makes this test fail", SkipAll);
       
  2505 #endif
       
  2506     QWidget parent;
       
  2507     parent.setWindowTitle("NormalGeometry parent");
       
  2508     QWidget *child = new QWidget(&parent);
       
  2509 
       
  2510     QCOMPARE(parent.normalGeometry(), parent.geometry());
       
  2511     QCOMPARE(child->normalGeometry(), QRect());
       
  2512 
       
  2513     parent.setGeometry(100, 100, 200, 200);
       
  2514     parent.show();
       
  2515     QTest::qWaitForWindowShown(&parent);
       
  2516     QApplication::processEvents();
       
  2517 
       
  2518     QRect geom = parent.geometry();
       
  2519     // ### the window manager places the top-left corner at
       
  2520     // ### 100,100... making geom something like 102,124 (offset by
       
  2521     // ### the frame/frame)... this indicates a rather large different
       
  2522     // ### between how X11 and Windows works
       
  2523     // QCOMPARE(geom, QRect(100, 100, 200, 200));
       
  2524     QCOMPARE(parent.normalGeometry(), geom);
       
  2525 
       
  2526     parent.setWindowState(parent.windowState() ^ Qt::WindowMaximized);
       
  2527     QTest::qWait(10);
       
  2528     QTRY_VERIFY(parent.windowState() & Qt::WindowMaximized);
       
  2529     QTRY_VERIFY(parent.geometry() != geom);
       
  2530     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2531 
       
  2532     parent.setWindowState(parent.windowState() ^ Qt::WindowMaximized);
       
  2533     QTest::qWait(10);
       
  2534     QTRY_VERIFY(!(parent.windowState() & Qt::WindowMaximized));
       
  2535     QTRY_COMPARE(parent.geometry(), geom);
       
  2536     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2537 
       
  2538     parent.showMaximized();
       
  2539     QTest::qWait(10);
       
  2540     QTRY_VERIFY(parent.windowState() & Qt::WindowMaximized);
       
  2541     QTRY_VERIFY(parent.geometry() != geom);
       
  2542     QCOMPARE(parent.normalGeometry(), geom);
       
  2543 
       
  2544     parent.showNormal();
       
  2545     QTest::qWait(10);
       
  2546     QTRY_VERIFY(!(parent.windowState() & Qt::WindowMaximized));
       
  2547     QTRY_COMPARE(parent.geometry(), geom);
       
  2548     QCOMPARE(parent.normalGeometry(), geom);
       
  2549 
       
  2550     parent.setWindowState(parent.windowState() ^ Qt::WindowMinimized);
       
  2551     QTest::qWait(10);
       
  2552     parent.setWindowState(parent.windowState() ^ Qt::WindowMaximized);
       
  2553     QTest::qWait(10);
       
  2554     QTRY_VERIFY(parent.windowState() & (Qt::WindowMinimized|Qt::WindowMaximized));
       
  2555     // ### when minimized and maximized at the same time, the geometry
       
  2556     // ### does *NOT* have to be the normal geometry, it could be the
       
  2557     // ### maximized geometry.
       
  2558     // QCOMPARE(parent.geometry(), geom);
       
  2559     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2560 
       
  2561     parent.setWindowState(parent.windowState() ^ Qt::WindowMinimized);
       
  2562     QTest::qWait(10);
       
  2563     QTRY_VERIFY(!(parent.windowState() & Qt::WindowMinimized));
       
  2564     QTRY_VERIFY(parent.windowState() & Qt::WindowMaximized);
       
  2565     QTRY_VERIFY(parent.geometry() != geom);
       
  2566     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2567 
       
  2568     parent.setWindowState(parent.windowState() ^ Qt::WindowMaximized);
       
  2569     QTest::qWait(10);
       
  2570     QTRY_VERIFY(!(parent.windowState() & Qt::WindowMaximized));
       
  2571     QTRY_COMPARE(parent.geometry(), geom);
       
  2572     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2573 
       
  2574     parent.setWindowState(parent.windowState() ^ Qt::WindowFullScreen);
       
  2575     QTest::qWait(10);
       
  2576     QTRY_VERIFY(parent.windowState() & Qt::WindowFullScreen);
       
  2577     QTRY_VERIFY(parent.geometry() != geom);
       
  2578     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2579 
       
  2580     parent.setWindowState(parent.windowState() ^ Qt::WindowFullScreen);
       
  2581     QTest::qWait(10);
       
  2582     QVERIFY(!(parent.windowState() & Qt::WindowFullScreen));
       
  2583     QTRY_COMPARE(parent.geometry(), geom);
       
  2584     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2585 
       
  2586     parent.showFullScreen();
       
  2587     QTest::qWait(10);
       
  2588     QTRY_VERIFY(parent.windowState() & Qt::WindowFullScreen);
       
  2589     QTRY_VERIFY(parent.geometry() != geom);
       
  2590     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2591 
       
  2592     parent.showNormal();
       
  2593     QTest::qWait(10);
       
  2594     QTRY_VERIFY(!(parent.windowState() & Qt::WindowFullScreen));
       
  2595     QTRY_COMPARE(parent.geometry(), geom);
       
  2596     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2597 
       
  2598     parent.showNormal();
       
  2599     parent.setWindowState(Qt:: WindowFullScreen | Qt::WindowMaximized);
       
  2600     parent.setWindowState(Qt::WindowMinimized | Qt:: WindowFullScreen | Qt::WindowMaximized);
       
  2601     parent.setWindowState(Qt:: WindowFullScreen | Qt::WindowMaximized);
       
  2602     QTest::qWait(10);
       
  2603     QTRY_COMPARE(parent.normalGeometry(), geom);
       
  2604 }
       
  2605 
       
  2606 
       
  2607 void tst_QWidget::setGeometry()
       
  2608 {
       
  2609     QWidget tlw;
       
  2610     QWidget child(&tlw);
       
  2611 
       
  2612     QRect tr(100,100,200,200);
       
  2613     QRect cr(50,50,50,50);
       
  2614     tlw.setGeometry(tr);
       
  2615     child.setGeometry(cr);
       
  2616     tlw.show();
       
  2617     QTest::qWait(50);
       
  2618     QCOMPARE(tlw.geometry().size(), tr.size());
       
  2619     QCOMPARE(child.geometry(), cr);
       
  2620 
       
  2621     tlw.setParent(0, Qt::Window|Qt::FramelessWindowHint);
       
  2622     tr = QRect(0,0,100,100);
       
  2623     tr.moveTopLeft(QApplication::desktop()->availableGeometry().topLeft());
       
  2624     tlw.setGeometry(tr);
       
  2625     QCOMPARE(tlw.geometry(), tr);
       
  2626     tlw.show();
       
  2627     QTest::qWait(50);
       
  2628     if (tlw.frameGeometry() != tlw.geometry())
       
  2629         QSKIP("Your window manager is too broken for this test", SkipAll);
       
  2630     QCOMPARE(tlw.geometry(), tr);
       
  2631 
       
  2632 }
       
  2633 
       
  2634 void tst_QWidget::windowOpacity()
       
  2635 {
       
  2636 #ifdef Q_OS_WINCE
       
  2637     QSKIP( "Windows CE does not support windowOpacity", SkipAll);
       
  2638 #endif
       
  2639     QWidget widget;
       
  2640     QWidget child(&widget);
       
  2641 
       
  2642     // Initial value should be 1.0
       
  2643     QCOMPARE(widget.windowOpacity(), 1.0);
       
  2644     // children should always return 1.0
       
  2645     QCOMPARE(child.windowOpacity(), 1.0);
       
  2646 
       
  2647     widget.setWindowOpacity(0.0);
       
  2648     QCOMPARE(widget.windowOpacity(), 0.0);
       
  2649     child.setWindowOpacity(0.0);
       
  2650     QCOMPARE(child.windowOpacity(), 1.0);
       
  2651 
       
  2652     widget.setWindowOpacity(1.0);
       
  2653     QCOMPARE(widget.windowOpacity(), 1.0);
       
  2654     child.setWindowOpacity(1.0);
       
  2655     QCOMPARE(child.windowOpacity(), 1.0);
       
  2656 
       
  2657     widget.setWindowOpacity(2.0);
       
  2658     QCOMPARE(widget.windowOpacity(), 1.0);
       
  2659     child.setWindowOpacity(2.0);
       
  2660     QCOMPARE(child.windowOpacity(), 1.0);
       
  2661 
       
  2662     widget.setWindowOpacity(-1.0);
       
  2663     QCOMPARE(widget.windowOpacity(), 0.0);
       
  2664     child.setWindowOpacity(-1.0);
       
  2665     QCOMPARE(child.windowOpacity(), 1.0);
       
  2666 }
       
  2667 
       
  2668 class UpdateWidget : public QWidget
       
  2669 {
       
  2670 public:
       
  2671     UpdateWidget(QWidget *parent = 0) : QWidget(parent) {
       
  2672         reset();
       
  2673     }
       
  2674 
       
  2675     void paintEvent(QPaintEvent *e) {
       
  2676         paintedRegion += e->region();
       
  2677         ++numPaintEvents;
       
  2678         if (resizeInPaintEvent) {
       
  2679             resizeInPaintEvent = false;
       
  2680             resize(size() + QSize(2, 2));
       
  2681         }
       
  2682     }
       
  2683 
       
  2684     bool event(QEvent *event)
       
  2685     {
       
  2686         switch (event->type()) {
       
  2687         case QEvent::ZOrderChange:
       
  2688             ++numZOrderChangeEvents;
       
  2689             break;
       
  2690         case QEvent::UpdateRequest:
       
  2691             ++numUpdateRequestEvents;
       
  2692             break;
       
  2693         case QEvent::ActivationChange:
       
  2694         case QEvent::FocusIn:
       
  2695         case QEvent::FocusOut:
       
  2696         case QEvent::WindowActivate:
       
  2697         case QEvent::WindowDeactivate:
       
  2698             if (!updateOnActivationChangeAndFocusIn)
       
  2699                 return true; // Filter out to avoid update() calls in QWidget.
       
  2700             break;
       
  2701         default:
       
  2702             break;
       
  2703         }
       
  2704         return QWidget::event(event);
       
  2705     }
       
  2706 
       
  2707     void reset() {
       
  2708         numPaintEvents = 0;
       
  2709         numZOrderChangeEvents = 0;
       
  2710         numUpdateRequestEvents = 0;
       
  2711         updateOnActivationChangeAndFocusIn = false;
       
  2712         resizeInPaintEvent = false;
       
  2713         paintedRegion = QRegion();
       
  2714     }
       
  2715 
       
  2716     int numPaintEvents;
       
  2717     int numZOrderChangeEvents;
       
  2718     int numUpdateRequestEvents;
       
  2719     bool updateOnActivationChangeAndFocusIn;
       
  2720     bool resizeInPaintEvent;
       
  2721     QRegion paintedRegion;
       
  2722 };
       
  2723 
       
  2724 void tst_QWidget::lostUpdatesOnHide()
       
  2725 {
       
  2726 #ifndef Q_WS_MAC
       
  2727     UpdateWidget widget;
       
  2728     widget.setAttribute(Qt::WA_DontShowOnScreen);
       
  2729     widget.show();
       
  2730     widget.hide();
       
  2731     QTest::qWait(50);
       
  2732     widget.show();
       
  2733     QTest::qWait(50);
       
  2734 
       
  2735     QCOMPARE(widget.numPaintEvents, 1);
       
  2736 #endif
       
  2737 }
       
  2738 
       
  2739 void tst_QWidget::raise()
       
  2740 {
       
  2741 #ifdef QT_MAC_USE_COCOA
       
  2742     QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events.", SkipAll);
       
  2743 #endif
       
  2744     QTest::qWait(10);
       
  2745     QWidget *parent = new QWidget(0);
       
  2746     QList<UpdateWidget *> allChildren;
       
  2747 
       
  2748     UpdateWidget *child1 = new UpdateWidget(parent);
       
  2749     child1->setAutoFillBackground(true);
       
  2750     allChildren.append(child1);
       
  2751 
       
  2752     UpdateWidget *child2 = new UpdateWidget(parent);
       
  2753     child2->setAutoFillBackground(true);
       
  2754     allChildren.append(child2);
       
  2755 
       
  2756     UpdateWidget *child3 = new UpdateWidget(parent);
       
  2757     child3->setAutoFillBackground(true);
       
  2758     allChildren.append(child3);
       
  2759 
       
  2760     UpdateWidget *child4 = new UpdateWidget(parent);
       
  2761     child4->setAutoFillBackground(true);
       
  2762     allChildren.append(child4);
       
  2763 
       
  2764     parent->show();
       
  2765     QTest::qWaitForWindowShown(parent);
       
  2766     QTest::qWait(10);
       
  2767 
       
  2768     QList<QObject *> list1;
       
  2769     list1 << child1 << child2 << child3 << child4;
       
  2770     QVERIFY(parent->children() == list1);
       
  2771     QCOMPARE(allChildren.count(), list1.count());
       
  2772 
       
  2773     foreach (UpdateWidget *child, allChildren) {
       
  2774         int expectedPaintEvents = child == child4 ? 1 : 0;
       
  2775         if (expectedPaintEvents == 0) {
       
  2776             QVERIFY(child->numPaintEvents == 0);
       
  2777         } else {
       
  2778             // show() issues multiple paint events on some window managers
       
  2779             QTRY_VERIFY(child->numPaintEvents >= expectedPaintEvents);
       
  2780         }
       
  2781         QCOMPARE(child->numZOrderChangeEvents, 0);
       
  2782         child->reset();
       
  2783     }
       
  2784 
       
  2785     for (int i = 0; i < 5; ++i)
       
  2786         child2->raise();
       
  2787     QTest::qWait(50);
       
  2788 
       
  2789     foreach (UpdateWidget *child, allChildren) {
       
  2790         int expectedPaintEvents = child == child2 ? 1 : 0;
       
  2791         int expectedZOrderChangeEvents = child == child2 ? 1 : 0;
       
  2792         QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
       
  2793         QCOMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
       
  2794         child->reset();
       
  2795     }
       
  2796 
       
  2797     QList<QObject *> list2;
       
  2798     list2 << child1 << child3 << child4 << child2;
       
  2799     QVERIFY(parent->children() == list2);
       
  2800 
       
  2801     // Creates a widget on top of all the children and checks that raising one of
       
  2802     // the children underneath doesn't trigger a repaint on the covering widget.
       
  2803     QWidget topLevel;
       
  2804     parent->setParent(&topLevel);
       
  2805     topLevel.show();
       
  2806     QTest::qWaitForWindowShown(&topLevel);
       
  2807     QTest::qWait(50);
       
  2808 
       
  2809     UpdateWidget *onTop = new UpdateWidget(&topLevel);
       
  2810     onTop->reset();
       
  2811     onTop->resize(topLevel.size());
       
  2812     onTop->setAutoFillBackground(true);
       
  2813     onTop->show();
       
  2814     QTest::qWait(50);
       
  2815     QTRY_VERIFY(onTop->numPaintEvents > 0);
       
  2816     onTop->reset();
       
  2817 
       
  2818     // Reset all the children.
       
  2819     foreach (UpdateWidget *child, allChildren)
       
  2820         child->reset();
       
  2821 
       
  2822     for (int i = 0; i < 5; ++i)
       
  2823         child3->raise();
       
  2824     QTest::qWait(50);
       
  2825 
       
  2826     QCOMPARE(onTop->numPaintEvents, 0);
       
  2827     QCOMPARE(onTop->numZOrderChangeEvents, 0);
       
  2828 
       
  2829     QList<QObject *> list3;
       
  2830     list3 << child1 << child4 << child2 << child3;
       
  2831     QVERIFY(parent->children() == list3);
       
  2832 
       
  2833     foreach (UpdateWidget *child, allChildren) {
       
  2834         int expectedPaintEvents = 0;
       
  2835         int expectedZOrderChangeEvents = child == child3 ? 1 : 0;
       
  2836         QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
       
  2837         QCOMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
       
  2838         child->reset();
       
  2839     }
       
  2840 }
       
  2841 
       
  2842 void tst_QWidget::lower()
       
  2843 {
       
  2844 #ifdef QT_MAC_USE_COCOA
       
  2845     QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events.", SkipAll);
       
  2846 #endif
       
  2847     QWidget *parent = new QWidget(0);
       
  2848     QList<UpdateWidget *> allChildren;
       
  2849 
       
  2850     UpdateWidget *child1 = new UpdateWidget(parent);
       
  2851     child1->setAutoFillBackground(true);
       
  2852     allChildren.append(child1);
       
  2853 
       
  2854     UpdateWidget *child2 = new UpdateWidget(parent);
       
  2855     child2->setAutoFillBackground(true);
       
  2856     allChildren.append(child2);
       
  2857 
       
  2858     UpdateWidget *child3 = new UpdateWidget(parent);
       
  2859     child3->setAutoFillBackground(true);
       
  2860     allChildren.append(child3);
       
  2861 
       
  2862     UpdateWidget *child4 = new UpdateWidget(parent);
       
  2863     child4->setAutoFillBackground(true);
       
  2864     allChildren.append(child4);
       
  2865 
       
  2866     parent->show();
       
  2867     QTest::qWaitForWindowShown(parent);
       
  2868     QTest::qWait(100);
       
  2869 
       
  2870     QList<QObject *> list1;
       
  2871     list1 << child1 << child2 << child3 << child4;
       
  2872     QVERIFY(parent->children() == list1);
       
  2873     QCOMPARE(allChildren.count(), list1.count());
       
  2874 
       
  2875     foreach (UpdateWidget *child, allChildren) {
       
  2876         int expectedPaintEvents = child == child4 ? 1 : 0;
       
  2877         if (expectedPaintEvents == 0) {
       
  2878             QVERIFY(child->numPaintEvents == 0);
       
  2879         } else {
       
  2880             // show() issues multiple paint events on some window managers
       
  2881             QTRY_VERIFY(child->numPaintEvents >= expectedPaintEvents);
       
  2882         }
       
  2883         QCOMPARE(child->numZOrderChangeEvents, 0);
       
  2884         child->reset();
       
  2885     }
       
  2886 
       
  2887     for (int i = 0; i < 5; ++i)
       
  2888         child4->lower();
       
  2889 
       
  2890     QTest::qWait(100);
       
  2891 
       
  2892     foreach (UpdateWidget *child, allChildren) {
       
  2893         int expectedPaintEvents = child == child3 ? 1 : 0;
       
  2894         int expectedZOrderChangeEvents = child == child4 ? 1 : 0;
       
  2895         QTRY_COMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
       
  2896         QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
       
  2897         child->reset();
       
  2898     }
       
  2899 
       
  2900     QList<QObject *> list2;
       
  2901     list2 << child4 << child1 << child2 << child3;
       
  2902     QVERIFY(parent->children() == list2);
       
  2903 
       
  2904     delete parent;
       
  2905 }
       
  2906 
       
  2907 void tst_QWidget::stackUnder()
       
  2908 {
       
  2909 #ifdef QT_MAC_USE_COCOA
       
  2910     QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events.", SkipAll);
       
  2911 #endif
       
  2912     QTest::qWait(10);
       
  2913     QWidget *parent = new QWidget(0);
       
  2914     QList<UpdateWidget *> allChildren;
       
  2915 
       
  2916     UpdateWidget *child1 = new UpdateWidget(parent);
       
  2917     child1->setAutoFillBackground(true);
       
  2918     allChildren.append(child1);
       
  2919 
       
  2920     UpdateWidget *child2 = new UpdateWidget(parent);
       
  2921     child2->setAutoFillBackground(true);
       
  2922     allChildren.append(child2);
       
  2923 
       
  2924     UpdateWidget *child3 = new UpdateWidget(parent);
       
  2925     child3->setAutoFillBackground(true);
       
  2926     allChildren.append(child3);
       
  2927 
       
  2928     UpdateWidget *child4 = new UpdateWidget(parent);
       
  2929     child4->setAutoFillBackground(true);
       
  2930     allChildren.append(child4);
       
  2931 
       
  2932     parent->show();
       
  2933     QTest::qWaitForWindowShown(parent);
       
  2934     QTest::qWait(10);
       
  2935 #ifdef Q_WS_QWS
       
  2936     QApplication::sendPostedEvents(); //glib workaround
       
  2937 #endif
       
  2938 
       
  2939     QList<QObject *> list1;
       
  2940     list1 << child1 << child2 << child3 << child4;
       
  2941     QVERIFY(parent->children() == list1);
       
  2942 
       
  2943     foreach (UpdateWidget *child, allChildren) {
       
  2944         int expectedPaintEvents = child == child4 ? 1 : 0;
       
  2945 #if defined(Q_WS_WIN) || defined(Q_WS_MAC)
       
  2946         if (expectedPaintEvents == 1 && child->numPaintEvents == 2)
       
  2947             QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue);
       
  2948 #endif
       
  2949         QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
       
  2950         QCOMPARE(child->numZOrderChangeEvents, 0);
       
  2951         child->reset();
       
  2952     }
       
  2953 
       
  2954     for (int i = 0; i < 5; ++i)
       
  2955         child4->stackUnder(child2);
       
  2956     QTest::qWait(10);
       
  2957 
       
  2958     QList<QObject *> list2;
       
  2959     list2 << child1 << child4 << child2 << child3;
       
  2960     QVERIFY(parent->children() == list2);
       
  2961 
       
  2962     foreach (UpdateWidget *child, allChildren) {
       
  2963         int expectedPaintEvents = child == child3 ? 1 : 0;
       
  2964         int expectedZOrderChangeEvents = child == child4 ? 1 : 0;
       
  2965         QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
       
  2966         QTRY_COMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
       
  2967         child->reset();
       
  2968     }
       
  2969 
       
  2970     for (int i = 0; i < 5; ++i)
       
  2971         child1->stackUnder(child3);
       
  2972     QTest::qWait(10);
       
  2973 
       
  2974     QList<QObject *> list3;
       
  2975     list3 << child4 << child2 << child1 << child3;
       
  2976     QVERIFY(parent->children() == list3);
       
  2977 
       
  2978     foreach (UpdateWidget *child, allChildren) {
       
  2979         int expectedZOrderChangeEvents = child == child1 ? 1 : 0;
       
  2980         if (child == child3) {
       
  2981 #ifdef Q_OS_WINCE
       
  2982             qApp->processEvents();
       
  2983 #endif
       
  2984 #ifndef Q_WS_MAC
       
  2985             QEXPECT_FAIL(0, "Task 153869", Continue);
       
  2986 #endif
       
  2987             QCOMPARE(child->numPaintEvents, 0);
       
  2988         } else {
       
  2989             QCOMPARE(child->numPaintEvents, 0);
       
  2990         }
       
  2991         QTRY_COMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
       
  2992         child->reset();
       
  2993     }
       
  2994 
       
  2995     delete parent;
       
  2996 }
       
  2997 
       
  2998 void drawPolygon(QPaintDevice *dev, int w, int h)
       
  2999 {
       
  3000     QPainter p(dev);
       
  3001     p.fillRect(0, 0, w, h, Qt::white);
       
  3002 
       
  3003     QPolygon a;
       
  3004     a << QPoint(0, 0) << QPoint(w/2, h/2) << QPoint(w, 0)
       
  3005       << QPoint(w/2, h) << QPoint(0, 0);
       
  3006 
       
  3007     p.setPen(QPen(Qt::black, 1));
       
  3008     p.setBrush(Qt::DiagCrossPattern);
       
  3009     p.drawPolygon(a);
       
  3010 }
       
  3011 
       
  3012 class ContentsPropagationWidget : public QWidget
       
  3013 {
       
  3014     Q_OBJECT
       
  3015 public:
       
  3016     ContentsPropagationWidget(QWidget *parent = 0) : QWidget(parent)
       
  3017     {
       
  3018         QWidget *child = this;
       
  3019         for (int i=0; i<32; ++i) {
       
  3020             child = new QWidget(child);
       
  3021             child->setGeometry(i, i, 400 - i*2, 400 - i*2);
       
  3022         }
       
  3023     }
       
  3024 
       
  3025     void setContentsPropagation(bool enable) {
       
  3026         foreach (QObject *child, children())
       
  3027             qobject_cast<QWidget *>(child)->setAutoFillBackground(!enable);
       
  3028     }
       
  3029 
       
  3030 protected:
       
  3031     void paintEvent(QPaintEvent *)
       
  3032     {
       
  3033         int w = width(), h = height();
       
  3034         drawPolygon(this, w, h);
       
  3035     }
       
  3036 
       
  3037     QSize sizeHint() const { return QSize(500, 500); }
       
  3038 };
       
  3039 
       
  3040 void tst_QWidget::testContentsPropagation()
       
  3041 {
       
  3042 #ifdef Q_WS_MAC
       
  3043     QSKIP("Pixmap is not antialiased whereas widget is.", SkipAll);
       
  3044 #endif
       
  3045     ContentsPropagationWidget widget;
       
  3046 #ifdef Q_WS_QWS
       
  3047     widget.resize(500,500);
       
  3048 #else
       
  3049     widget.setFixedSize(500, 500);
       
  3050 #endif
       
  3051     widget.setContentsPropagation(false);
       
  3052     QPixmap widgetSnapshot = QPixmap::grabWidget(&widget);
       
  3053 
       
  3054     QPixmap correct(500, 500);
       
  3055     drawPolygon(&correct, 500, 500);
       
  3056     //correct.save("correct.png", "PNG");
       
  3057 
       
  3058     //widgetSnapshot.save("snap1.png", "PNG");
       
  3059     QVERIFY(widgetSnapshot.toImage() != correct.toImage());
       
  3060 
       
  3061     widget.setContentsPropagation(true);
       
  3062     widgetSnapshot = QPixmap::grabWidget(&widget);
       
  3063     //widgetSnapshot.save("snap2.png", "PNG");
       
  3064 
       
  3065     QCOMPARE(widgetSnapshot, correct);
       
  3066 }
       
  3067 
       
  3068 /*
       
  3069     Test that saving and restoring window geometry with
       
  3070     saveGeometry() and restoreGeometry() works.
       
  3071 */
       
  3072 void tst_QWidget::saveRestoreGeometry()
       
  3073 {
       
  3074 #ifdef Q_OS_IRIX
       
  3075     QSKIP("4DWM issues on IRIX makes this test fail", SkipAll);
       
  3076 #endif
       
  3077     const QPoint position(100, 100);
       
  3078     const QSize size(200, 200);
       
  3079 
       
  3080     QByteArray savedGeometry;
       
  3081 
       
  3082     {
       
  3083         QWidget widget;
       
  3084         widget.move(position);
       
  3085         widget.resize(size);
       
  3086         widget.show();
       
  3087         QTest::qWaitForWindowShown(&widget);
       
  3088         QApplication::processEvents();
       
  3089 
       
  3090         QTRY_COMPARE(widget.pos(), position);
       
  3091         QCOMPARE(widget.size(), size);
       
  3092         savedGeometry = widget.saveGeometry();
       
  3093     }
       
  3094 
       
  3095     {
       
  3096         QWidget widget;
       
  3097 
       
  3098         const QByteArray empty;
       
  3099         const QByteArray one("a");
       
  3100         const QByteArray two("ab");
       
  3101         const QByteArray three("abc");
       
  3102         const QByteArray four("abca");
       
  3103         const QByteArray garbage("abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc");
       
  3104 
       
  3105         QVERIFY(widget.restoreGeometry(empty) == false);
       
  3106         QVERIFY(widget.restoreGeometry(one) == false);
       
  3107         QVERIFY(widget.restoreGeometry(two) == false);
       
  3108         QVERIFY(widget.restoreGeometry(three) == false);
       
  3109         QVERIFY(widget.restoreGeometry(four) == false);
       
  3110         QVERIFY(widget.restoreGeometry(garbage) == false);
       
  3111 
       
  3112         QVERIFY(widget.restoreGeometry(savedGeometry));
       
  3113         widget.show();
       
  3114         QTest::qWaitForWindowShown(&widget);
       
  3115         QApplication::processEvents();
       
  3116 
       
  3117         QTRY_COMPARE(widget.pos(), position);
       
  3118         QCOMPARE(widget.size(), size);
       
  3119         widget.show();
       
  3120         QCOMPARE(widget.pos(), position);
       
  3121         QCOMPARE(widget.size(), size);
       
  3122     }
       
  3123 
       
  3124     {
       
  3125         QWidget widget;
       
  3126         widget.move(position);
       
  3127         widget.resize(size);
       
  3128         widget.show();
       
  3129         QTest::qWaitForWindowShown(&widget);
       
  3130         QTest::qWait(500);
       
  3131         QTRY_COMPARE(widget.geometry().size(), size);
       
  3132 
       
  3133         QRect geom;
       
  3134 
       
  3135         //Restore from Full screen
       
  3136         savedGeometry = widget.saveGeometry();
       
  3137         geom = widget.geometry();
       
  3138         widget.setWindowState(widget.windowState() | Qt::WindowFullScreen);
       
  3139         QTRY_VERIFY((widget.windowState() & Qt::WindowFullScreen));
       
  3140         QTest::qWait(500);
       
  3141         QVERIFY(widget.restoreGeometry(savedGeometry));
       
  3142         QTest::qWait(120);
       
  3143         QTRY_VERIFY(!(widget.windowState() & Qt::WindowFullScreen));
       
  3144         QTRY_COMPARE(widget.geometry(), geom);
       
  3145 
       
  3146         //Restore to full screen
       
  3147         widget.setWindowState(widget.windowState() | Qt::WindowFullScreen);
       
  3148         QTest::qWait(120);
       
  3149         QTRY_VERIFY((widget.windowState() & Qt::WindowFullScreen));
       
  3150         QTest::qWait(500);
       
  3151         savedGeometry = widget.saveGeometry();
       
  3152         geom = widget.geometry();
       
  3153         widget.setWindowState(widget.windowState() ^ Qt::WindowFullScreen);
       
  3154         QTest::qWait(120);
       
  3155         QTRY_VERIFY(!(widget.windowState() & Qt::WindowFullScreen));
       
  3156         QTest::qWait(400);
       
  3157         QVERIFY(widget.restoreGeometry(savedGeometry));
       
  3158         QTest::qWait(120);
       
  3159         QTRY_VERIFY((widget.windowState() & Qt::WindowFullScreen));
       
  3160         QTRY_COMPARE(widget.geometry(), geom);
       
  3161         QVERIFY((widget.windowState() & Qt::WindowFullScreen));
       
  3162         widget.setWindowState(widget.windowState() ^ Qt::WindowFullScreen);
       
  3163         QTest::qWait(120);
       
  3164         QTRY_VERIFY(!(widget.windowState() & Qt::WindowFullScreen));
       
  3165         QTest::qWait(120);
       
  3166 
       
  3167         //Restore from Maximised
       
  3168         widget.move(position);
       
  3169         widget.resize(size);
       
  3170         QTest::qWait(10);
       
  3171         QTRY_COMPARE(widget.size(), size);
       
  3172         QTest::qWait(500);
       
  3173         savedGeometry = widget.saveGeometry();
       
  3174         geom = widget.geometry();
       
  3175         widget.setWindowState(widget.windowState() | Qt::WindowMaximized);
       
  3176         QTest::qWait(120);
       
  3177         QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized));
       
  3178         QTRY_VERIFY(widget.geometry() != geom);
       
  3179         QTest::qWait(500);
       
  3180         QVERIFY(widget.restoreGeometry(savedGeometry));
       
  3181         QTest::qWait(120);
       
  3182         QTRY_COMPARE(widget.geometry(), geom);
       
  3183 
       
  3184         QVERIFY(!(widget.windowState() & Qt::WindowMaximized));
       
  3185 
       
  3186         //Restore to maximised
       
  3187         widget.setWindowState(widget.windowState() | Qt::WindowMaximized);
       
  3188         QTest::qWait(120);
       
  3189         QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized));
       
  3190         QTest::qWait(500);
       
  3191         geom = widget.geometry();
       
  3192         savedGeometry = widget.saveGeometry();
       
  3193         widget.setWindowState(widget.windowState() ^ Qt::WindowMaximized);
       
  3194         QTest::qWait(120);
       
  3195         QTRY_VERIFY(!(widget.windowState() & Qt::WindowMaximized));
       
  3196         QTest::qWait(500);
       
  3197         QVERIFY(widget.restoreGeometry(savedGeometry));
       
  3198         QTest::qWait(120);
       
  3199         QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized));
       
  3200         QTRY_COMPARE(widget.geometry(), geom);
       
  3201     }
       
  3202 }
       
  3203 
       
  3204 void tst_QWidget::restoreVersion1Geometry_data()
       
  3205 {
       
  3206     QTest::addColumn<QString>("fileName");
       
  3207     QTest::addColumn<uint>("expectedWindowState");
       
  3208     QTest::addColumn<QPoint>("expectedPosition");
       
  3209     QTest::addColumn<QSize>("expectedSize");
       
  3210     QTest::addColumn<QRect>("expectedNormalGeometry");
       
  3211     const QPoint position(100, 100);
       
  3212     const QSize size(200, 200);
       
  3213     const QRect normalGeometry(102, 124, 200, 200);
       
  3214 
       
  3215     QTest::newRow("geometry.dat") << ":geometry.dat" << uint(Qt::WindowNoState) << position << size << normalGeometry;
       
  3216     QTest::newRow("geometry-maximized.dat") << ":geometry-maximized.dat" << uint(Qt::WindowMaximized) << position << size << normalGeometry;
       
  3217     QTest::newRow("geometry-fullscreen.dat") << ":geometry-fullscreen.dat" << uint(Qt::WindowFullScreen) << position << size << normalGeometry;
       
  3218 }
       
  3219 
       
  3220 /*
       
  3221     Test that the current version of restoreGeometry() can restore geometry
       
  3222     saved width saveGeometry() version 1.0.
       
  3223 */
       
  3224 void tst_QWidget::restoreVersion1Geometry()
       
  3225 {
       
  3226 #ifdef Q_OS_IRIX
       
  3227     QSKIP("4DWM issues on IRIX makes this test fail", SkipAll);
       
  3228 #endif
       
  3229 
       
  3230     QFETCH(QString, fileName);
       
  3231     QFETCH(uint, expectedWindowState);
       
  3232     QFETCH(QPoint, expectedPosition);
       
  3233     QFETCH(QSize, expectedSize);
       
  3234     QFETCH(QRect, expectedNormalGeometry);
       
  3235 
       
  3236     // WindowActive is uninteresting for this test
       
  3237     const uint WindowStateMask = Qt::WindowFullScreen | Qt::WindowMaximized | Qt::WindowMinimized;
       
  3238 
       
  3239     QFile f(fileName);
       
  3240     QVERIFY(f.exists());
       
  3241     f.open(QIODevice::ReadOnly);
       
  3242     const QByteArray savedGeometry = f.readAll();
       
  3243     QCOMPARE(savedGeometry.count(), 46);
       
  3244     f.close();
       
  3245 
       
  3246     QWidget widget;
       
  3247 
       
  3248     QVERIFY(widget.restoreGeometry(savedGeometry));
       
  3249 
       
  3250     QCOMPARE(uint(widget.windowState() & WindowStateMask), expectedWindowState);
       
  3251     if (expectedWindowState == Qt::WindowNoState) {
       
  3252         QCOMPARE(widget.pos(), expectedPosition);
       
  3253         QCOMPARE(widget.size(), expectedSize);
       
  3254     }
       
  3255     widget.show();
       
  3256     QTest::qWaitForWindowShown(&widget);
       
  3257     QTest::qWait(100);
       
  3258 
       
  3259     if (expectedWindowState == Qt::WindowNoState) {
       
  3260         QTRY_COMPARE(widget.pos(), expectedPosition);
       
  3261         QTRY_COMPARE(widget.size(), expectedSize);
       
  3262     }
       
  3263 
       
  3264     widget.showNormal();
       
  3265     QTest::qWait(10);
       
  3266 
       
  3267     if (expectedWindowState != Qt::WindowNoState) {
       
  3268         // restoring from maximized or fullscreen, we can only restore to the normal geometry
       
  3269         QTRY_COMPARE(widget.geometry(), expectedNormalGeometry);
       
  3270     } else {
       
  3271         QTRY_COMPARE(widget.pos(), expectedPosition);
       
  3272         QTRY_COMPARE(widget.size(), expectedSize);
       
  3273     }
       
  3274 
       
  3275 #if 0
       
  3276     // Code for saving a new geometry*.dat files
       
  3277     {
       
  3278         QWidget widgetToSave;
       
  3279         widgetToSave.move(expectedPosition);
       
  3280         widgetToSave.resize(expectedSize);
       
  3281         widgetToSave.show();
       
  3282 #ifdef Q_WS_X11
       
  3283         qt_x11_wait_for_window_manager(&widget);
       
  3284 #endif
       
  3285         QTest::qWait(500); // stabilize
       
  3286         widgetToSave.setWindowState(Qt::WindowStates(expectedWindowState));
       
  3287         QTest::qWait(500); // stabilize
       
  3288 
       
  3289         QByteArray geometryToSave = widgetToSave.saveGeometry();
       
  3290 
       
  3291         // Code for saving a new geometry.dat file.
       
  3292         f.setFileName(fileName.mid(1));
       
  3293         QVERIFY(f.open(QIODevice::WriteOnly)); // did you forget to 'p4 edit *.dat'? :)
       
  3294         f.write(geometryToSave);
       
  3295         f.close();
       
  3296     }
       
  3297 #endif
       
  3298 
       
  3299 }
       
  3300 
       
  3301 void tst_QWidget::widgetAt()
       
  3302 {
       
  3303     Q_CHECK_PAINTEVENTS
       
  3304 
       
  3305     QWidget *w1 = new QWidget(0, Qt::X11BypassWindowManagerHint);
       
  3306     w1->setGeometry(0,0,150,150);
       
  3307     w1->setObjectName("w1");
       
  3308 
       
  3309     QWidget *w2 = new QWidget(0, Qt::X11BypassWindowManagerHint  | Qt::FramelessWindowHint);
       
  3310     w2->setGeometry(50,50,100,100);
       
  3311     w2->setObjectName("w2");
       
  3312     w1->show();
       
  3313     QTest::qWaitForWindowShown(w1);
       
  3314     qApp->processEvents();
       
  3315     QWidget *wr;
       
  3316     QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)));
       
  3317     QCOMPARE(wr->objectName(), QString("w1"));
       
  3318 
       
  3319     w2->show();
       
  3320     QTest::qWaitForWindowShown(w2);
       
  3321     qApp->processEvents();
       
  3322     qApp->processEvents();
       
  3323     qApp->processEvents();
       
  3324     QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)));
       
  3325     QCOMPARE(wr->objectName(), QString("w2"));
       
  3326 
       
  3327     w2->lower();
       
  3328     qApp->processEvents();
       
  3329     QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)));
       
  3330     QCOMPARE(wr->objectName(), QString("w1"));
       
  3331 
       
  3332     w2->raise();
       
  3333     qApp->processEvents();
       
  3334     QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)));
       
  3335     QCOMPARE(wr->objectName(), QString("w2"));
       
  3336 
       
  3337 
       
  3338     QWidget *w3 = new QWidget(w2);
       
  3339     w3->setGeometry(10,10,50,50);
       
  3340     w3->setObjectName("w3");
       
  3341     w3->show();
       
  3342     qApp->processEvents();
       
  3343     QTRY_VERIFY((wr = QApplication::widgetAt(100,100)));
       
  3344     QCOMPARE(wr->objectName(), QString("w3"));
       
  3345 
       
  3346     w3->setAttribute(Qt::WA_TransparentForMouseEvents);
       
  3347     qApp->processEvents();
       
  3348     QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)));
       
  3349     QCOMPARE(wr->objectName(), QString("w2"));
       
  3350 
       
  3351     QRegion rgn = QRect(QPoint(0,0), w2->size());
       
  3352     QPoint point = w2->mapFromGlobal(QPoint(100,100));
       
  3353     rgn -= QRect(point, QSize(1,1));
       
  3354     w2->setMask(rgn);
       
  3355     qApp->processEvents();
       
  3356     QTest::qWait(10);
       
  3357 #if defined(Q_OS_WINCE)
       
  3358     QEXPECT_FAIL("", "Windows CE does only support rectangular regions", Continue); //See also task 147191
       
  3359 #endif
       
  3360 #if defined(Q_OS_SYMBIAN)
       
  3361     QEXPECT_FAIL("", "Symbian/S60 does only support rectangular regions", Continue); //See also task 147191
       
  3362 #endif
       
  3363     QTRY_COMPARE(QApplication::widgetAt(100,100)->objectName(), w1->objectName());
       
  3364     QTRY_COMPARE(QApplication::widgetAt(101,101)->objectName(), w2->objectName());
       
  3365 
       
  3366     QBitmap bitmap(w2->size());
       
  3367     QPainter p(&bitmap);
       
  3368     p.fillRect(bitmap.rect(), Qt::color1);
       
  3369     p.setPen(Qt::color0);
       
  3370     p.drawPoint(w2->mapFromGlobal(QPoint(100,100)));
       
  3371     p.end();
       
  3372     w2->setMask(bitmap);
       
  3373     qApp->processEvents();
       
  3374     QTest::qWait(10);
       
  3375 #if defined(Q_OS_WINCE)
       
  3376     QEXPECT_FAIL("", "Windows CE does only support rectangular regions", Continue); //See also task 147191
       
  3377 #endif
       
  3378 #if defined(Q_OS_SYMBIAN)
       
  3379     QEXPECT_FAIL("", "Symbian/S60 does only support rectangular regions", Continue); //See also task 147191
       
  3380 #endif
       
  3381     QTRY_VERIFY(QApplication::widgetAt(100,100) == w1);
       
  3382     QTRY_VERIFY(QApplication::widgetAt(101,101) == w2);
       
  3383 
       
  3384     delete w2;
       
  3385     delete w1;
       
  3386 }
       
  3387 
       
  3388 #if defined(Q_WS_X11)
       
  3389 bool getProperty(Display *display, Window target, Atom type, Atom property,
       
  3390                  unsigned char** data, unsigned long* count)
       
  3391 {
       
  3392     Atom atom_return;
       
  3393     int size;
       
  3394     unsigned long nitems, bytes_left;
       
  3395 
       
  3396     int ret = XGetWindowProperty(display, target, property,
       
  3397                                  0l, 1l, false,
       
  3398                                  type, &atom_return, &size,
       
  3399                                  &nitems, &bytes_left, data);
       
  3400     if (ret != Success || nitems < 1)
       
  3401         return false;
       
  3402 
       
  3403     if (bytes_left != 0) {
       
  3404         XFree(*data);
       
  3405         unsigned long remain = ((size / 8) * nitems) + bytes_left;
       
  3406         ret = XGetWindowProperty(display, target,
       
  3407                                  property, 0l, remain, false,
       
  3408                                  type, &atom_return, &size,
       
  3409                                  &nitems, &bytes_left, data);
       
  3410         if (ret != Success)
       
  3411             return false;
       
  3412     }
       
  3413 
       
  3414     *count = nitems;
       
  3415     return true;
       
  3416 }
       
  3417 
       
  3418 QString textPropertyToString(Display *display, XTextProperty& text_prop)
       
  3419 {
       
  3420     QString ret;
       
  3421     if (text_prop.value && text_prop.nitems > 0) {
       
  3422         if (text_prop.encoding == XA_STRING) {
       
  3423             ret = reinterpret_cast<char *>(text_prop.value);
       
  3424         } else {
       
  3425             text_prop.nitems = strlen(reinterpret_cast<char *>(text_prop.value));
       
  3426             char **list;
       
  3427             int num;
       
  3428             if (XmbTextPropertyToTextList(display, &text_prop, &list, &num) == Success
       
  3429                 && num > 0 && *list) {
       
  3430                 ret = QString::fromLocal8Bit(*list);
       
  3431                 XFreeStringList(list);
       
  3432             }
       
  3433         }
       
  3434     }
       
  3435     return ret;
       
  3436 }
       
  3437 
       
  3438 #endif
       
  3439 
       
  3440 #if defined(Q_WS_S60)
       
  3441 // Returns the application's status pane control, if not present returns NULL.
       
  3442 static CCoeControl* GetStatusPaneControl( TInt aPaneId )
       
  3443 {
       
  3444     const TUid paneUid = { aPaneId };
       
  3445 
       
  3446     CEikStatusPane* statusPane = CEikonEnv::Static()->AppUiFactory()->StatusPane();
       
  3447     if (statusPane && statusPane->PaneCapabilities(paneUid).IsPresent()){
       
  3448 		CCoeControl* control = NULL;
       
  3449         // ControlL shouldn't leave because the pane is present
       
  3450 		TRAPD(err, control = statusPane->ControlL(paneUid));
       
  3451 		return err != KErrNone ? NULL : control;
       
  3452     }
       
  3453     return NULL;
       
  3454 }
       
  3455 // Returns the application's title pane, if not present returns NULL.
       
  3456 static CAknTitlePane* TitlePane()
       
  3457 {
       
  3458     return static_cast<CAknTitlePane*>(GetStatusPaneControl(EEikStatusPaneUidTitle));
       
  3459 }
       
  3460 
       
  3461 // Returns the application's title pane, if not present returns NULL.
       
  3462 static CAknContextPane* ContextPane()
       
  3463 {
       
  3464     return static_cast<CAknContextPane*>(GetStatusPaneControl(EEikStatusPaneUidContext));
       
  3465 }
       
  3466 #endif
       
  3467 
       
  3468 static QString visibleWindowTitle(QWidget *window, Qt::WindowState state = Qt::WindowNoState)
       
  3469 {
       
  3470     QString vTitle;
       
  3471 
       
  3472 #ifdef Q_WS_WIN
       
  3473     Q_UNUSED(state);
       
  3474     const size_t maxTitleLength = 256;
       
  3475     wchar_t title[maxTitleLength];
       
  3476     GetWindowText(window->winId(), title, maxTitleLength);
       
  3477     vTitle = QString::fromWCharArray(title);
       
  3478 #elif defined(Q_WS_X11)
       
  3479     /*
       
  3480       We can't check what the window manager displays, but we can
       
  3481       check what we tell the window manager to display.  This will
       
  3482       have to do.
       
  3483     */
       
  3484     Atom UTF8_STRING = XInternAtom(window->x11Info().display(), "UTF8_STRING", false);
       
  3485     Atom _NET_WM_NAME = XInternAtom(window->x11Info().display(), "_NET_WM_NAME", false);
       
  3486     Atom _NET_WM_ICON_NAME = XInternAtom(window->x11Info().display(), "_NET_WM_ICON_NAME", false);
       
  3487     uchar *data = 0;
       
  3488     ulong length = 0;
       
  3489     if (state == Qt::WindowMinimized) {
       
  3490         if (getProperty(window->x11Info().display(), window->winId(),
       
  3491                     UTF8_STRING, _NET_WM_ICON_NAME, &data, &length)) {
       
  3492             vTitle = QString::fromUtf8((char *) data, length);
       
  3493             XFree(data);
       
  3494         } else {
       
  3495             XTextProperty text_prop;
       
  3496             if (XGetWMIconName(window->x11Info().display(), window->winId(), &text_prop)) {
       
  3497                 vTitle = textPropertyToString(window->x11Info().display(), text_prop);
       
  3498                 XFree((char *) text_prop.value);
       
  3499             }
       
  3500         }
       
  3501     } else {
       
  3502         if (getProperty(window->x11Info().display(), window->winId(),
       
  3503                     UTF8_STRING, _NET_WM_NAME, &data, &length)) {
       
  3504             vTitle = QString::fromUtf8((char *) data, length);
       
  3505             XFree(data);
       
  3506         } else {
       
  3507             XTextProperty text_prop;
       
  3508             if (XGetWMName(window->x11Info().display(), window->winId(), &text_prop)) {
       
  3509                 vTitle = textPropertyToString(window->x11Info().display(), text_prop);
       
  3510                 XFree((char *) text_prop.value);
       
  3511             }
       
  3512         }
       
  3513     }
       
  3514 #elif defined(Q_WS_MAC)
       
  3515     vTitle = nativeWindowTitle(window, state);
       
  3516 #elif defined(Q_WS_QWS)
       
  3517     if (qwsServer) {
       
  3518     const QWSWindow *win = 0;
       
  3519     const QList<QWSWindow*> windows = qwsServer->clientWindows();
       
  3520     for (int i = 0; i < windows.count(); ++i) {
       
  3521         const QWSWindow* w = windows.at(i);
       
  3522         if (w->winId() == window->winId()) {
       
  3523             win = w;
       
  3524             break;
       
  3525         }
       
  3526     }
       
  3527     if (win)
       
  3528         vTitle = win->caption();
       
  3529     }
       
  3530 #elif defined (Q_WS_S60)
       
  3531     CAknTitlePane* titlePane = TitlePane();
       
  3532     if(titlePane)
       
  3533         {
       
  3534         const TDesC* nTitle = titlePane->Text();
       
  3535         vTitle = QString::fromUtf16(nTitle->Ptr(), nTitle->Length());
       
  3536         }
       
  3537 #endif
       
  3538 
       
  3539     return vTitle;
       
  3540 }
       
  3541 
       
  3542 void tst_QWidget::windowTitle()
       
  3543 {
       
  3544     QWidget widget(0);
       
  3545     widget.setWindowTitle("Application Name");
       
  3546     widget.winId(); // Make sure the window is created...
       
  3547     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3548 
       
  3549     widget.setWindowTitle("Application Name *");
       
  3550     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name *"));
       
  3551 
       
  3552     widget.setWindowTitle("Application Name[*]");
       
  3553     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3554 
       
  3555     widget.setWindowTitle("Application Name[*][*]");
       
  3556     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name[*]"));
       
  3557 
       
  3558     widget.setWindowTitle("Application Name[*][*][*]");
       
  3559     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name[*]"));
       
  3560 
       
  3561     widget.setWindowTitle("Application Name[*][*][*][*]");
       
  3562     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name[*][*]"));
       
  3563 }
       
  3564 
       
  3565 void tst_QWidget::windowIconText()
       
  3566 {
       
  3567 #ifdef Q_OS_SYMBIAN
       
  3568     QSKIP("Symbian/S60 windows don't have window icon text", SkipAll);
       
  3569 #endif
       
  3570     QWidget widget(0);
       
  3571 
       
  3572     widget.setWindowTitle("Application Name");
       
  3573     widget.setWindowIconText("Application Minimized");
       
  3574     widget.showNormal();
       
  3575     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3576     widget.showMinimized();
       
  3577 #if defined(Q_WS_QWS) || defined(Q_OS_WINCE)
       
  3578     QEXPECT_FAIL(0, "Qt/Embedded/WinCE does not implement showMinimized()", Continue);
       
  3579     //See task 147193 for WinCE
       
  3580 #endif
       
  3581     QApplication::instance()->processEvents();
       
  3582     QCOMPARE(visibleWindowTitle(&widget, Qt::WindowMinimized),
       
  3583             QString("Application Minimized"));
       
  3584 
       
  3585     widget.setWindowTitle("Application Name[*]");
       
  3586     widget.setWindowIconText("Application Minimized[*]");
       
  3587     widget.showNormal();
       
  3588     QApplication::instance()->processEvents();
       
  3589     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3590     widget.showMinimized();
       
  3591 #if defined (Q_WS_QWS) || defined(Q_OS_WINCE)
       
  3592     QEXPECT_FAIL(0, "Qt/Embedded/WinCE does not implement showMinimized()", Continue);
       
  3593     //See task 147193 for WinCE
       
  3594 #endif
       
  3595     QApplication::instance()->processEvents();
       
  3596     QCOMPARE(visibleWindowTitle(&widget, Qt::WindowMinimized),
       
  3597             QString("Application Minimized"));
       
  3598 
       
  3599     widget.setWindowModified(true);
       
  3600     widget.showNormal();
       
  3601     QApplication::instance()->processEvents();
       
  3602     if (widget.style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, &widget))
       
  3603         QCOMPARE(visibleWindowTitle(&widget), QString("Application Name*"));
       
  3604     else
       
  3605         QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3606     widget.showMinimized();
       
  3607 #if defined (Q_WS_QWS) || defined(Q_OS_WINCE)
       
  3608     QEXPECT_FAIL(0, "Qt/Embedded/WinCE does not implement showMinimized()", Continue);
       
  3609     //See task 147193 for WinCE
       
  3610 #endif
       
  3611     QApplication::instance()->processEvents();
       
  3612 #ifdef Q_WS_MAC
       
  3613     QCOMPARE(visibleWindowTitle(&widget, Qt::WindowMinimized),
       
  3614             QString("Application Minimized"));
       
  3615     QVERIFY(nativeWindowModified(&widget));
       
  3616 #else
       
  3617     QCOMPARE(visibleWindowTitle(&widget, Qt::WindowMinimized),
       
  3618             QString("Application Minimized*"));
       
  3619 #endif
       
  3620 }
       
  3621 
       
  3622 void tst_QWidget::windowModified()
       
  3623 {
       
  3624     QWidget widget(0);
       
  3625     widget.show();
       
  3626     QTest::qWaitForWindowShown(&widget);
       
  3627 #ifndef Q_WS_MAC
       
  3628     QTest::ignoreMessage(QtWarningMsg, "QWidget::setWindowModified: The window title does not contain a '[*]' placeholder");
       
  3629 #endif
       
  3630     widget.setWindowTitle("Application Name");
       
  3631     QTest::qWait(10);
       
  3632     QTRY_COMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3633 
       
  3634 #ifdef Q_WS_MAC
       
  3635     widget.setWindowModified(true);
       
  3636     QVERIFY(nativeWindowModified(&widget));
       
  3637 #else
       
  3638     widget.setWindowModified(true);
       
  3639     QApplication::instance()->processEvents();
       
  3640     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3641 
       
  3642     widget.setWindowModified(false);
       
  3643     QApplication::instance()->processEvents();
       
  3644     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3645 
       
  3646     widget.setWindowTitle("Application Name[*]");
       
  3647 
       
  3648     widget.setWindowModified(true);
       
  3649     QApplication::instance()->processEvents();
       
  3650     if (widget.style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, &widget))
       
  3651         QCOMPARE(visibleWindowTitle(&widget), QString("Application Name*"));
       
  3652     else
       
  3653         QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3654 
       
  3655     widget.setWindowModified(false);
       
  3656     QApplication::instance()->processEvents();
       
  3657     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3658 
       
  3659     widget.setWindowTitle("Application[*] Name[*]");
       
  3660 
       
  3661     widget.setWindowModified(true);
       
  3662     QApplication::instance()->processEvents();
       
  3663     QCOMPARE(visibleWindowTitle(&widget), QString("Application* Name*"));
       
  3664 
       
  3665     widget.setWindowModified(false);
       
  3666     QApplication::instance()->processEvents();
       
  3667     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name"));
       
  3668 
       
  3669     widget.setWindowTitle("Application Name[*][*]");
       
  3670 
       
  3671     widget.setWindowModified(true);
       
  3672     QApplication::instance()->processEvents();
       
  3673     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name[*]"));
       
  3674 
       
  3675     widget.setWindowModified(false);
       
  3676     QApplication::instance()->processEvents();
       
  3677     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name[*]"));
       
  3678 
       
  3679     widget.setWindowTitle("Application[*][*] Name[*][*]");
       
  3680 
       
  3681     widget.setWindowModified(true);
       
  3682     QApplication::instance()->processEvents();
       
  3683     QCOMPARE(visibleWindowTitle(&widget), QString("Application[*] Name[*]"));
       
  3684 
       
  3685     widget.setWindowModified(false);
       
  3686     QApplication::instance()->processEvents();
       
  3687     QCOMPARE(visibleWindowTitle(&widget), QString("Application[*] Name[*]"));
       
  3688 
       
  3689     widget.setWindowTitle("Application[*] Name[*][*][*]");
       
  3690 
       
  3691     widget.setWindowModified(true);
       
  3692     QApplication::instance()->processEvents();
       
  3693     QCOMPARE(visibleWindowTitle(&widget), QString("Application* Name[*]*"));
       
  3694 
       
  3695     widget.setWindowModified(false);
       
  3696     QApplication::instance()->processEvents();
       
  3697     QCOMPARE(visibleWindowTitle(&widget), QString("Application Name[*]"));
       
  3698 
       
  3699     widget.setWindowTitle("Application[*][*][*] Name[*][*][*]");
       
  3700 
       
  3701     widget.setWindowModified(true);
       
  3702     QApplication::instance()->processEvents();
       
  3703     QCOMPARE(visibleWindowTitle(&widget), QString("Application[*]* Name[*]*"));
       
  3704 
       
  3705     widget.setWindowModified(false);
       
  3706     QApplication::instance()->processEvents();
       
  3707     QCOMPARE(visibleWindowTitle(&widget), QString("Application[*] Name[*]"));
       
  3708 #endif
       
  3709 }
       
  3710 
       
  3711 void tst_QWidget::task110173()
       
  3712 {
       
  3713     QWidget w;
       
  3714 
       
  3715     QPushButton *pb1 = new QPushButton("click", &w);
       
  3716     pb1->setFocusPolicy(Qt::ClickFocus);
       
  3717     pb1->move(100, 100);
       
  3718 
       
  3719     QPushButton *pb2 = new QPushButton("push", &w);
       
  3720     pb2->setFocusPolicy(Qt::ClickFocus);
       
  3721     pb2->move(300, 300);
       
  3722 
       
  3723     QTest::keyClick( &w, Qt::Key_Tab );
       
  3724     w.show();
       
  3725     QTest::qWaitForWindowShown(&w);
       
  3726     QTest::qWait(200);
       
  3727 }
       
  3728 
       
  3729 class Widget : public QWidget
       
  3730 {
       
  3731 public:
       
  3732     Widget() : deleteThis(false) { setFocusPolicy(Qt::StrongFocus); }
       
  3733     void actionEvent(QActionEvent *) { if (deleteThis) delete this; }
       
  3734     void changeEvent(QEvent *) { if (deleteThis) delete this; }
       
  3735     void closeEvent(QCloseEvent *) { if (deleteThis) delete this; }
       
  3736     void hideEvent(QHideEvent *) { if (deleteThis) delete this; }
       
  3737     void focusOutEvent(QFocusEvent *) { if (deleteThis) delete this; }
       
  3738     void keyPressEvent(QKeyEvent *) { if (deleteThis) delete this; }
       
  3739     void keyReleaseEvent(QKeyEvent *) { if (deleteThis) delete this; }
       
  3740     void mouseDoubleClickEvent(QMouseEvent *) { if (deleteThis) delete this; }
       
  3741     void mousePressEvent(QMouseEvent *) { if (deleteThis) delete this; }
       
  3742     void mouseReleaseEvent(QMouseEvent *) { if (deleteThis) delete this; }
       
  3743     void mouseMoveEvent(QMouseEvent *) { if (deleteThis) delete this; }
       
  3744 
       
  3745     bool deleteThis;
       
  3746 };
       
  3747 
       
  3748 void tst_QWidget::testDeletionInEventHandlers()
       
  3749 {
       
  3750     // closeEvent
       
  3751     QPointer<Widget> w = new Widget;
       
  3752     w->deleteThis = true;
       
  3753     w->close();
       
  3754     QVERIFY(w == 0);
       
  3755     delete w;
       
  3756 
       
  3757     // focusOut (crashes)
       
  3758     //w = new Widget;
       
  3759     //w->show();
       
  3760     //w->setFocus();
       
  3761     //QVERIFY(qApp->focusWidget() == w);
       
  3762     //w->deleteThis = true;
       
  3763     //w->clearFocus();
       
  3764     //QVERIFY(w == 0);
       
  3765 
       
  3766     // key press
       
  3767     w = new Widget;
       
  3768     w->show();
       
  3769     w->deleteThis = true;
       
  3770     QTest::keyPress(w, Qt::Key_A);
       
  3771     QVERIFY(w == 0);
       
  3772     delete w;
       
  3773 
       
  3774     // key release
       
  3775     w = new Widget;
       
  3776     w->show();
       
  3777     w->deleteThis = true;
       
  3778     QTest::keyRelease(w, Qt::Key_A);
       
  3779     QVERIFY(w == 0);
       
  3780     delete w;
       
  3781 
       
  3782     // mouse press
       
  3783     w = new Widget;
       
  3784     w->show();
       
  3785     w->deleteThis = true;
       
  3786     QTest::mousePress(w, Qt::LeftButton);
       
  3787     QVERIFY(w == 0);
       
  3788     delete w;
       
  3789 
       
  3790     // mouse release
       
  3791     w = new Widget;
       
  3792     w->show();
       
  3793     w->deleteThis = true;
       
  3794     QTest::mouseRelease(w, Qt::LeftButton);
       
  3795     QVERIFY(w == 0);
       
  3796     delete w;
       
  3797 
       
  3798     // mouse double click
       
  3799     w = new Widget;
       
  3800     w->show();
       
  3801     w->deleteThis = true;
       
  3802     QTest::mouseDClick(w, Qt::LeftButton);
       
  3803     QVERIFY(w == 0);
       
  3804     delete w;
       
  3805 
       
  3806     // hide event (crashes)
       
  3807     //w = new Widget;
       
  3808     //w->show();
       
  3809     //w->deleteThis = true;
       
  3810     //w->hide();
       
  3811     //QVERIFY(w == 0);
       
  3812 
       
  3813     // action event
       
  3814     w = new Widget;
       
  3815     w->deleteThis = true;
       
  3816     w->addAction(new QAction(w));
       
  3817     QVERIFY(w == 0);
       
  3818     delete w;
       
  3819 
       
  3820     // change event
       
  3821     w = new Widget;
       
  3822     w->show();
       
  3823     w->deleteThis = true;
       
  3824     w->setMouseTracking(true);
       
  3825     QVERIFY(w == 0);
       
  3826     delete w;
       
  3827 
       
  3828     w = new Widget;
       
  3829     w->setMouseTracking(true);
       
  3830     w->show();
       
  3831     w->deleteThis = true;
       
  3832     QMouseEvent me(QEvent::MouseMove, QPoint(0, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
       
  3833     QApplication::sendEvent(w, &me);
       
  3834     QVERIFY(w == 0);
       
  3835     delete w;
       
  3836 }
       
  3837 
       
  3838 #ifdef Q_WS_MAC
       
  3839 
       
  3840 bool testAndRelease(const HIViewRef view)
       
  3841 {
       
  3842 //    qDebug() << CFGetRetainCount(view);
       
  3843     if (CFGetRetainCount(view) != 2)
       
  3844         return false;
       
  3845     CFRelease(view);
       
  3846     CFRelease(view);
       
  3847     return true;
       
  3848 }
       
  3849 
       
  3850 typedef QPair<QWidget *, HIViewRef> WidgetViewPair;
       
  3851 
       
  3852 WidgetViewPair createAndRetain(QWidget * const parent = 0)
       
  3853 {
       
  3854     QWidget * const widget = new QWidget(parent);
       
  3855     const HIViewRef view = (HIViewRef)widget->winId();
       
  3856     // Retain twice so we can safely call CFGetRetaintCount even if the retain count
       
  3857     // is off by one because of a double release.
       
  3858     CFRetain(view);
       
  3859     CFRetain(view);
       
  3860     return qMakePair(widget, view);
       
  3861 }
       
  3862 
       
  3863 /*
       
  3864     Test that retaining and releasing the HIView returned by QWidget::winId()
       
  3865     works even if the widget itself is deleted.
       
  3866 */
       
  3867 void tst_QWidget::retainHIView()
       
  3868 {
       
  3869     // Single window
       
  3870     {
       
  3871         const WidgetViewPair window  = createAndRetain();
       
  3872         delete window.first;
       
  3873         QVERIFY(testAndRelease(window.second));
       
  3874     }
       
  3875 
       
  3876     // Child widget
       
  3877     {
       
  3878         const WidgetViewPair parent = createAndRetain();
       
  3879         const WidgetViewPair child = createAndRetain(parent.first);
       
  3880 
       
  3881         delete parent.first;
       
  3882         QVERIFY(testAndRelease(parent.second));
       
  3883         QVERIFY(testAndRelease(child.second));
       
  3884     }
       
  3885 
       
  3886     // Multiple children
       
  3887     {
       
  3888         const WidgetViewPair parent = createAndRetain();
       
  3889         const WidgetViewPair child1 = createAndRetain(parent.first);
       
  3890         const WidgetViewPair child2 = createAndRetain(parent.first);
       
  3891 
       
  3892         delete parent.first;
       
  3893         QVERIFY(testAndRelease(parent.second));
       
  3894         QVERIFY(testAndRelease(child1.second));
       
  3895         QVERIFY(testAndRelease(child2.second));
       
  3896     }
       
  3897 
       
  3898     // Grandchild widget
       
  3899     {
       
  3900         const WidgetViewPair parent = createAndRetain();
       
  3901         const WidgetViewPair child = createAndRetain(parent.first);
       
  3902         const WidgetViewPair grandchild = createAndRetain(child.first);
       
  3903 
       
  3904         delete parent.first;
       
  3905         QVERIFY(testAndRelease(parent.second));
       
  3906         QVERIFY(testAndRelease(child.second));
       
  3907         QVERIFY(testAndRelease(grandchild.second));
       
  3908     }
       
  3909 
       
  3910     // Reparent child widget
       
  3911     {
       
  3912         const WidgetViewPair parent1 = createAndRetain();
       
  3913         const WidgetViewPair parent2 = createAndRetain();
       
  3914         const WidgetViewPair child = createAndRetain(parent1.first);
       
  3915 
       
  3916         child.first->setParent(parent2.first);
       
  3917 
       
  3918         delete parent1.first;
       
  3919         QVERIFY(testAndRelease(parent1.second));
       
  3920         delete parent2.first;
       
  3921         QVERIFY(testAndRelease(parent2.second));
       
  3922         QVERIFY(testAndRelease(child.second));
       
  3923     }
       
  3924 
       
  3925     // Reparent window
       
  3926     {
       
  3927         const WidgetViewPair window1 = createAndRetain();
       
  3928         const WidgetViewPair window2 = createAndRetain();
       
  3929         const WidgetViewPair child1 = createAndRetain(window1.first);
       
  3930         const WidgetViewPair child2 = createAndRetain(window2.first);
       
  3931 
       
  3932         window2.first->setParent(window1.first);
       
  3933 
       
  3934         delete window2.first;
       
  3935         QVERIFY(testAndRelease(window2.second));
       
  3936         QVERIFY(testAndRelease(child2.second));
       
  3937         delete window1.first;
       
  3938         QVERIFY(testAndRelease(window1.second));
       
  3939         QVERIFY(testAndRelease(child1.second));
       
  3940     }
       
  3941 
       
  3942     // Delete child widget
       
  3943     {
       
  3944         const WidgetViewPair parent = createAndRetain();
       
  3945         const WidgetViewPair child = createAndRetain(parent.first);
       
  3946 
       
  3947         delete child.first;
       
  3948         QVERIFY(testAndRelease(child.second));
       
  3949         delete parent.first;
       
  3950         QVERIFY(testAndRelease(parent.second));
       
  3951     }
       
  3952 }
       
  3953 
       
  3954 void tst_QWidget::sheetOpacity()
       
  3955 {
       
  3956     QWidget tmpWindow;
       
  3957     QWidget sheet(&tmpWindow, Qt::Sheet);
       
  3958     tmpWindow.show();
       
  3959     sheet.show();
       
  3960     QCOMPARE(int(sheet.windowOpacity() * 255), 242);  // 95%
       
  3961     sheet.setParent(0, Qt::Dialog);
       
  3962     QCOMPARE(int(sheet.windowOpacity() * 255), 255);
       
  3963 }
       
  3964 
       
  3965 class MaskedPainter : public QWidget
       
  3966 {
       
  3967 public:
       
  3968     QRect mask;
       
  3969 
       
  3970     MaskedPainter()
       
  3971     : mask(20, 20, 50, 50)
       
  3972     {
       
  3973         setMask(mask);
       
  3974     }
       
  3975 
       
  3976     void paintEvent(QPaintEvent *)
       
  3977     {
       
  3978         QPainter p(this);
       
  3979         p.fillRect(mask, QColor(Qt::red));
       
  3980     }
       
  3981 };
       
  3982 
       
  3983 /*
       
  3984     Verifies that the entire area inside the mask is painted red.
       
  3985 */
       
  3986 bool verifyWidgetMask(QWidget *widget, QRect mask)
       
  3987 {
       
  3988     const QImage image = QPixmap::grabWindow(widget->winId()).toImage();
       
  3989 
       
  3990     const QImage masked = image.copy(mask);
       
  3991     QImage red(masked);
       
  3992     red.fill(QColor(Qt::red).rgb());
       
  3993 
       
  3994     return (masked == red);
       
  3995 }
       
  3996 
       
  3997 void tst_QWidget::setMask()
       
  3998 {
       
  3999     testWidget->hide(); // get this out of the way.
       
  4000 
       
  4001     {
       
  4002         MaskedPainter w;
       
  4003         w.resize(200, 200);
       
  4004         w.show();
       
  4005         QTest::qWait(100);
       
  4006         QVERIFY(verifyWidgetMask(&w, w.mask));
       
  4007     }
       
  4008     {
       
  4009         MaskedPainter w;
       
  4010         w.resize(200, 200);
       
  4011         w.setWindowFlags(w.windowFlags() | Qt::FramelessWindowHint);
       
  4012         w.show();
       
  4013         QTest::qWait(100);
       
  4014         QRect mask = w.mask;
       
  4015 
       
  4016         QVERIFY(verifyWidgetMask(&w, mask));
       
  4017     }
       
  4018 }
       
  4019 #endif
       
  4020 
       
  4021 class StaticWidget : public QWidget
       
  4022 {
       
  4023 Q_OBJECT
       
  4024 public:
       
  4025     bool partial;
       
  4026     bool gotPaintEvent;
       
  4027     QRegion paintedRegion;
       
  4028 
       
  4029     StaticWidget(QWidget *parent = 0)
       
  4030     :QWidget(parent)
       
  4031     {
       
  4032         setAttribute(Qt::WA_StaticContents);
       
  4033         setAttribute(Qt::WA_OpaquePaintEvent);
       
  4034         setPalette(Qt::red); // Make sure we have an opaque palette.
       
  4035         setAutoFillBackground(true);
       
  4036         gotPaintEvent = false;
       
  4037     }
       
  4038 
       
  4039     void paintEvent(QPaintEvent *e)
       
  4040     {
       
  4041         paintedRegion += e->region();
       
  4042         gotPaintEvent = true;
       
  4043 //        qDebug() << "paint" << e->region();
       
  4044         // Look for a full update, set partial to false if found.
       
  4045         foreach(QRect r, e->region().rects()) {
       
  4046             partial = (r != rect());
       
  4047             if (partial == false)
       
  4048                 break;
       
  4049         }
       
  4050     }
       
  4051 };
       
  4052 
       
  4053 /*
       
  4054     Test that widget resizes and moves can be done with minimal repaints when WA_StaticContents
       
  4055     and WA_OpaquePaintEvent is set. Test is mac-only for now.
       
  4056 */
       
  4057 void tst_QWidget::optimizedResizeMove()
       
  4058 {
       
  4059     QWidget parent;
       
  4060     parent.resize(400, 400);
       
  4061 
       
  4062     StaticWidget staticWidget(&parent);
       
  4063     staticWidget.gotPaintEvent = false;
       
  4064     staticWidget.move(150, 150);
       
  4065     staticWidget.resize(150, 150);
       
  4066     parent.show();
       
  4067     QTest::qWaitForWindowShown(&parent);
       
  4068     QTest::qWait(20);
       
  4069     QTRY_COMPARE(staticWidget.gotPaintEvent, true);
       
  4070 
       
  4071     staticWidget.gotPaintEvent = false;
       
  4072     staticWidget.move(staticWidget.pos() + QPoint(10, 10));
       
  4073     QTest::qWait(20);
       
  4074     QCOMPARE(staticWidget.gotPaintEvent, false);
       
  4075 
       
  4076     staticWidget.gotPaintEvent = false;
       
  4077     staticWidget.move(staticWidget.pos() + QPoint(-10, -10));
       
  4078     QTest::qWait(20);
       
  4079     QCOMPARE(staticWidget.gotPaintEvent, false);
       
  4080 
       
  4081     staticWidget.gotPaintEvent = false;
       
  4082     staticWidget.move(staticWidget.pos() + QPoint(-10, 10));
       
  4083     QTest::qWait(20);
       
  4084     QCOMPARE(staticWidget.gotPaintEvent, false);
       
  4085 
       
  4086     staticWidget.gotPaintEvent = false;
       
  4087     staticWidget.resize(staticWidget.size() + QSize(10, 10));
       
  4088     QTest::qWait(20);
       
  4089     QCOMPARE(staticWidget.gotPaintEvent, true);
       
  4090     QCOMPARE(staticWidget.partial, true);
       
  4091 
       
  4092     staticWidget.gotPaintEvent = false;
       
  4093     staticWidget.resize(staticWidget.size() + QSize(-10, -10));
       
  4094     QTest::qWait(20);
       
  4095     QCOMPARE(staticWidget.gotPaintEvent, false);
       
  4096 
       
  4097     staticWidget.gotPaintEvent = false;
       
  4098     staticWidget.resize(staticWidget.size() + QSize(10, -10));
       
  4099     QTest::qWait(20);
       
  4100     QCOMPARE(staticWidget.gotPaintEvent, true);
       
  4101     QCOMPARE(staticWidget.partial, true);
       
  4102 
       
  4103     staticWidget.gotPaintEvent = false;
       
  4104     staticWidget.move(staticWidget.pos() + QPoint(10, 10));
       
  4105     staticWidget.resize(staticWidget.size() + QSize(-10, -10));
       
  4106     QTest::qWait(20);
       
  4107     QCOMPARE(staticWidget.gotPaintEvent, false);
       
  4108 
       
  4109     staticWidget.gotPaintEvent = false;
       
  4110     staticWidget.move(staticWidget.pos() + QPoint(10, 10));
       
  4111     staticWidget.resize(staticWidget.size() + QSize(10, 10));
       
  4112     QTest::qWait(20);
       
  4113     QCOMPARE(staticWidget.gotPaintEvent, true);
       
  4114     QCOMPARE(staticWidget.partial, true);
       
  4115 
       
  4116     staticWidget.gotPaintEvent = false;
       
  4117     staticWidget.move(staticWidget.pos() + QPoint(-10, -10));
       
  4118     staticWidget.resize(staticWidget.size() + QSize(-10, -10));
       
  4119     QTest::qWait(20);
       
  4120     QCOMPARE(staticWidget.gotPaintEvent, false);
       
  4121 
       
  4122     staticWidget.setAttribute(Qt::WA_StaticContents, false);
       
  4123     staticWidget.gotPaintEvent = false;
       
  4124     staticWidget.move(staticWidget.pos() + QPoint(-10, -10));
       
  4125     staticWidget.resize(staticWidget.size() + QSize(-10, -10));
       
  4126     QTest::qWait(20);
       
  4127     QCOMPARE(staticWidget.gotPaintEvent, true);
       
  4128     QCOMPARE(staticWidget.partial, false);
       
  4129     staticWidget.setAttribute(Qt::WA_StaticContents, true);
       
  4130 
       
  4131     staticWidget.setAttribute(Qt::WA_StaticContents, false);
       
  4132     staticWidget.gotPaintEvent = false;
       
  4133     staticWidget.move(staticWidget.pos() + QPoint(10, 10));
       
  4134     QTest::qWait(20);
       
  4135     QCOMPARE(staticWidget.gotPaintEvent, false);
       
  4136     staticWidget.setAttribute(Qt::WA_StaticContents, true);
       
  4137 }
       
  4138 
       
  4139 void tst_QWidget::optimizedResize_topLevel()
       
  4140 {
       
  4141 #if defined(Q_WS_MAC) || defined(Q_WS_QWS)
       
  4142     QSKIP("We do not yet have static contents support for *top-levels* on this platform", SkipAll);
       
  4143 #endif
       
  4144 
       
  4145     StaticWidget topLevel;
       
  4146     topLevel.gotPaintEvent = false;
       
  4147     topLevel.show();
       
  4148     QTest::qWaitForWindowShown(&topLevel);
       
  4149     QTest::qWait(10);
       
  4150     QTRY_COMPARE(topLevel.gotPaintEvent, true);
       
  4151 
       
  4152     topLevel.gotPaintEvent = false;
       
  4153     topLevel.partial = false;
       
  4154     topLevel.paintedRegion = QRegion();
       
  4155 
       
  4156 #ifndef Q_WS_WIN
       
  4157     topLevel.resize(topLevel.size() + QSize(10, 10));
       
  4158 #else
       
  4159     // Static contents does not work when programmatically resizing
       
  4160     // top-levels with QWidget::resize. We do some funky stuff in
       
  4161     // setGeometry_sys. However, resizing it with the mouse or with
       
  4162     // a native function call works (it basically has to go through
       
  4163     // WM_RESIZE in QApplication). This is a corner case, though.
       
  4164     // See task 243708
       
  4165     const QRect frame = topLevel.frameGeometry();
       
  4166     MoveWindow(topLevel.winId(), frame.x(), frame.y(),
       
  4167                frame.width() + 10, frame.height() + 10,
       
  4168                true);
       
  4169 #endif
       
  4170 
       
  4171     QTest::qWait(100);
       
  4172 
       
  4173     // Expected update region: New rect - old rect.
       
  4174     QRegion expectedUpdateRegion(topLevel.rect());
       
  4175     expectedUpdateRegion -= QRect(QPoint(), topLevel.size() - QSize(10, 10));
       
  4176 
       
  4177     QTRY_COMPARE(topLevel.gotPaintEvent, true);
       
  4178     QCOMPARE(topLevel.partial, true);
       
  4179     QCOMPARE(topLevel.paintedRegion, expectedUpdateRegion);
       
  4180 }
       
  4181 
       
  4182 class SiblingDeleter : public QWidget
       
  4183 {
       
  4184 public:
       
  4185     inline SiblingDeleter(QWidget *sibling, QWidget *parent)
       
  4186         : QWidget(parent), sibling(sibling) {}
       
  4187     inline virtual ~SiblingDeleter() { delete sibling; }
       
  4188 
       
  4189 private:
       
  4190     QPointer<QWidget> sibling;
       
  4191 };
       
  4192 
       
  4193 
       
  4194 void tst_QWidget::childDeletesItsSibling()
       
  4195 {
       
  4196     QWidget *commonParent = new QWidget(0);
       
  4197     QPointer<QWidget> child = new QWidget(0);
       
  4198     QPointer<QWidget> siblingDeleter = new SiblingDeleter(child, commonParent);
       
  4199     child->setParent(commonParent);
       
  4200     delete commonParent; // don't crash
       
  4201     QVERIFY(!child);
       
  4202     QVERIFY(!siblingDeleter);
       
  4203 
       
  4204 }
       
  4205 
       
  4206 #ifdef Q_WS_QWS
       
  4207 # define SET_SAFE_SIZE(w) \
       
  4208     do { \
       
  4209         QSize safeSize(qt_screen->width() - 250, qt_screen->height() - 250);      \
       
  4210          if (!safeSize.isValid()) \
       
  4211              QSKIP("Screen size too small", SkipAll); \
       
  4212          if (defaultSize.width() > safeSize.width() || defaultSize.height() > safeSize.height()) { \
       
  4213              defaultSize = safeSize; \
       
  4214              w.resize(defaultSize); \
       
  4215              w.setAttribute(Qt::WA_Resized, false); \
       
  4216          } \
       
  4217     } while (false)
       
  4218 #else
       
  4219 # define SET_SAFE_SIZE(w)
       
  4220 #endif
       
  4221 
       
  4222 
       
  4223 void tst_QWidget::setMinimumSize()
       
  4224 {
       
  4225     QWidget w;
       
  4226     QSize defaultSize = w.size();
       
  4227     SET_SAFE_SIZE(w);
       
  4228 
       
  4229     w.setMinimumSize(defaultSize + QSize(100, 100));
       
  4230     QCOMPARE(w.size(), defaultSize + QSize(100, 100));
       
  4231     QVERIFY(!w.testAttribute(Qt::WA_Resized));
       
  4232 
       
  4233     w.setMinimumSize(defaultSize + QSize(50, 50));
       
  4234     QCOMPARE(w.size(), defaultSize + QSize(100, 100));
       
  4235     QVERIFY(!w.testAttribute(Qt::WA_Resized));
       
  4236 
       
  4237     w.setMinimumSize(defaultSize + QSize(200, 200));
       
  4238     QCOMPARE(w.size(), defaultSize + QSize(200, 200));
       
  4239     QVERIFY(!w.testAttribute(Qt::WA_Resized));
       
  4240 
       
  4241 #ifdef Q_OS_WINCE
       
  4242     QSKIP("Setting a minimum size larger than the desktop does not work", SkipAll);
       
  4243 #endif
       
  4244     QSize nonDefaultSize = defaultSize + QSize(5,5);
       
  4245     w.setMinimumSize(nonDefaultSize);
       
  4246     w.show();
       
  4247     QTest::qWait(50);
       
  4248     QVERIFY(w.height() >= nonDefaultSize.height());
       
  4249     QVERIFY(w.width() >= nonDefaultSize.width());
       
  4250 }
       
  4251 
       
  4252 void tst_QWidget::setMaximumSize()
       
  4253 {
       
  4254     QWidget w;
       
  4255     QSize defaultSize = w.size();
       
  4256     SET_SAFE_SIZE(w);
       
  4257 
       
  4258     w.setMinimumSize(defaultSize + QSize(100, 100));
       
  4259     QCOMPARE(w.size(), defaultSize + QSize(100, 100));
       
  4260     QVERIFY(!w.testAttribute(Qt::WA_Resized));
       
  4261     w.setMinimumSize(defaultSize);
       
  4262 
       
  4263     w.setMaximumSize(defaultSize + QSize(200, 200));
       
  4264     QCOMPARE(w.size(), defaultSize + QSize(100, 100));
       
  4265     QVERIFY(!w.testAttribute(Qt::WA_Resized));
       
  4266 
       
  4267     w.setMaximumSize(defaultSize + QSize(50, 50));
       
  4268     QCOMPARE(w.size(), defaultSize + QSize(50, 50));
       
  4269     QVERIFY(!w.testAttribute(Qt::WA_Resized));
       
  4270 
       
  4271 #if 0
       
  4272     //we don't enforce maximum size on show, apparently
       
  4273     QSize nonDefaultSize = defaultSize - QSize(5,5);
       
  4274     w.setMaximumSize(nonDefaultSize);
       
  4275     w.show();
       
  4276     QTest::qWait(50);
       
  4277     qDebug() << nonDefaultSize << w.size();
       
  4278     QVERIFY(w.height() <= nonDefaultSize.height());
       
  4279     QVERIFY(w.width() <= nonDefaultSize.width());
       
  4280 #endif
       
  4281 }
       
  4282 
       
  4283 void tst_QWidget::setFixedSize()
       
  4284 {
       
  4285     QWidget w;
       
  4286     QSize defaultSize = w.size();
       
  4287     SET_SAFE_SIZE(w);
       
  4288 
       
  4289     w.setFixedSize(defaultSize + QSize(100, 100));
       
  4290     QCOMPARE(w.size(), defaultSize + QSize(100, 100));
       
  4291     QVERIFY(w.testAttribute(Qt::WA_Resized));
       
  4292 
       
  4293     w.setFixedSize(defaultSize + QSize(200, 200));
       
  4294 
       
  4295     QCOMPARE(w.minimumSize(), defaultSize + QSize(200,200));
       
  4296     QCOMPARE(w.maximumSize(), defaultSize + QSize(200,200));
       
  4297     QCOMPARE(w.size(), defaultSize + QSize(200, 200));
       
  4298     QVERIFY(w.testAttribute(Qt::WA_Resized));
       
  4299 
       
  4300     w.setFixedSize(defaultSize + QSize(50, 50));
       
  4301     QCOMPARE(w.size(), defaultSize + QSize(50, 50));
       
  4302     QVERIFY(w.testAttribute(Qt::WA_Resized));
       
  4303 
       
  4304     w.setAttribute(Qt::WA_Resized, false);
       
  4305     w.setFixedSize(defaultSize + QSize(50, 50));
       
  4306     QVERIFY(!w.testAttribute(Qt::WA_Resized));
       
  4307 
       
  4308     w.setFixedSize(defaultSize + QSize(150, 150));
       
  4309     w.show();
       
  4310     QTest::qWait(50);
       
  4311     QVERIFY(w.size() == defaultSize + QSize(150,150));
       
  4312 }
       
  4313 
       
  4314 void tst_QWidget::ensureCreated()
       
  4315 {
       
  4316     {
       
  4317         QWidget widget;
       
  4318         WId widgetWinId = widget.winId();
       
  4319         Q_UNUSED(widgetWinId);
       
  4320         QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
       
  4321     }
       
  4322 
       
  4323     {
       
  4324         QWidget window;
       
  4325 
       
  4326         QDialog dialog(&window);
       
  4327         dialog.setWindowModality(Qt::NonModal);
       
  4328 
       
  4329         WId dialogWinId = dialog.winId();
       
  4330         Q_UNUSED(dialogWinId);
       
  4331         QVERIFY(dialog.testAttribute(Qt::WA_WState_Created));
       
  4332         QVERIFY(window.testAttribute(Qt::WA_WState_Created));
       
  4333     }
       
  4334 
       
  4335     {
       
  4336         QWidget window;
       
  4337 
       
  4338         QDialog dialog(&window);
       
  4339         dialog.setWindowModality(Qt::WindowModal);
       
  4340 
       
  4341         WId dialogWinId = dialog.winId();
       
  4342         Q_UNUSED(dialogWinId);
       
  4343         QVERIFY(dialog.testAttribute(Qt::WA_WState_Created));
       
  4344         QVERIFY(window.testAttribute(Qt::WA_WState_Created));
       
  4345     }
       
  4346 
       
  4347     {
       
  4348         QWidget window;
       
  4349 
       
  4350         QDialog dialog(&window);
       
  4351         dialog.setWindowModality(Qt::ApplicationModal);
       
  4352 
       
  4353         WId dialogWinId = dialog.winId();
       
  4354         Q_UNUSED(dialogWinId);
       
  4355         QVERIFY(dialog.testAttribute(Qt::WA_WState_Created));
       
  4356         QVERIFY(window.testAttribute(Qt::WA_WState_Created));
       
  4357     }
       
  4358 }
       
  4359 
       
  4360 class WinIdChangeWidget : public QWidget {
       
  4361 public:
       
  4362     WinIdChangeWidget(QWidget *p = 0)
       
  4363         : QWidget(p)
       
  4364         , m_winIdChangeEventCount(0)
       
  4365     {
       
  4366 
       
  4367     }
       
  4368 protected:
       
  4369     bool event(QEvent *e)
       
  4370     {
       
  4371         if (e->type() == QEvent::WinIdChange) {
       
  4372             ++m_winIdChangeEventCount;
       
  4373             return true;
       
  4374         }
       
  4375         return QWidget::event(e);
       
  4376     }
       
  4377 public:
       
  4378     int m_winIdChangeEventCount;
       
  4379 };
       
  4380 
       
  4381 void tst_QWidget::winIdChangeEvent()
       
  4382 {
       
  4383     {
       
  4384         // Transforming an alien widget into a native widget
       
  4385         WinIdChangeWidget widget;
       
  4386         const WId winIdBefore = widget.internalWinId();
       
  4387         const WId winIdAfter = widget.winId();
       
  4388         QVERIFY(winIdBefore != winIdAfter);
       
  4389         QCOMPARE(widget.m_winIdChangeEventCount, 1);
       
  4390     }
       
  4391 
       
  4392     {
       
  4393         // Changing parent of a native widget
       
  4394         // Should cause winId of child to change, on all platforms
       
  4395         QWidget parent1, parent2;
       
  4396         WinIdChangeWidget child(&parent1);
       
  4397         const WId winIdBefore = child.winId();
       
  4398         QCOMPARE(child.m_winIdChangeEventCount, 1);
       
  4399         child.setParent(&parent2);
       
  4400         const WId winIdAfter = child.internalWinId();
       
  4401         QVERIFY(winIdBefore != winIdAfter);
       
  4402         QCOMPARE(child.m_winIdChangeEventCount, 2);
       
  4403     }
       
  4404 
       
  4405     {
       
  4406         // Changing grandparent of a native widget
       
  4407         // Should cause winId of grandchild to change only on Symbian
       
  4408         QWidget grandparent1, grandparent2;
       
  4409         QWidget parent(&grandparent1);
       
  4410         WinIdChangeWidget child(&parent);
       
  4411         const WId winIdBefore = child.winId();
       
  4412         QCOMPARE(child.m_winIdChangeEventCount, 1);
       
  4413         parent.setParent(&grandparent2);
       
  4414         const WId winIdAfter = child.internalWinId();
       
  4415 #ifdef Q_OS_SYMBIAN
       
  4416         QVERIFY(winIdBefore != winIdAfter);
       
  4417         QCOMPARE(child.m_winIdChangeEventCount, 2);
       
  4418 #else
       
  4419         QCOMPARE(winIdBefore, winIdAfter);
       
  4420         QCOMPARE(child.m_winIdChangeEventCount, 1);
       
  4421 #endif
       
  4422     }
       
  4423 
       
  4424     {
       
  4425         // Changing parent of an alien widget
       
  4426         QWidget parent1, parent2;
       
  4427         WinIdChangeWidget child(&parent1);
       
  4428         const WId winIdBefore = child.internalWinId();
       
  4429         child.setParent(&parent2);
       
  4430         const WId winIdAfter = child.internalWinId();
       
  4431         QCOMPARE(winIdBefore, winIdAfter);
       
  4432         QCOMPARE(child.m_winIdChangeEventCount, 0);
       
  4433     }
       
  4434 
       
  4435     {
       
  4436         // Making native child widget into a top-level window
       
  4437         QWidget parent;
       
  4438         WinIdChangeWidget child(&parent);
       
  4439         child.winId();
       
  4440         const WId winIdBefore = child.internalWinId();
       
  4441         QCOMPARE(child.m_winIdChangeEventCount, 1);
       
  4442         const Qt::WindowFlags flags = child.windowFlags();
       
  4443         child.setWindowFlags(flags | Qt::Window);
       
  4444         const WId winIdAfter = child.internalWinId();
       
  4445         QVERIFY(winIdBefore != winIdAfter);
       
  4446         QCOMPARE(child.m_winIdChangeEventCount, 2);
       
  4447     }
       
  4448 }
       
  4449 
       
  4450 #ifdef Q_OS_SYMBIAN
       
  4451 void tst_QWidget::reparentCausesChildWinIdChange()
       
  4452 {
       
  4453     QWidget *parent = new QWidget;
       
  4454     QWidget *w1 = new QWidget;
       
  4455     QWidget *w2 = new QWidget;
       
  4456     QWidget *w3 = new QWidget;
       
  4457     w1->setParent(parent);
       
  4458     w2->setParent(w1);
       
  4459     w3->setParent(w2);
       
  4460 
       
  4461     WId winId1 = w1->winId();
       
  4462     WId winId2 = w2->winId();
       
  4463     WId winId3 = w3->winId();
       
  4464 
       
  4465     // reparenting causes winIds of the widget being reparented, and all of its children, to change
       
  4466     w1->setParent(0);
       
  4467     QVERIFY(w1->winId() != winId1);
       
  4468     winId1 = w1->winId();
       
  4469     QVERIFY(w2->winId() != winId2);
       
  4470     winId2 = w2->winId();
       
  4471     QVERIFY(w3->winId() != winId3);
       
  4472     winId3 = w3->winId();
       
  4473 
       
  4474     w1->setParent(parent);
       
  4475     QVERIFY(w1->winId() != winId1);
       
  4476     winId1 = w1->winId();
       
  4477     QVERIFY(w2->winId() != winId2);
       
  4478     winId2 = w2->winId();
       
  4479     QVERIFY(w3->winId() != winId3);
       
  4480     winId3 = w3->winId();
       
  4481 
       
  4482     w2->setParent(0);
       
  4483     QVERIFY(w2->winId() != winId2);
       
  4484     winId2 = w2->winId();
       
  4485     QVERIFY(w3->winId() != winId3);
       
  4486     winId3 = w3->winId();
       
  4487 
       
  4488     w2->setParent(parent);
       
  4489     QVERIFY(w2->winId() != winId2);
       
  4490     winId2 = w2->winId();
       
  4491     QVERIFY(w3->winId() != winId3);
       
  4492     winId3 = w3->winId();
       
  4493 
       
  4494     w2->setParent(w1);
       
  4495     QVERIFY(w2->winId() != winId2);
       
  4496     winId2 = w2->winId();
       
  4497     QVERIFY(w3->winId() != winId3);
       
  4498     winId3 = w3->winId();
       
  4499 
       
  4500     w3->setParent(0);
       
  4501     QVERIFY(w3->winId() != winId3);
       
  4502     winId3 = w3->winId();
       
  4503 
       
  4504     w3->setParent(w1);
       
  4505     QVERIFY(w3->winId() != winId3);
       
  4506     winId3 = w3->winId();
       
  4507 
       
  4508     w3->setParent(w2);
       
  4509     QVERIFY(w3->winId() != winId3);
       
  4510     winId3 = w3->winId();
       
  4511 
       
  4512     delete parent;
       
  4513 }
       
  4514 #else
       
  4515 void tst_QWidget::persistentWinId()
       
  4516 {
       
  4517     QWidget *parent = new QWidget;
       
  4518     QWidget *w1 = new QWidget;
       
  4519     QWidget *w2 = new QWidget;
       
  4520     QWidget *w3 = new QWidget;
       
  4521     w1->setParent(parent);
       
  4522     w2->setParent(w1);
       
  4523     w3->setParent(w2);
       
  4524 
       
  4525     WId winId1 = w1->winId();
       
  4526     WId winId2 = w2->winId();
       
  4527     WId winId3 = w3->winId();
       
  4528 
       
  4529     // reparenting should change the winId of the widget being reparented, but not of its children
       
  4530     w1->setParent(0);
       
  4531     QVERIFY(w1->winId() != winId1);
       
  4532     winId1 = w1->winId();
       
  4533     QCOMPARE(w2->winId(), winId2);
       
  4534     QCOMPARE(w3->winId(), winId3);
       
  4535 
       
  4536     w1->setParent(parent);
       
  4537     QVERIFY(w1->winId() != winId1);
       
  4538     winId1 = w1->winId();
       
  4539     QCOMPARE(w2->winId(), winId2);
       
  4540     QCOMPARE(w3->winId(), winId3);
       
  4541 
       
  4542     w2->setParent(0);
       
  4543     QVERIFY(w2->winId() != winId2);
       
  4544     winId2 = w2->winId();
       
  4545     QCOMPARE(w3->winId(), winId3);
       
  4546 
       
  4547     w2->setParent(parent);
       
  4548     QVERIFY(w2->winId() != winId2);
       
  4549     winId2 = w2->winId();
       
  4550     QCOMPARE(w3->winId(), winId3);
       
  4551 
       
  4552     w2->setParent(w1);
       
  4553     QVERIFY(w2->winId() != winId2);
       
  4554     winId2 = w2->winId();
       
  4555     QCOMPARE(w3->winId(), winId3);
       
  4556 
       
  4557     w3->setParent(0);
       
  4558     QVERIFY(w3->winId() != winId3);
       
  4559     winId3 = w3->winId();
       
  4560 
       
  4561     w3->setParent(w1);
       
  4562     QVERIFY(w3->winId() != winId3);
       
  4563     winId3 = w3->winId();
       
  4564 
       
  4565     w3->setParent(w2);
       
  4566     QVERIFY(w3->winId() != winId3);
       
  4567     winId3 = w3->winId();
       
  4568 
       
  4569     delete parent;
       
  4570 }
       
  4571 #endif // Q_OS_SYMBIAN
       
  4572 
       
  4573 class ShowHideEventWidget : public QWidget
       
  4574 {
       
  4575 public:
       
  4576     int numberOfShowEvents, numberOfHideEvents;
       
  4577 
       
  4578     ShowHideEventWidget(QWidget *parent = 0)
       
  4579         : QWidget(parent), numberOfShowEvents(0), numberOfHideEvents(0)
       
  4580     { }
       
  4581 
       
  4582     void create()
       
  4583     { QWidget::create(); }
       
  4584 
       
  4585     void showEvent(QShowEvent *)
       
  4586     { ++numberOfShowEvents; }
       
  4587 
       
  4588     void hideEvent(QHideEvent *)
       
  4589     { ++numberOfHideEvents; }
       
  4590 };
       
  4591 
       
  4592 void tst_QWidget::showHideEvent_data()
       
  4593 {
       
  4594     QTest::addColumn<bool>("show");
       
  4595     QTest::addColumn<bool>("hide");
       
  4596     QTest::addColumn<bool>("create");
       
  4597     QTest::addColumn<int>("expectedShowEvents");
       
  4598     QTest::addColumn<int>("expectedHideEvents");
       
  4599 
       
  4600     QTest::newRow("window: only show")
       
  4601             << true
       
  4602             << false
       
  4603             << false
       
  4604             << 1
       
  4605             << 0;
       
  4606     QTest::newRow("window: show/hide")
       
  4607             << true
       
  4608             << true
       
  4609             << false
       
  4610             << 1
       
  4611             << 1;
       
  4612     QTest::newRow("window: show/hide/create")
       
  4613             << true
       
  4614             << true
       
  4615             << true
       
  4616             << 1
       
  4617             << 1;
       
  4618     QTest::newRow("window: hide/create")
       
  4619             << false
       
  4620             << true
       
  4621             << true
       
  4622             << 0
       
  4623             << 0;
       
  4624     QTest::newRow("window: only hide")
       
  4625             << false
       
  4626             << true
       
  4627             << false
       
  4628             << 0
       
  4629             << 0;
       
  4630     QTest::newRow("window: nothing")
       
  4631             << false
       
  4632             << false
       
  4633             << false
       
  4634             << 0
       
  4635             << 0;
       
  4636 }
       
  4637 
       
  4638 void tst_QWidget::showHideEvent()
       
  4639 {
       
  4640     QFETCH(bool, show);
       
  4641     QFETCH(bool, hide);
       
  4642     QFETCH(bool, create);
       
  4643     QFETCH(int, expectedShowEvents);
       
  4644     QFETCH(int, expectedHideEvents);
       
  4645 
       
  4646     ShowHideEventWidget widget;
       
  4647     if (show)
       
  4648         widget.show();
       
  4649     if (hide)
       
  4650         widget.hide();
       
  4651     if (create && !widget.testAttribute(Qt::WA_WState_Created))
       
  4652         widget.create();
       
  4653 
       
  4654     QCOMPARE(widget.numberOfShowEvents, expectedShowEvents);
       
  4655     QCOMPARE(widget.numberOfHideEvents, expectedHideEvents);
       
  4656 }
       
  4657 
       
  4658 void tst_QWidget::update()
       
  4659 {
       
  4660     QTest::qWait(10);  // Wait for the initStuff to do it's stuff.
       
  4661     Q_CHECK_PAINTEVENTS
       
  4662 
       
  4663     UpdateWidget w;
       
  4664     w.setGeometry(50, 50, 100, 100);
       
  4665     w.show();
       
  4666     QTest::qWaitForWindowShown(&w);
       
  4667 
       
  4668     QApplication::processEvents();
       
  4669     QApplication::processEvents();
       
  4670 
       
  4671     QTRY_COMPARE(w.numPaintEvents, 1);
       
  4672 
       
  4673     QCOMPARE(w.visibleRegion(), QRegion(w.rect()));
       
  4674     QCOMPARE(w.paintedRegion, w.visibleRegion());
       
  4675     w.reset();
       
  4676 
       
  4677     UpdateWidget child(&w);
       
  4678     child.setGeometry(10, 10, 80, 80);
       
  4679     child.show();
       
  4680 
       
  4681     QPoint childOffset = child.mapToParent(QPoint());
       
  4682 
       
  4683     // widgets are transparent by default, so both should get repaints
       
  4684     {
       
  4685         QApplication::processEvents();
       
  4686         QApplication::processEvents();
       
  4687         QCOMPARE(child.numPaintEvents, 1);
       
  4688         QCOMPARE(child.visibleRegion(), QRegion(child.rect()));
       
  4689         QCOMPARE(child.paintedRegion, child.visibleRegion());
       
  4690         QCOMPARE(w.numPaintEvents, 1);
       
  4691         QCOMPARE(w.visibleRegion(), QRegion(w.rect()));
       
  4692         QCOMPARE(w.paintedRegion, child.visibleRegion().translated(childOffset));
       
  4693 
       
  4694         w.reset();
       
  4695         child.reset();
       
  4696 
       
  4697         w.update();
       
  4698         QApplication::processEvents();
       
  4699         QApplication::processEvents();
       
  4700         QCOMPARE(child.numPaintEvents, 1);
       
  4701         QCOMPARE(child.visibleRegion(), QRegion(child.rect()));
       
  4702         QCOMPARE(child.paintedRegion, child.visibleRegion());
       
  4703         QCOMPARE(w.numPaintEvents, 1);
       
  4704         QCOMPARE(w.visibleRegion(), QRegion(w.rect()));
       
  4705         QCOMPARE(w.paintedRegion, w.visibleRegion());
       
  4706     }
       
  4707 
       
  4708     QPalette opaquePalette = child.palette();
       
  4709     opaquePalette.setColor(child.backgroundRole(), QColor(Qt::red));
       
  4710 
       
  4711     // setting an opaque background on the child should prevent paint-events
       
  4712     // for the parent in the child area
       
  4713     {
       
  4714         child.setPalette(opaquePalette);
       
  4715         child.setAutoFillBackground(true);
       
  4716         QApplication::processEvents();
       
  4717 
       
  4718         w.reset();
       
  4719         child.reset();
       
  4720 
       
  4721         w.update();
       
  4722         QApplication::processEvents();
       
  4723         QApplication::processEvents();
       
  4724 
       
  4725         QCOMPARE(w.numPaintEvents, 1);
       
  4726         QRegion expectedVisible = QRegion(w.rect())
       
  4727                                   - child.visibleRegion().translated(childOffset);
       
  4728         QCOMPARE(w.visibleRegion(), expectedVisible);
       
  4729 #ifdef QT_MAC_USE_COCOA
       
  4730         QEXPECT_FAIL(0, "Cocoa compositor paints the content view", Continue);
       
  4731 #endif
       
  4732         QCOMPARE(w.paintedRegion, expectedVisible);
       
  4733 #ifdef QT_MAC_USE_COCOA
       
  4734         QEXPECT_FAIL(0, "Cocoa compositor says to paint this.", Continue);
       
  4735 #endif
       
  4736         QCOMPARE(child.numPaintEvents, 0);
       
  4737 
       
  4738         w.reset();
       
  4739         child.reset();
       
  4740 
       
  4741         child.update();
       
  4742         QApplication::processEvents();
       
  4743         QApplication::processEvents();
       
  4744 
       
  4745         QCOMPARE(w.numPaintEvents, 0);
       
  4746         QCOMPARE(child.numPaintEvents, 1);
       
  4747         QCOMPARE(child.paintedRegion, child.visibleRegion());
       
  4748 
       
  4749         w.reset();
       
  4750         child.reset();
       
  4751     }
       
  4752 
       
  4753     // overlapping sibling
       
  4754     UpdateWidget sibling(&w);
       
  4755     child.setGeometry(10, 10, 20, 20);
       
  4756     sibling.setGeometry(15, 15, 20, 20);
       
  4757     sibling.show();
       
  4758 
       
  4759     QApplication::processEvents();
       
  4760     w.reset();
       
  4761     child.reset();
       
  4762     sibling.reset();
       
  4763 
       
  4764     const QPoint siblingOffset = sibling.mapToParent(QPoint());
       
  4765 
       
  4766     sibling.update();
       
  4767     QApplication::processEvents();
       
  4768     QApplication::processEvents();
       
  4769 
       
  4770     // child is opaque, sibling transparent
       
  4771     {
       
  4772         QCOMPARE(sibling.numPaintEvents, 1);
       
  4773         QCOMPARE(sibling.paintedRegion, sibling.visibleRegion());
       
  4774 
       
  4775         QCOMPARE(child.numPaintEvents, 1);
       
  4776         QCOMPARE(child.paintedRegion.translated(childOffset),
       
  4777                  child.visibleRegion().translated(childOffset)
       
  4778                  & sibling.visibleRegion().translated(siblingOffset));
       
  4779 
       
  4780         QCOMPARE(w.numPaintEvents, 1);
       
  4781 #ifdef QT_MAC_USE_COCOA
       
  4782         QEXPECT_FAIL(0, "Cocoa compositor paints the content view", Continue);
       
  4783 #endif
       
  4784         QCOMPARE(w.paintedRegion,
       
  4785                  w.visibleRegion() & sibling.visibleRegion().translated(siblingOffset));
       
  4786 #ifdef QT_MAC_USE_COCOA
       
  4787         QEXPECT_FAIL(0, "Cocoa compositor paints the content view", Continue);
       
  4788 #endif
       
  4789         QCOMPARE(w.paintedRegion,
       
  4790                  (w.visibleRegion() - child.visibleRegion().translated(childOffset))
       
  4791                  & sibling.visibleRegion().translated(siblingOffset));
       
  4792 
       
  4793     }
       
  4794     w.reset();
       
  4795     child.reset();
       
  4796     sibling.reset();
       
  4797 
       
  4798     sibling.setPalette(opaquePalette);
       
  4799     sibling.setAutoFillBackground(true);
       
  4800 
       
  4801     sibling.update();
       
  4802     QApplication::processEvents();
       
  4803     QApplication::processEvents();
       
  4804 
       
  4805     // child opaque, sibling opaque
       
  4806     {
       
  4807         QCOMPARE(sibling.numPaintEvents, 1);
       
  4808         QCOMPARE(sibling.paintedRegion, sibling.visibleRegion());
       
  4809 
       
  4810 #ifdef QT_MAC_USE_COCOA
       
  4811         QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue);
       
  4812 #endif
       
  4813         QCOMPARE(child.numPaintEvents, 0);
       
  4814         QCOMPARE(child.visibleRegion(),
       
  4815                  QRegion(child.rect())
       
  4816                  - sibling.visibleRegion().translated(siblingOffset - childOffset));
       
  4817 
       
  4818         QCOMPARE(w.numPaintEvents, 0);
       
  4819         QCOMPARE(w.visibleRegion(),
       
  4820                  QRegion(w.rect())
       
  4821                  - child.visibleRegion().translated(childOffset)
       
  4822                  - sibling.visibleRegion().translated(siblingOffset));
       
  4823     }
       
  4824 }
       
  4825 
       
  4826 static inline bool isOpaque(QWidget *widget)
       
  4827 {
       
  4828     if (!widget)
       
  4829         return false;
       
  4830     return qt_widget_private(widget)->isOpaque;
       
  4831 }
       
  4832 
       
  4833 void tst_QWidget::isOpaque()
       
  4834 {
       
  4835 #ifndef Q_WS_MAC
       
  4836     QWidget w;
       
  4837     QVERIFY(::isOpaque(&w));
       
  4838 
       
  4839     QWidget child(&w);
       
  4840     QVERIFY(!::isOpaque(&child));
       
  4841 
       
  4842     child.setAutoFillBackground(true);
       
  4843     QVERIFY(::isOpaque(&child));
       
  4844 
       
  4845     QPalette palette;
       
  4846 
       
  4847     // background color
       
  4848 
       
  4849     palette = child.palette();
       
  4850     palette.setColor(child.backgroundRole(), QColor(255, 0, 0, 127));
       
  4851     child.setPalette(palette);
       
  4852     QVERIFY(!::isOpaque(&child));
       
  4853 
       
  4854     palette.setColor(child.backgroundRole(), QColor(255, 0, 0, 255));
       
  4855     child.setPalette(palette);
       
  4856     QVERIFY(::isOpaque(&child));
       
  4857 
       
  4858     palette.setColor(QPalette::Window, QColor(0, 0, 255, 127));
       
  4859     w.setPalette(palette);
       
  4860 
       
  4861     QVERIFY(!::isOpaque(&w));
       
  4862 
       
  4863     child.setAutoFillBackground(false);
       
  4864     QVERIFY(!::isOpaque(&child));
       
  4865 
       
  4866     // Qt::WA_OpaquePaintEvent
       
  4867 
       
  4868     child.setAttribute(Qt::WA_OpaquePaintEvent);
       
  4869     QVERIFY(::isOpaque(&child));
       
  4870 
       
  4871     child.setAttribute(Qt::WA_OpaquePaintEvent, false);
       
  4872     QVERIFY(!::isOpaque(&child));
       
  4873 
       
  4874     // Qt::WA_NoSystemBackground
       
  4875 
       
  4876     child.setAttribute(Qt::WA_NoSystemBackground);
       
  4877     QVERIFY(!::isOpaque(&child));
       
  4878 
       
  4879     child.setAttribute(Qt::WA_NoSystemBackground, false);
       
  4880     QVERIFY(!::isOpaque(&child));
       
  4881 
       
  4882     palette.setColor(QPalette::Window, QColor(0, 0, 255, 255));
       
  4883     w.setPalette(palette);
       
  4884     QVERIFY(::isOpaque(&w));
       
  4885 
       
  4886     w.setAttribute(Qt::WA_NoSystemBackground);
       
  4887     QVERIFY(!::isOpaque(&w));
       
  4888 
       
  4889     w.setAttribute(Qt::WA_NoSystemBackground, false);
       
  4890     QVERIFY(::isOpaque(&w));
       
  4891 
       
  4892     {
       
  4893         QPalette palette = QApplication::palette();
       
  4894         QPalette old = palette;
       
  4895         palette.setColor(QPalette::Window, Qt::transparent);
       
  4896         QApplication::setPalette(palette);
       
  4897 
       
  4898         QWidget widget;
       
  4899         QVERIFY(!::isOpaque(&widget));
       
  4900 
       
  4901         QApplication::setPalette(old);
       
  4902         QCOMPARE(::isOpaque(&widget), old.color(QPalette::Window).alpha() == 255);
       
  4903     }
       
  4904 #endif
       
  4905 }
       
  4906 
       
  4907 #ifndef Q_WS_MAC
       
  4908 /*
       
  4909     Test that scrolling of a widget invalidates the correct regions
       
  4910 */
       
  4911 void tst_QWidget::scroll()
       
  4912 {
       
  4913     UpdateWidget updateWidget;
       
  4914     updateWidget.resize(500, 500);
       
  4915     updateWidget.reset();
       
  4916     updateWidget.show();
       
  4917     QTest::qWaitForWindowShown(&updateWidget);
       
  4918     QTest::qWait(50);
       
  4919     qApp->processEvents();
       
  4920     QTRY_VERIFY(updateWidget.numPaintEvents > 0);
       
  4921 
       
  4922     {
       
  4923         updateWidget.reset();
       
  4924         updateWidget.scroll(10, 10);
       
  4925         qApp->processEvents();
       
  4926         QRegion dirty(QRect(0, 0, 500, 10));
       
  4927         dirty += QRegion(QRect(0, 10, 10, 490));
       
  4928         QCOMPARE(updateWidget.paintedRegion, dirty);
       
  4929     }
       
  4930 
       
  4931     {
       
  4932         updateWidget.reset();
       
  4933         updateWidget.update(0, 0, 10, 10);
       
  4934         updateWidget.scroll(0, 10);
       
  4935         qApp->processEvents();
       
  4936         QRegion dirty(QRect(0, 0, 500, 10));
       
  4937         dirty += QRegion(QRect(0, 10, 10, 10));
       
  4938         QCOMPARE(updateWidget.paintedRegion, dirty);
       
  4939     }
       
  4940 
       
  4941     {
       
  4942         updateWidget.reset();
       
  4943         updateWidget.update(0, 0, 100, 100);
       
  4944         updateWidget.scroll(10, 10, QRect(50, 50, 100, 100));
       
  4945         qApp->processEvents();
       
  4946         QRegion dirty(QRect(0, 0, 100, 50));
       
  4947         dirty += QRegion(QRect(0, 50, 150, 10));
       
  4948         dirty += QRegion(QRect(0, 60, 110, 40));
       
  4949         dirty += QRegion(QRect(50, 100, 60, 10));
       
  4950         dirty += QRegion(QRect(50, 110, 10, 40));
       
  4951         QCOMPARE(updateWidget.paintedRegion, dirty);
       
  4952     }
       
  4953 
       
  4954     {
       
  4955         updateWidget.reset();
       
  4956         updateWidget.update(0, 0, 100, 100);
       
  4957         updateWidget.scroll(10, 10, QRect(100, 100, 100, 100));
       
  4958         qApp->processEvents();
       
  4959         QRegion dirty(QRect(0, 0, 100, 100));
       
  4960         dirty += QRegion(QRect(100, 100, 100, 10));
       
  4961         dirty += QRegion(QRect(100, 110, 10, 90));
       
  4962         QCOMPARE(updateWidget.paintedRegion, dirty);
       
  4963     }
       
  4964 }
       
  4965 #endif
       
  4966 
       
  4967 class DestroyedSlotChecker : public QObject
       
  4968 {
       
  4969     Q_OBJECT
       
  4970 
       
  4971 public:
       
  4972     bool wasQWidget;
       
  4973 
       
  4974     DestroyedSlotChecker()
       
  4975         : wasQWidget(false)
       
  4976     {
       
  4977     }
       
  4978 
       
  4979 public slots:
       
  4980     void destroyedSlot(QObject *object)
       
  4981     {
       
  4982         wasQWidget = (qobject_cast<QWidget *>(object) != 0 || object->isWidgetType());
       
  4983     }
       
  4984 };
       
  4985 
       
  4986 /*
       
  4987     Test that qobject_cast<QWidget*> returns 0 in a slot
       
  4988     connected to QObject::destroyed.
       
  4989 */
       
  4990 void tst_QWidget::qobject_castInDestroyedSlot()
       
  4991 {
       
  4992     DestroyedSlotChecker checker;
       
  4993     QWidget *widget = new QWidget();
       
  4994 
       
  4995     QObject::connect(widget, SIGNAL(destroyed(QObject *)), &checker, SLOT(destroyedSlot(QObject *)));
       
  4996     delete widget;
       
  4997 
       
  4998     QVERIFY(checker.wasQWidget == true);
       
  4999 }
       
  5000 
       
  5001 Q_DECLARE_METATYPE(QList<QRect>)
       
  5002 
       
  5003 void tst_QWidget::setWindowGeometry_data()
       
  5004 {
       
  5005     QTest::addColumn<QList<QRect> >("rects");
       
  5006     QTest::addColumn<int>("windowFlags");
       
  5007 
       
  5008     QList<QList<QRect> > rects;
       
  5009     rects << (QList<QRect>()
       
  5010               << QRect(100, 100, 200, 200)
       
  5011               << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100)
       
  5012               << QRect(130, 100, 0, 200)
       
  5013               << QRect(100, 50, 200, 0)
       
  5014               << QRect(130, 50, 0, 0))
       
  5015           << (QList<QRect>()
       
  5016               << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100)
       
  5017               << QRect(130, 100, 0, 200)
       
  5018               << QRect(100, 50, 200, 0)
       
  5019               << QRect(130, 50, 0, 0)
       
  5020               << QRect(100, 100, 200, 200))
       
  5021           << (QList<QRect>()
       
  5022               << QRect(130, 100, 0, 200)
       
  5023               << QRect(100, 50, 200, 0)
       
  5024               << QRect(130, 50, 0, 0)
       
  5025               << QRect(100, 100, 200, 200)
       
  5026               << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100))
       
  5027           << (QList<QRect>()
       
  5028               << QRect(100, 50, 200, 0)
       
  5029               << QRect(130, 50, 0, 0)
       
  5030               << QRect(100, 100, 200, 200)
       
  5031               << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100)
       
  5032               << QRect(130, 100, 0, 200))
       
  5033           << (QList<QRect>()
       
  5034               << QRect(130, 50, 0, 0)
       
  5035               << QRect(100, 100, 200, 200)
       
  5036               << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100)
       
  5037               << QRect(130, 100, 0, 200)
       
  5038               << QRect(100, 50, 200, 0));
       
  5039 
       
  5040     QList<int> windowFlags;
       
  5041     windowFlags << 0
       
  5042                 << Qt::FramelessWindowHint
       
  5043 #ifdef Q_WS_X11
       
  5044                 << Qt::X11BypassWindowManagerHint
       
  5045 #endif
       
  5046                 ;
       
  5047 
       
  5048     foreach (QList<QRect> l, rects) {
       
  5049         QRect rect = l.first();
       
  5050         foreach (int windowFlag, windowFlags) {
       
  5051             QTest::newRow(QString("%1,%2 %3x%4, flags %5")
       
  5052                           .arg(rect.x())
       
  5053                           .arg(rect.y())
       
  5054                           .arg(rect.width())
       
  5055                           .arg(rect.height())
       
  5056                           .arg(windowFlag, 0, 16).toAscii())
       
  5057                 << l
       
  5058                 << windowFlag;
       
  5059         }
       
  5060     }
       
  5061 }
       
  5062 
       
  5063 void tst_QWidget::setWindowGeometry()
       
  5064 {
       
  5065 #ifdef Q_WS_X11
       
  5066     //Since WindowManager operation are all assync, and we have no way to know if the window
       
  5067     // manager has finished playing with the window geometry, this test can't be reliable.
       
  5068     QSKIP("Window Manager behaviour are too random for this test", SkipAll);
       
  5069 #endif
       
  5070     QFETCH(QList<QRect>, rects);
       
  5071     QFETCH(int, windowFlags);
       
  5072     QRect rect = rects.takeFirst();
       
  5073 
       
  5074     {
       
  5075         // test setGeometry() without actually showing the window
       
  5076         QWidget widget;
       
  5077         if (windowFlags != 0)
       
  5078             widget.setWindowFlags(Qt::WindowFlags(windowFlags));
       
  5079 
       
  5080         widget.setGeometry(rect);
       
  5081         QTest::qWait(100);
       
  5082         QCOMPARE(widget.geometry(), rect);
       
  5083 
       
  5084         // setGeometry() without showing
       
  5085         foreach (QRect r, rects) {
       
  5086             widget.setGeometry(r);
       
  5087             QTest::qWait(100);
       
  5088             QCOMPARE(widget.geometry(), r);
       
  5089         }
       
  5090     }
       
  5091 
       
  5092     {
       
  5093         // setGeometry() first, then show()
       
  5094         QWidget widget;
       
  5095         if (windowFlags != 0)
       
  5096             widget.setWindowFlags(Qt::WindowFlags(windowFlags));
       
  5097 
       
  5098         widget.setGeometry(rect);
       
  5099         widget.show();
       
  5100         QTest::qWaitForWindowShown(&widget);
       
  5101         QTest::qWait(20);
       
  5102         QTRY_COMPARE(widget.geometry(), rect);
       
  5103 
       
  5104         // setGeometry() while shown
       
  5105         foreach (QRect r, rects) {
       
  5106             widget.setGeometry(r);
       
  5107             QTest::qWait(10);
       
  5108             QTRY_COMPARE(widget.geometry(), r);
       
  5109         }
       
  5110         widget.setGeometry(rect);
       
  5111         QTest::qWait(20);
       
  5112         QTRY_COMPARE(widget.geometry(), rect);
       
  5113 
       
  5114         // now hide
       
  5115         widget.hide();
       
  5116         QTest::qWait(20);
       
  5117         QTRY_COMPARE(widget.geometry(), rect);
       
  5118 
       
  5119         // setGeometry() after hide()
       
  5120         foreach (QRect r, rects) {
       
  5121             widget.setGeometry(r);
       
  5122             QTest::qWait(10);
       
  5123             QTRY_COMPARE(widget.geometry(), r);
       
  5124         }
       
  5125         widget.setGeometry(rect);
       
  5126         QTest::qWait(10);
       
  5127         QTRY_COMPARE(widget.geometry(), rect);
       
  5128 
       
  5129         // show() again, geometry() should still be the same
       
  5130         widget.show();
       
  5131         QTest::qWaitForWindowShown(&widget);
       
  5132         QTest::qWait(10);
       
  5133         QTRY_COMPARE(widget.geometry(), rect);
       
  5134 
       
  5135         // final hide(), again geometry() should be unchanged
       
  5136         widget.hide();
       
  5137         QTest::qWait(10);
       
  5138         QTRY_COMPARE(widget.geometry(), rect);
       
  5139     }
       
  5140 
       
  5141     {
       
  5142         // show() first, then setGeometry()
       
  5143         QWidget widget;
       
  5144         if (windowFlags != 0)
       
  5145             widget.setWindowFlags(Qt::WindowFlags(windowFlags));
       
  5146 
       
  5147         widget.show();
       
  5148         QTest::qWaitForWindowShown(&widget);
       
  5149         widget.setGeometry(rect);
       
  5150         QTest::qWait(10);
       
  5151         QTRY_COMPARE(widget.geometry(), rect);
       
  5152 
       
  5153         // setGeometry() while shown
       
  5154         foreach (QRect r, rects) {
       
  5155             widget.setGeometry(r);
       
  5156             QTest::qWait(10);
       
  5157             QTRY_COMPARE(widget.geometry(), r);
       
  5158         }
       
  5159         widget.setGeometry(rect);
       
  5160         QTest::qWait(10);
       
  5161         QTRY_COMPARE(widget.geometry(), rect);
       
  5162 
       
  5163         // now hide
       
  5164         widget.hide();
       
  5165         QTest::qWait(10);
       
  5166         QTRY_COMPARE(widget.geometry(), rect);
       
  5167 
       
  5168         // setGeometry() after hide()
       
  5169         foreach (QRect r, rects) {
       
  5170             widget.setGeometry(r);
       
  5171             QTest::qWait(10);
       
  5172             QTRY_COMPARE(widget.geometry(), r);
       
  5173         }
       
  5174         widget.setGeometry(rect);
       
  5175         QTest::qWait(10);
       
  5176         QTRY_COMPARE(widget.geometry(), rect);
       
  5177 
       
  5178         // show() again, geometry() should still be the same
       
  5179         widget.show();
       
  5180         QTest::qWaitForWindowShown(&widget);
       
  5181         QTest::qWait(10);
       
  5182         QTRY_COMPARE(widget.geometry(), rect);
       
  5183 
       
  5184         // final hide(), again geometry() should be unchanged
       
  5185         widget.hide();
       
  5186         QTest::qWait(10);
       
  5187         QTRY_COMPARE(widget.geometry(), rect);
       
  5188     }
       
  5189 }
       
  5190 
       
  5191 #if defined (Q_WS_WIN) && !defined(Q_OS_WINCE)
       
  5192 void tst_QWidget::setGeometry_win()
       
  5193 {
       
  5194     QWidget widget;
       
  5195     widget.setGeometry(0, 600, 100,100);
       
  5196     widget.show();
       
  5197     widget.setWindowState(widget.windowState() | Qt::WindowMaximized);
       
  5198     QRect geom = widget.normalGeometry();
       
  5199     widget.close();
       
  5200     widget.setGeometry(geom);
       
  5201     widget.setWindowState(widget.windowState() | Qt::WindowMaximized);
       
  5202     widget.show();
       
  5203     RECT rt;
       
  5204     ::GetWindowRect(widget.internalWinId(), &rt);
       
  5205     QVERIFY(rt.left <= 0);
       
  5206     QVERIFY(rt.top <= 0);
       
  5207 }
       
  5208 #endif
       
  5209 
       
  5210 void tst_QWidget::windowMoveResize_data()
       
  5211 {
       
  5212     setWindowGeometry_data();
       
  5213 }
       
  5214 
       
  5215 void tst_QWidget::windowMoveResize()
       
  5216 {
       
  5217 #ifdef Q_WS_X11
       
  5218     //Since WindowManager operation are all assync, and we have no way to know if the window
       
  5219     // manager has finished playing with the window geometry, this test can't be reliable.
       
  5220     QSKIP("Window Manager behaviour are too random for this test", SkipAll);
       
  5221 #endif
       
  5222 #ifdef Q_OS_IRIX
       
  5223     QSKIP("4DWM issues on IRIX makes this test fail", SkipAll);
       
  5224 #endif
       
  5225     QFETCH(QList<QRect>, rects);
       
  5226     QFETCH(int, windowFlags);
       
  5227 
       
  5228     QRect rect = rects.takeFirst();
       
  5229 
       
  5230     {
       
  5231         // test setGeometry() without actually showing the window
       
  5232         QWidget widget;
       
  5233         if (windowFlags != 0)
       
  5234             widget.setWindowFlags(Qt::WindowFlags(windowFlags));
       
  5235 
       
  5236         widget.move(rect.topLeft());
       
  5237         widget.resize(rect.size());
       
  5238         QTest::qWait(10);
       
  5239         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5240         QTRY_COMPARE(widget.size(), rect.size());
       
  5241 
       
  5242         // move() without showing
       
  5243         foreach (QRect r, rects) {
       
  5244             widget.move(r.topLeft());
       
  5245             widget.resize(r.size());
       
  5246             QApplication::processEvents();
       
  5247             QTRY_COMPARE(widget.pos(), r.topLeft());
       
  5248             QTRY_COMPARE(widget.size(), r.size());
       
  5249         }
       
  5250     }
       
  5251 
       
  5252     {
       
  5253         // move() first, then show()
       
  5254         QWidget widget;
       
  5255         if (windowFlags != 0)
       
  5256             widget.setWindowFlags(Qt::WindowFlags(windowFlags));
       
  5257 
       
  5258         widget.move(rect.topLeft());
       
  5259         widget.resize(rect.size());
       
  5260         widget.show();
       
  5261 
       
  5262         QTest::qWait(10);
       
  5263 #if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
       
  5264         QEXPECT_FAIL("130,50 0x0, flags 0",
       
  5265                      "Showing a window with 0x0 size shifts it up.",
       
  5266                      Continue);
       
  5267 #endif
       
  5268         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5269         QTRY_COMPARE(widget.size(), rect.size());
       
  5270 
       
  5271         // move() while shown
       
  5272         foreach (QRect r, rects) {
       
  5273 #ifdef Q_WS_X11
       
  5274             if ((widget.width() == 0 || widget.height() == 0) && r.width() != 0 && r.height() != 0) {
       
  5275                 QEXPECT_FAIL("130,100 0x200, flags 0",
       
  5276                              "First resize after show of zero-sized gets wrong win_gravity.",
       
  5277                              Continue);
       
  5278                 QEXPECT_FAIL("100,50 200x0, flags 0",
       
  5279                              "First resize after show of zero-sized gets wrong win_gravity.",
       
  5280                              Continue);
       
  5281                 QEXPECT_FAIL("130,50 0x0, flags 0",
       
  5282                              "First resize after show of zero-sized gets wrong win_gravity.",
       
  5283                              Continue);
       
  5284             }
       
  5285 #endif
       
  5286             widget.move(r.topLeft());
       
  5287             widget.resize(r.size());
       
  5288             QApplication::processEvents();
       
  5289             QTRY_COMPARE(widget.pos(), r.topLeft());
       
  5290             QTRY_COMPARE(widget.size(), r.size());
       
  5291         }
       
  5292         widget.move(rect.topLeft());
       
  5293         widget.resize(rect.size());
       
  5294         QApplication::processEvents();
       
  5295         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5296         QTRY_COMPARE(widget.size(), rect.size());
       
  5297 
       
  5298         // now hide
       
  5299         widget.hide();
       
  5300         QTest::qWait(10);
       
  5301         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5302         QTRY_COMPARE(widget.size(), rect.size());
       
  5303 
       
  5304         // move() after hide()
       
  5305         foreach (QRect r, rects) {
       
  5306             widget.move(r.topLeft());
       
  5307             widget.resize(r.size());
       
  5308             QApplication::processEvents();
       
  5309 #if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
       
  5310             if (r.width() == 0 && r.height() > 0) {
       
  5311                 widget.move(r.topLeft());
       
  5312                 widget.resize(r.size());
       
  5313              }
       
  5314 #endif
       
  5315             QTRY_COMPARE(widget.pos(), r.topLeft());
       
  5316             QTRY_COMPARE(widget.size(), r.size());
       
  5317         }
       
  5318         widget.move(rect.topLeft());
       
  5319         widget.resize(rect.size());
       
  5320         QTest::qWait(10);
       
  5321         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5322         QTRY_COMPARE(widget.size(), rect.size());
       
  5323 
       
  5324         // show() again, pos() should be the same
       
  5325         widget.show();
       
  5326         QTest::qWaitForWindowShown(&widget);
       
  5327         QApplication::processEvents();
       
  5328         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5329         QTRY_COMPARE(widget.size(), rect.size());
       
  5330 
       
  5331         // final hide(), again pos() should be unchanged
       
  5332         widget.hide();
       
  5333         QApplication::processEvents();
       
  5334         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5335         QTRY_COMPARE(widget.size(), rect.size());
       
  5336     }
       
  5337 
       
  5338     {
       
  5339         // show() first, then move()
       
  5340         QWidget widget;
       
  5341         if (windowFlags != 0)
       
  5342             widget.setWindowFlags(Qt::WindowFlags(windowFlags));
       
  5343 
       
  5344         widget.show();
       
  5345         QTest::qWaitForWindowShown(&widget);
       
  5346         QApplication::processEvents();
       
  5347         widget.move(rect.topLeft());
       
  5348         widget.resize(rect.size());
       
  5349         QApplication::processEvents();
       
  5350         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5351         QTRY_COMPARE(widget.size(), rect.size());
       
  5352 
       
  5353         // move() while shown
       
  5354         foreach (QRect r, rects) {
       
  5355             widget.move(r.topLeft());
       
  5356             widget.resize(r.size());
       
  5357             QApplication::processEvents();
       
  5358             QTRY_COMPARE(widget.pos(), r.topLeft());
       
  5359             QTRY_COMPARE(widget.size(), r.size());
       
  5360         }
       
  5361         widget.move(rect.topLeft());
       
  5362         widget.resize(rect.size());
       
  5363         QApplication::processEvents();
       
  5364         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5365         QTRY_COMPARE(widget.size(), rect.size());
       
  5366 
       
  5367         // now hide
       
  5368         widget.hide();
       
  5369         QApplication::processEvents();
       
  5370         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5371         QTRY_COMPARE(widget.size(), rect.size());
       
  5372 
       
  5373         // move() after hide()
       
  5374         foreach (QRect r, rects) {
       
  5375             widget.move(r.topLeft());
       
  5376             widget.resize(r.size());
       
  5377             QApplication::processEvents();
       
  5378 #if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
       
  5379             if (r.width() == 0 && r.height() > 0) {
       
  5380                 widget.move(r.topLeft());
       
  5381                 widget.resize(r.size());
       
  5382              }
       
  5383 #endif
       
  5384             QTRY_COMPARE(widget.pos(), r.topLeft());
       
  5385             QTRY_COMPARE(widget.size(), r.size());
       
  5386         }
       
  5387         widget.move(rect.topLeft());
       
  5388         widget.resize(rect.size());
       
  5389         QApplication::processEvents();
       
  5390         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5391         QTRY_COMPARE(widget.size(), rect.size());
       
  5392 
       
  5393         // show() again, pos() should be the same
       
  5394         widget.show();
       
  5395         QTest::qWaitForWindowShown(&widget);
       
  5396         QTest::qWait(10);
       
  5397         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5398         QTRY_COMPARE(widget.size(), rect.size());
       
  5399 
       
  5400         // final hide(), again pos() should be unchanged
       
  5401         widget.hide();
       
  5402         QTest::qWait(10);
       
  5403         QTRY_COMPARE(widget.pos(), rect.topLeft());
       
  5404         QTRY_COMPARE(widget.size(), rect.size());
       
  5405     }
       
  5406 }
       
  5407 
       
  5408 class ColorWidget : public QWidget
       
  5409 {
       
  5410 public:
       
  5411     ColorWidget(QWidget *parent = 0, const QColor &c = QColor(Qt::red))
       
  5412         : QWidget(parent, Qt::FramelessWindowHint), color(c)
       
  5413     {
       
  5414         QPalette opaquePalette = palette();
       
  5415         opaquePalette.setColor(backgroundRole(), color);
       
  5416         setPalette(opaquePalette);
       
  5417         setAutoFillBackground(true);
       
  5418     }
       
  5419 
       
  5420     void paintEvent(QPaintEvent *e) {
       
  5421         r += e->region();
       
  5422     }
       
  5423 
       
  5424     void reset() {
       
  5425         r = QRegion();
       
  5426     }
       
  5427 
       
  5428     QColor color;
       
  5429     QRegion r;
       
  5430 };
       
  5431 
       
  5432 template<typename R, typename C>
       
  5433 void verifyColor(R const& region, C const& color)
       
  5434 {
       
  5435     const QRegion r = QRegion(region);
       
  5436     for (int i = 0; i < r.rects().size(); ++i) {
       
  5437         const QRect rect = r.rects().at(i);
       
  5438         for (int t = 0; t < 5; t++) {
       
  5439             const QPixmap pixmap = QPixmap::grabWindow(QDesktopWidget().winId(),
       
  5440                                                    rect.left(), rect.top(),
       
  5441                                                    rect.width(), rect.height());
       
  5442             QCOMPARE(pixmap.size(), rect.size());
       
  5443             QPixmap expectedPixmap(pixmap); /* ensure equal formats */
       
  5444             expectedPixmap.fill(color);
       
  5445             if (pixmap.toImage().pixel(0,0) != QColor(color).rgb() && t < 4 )
       
  5446             { QTest::qWait(200); continue; }
       
  5447             QCOMPARE(pixmap.toImage().pixel(0,0), QColor(color).rgb());
       
  5448             QCOMPARE(pixmap, expectedPixmap);
       
  5449             break;
       
  5450         }
       
  5451     }
       
  5452 }
       
  5453 
       
  5454 void tst_QWidget::moveChild_data()
       
  5455 {
       
  5456     QTest::addColumn<QPoint>("offset");
       
  5457 
       
  5458     QTest::newRow("right") << QPoint(20, 0);
       
  5459     QTest::newRow("down") << QPoint(0, 20);
       
  5460     QTest::newRow("left") << QPoint(-20, 0);
       
  5461     QTest::newRow("up") << QPoint(0, -20);
       
  5462 }
       
  5463 
       
  5464 void tst_QWidget::moveChild()
       
  5465 {
       
  5466     QFETCH(QPoint, offset);
       
  5467 
       
  5468     ColorWidget parent;
       
  5469     // prevent custom styles
       
  5470     parent.setStyle(new QWindowsStyle);
       
  5471     ColorWidget child(&parent, Qt::blue);
       
  5472 
       
  5473 #ifndef Q_OS_WINCE
       
  5474     parent.setGeometry(QRect(QPoint(QApplication::desktop()->availableGeometry(&parent).topLeft()),
       
  5475                              QSize(100, 100)));
       
  5476 #else
       
  5477     parent.setGeometry(60, 60, 150, 150);
       
  5478 #endif
       
  5479     child.setGeometry(25, 25, 50, 50);
       
  5480     QPoint childOffset = child.mapToGlobal(QPoint());
       
  5481 
       
  5482     parent.show();
       
  5483     QTest::qWaitForWindowShown(&parent);
       
  5484     QTest::qWait(30);
       
  5485     const QPoint tlwOffset = parent.geometry().topLeft();
       
  5486 
       
  5487 #ifdef QT_MAC_USE_COCOA
       
  5488     QEXPECT_FAIL(0, "Cocoa compositor paints the entire content view, even when opaque", Continue);
       
  5489 #endif
       
  5490     QTRY_COMPARE(parent.r, QRegion(parent.rect()) - child.geometry());
       
  5491     QTRY_COMPARE(child.r, QRegion(child.rect()));
       
  5492     verifyColor(child.geometry().translated(tlwOffset),
       
  5493                  child.color);
       
  5494     verifyColor(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset),
       
  5495                  parent.color);
       
  5496     parent.reset();
       
  5497     child.reset();
       
  5498 
       
  5499     // move
       
  5500 
       
  5501     const QRect oldGeometry = child.geometry();
       
  5502 
       
  5503     QPoint pos = child.pos() + offset;
       
  5504     child.move(pos);
       
  5505     QTest::qWait(100);
       
  5506     QTRY_COMPARE(pos, child.pos());
       
  5507 
       
  5508     QCOMPARE(parent.r, QRegion(oldGeometry) - child.geometry());
       
  5509 #if !defined(Q_WS_MAC)
       
  5510     // should be scrolled in backingstore
       
  5511     QCOMPARE(child.r, QRegion());
       
  5512 #endif
       
  5513     verifyColor(child.geometry().translated(tlwOffset),
       
  5514                 child.color);
       
  5515     verifyColor(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset),
       
  5516                 parent.color);
       
  5517 }
       
  5518 
       
  5519 void tst_QWidget::showAndMoveChild()
       
  5520 {
       
  5521     QWidget parent(0, Qt::FramelessWindowHint);
       
  5522     // prevent custom styles
       
  5523     parent.setStyle(new QWindowsStyle);
       
  5524 
       
  5525     QDesktopWidget desktop;
       
  5526     QRect desktopDimensions = desktop.availableGeometry(&parent);
       
  5527 
       
  5528     parent.setGeometry(desktopDimensions);
       
  5529     parent.setPalette(Qt::red);
       
  5530     parent.show();
       
  5531     QTest::qWaitForWindowShown(&parent);
       
  5532     QTest::qWait(10);
       
  5533 
       
  5534     const QPoint tlwOffset = parent.geometry().topLeft();
       
  5535     QWidget child(&parent);
       
  5536     child.resize(desktopDimensions.width()/2, desktopDimensions.height()/2);
       
  5537     child.setPalette(Qt::blue);
       
  5538     child.setAutoFillBackground(true);
       
  5539 
       
  5540     // Ensure that the child is repainted correctly when moved right after show.
       
  5541     // NB! Do NOT processEvents() (or qWait()) in between show() and move().
       
  5542     child.show();
       
  5543     child.move(desktopDimensions.width()/2, desktopDimensions.height()/2);
       
  5544     qApp->processEvents();
       
  5545 
       
  5546     verifyColor(child.geometry().translated(tlwOffset), Qt::blue);
       
  5547     verifyColor(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), Qt::red);
       
  5548 }
       
  5549 
       
  5550 void tst_QWidget::subtractOpaqueSiblings()
       
  5551 {
       
  5552 #ifdef QT_MAC_USE_COCOA
       
  5553     QSKIP("Cocoa only has rect granularity.", SkipAll);
       
  5554 #else
       
  5555     QWidget w;
       
  5556     w.setGeometry(50, 50, 300, 300);
       
  5557 
       
  5558     ColorWidget *large = new ColorWidget(&w, Qt::red);
       
  5559     large->setGeometry(50, 50, 200, 200);
       
  5560 
       
  5561     ColorWidget *medium = new ColorWidget(large, Qt::gray);
       
  5562     medium->setGeometry(50, 50, 100, 100);
       
  5563 
       
  5564     ColorWidget *tall = new ColorWidget(&w, Qt::blue);
       
  5565     tall->setGeometry(100, 30, 50, 100);
       
  5566 
       
  5567     w.show();
       
  5568     QTest::qWaitForWindowShown(&w);
       
  5569     QTest::qWait(10);
       
  5570 
       
  5571     large->reset();
       
  5572     medium->reset();
       
  5573     tall->reset();
       
  5574 
       
  5575     medium->update();
       
  5576     QTest::qWait(10);
       
  5577 
       
  5578     // QWidgetPrivate::subtractOpaqueSiblings() should prevent parts of medium
       
  5579     // to be repainted and tall from be repainted at all.
       
  5580 
       
  5581     QTRY_COMPARE(large->r, QRegion());
       
  5582     QTRY_COMPARE(tall->r, QRegion());
       
  5583     QTRY_COMPARE(medium->r.translated(medium->mapTo(&w, QPoint())),
       
  5584              QRegion(medium->geometry().translated(large->pos()))
       
  5585              - tall->geometry());
       
  5586 #endif
       
  5587 }
       
  5588 
       
  5589 void tst_QWidget::deleteStyle()
       
  5590 {
       
  5591     QWidget widget;
       
  5592     widget.setStyle(new QWindowsStyle);
       
  5593     widget.show();
       
  5594     delete widget.style();
       
  5595     qApp->processEvents();
       
  5596 }
       
  5597 
       
  5598 #ifdef Q_WS_WIN
       
  5599 void tst_QWidget::getDC()
       
  5600 {
       
  5601     QWidget widget;
       
  5602     widget.setGeometry(0, 0, 2, 4);
       
  5603 
       
  5604     HDC dc = widget.getDC();
       
  5605     QVERIFY(dc != 0);
       
  5606 
       
  5607     widget.releaseDC(dc);
       
  5608 }
       
  5609 #endif
       
  5610 
       
  5611 class TopLevelFocusCheck: public QWidget
       
  5612 {
       
  5613     Q_OBJECT
       
  5614 public:
       
  5615     QLineEdit* edit;
       
  5616     TopLevelFocusCheck(QWidget* parent = 0) : QWidget(parent)
       
  5617     {
       
  5618         edit = new QLineEdit(this);
       
  5619         edit->hide();
       
  5620         edit->installEventFilter(this);
       
  5621     }
       
  5622 
       
  5623 public slots:
       
  5624     void mouseDoubleClickEvent ( QMouseEvent * /*event*/ )
       
  5625     {
       
  5626         edit->show();
       
  5627         edit->setFocus(Qt::OtherFocusReason);
       
  5628         qApp->processEvents();
       
  5629     }
       
  5630     bool eventFilter(QObject *obj, QEvent *event)
       
  5631     {
       
  5632         if (obj == edit && event->type()== QEvent::FocusOut) {
       
  5633             edit->hide();
       
  5634             return true;
       
  5635         }
       
  5636         return false;
       
  5637     }
       
  5638 };
       
  5639 
       
  5640 void tst_QWidget::multipleToplevelFocusCheck()
       
  5641 {
       
  5642     TopLevelFocusCheck w1;
       
  5643     TopLevelFocusCheck w2;
       
  5644 
       
  5645     w1.resize(200, 200);
       
  5646     w1.show();
       
  5647     QTest::qWaitForWindowShown(&w1);
       
  5648     w2.resize(200,200);
       
  5649     w2.show();
       
  5650     QTest::qWaitForWindowShown(&w2);
       
  5651 
       
  5652     QTest::qWait(100);
       
  5653 
       
  5654     QApplication::setActiveWindow(&w1);
       
  5655     w1.activateWindow();
       
  5656     QApplication::processEvents();
       
  5657     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1));
       
  5658     QTest::qWait(50);
       
  5659     QTest::mouseDClick(&w1, Qt::LeftButton);
       
  5660     QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit));
       
  5661 
       
  5662     w2.activateWindow();
       
  5663     QApplication::setActiveWindow(&w2);
       
  5664     QApplication::processEvents();
       
  5665     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2));
       
  5666     QTest::mouseClick(&w2, Qt::LeftButton);
       
  5667 #ifdef Q_WS_QWS
       
  5668     QEXPECT_FAIL("", "embedded toplevels take focus anyway", Continue);
       
  5669 #endif
       
  5670     QTRY_COMPARE(QApplication::focusWidget(), (QWidget *)0);
       
  5671 
       
  5672     QTest::mouseDClick(&w2, Qt::LeftButton);
       
  5673     QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w2.edit));
       
  5674 
       
  5675     w1.activateWindow();
       
  5676     QApplication::setActiveWindow(&w1);
       
  5677     QApplication::processEvents();
       
  5678     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1));
       
  5679     QTest::mouseDClick(&w1, Qt::LeftButton);
       
  5680     QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit));
       
  5681 
       
  5682     w2.activateWindow();
       
  5683     QApplication::setActiveWindow(&w2);
       
  5684     QApplication::processEvents();
       
  5685     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2));
       
  5686     QTest::mouseClick(&w2, Qt::LeftButton);
       
  5687     QTRY_COMPARE(QApplication::focusWidget(), (QWidget *)0);
       
  5688 }
       
  5689 
       
  5690 void tst_QWidget::setFocus()
       
  5691 {
       
  5692     {
       
  5693         // move focus to another window
       
  5694         testWidget->activateWindow();
       
  5695         QApplication::setActiveWindow(testWidget);
       
  5696         if (testWidget->focusWidget())
       
  5697             testWidget->focusWidget()->clearFocus();
       
  5698         else
       
  5699             testWidget->clearFocus();
       
  5700 
       
  5701         // window and children never shown, nobody gets focus
       
  5702         QWidget window;
       
  5703 
       
  5704         QWidget child1(&window);
       
  5705         child1.setFocusPolicy(Qt::StrongFocus);
       
  5706 
       
  5707         QWidget child2(&window);
       
  5708         child2.setFocusPolicy(Qt::StrongFocus);
       
  5709 
       
  5710         child1.setFocus();
       
  5711         QVERIFY(!child1.hasFocus());
       
  5712         QCOMPARE(window.focusWidget(), &child1);
       
  5713         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5714 
       
  5715         child2.setFocus();
       
  5716         QVERIFY(!child2.hasFocus());
       
  5717         QCOMPARE(window.focusWidget(), &child2);
       
  5718         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5719     }
       
  5720 
       
  5721     {
       
  5722         // window and children show, but window not active, nobody gets focus
       
  5723         QWidget window;
       
  5724 
       
  5725         QWidget child1(&window);
       
  5726         child1.setFocusPolicy(Qt::StrongFocus);
       
  5727 
       
  5728         QWidget child2(&window);
       
  5729         child2.setFocusPolicy(Qt::StrongFocus);
       
  5730 
       
  5731         window.show();
       
  5732 
       
  5733         // note: window may be active, but we don't want it to be
       
  5734         testWidget->activateWindow();
       
  5735         QApplication::setActiveWindow(testWidget);
       
  5736         if (testWidget->focusWidget())
       
  5737             testWidget->focusWidget()->clearFocus();
       
  5738         else
       
  5739             testWidget->clearFocus();
       
  5740 
       
  5741         child1.setFocus();
       
  5742         QVERIFY(!child1.hasFocus());
       
  5743         QCOMPARE(window.focusWidget(), &child1);
       
  5744         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5745 
       
  5746         child2.setFocus();
       
  5747         QVERIFY(!child2.hasFocus());
       
  5748         QCOMPARE(window.focusWidget(), &child2);
       
  5749         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5750     }
       
  5751 
       
  5752     {
       
  5753         // window and children show, but window *is* active, children get focus
       
  5754         QWidget window;
       
  5755 
       
  5756         QWidget child1(&window);
       
  5757         child1.setFocusPolicy(Qt::StrongFocus);
       
  5758 
       
  5759         QWidget child2(&window);
       
  5760         child2.setFocusPolicy(Qt::StrongFocus);
       
  5761 
       
  5762         window.show();
       
  5763 #ifdef Q_WS_X11
       
  5764         QApplication::setActiveWindow(&window);
       
  5765         QTest::qWaitForWindowShown(&window);
       
  5766 #else
       
  5767         window.activateWindow();
       
  5768         QApplication::processEvents();
       
  5769 #endif
       
  5770 
       
  5771         child1.setFocus();
       
  5772         QTRY_VERIFY(child1.hasFocus());
       
  5773         QCOMPARE(window.focusWidget(), &child1);
       
  5774         QCOMPARE(QApplication::focusWidget(), &child1);
       
  5775 
       
  5776         child2.setFocus();
       
  5777         QVERIFY(child2.hasFocus());
       
  5778         QCOMPARE(window.focusWidget(), &child2);
       
  5779         QCOMPARE(QApplication::focusWidget(), &child2);
       
  5780     }
       
  5781 
       
  5782     {
       
  5783         // window shown and active, children created, don't get focus, but get focus when shown
       
  5784         QWidget window;
       
  5785 
       
  5786         window.show();
       
  5787 #ifdef Q_WS_X11
       
  5788         QApplication::setActiveWindow(&window);
       
  5789         QTest::qWaitForWindowShown(&window);
       
  5790 #else
       
  5791         window.activateWindow();
       
  5792 #endif
       
  5793 
       
  5794         QWidget child1(&window);
       
  5795         child1.setFocusPolicy(Qt::StrongFocus);
       
  5796 
       
  5797         QWidget child2(&window);
       
  5798         child2.setFocusPolicy(Qt::StrongFocus);
       
  5799 
       
  5800         child1.setFocus();
       
  5801         QVERIFY(!child1.hasFocus());
       
  5802         QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
       
  5803         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5804 
       
  5805         child1.show();
       
  5806 #ifdef Q_WS_X11
       
  5807         QApplication::setActiveWindow(&child1);
       
  5808         child1.activateWindow();
       
  5809 #endif
       
  5810         QApplication::processEvents();
       
  5811         QTRY_VERIFY(child1.hasFocus());
       
  5812         QCOMPARE(window.focusWidget(), &child1);
       
  5813         QCOMPARE(QApplication::focusWidget(), &child1);
       
  5814 
       
  5815         child2.setFocus();
       
  5816         QVERIFY(!child2.hasFocus());
       
  5817         QCOMPARE(window.focusWidget(), &child1);
       
  5818         QCOMPARE(QApplication::focusWidget(), &child1);
       
  5819 
       
  5820         child2.show();
       
  5821         QVERIFY(child2.hasFocus());
       
  5822         QCOMPARE(window.focusWidget(), &child2);
       
  5823         QCOMPARE(QApplication::focusWidget(), &child2);
       
  5824     }
       
  5825 
       
  5826     {
       
  5827         // window shown and active, children created, don't get focus,
       
  5828         // even after setFocus(), hide(), then show()
       
  5829         QWidget window;
       
  5830 
       
  5831         window.show();
       
  5832 #ifdef Q_WS_X11
       
  5833         QApplication::setActiveWindow(&window);
       
  5834         QTest::qWaitForWindowShown(&window);
       
  5835 #else
       
  5836         window.activateWindow();
       
  5837 #endif
       
  5838 
       
  5839         QWidget child1(&window);
       
  5840         child1.setFocusPolicy(Qt::StrongFocus);
       
  5841 
       
  5842         QWidget child2(&window);
       
  5843         child2.setFocusPolicy(Qt::StrongFocus);
       
  5844 
       
  5845         child1.setFocus();
       
  5846         QVERIFY(!child1.hasFocus());
       
  5847         QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
       
  5848         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5849 
       
  5850         child1.hide();
       
  5851         QVERIFY(!child1.hasFocus());
       
  5852         QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
       
  5853         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5854 
       
  5855         child1.show();
       
  5856         QVERIFY(!child1.hasFocus());
       
  5857         QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
       
  5858         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5859 
       
  5860         child2.setFocus();
       
  5861         QVERIFY(!child2.hasFocus());
       
  5862         QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
       
  5863         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5864 
       
  5865         child2.hide();
       
  5866         QVERIFY(!child2.hasFocus());
       
  5867         QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
       
  5868         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5869 
       
  5870         child2.show();
       
  5871         QVERIFY(!child2.hasFocus());
       
  5872         QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
       
  5873         QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
       
  5874     }
       
  5875 }
       
  5876 
       
  5877 class EventSpy : public QObject
       
  5878 {
       
  5879 public:
       
  5880     EventSpy(QWidget *widget, QEvent::Type event)
       
  5881         : m_widget(widget), eventToSpy(event), m_count(0)
       
  5882     {
       
  5883         if (m_widget)
       
  5884             m_widget->installEventFilter(this);
       
  5885     }
       
  5886 
       
  5887     QWidget *widget() const { return m_widget; }
       
  5888     int count() const { return m_count; }
       
  5889     void clear() { m_count = 0; }
       
  5890 
       
  5891 protected:
       
  5892     bool eventFilter(QObject *object, QEvent *event)
       
  5893     {
       
  5894         if (event->type() == eventToSpy)
       
  5895             ++m_count;
       
  5896         return  QObject::eventFilter(object, event);
       
  5897     }
       
  5898 
       
  5899 private:
       
  5900     QWidget *m_widget;
       
  5901     QEvent::Type eventToSpy;
       
  5902     int m_count;
       
  5903 };
       
  5904 
       
  5905 void tst_QWidget::setCursor()
       
  5906 {
       
  5907 #ifndef QT_NO_CURSOR
       
  5908     {
       
  5909         QWidget window;
       
  5910         QWidget child(&window);
       
  5911 
       
  5912         QVERIFY(!window.testAttribute(Qt::WA_SetCursor));
       
  5913         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5914 
       
  5915         window.setCursor(window.cursor());
       
  5916         QVERIFY(window.testAttribute(Qt::WA_SetCursor));
       
  5917         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5918         QCOMPARE(child.cursor().shape(), window.cursor().shape());
       
  5919     }
       
  5920 
       
  5921     // do it again, but with window show()n
       
  5922     {
       
  5923         QWidget window;
       
  5924         QWidget child(&window);
       
  5925         window.show();
       
  5926 
       
  5927         QVERIFY(!window.testAttribute(Qt::WA_SetCursor));
       
  5928         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5929 
       
  5930         window.setCursor(window.cursor());
       
  5931         QVERIFY(window.testAttribute(Qt::WA_SetCursor));
       
  5932         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5933         QCOMPARE(child.cursor().shape(), window.cursor().shape());
       
  5934     }
       
  5935 
       
  5936 
       
  5937     {
       
  5938         QWidget window;
       
  5939         QWidget child(&window);
       
  5940 
       
  5941         window.setCursor(Qt::WaitCursor);
       
  5942         QVERIFY(window.testAttribute(Qt::WA_SetCursor));
       
  5943         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5944         QCOMPARE(child.cursor().shape(), window.cursor().shape());
       
  5945     }
       
  5946 
       
  5947     // same thing again, just with window show()n
       
  5948     {
       
  5949         QWidget window;
       
  5950         QWidget child(&window);
       
  5951 
       
  5952         window.show();
       
  5953         window.setCursor(Qt::WaitCursor);
       
  5954         QVERIFY(window.testAttribute(Qt::WA_SetCursor));
       
  5955         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5956         QCOMPARE(child.cursor().shape(), window.cursor().shape());
       
  5957     }
       
  5958 
       
  5959     // reparenting child should not cause the WA_SetCursor to become set
       
  5960     {
       
  5961         QWidget window;
       
  5962         QWidget window2;
       
  5963         QWidget child(&window);
       
  5964 
       
  5965         window.setCursor(Qt::WaitCursor);
       
  5966 
       
  5967         child.setParent(0);
       
  5968         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5969         QCOMPARE(child.cursor().shape(), QCursor().shape());
       
  5970 
       
  5971         child.setParent(&window2);
       
  5972         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5973         QCOMPARE(child.cursor().shape(), window2.cursor().shape());
       
  5974 
       
  5975             window2.setCursor(Qt::WaitCursor);
       
  5976         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5977         QCOMPARE(child.cursor().shape(), window2.cursor().shape());
       
  5978     }
       
  5979 
       
  5980     // again, with windows show()n
       
  5981     {
       
  5982         QWidget window;
       
  5983         QWidget window2;
       
  5984         QWidget child(&window);
       
  5985 
       
  5986         window.setCursor(Qt::WaitCursor);
       
  5987         window.show();
       
  5988 
       
  5989         child.setParent(0);
       
  5990         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5991         QCOMPARE(child.cursor().shape(), QCursor().shape());
       
  5992 
       
  5993         child.setParent(&window2);
       
  5994         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  5995         QCOMPARE(child.cursor().shape(), window2.cursor().shape());
       
  5996 
       
  5997         window2.show();
       
  5998         window2.setCursor(Qt::WaitCursor);
       
  5999         QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
       
  6000         QCOMPARE(child.cursor().shape(), window2.cursor().shape());
       
  6001     }
       
  6002 
       
  6003     // test if CursorChange is sent
       
  6004     {
       
  6005         QWidget widget;
       
  6006         EventSpy spy(&widget, QEvent::CursorChange);
       
  6007         QCOMPARE(spy.count(), 0);
       
  6008         widget.setCursor(QCursor(Qt::WaitCursor));
       
  6009         QCOMPARE(spy.count(), 1);
       
  6010         widget.unsetCursor();
       
  6011         QCOMPARE(spy.count(), 2);
       
  6012     }
       
  6013 #endif
       
  6014 }
       
  6015 
       
  6016 void tst_QWidget::setToolTip()
       
  6017 {
       
  6018     QWidget widget;
       
  6019     EventSpy spy(&widget, QEvent::ToolTipChange);
       
  6020     QCOMPARE(spy.count(), 0);
       
  6021 
       
  6022     QCOMPARE(widget.toolTip(), QString());
       
  6023     widget.setToolTip(QString("Hello"));
       
  6024     QCOMPARE(widget.toolTip(), QString("Hello"));
       
  6025     QCOMPARE(spy.count(), 1);
       
  6026     widget.setToolTip(QString());
       
  6027     QCOMPARE(widget.toolTip(), QString());
       
  6028     QCOMPARE(spy.count(), 2);
       
  6029 
       
  6030 #ifdef Q_OS_WINCE_WM
       
  6031     QSKIP("Mouse over doesn't work on Windows mobile.", SkipAll);
       
  6032 #endif
       
  6033 
       
  6034     for (int pass = 0; pass < 2; ++pass) {
       
  6035         QWidget *popup = new QWidget(0, Qt::Popup);
       
  6036         popup->resize(150, 50);
       
  6037         QFrame *frame = new QFrame(popup);
       
  6038         frame->setGeometry(0, 0, 50, 50);
       
  6039         frame->setFrameStyle(QFrame::Box | QFrame::Plain);
       
  6040         EventSpy spy1(frame, QEvent::ToolTip);
       
  6041         EventSpy spy2(popup, QEvent::ToolTip);
       
  6042         frame->setMouseTracking(pass == 0 ? false : true);
       
  6043         frame->setToolTip(QLatin1String("TOOLTIP FRAME"));
       
  6044         popup->setToolTip(QLatin1String("TOOLTIP POPUP"));
       
  6045         popup->show();
       
  6046         QTest::qWaitForWindowShown(popup);
       
  6047         QTest::qWait(10);
       
  6048         QTest::mouseMove(frame);
       
  6049         QTest::qWait(900);          // delay is 700
       
  6050 
       
  6051         QCOMPARE(spy1.count(), 1);
       
  6052         QCOMPARE(spy2.count(), 0);
       
  6053         if (pass == 0)
       
  6054             QTest::qWait(2200);     // delay is 2000
       
  6055         QTest::mouseMove(popup);
       
  6056         delete popup;
       
  6057     }
       
  6058 }
       
  6059 
       
  6060 void tst_QWidget::testWindowIconChangeEventPropagation()
       
  6061 {
       
  6062     // Create widget hierarchy.
       
  6063     QWidget topLevelWidget;
       
  6064     QWidget topLevelChild(&topLevelWidget);
       
  6065 
       
  6066     QDialog dialog(&topLevelWidget);
       
  6067     QWidget dialogChild(&dialog);
       
  6068 
       
  6069     QWidgetList widgets;
       
  6070     widgets << &topLevelWidget << &topLevelChild
       
  6071             << &dialog << &dialogChild;
       
  6072     QCOMPARE(widgets.count(), 4);
       
  6073 
       
  6074     // Create spy lists.
       
  6075     QList <EventSpy *> applicationEventSpies;
       
  6076     QList <EventSpy *> widgetEventSpies;
       
  6077     foreach (QWidget *widget, widgets) {
       
  6078         applicationEventSpies.append(new EventSpy(widget, QEvent::ApplicationWindowIconChange));
       
  6079         widgetEventSpies.append(new EventSpy(widget, QEvent::WindowIconChange));
       
  6080     }
       
  6081 
       
  6082     // QApplication::setWindowIcon
       
  6083     const QIcon windowIcon = qApp->style()->standardIcon(QStyle::SP_TitleBarMenuButton);
       
  6084     qApp->setWindowIcon(windowIcon);
       
  6085 
       
  6086     for (int i = 0; i < widgets.count(); ++i) {
       
  6087         // Check QEvent::ApplicationWindowIconChange
       
  6088         EventSpy *spy = applicationEventSpies.at(i);
       
  6089         QWidget *widget = spy->widget();
       
  6090         if (widget->isWindow()) {
       
  6091             QCOMPARE(spy->count(), 1);
       
  6092             QCOMPARE(widget->windowIcon(), windowIcon);
       
  6093         } else {
       
  6094             QCOMPARE(spy->count(), 0);
       
  6095         }
       
  6096         spy->clear();
       
  6097 
       
  6098         // Check QEvent::WindowIconChange
       
  6099         spy = widgetEventSpies.at(i);
       
  6100         QCOMPARE(spy->count(), 1);
       
  6101         spy->clear();
       
  6102     }
       
  6103 
       
  6104     // Set icon on a top-level widget.
       
  6105     topLevelWidget.setWindowIcon(*new QIcon);
       
  6106 
       
  6107     for (int i = 0; i < widgets.count(); ++i) {
       
  6108         // Check QEvent::ApplicationWindowIconChange
       
  6109         EventSpy *spy = applicationEventSpies.at(i);
       
  6110         QCOMPARE(spy->count(), 0);
       
  6111         spy->clear();
       
  6112 
       
  6113         // Check QEvent::WindowIconChange
       
  6114         spy = widgetEventSpies.at(i);
       
  6115         QWidget *widget = spy->widget();
       
  6116         if (widget == &topLevelWidget) {
       
  6117             QCOMPARE(widget->windowIcon(), QIcon());
       
  6118             QCOMPARE(spy->count(), 1);
       
  6119         } else if (topLevelWidget.isAncestorOf(widget)) {
       
  6120             QCOMPARE(spy->count(), 1);
       
  6121         } else {
       
  6122             QCOMPARE(spy->count(), 0);
       
  6123         }
       
  6124         spy->clear();
       
  6125     }
       
  6126 
       
  6127     // Cleanup.
       
  6128     for (int i = 0; i < widgets.count(); ++i) {
       
  6129         delete applicationEventSpies.at(i);
       
  6130         delete widgetEventSpies.at(i);
       
  6131     }
       
  6132     qApp->setWindowIcon(QIcon());
       
  6133 }
       
  6134 
       
  6135 #ifdef Q_WS_X11
       
  6136 void tst_QWidget::minAndMaxSizeWithX11BypassWindowManagerHint()
       
  6137 {
       
  6138     // Same size as in QWidget::create_sys().
       
  6139     const QSize desktopSize = QApplication::desktop()->size();
       
  6140     const QSize originalSize(desktopSize.width() / 2, desktopSize.height() * 4 / 10);
       
  6141 
       
  6142     { // Maximum size.
       
  6143     QWidget widget(0, Qt::X11BypassWindowManagerHint);
       
  6144 
       
  6145     const QSize newMaximumSize = widget.size().boundedTo(originalSize) - QSize(10, 10);
       
  6146     widget.setMaximumSize(newMaximumSize);
       
  6147     QCOMPARE(widget.size(), newMaximumSize);
       
  6148 
       
  6149     widget.show();
       
  6150     qt_x11_wait_for_window_manager(&widget);
       
  6151     QCOMPARE(widget.size(), newMaximumSize);
       
  6152     }
       
  6153 
       
  6154     { // Minimum size.
       
  6155     QWidget widget(0, Qt::X11BypassWindowManagerHint);
       
  6156 
       
  6157     const QSize newMinimumSize = widget.size().expandedTo(originalSize) + QSize(10, 10);
       
  6158     widget.setMinimumSize(newMinimumSize);
       
  6159     QCOMPARE(widget.size(), newMinimumSize);
       
  6160 
       
  6161     widget.show();
       
  6162     qt_x11_wait_for_window_manager(&widget);
       
  6163     QCOMPARE(widget.size(), newMinimumSize);
       
  6164     }
       
  6165 }
       
  6166 
       
  6167 class ShowHideShowWidget : public QWidget
       
  6168 {
       
  6169     Q_OBJECT
       
  6170 
       
  6171     int state;
       
  6172 public:
       
  6173     bool gotExpectedMapNotify;
       
  6174 
       
  6175     ShowHideShowWidget()
       
  6176         : state(0), gotExpectedMapNotify(false)
       
  6177     {
       
  6178         startTimer(1000);
       
  6179     }
       
  6180 
       
  6181     void timerEvent(QTimerEvent *)
       
  6182     {
       
  6183         switch (state++) {
       
  6184         case 0:
       
  6185             show();
       
  6186             break;
       
  6187         case 1:
       
  6188             emit done();
       
  6189             break;
       
  6190         }
       
  6191     }
       
  6192 
       
  6193     bool x11Event(XEvent *event)
       
  6194     {
       
  6195         if (state == 1 && event->type == MapNotify)
       
  6196             gotExpectedMapNotify = true;
       
  6197         return false;
       
  6198     }
       
  6199 
       
  6200 signals:
       
  6201     void done();
       
  6202 };
       
  6203 
       
  6204 void tst_QWidget::showHideShow()
       
  6205 {
       
  6206     ShowHideShowWidget w;
       
  6207     w.show();
       
  6208     w.hide();
       
  6209 
       
  6210     QEventLoop eventLoop;
       
  6211     connect(&w, SIGNAL(done()), &eventLoop, SLOT(quit()));
       
  6212     eventLoop.exec();
       
  6213 
       
  6214     QVERIFY(w.gotExpectedMapNotify);
       
  6215 }
       
  6216 
       
  6217 void tst_QWidget::clean_qt_x11_enforce_cursor()
       
  6218 {
       
  6219     {
       
  6220         QWidget window;
       
  6221         QWidget *w = new QWidget(&window);
       
  6222         QWidget *child = new QWidget(w);
       
  6223         child->setAttribute(Qt::WA_SetCursor, true);
       
  6224 
       
  6225         window.show();
       
  6226         QApplication::setActiveWindow(&window);
       
  6227         QTest::qWaitForWindowShown(&window);
       
  6228         QTest::qWait(100);
       
  6229         QCursor::setPos(window.geometry().center());
       
  6230         QTest::qWait(100);
       
  6231 
       
  6232         child->setFocus();
       
  6233         QApplication::processEvents();
       
  6234         QTest::qWait(100);
       
  6235 
       
  6236         delete w;
       
  6237     }
       
  6238 
       
  6239     QGraphicsScene scene;
       
  6240     QLineEdit *edit = new QLineEdit;
       
  6241     scene.addWidget(edit);
       
  6242 
       
  6243     // If the test didn't crash, then it passed.
       
  6244 }
       
  6245 #endif
       
  6246 
       
  6247 class EventRecorder : public QObject
       
  6248 {
       
  6249     Q_OBJECT
       
  6250 
       
  6251 public:
       
  6252     typedef QList<QPair<QWidget *, QEvent::Type> > EventList;
       
  6253 
       
  6254     EventRecorder(QObject *parent = 0)
       
  6255         : QObject(parent)
       
  6256     { }
       
  6257 
       
  6258     EventList eventList()
       
  6259     {
       
  6260         return events;
       
  6261     }
       
  6262 
       
  6263     void clear()
       
  6264     {
       
  6265         events.clear();
       
  6266     }
       
  6267 
       
  6268     bool eventFilter(QObject *object, QEvent *event)
       
  6269     {
       
  6270         QWidget *widget = qobject_cast<QWidget *>(object);
       
  6271         if (widget && !event->spontaneous())
       
  6272             events.append(qMakePair(widget, event->type()));
       
  6273         return false;
       
  6274     }
       
  6275 
       
  6276 private:
       
  6277     EventList events;
       
  6278 };
       
  6279 
       
  6280 void tst_QWidget::compatibilityChildInsertedEvents()
       
  6281 {
       
  6282     EventRecorder::EventList expected;
       
  6283     bool accessibilityEnabled = false;
       
  6284 #if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
       
  6285     accessibilityEnabled = AXAPIEnabled();
       
  6286 #endif
       
  6287 
       
  6288     // Move away the cursor; otherwise it might result in an enter event if it's
       
  6289     // inside the widget when the widget is shown.
       
  6290     QCursor::setPos(qApp->desktop()->availableGeometry().bottomRight());
       
  6291     QTest::qWait(100);
       
  6292 
       
  6293     {
       
  6294         // no children created, not shown
       
  6295         QWidget widget;
       
  6296         EventRecorder spy;
       
  6297         widget.installEventFilter(&spy);
       
  6298 
       
  6299         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
       
  6300 
       
  6301         QCoreApplication::sendPostedEvents();
       
  6302 
       
  6303         expected =
       
  6304             EventRecorder::EventList()
       
  6305             << qMakePair(&widget, QEvent::PolishRequest)
       
  6306             << qMakePair(&widget, QEvent::Polish)
       
  6307             << qMakePair(&widget, QEvent::Type(QEvent::User + 1));
       
  6308         QCOMPARE(spy.eventList(), expected);
       
  6309     }
       
  6310 
       
  6311     {
       
  6312         // no children, shown
       
  6313         QWidget widget;
       
  6314         EventRecorder spy;
       
  6315         widget.installEventFilter(&spy);
       
  6316 
       
  6317         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
       
  6318 
       
  6319         widget.show();
       
  6320         expected =
       
  6321             EventRecorder::EventList()
       
  6322             << qMakePair(&widget, QEvent::Polish)
       
  6323             << qMakePair(&widget, QEvent::Move)
       
  6324             << qMakePair(&widget, QEvent::Resize)
       
  6325             << qMakePair(&widget, QEvent::Show);
       
  6326 
       
  6327         if (accessibilityEnabled)
       
  6328             expected << qMakePair(&widget, QEvent::AccessibilityPrepare);
       
  6329         expected << qMakePair(&widget, QEvent::ShowToParent);
       
  6330         QCOMPARE(spy.eventList(), expected);
       
  6331         spy.clear();
       
  6332 
       
  6333         QCoreApplication::sendPostedEvents();
       
  6334         expected =
       
  6335             EventRecorder::EventList()
       
  6336             << qMakePair(&widget, QEvent::PolishRequest)
       
  6337             << qMakePair(&widget, QEvent::Type(QEvent::User + 1))
       
  6338 #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_S60)
       
  6339             << qMakePair(&widget, QEvent::UpdateRequest)
       
  6340 #endif
       
  6341             ;
       
  6342         QCOMPARE(spy.eventList(), expected);
       
  6343     }
       
  6344 
       
  6345     {
       
  6346         // 2 children, not shown
       
  6347         QWidget widget;
       
  6348         EventRecorder spy;
       
  6349         widget.installEventFilter(&spy);
       
  6350 
       
  6351         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
       
  6352 
       
  6353         QWidget child1(&widget);
       
  6354         QWidget child2;
       
  6355         child2.setParent(&widget);
       
  6356 
       
  6357         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 2)));
       
  6358 
       
  6359         expected =
       
  6360             EventRecorder::EventList()
       
  6361             << qMakePair(&widget, QEvent::ChildAdded)
       
  6362             << qMakePair(&widget, QEvent::ChildAdded);
       
  6363         QCOMPARE(spy.eventList(), expected);
       
  6364         spy.clear();
       
  6365 
       
  6366         QCoreApplication::sendPostedEvents();
       
  6367         expected =
       
  6368             EventRecorder::EventList()
       
  6369 #ifdef QT_HAS_QT3SUPPORT
       
  6370             << qMakePair(&widget, QEvent::ChildInsertedRequest)
       
  6371             << qMakePair(&widget, QEvent::ChildInserted)
       
  6372             << qMakePair(&widget, QEvent::ChildInserted)
       
  6373 #endif
       
  6374             << qMakePair(&widget, QEvent::PolishRequest)
       
  6375             << qMakePair(&widget, QEvent::Polish)
       
  6376             << qMakePair(&widget, QEvent::ChildPolished)
       
  6377             << qMakePair(&widget, QEvent::ChildPolished)
       
  6378             << qMakePair(&widget, QEvent::Type(QEvent::User + 1))
       
  6379             << qMakePair(&widget, QEvent::Type(QEvent::User + 2));
       
  6380         QCOMPARE(spy.eventList(), expected);
       
  6381     }
       
  6382 
       
  6383     {
       
  6384         // 2 children, widget shown
       
  6385         QWidget widget;
       
  6386         EventRecorder spy;
       
  6387         widget.installEventFilter(&spy);
       
  6388 
       
  6389         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
       
  6390 
       
  6391         QWidget child1(&widget);
       
  6392         QWidget child2;
       
  6393         child2.setParent(&widget);
       
  6394 
       
  6395         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 2)));
       
  6396 
       
  6397         expected =
       
  6398             EventRecorder::EventList()
       
  6399             << qMakePair(&widget, QEvent::ChildAdded)
       
  6400             << qMakePair(&widget, QEvent::ChildAdded);
       
  6401         QCOMPARE(spy.eventList(), expected);
       
  6402         spy.clear();
       
  6403 
       
  6404         widget.show();
       
  6405         expected =
       
  6406             EventRecorder::EventList()
       
  6407             << qMakePair(&widget, QEvent::Polish)
       
  6408 #ifdef QT_HAS_QT3SUPPORT
       
  6409             << qMakePair(&widget, QEvent::ChildInserted)
       
  6410             << qMakePair(&widget, QEvent::ChildInserted)
       
  6411 #endif
       
  6412             << qMakePair(&widget, QEvent::ChildPolished)
       
  6413             << qMakePair(&widget, QEvent::ChildPolished)
       
  6414             << qMakePair(&widget, QEvent::Move)
       
  6415             << qMakePair(&widget, QEvent::Resize)
       
  6416             << qMakePair(&widget, QEvent::Show);
       
  6417 
       
  6418         if (accessibilityEnabled)
       
  6419             expected << qMakePair(&widget, QEvent::AccessibilityPrepare);
       
  6420         expected << qMakePair(&widget, QEvent::ShowToParent);
       
  6421         QCOMPARE(spy.eventList(), expected);
       
  6422         spy.clear();
       
  6423 
       
  6424         QCoreApplication::sendPostedEvents();
       
  6425         expected =
       
  6426             EventRecorder::EventList()
       
  6427 #ifdef QT_HAS_QT3SUPPORT
       
  6428             << qMakePair(&widget, QEvent::ChildInsertedRequest)
       
  6429 #endif
       
  6430             << qMakePair(&widget, QEvent::PolishRequest)
       
  6431             << qMakePair(&widget, QEvent::Type(QEvent::User + 1))
       
  6432             << qMakePair(&widget, QEvent::Type(QEvent::User + 2))
       
  6433 #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_S60)
       
  6434             << qMakePair(&widget, QEvent::UpdateRequest)
       
  6435 #endif
       
  6436             ;
       
  6437         QCOMPARE(spy.eventList(), expected);
       
  6438     }
       
  6439 
       
  6440     {
       
  6441         // 2 children, but one is reparented away, not shown
       
  6442         QWidget widget;
       
  6443         EventRecorder spy;
       
  6444         widget.installEventFilter(&spy);
       
  6445 
       
  6446         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
       
  6447 
       
  6448         QWidget child1(&widget);
       
  6449         QWidget child2;
       
  6450         child2.setParent(&widget);
       
  6451         child2.setParent(0);
       
  6452 
       
  6453         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 2)));
       
  6454 
       
  6455         expected =
       
  6456             EventRecorder::EventList()
       
  6457             << qMakePair(&widget, QEvent::ChildAdded)
       
  6458             << qMakePair(&widget, QEvent::ChildAdded)
       
  6459             << qMakePair(&widget, QEvent::ChildRemoved);
       
  6460         QCOMPARE(spy.eventList(), expected);
       
  6461         spy.clear();
       
  6462 
       
  6463         QCoreApplication::sendPostedEvents();
       
  6464         expected =
       
  6465             EventRecorder::EventList()
       
  6466 #ifdef QT_HAS_QT3SUPPORT
       
  6467             << qMakePair(&widget, QEvent::ChildInsertedRequest)
       
  6468             << qMakePair(&widget, QEvent::ChildInserted)
       
  6469 #endif
       
  6470             << qMakePair(&widget, QEvent::PolishRequest)
       
  6471             << qMakePair(&widget, QEvent::Polish)
       
  6472             << qMakePair(&widget, QEvent::ChildPolished)
       
  6473             << qMakePair(&widget, QEvent::Type(QEvent::User + 1))
       
  6474             << qMakePair(&widget, QEvent::Type(QEvent::User + 2));
       
  6475         QCOMPARE(spy.eventList(), expected);
       
  6476     }
       
  6477 
       
  6478     {
       
  6479         // 2 children, but one is reparented away, then widget is shown
       
  6480         QWidget widget;
       
  6481         EventRecorder spy;
       
  6482         widget.installEventFilter(&spy);
       
  6483 
       
  6484         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
       
  6485 
       
  6486         QWidget child1(&widget);
       
  6487         QWidget child2;
       
  6488         child2.setParent(&widget);
       
  6489         child2.setParent(0);
       
  6490 
       
  6491         QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 2)));
       
  6492 
       
  6493         expected =
       
  6494             EventRecorder::EventList()
       
  6495             << qMakePair(&widget, QEvent::ChildAdded)
       
  6496             << qMakePair(&widget, QEvent::ChildAdded)
       
  6497             << qMakePair(&widget, QEvent::ChildRemoved);
       
  6498         QCOMPARE(spy.eventList(), expected);
       
  6499         spy.clear();
       
  6500 
       
  6501         widget.show();
       
  6502         expected =
       
  6503             EventRecorder::EventList()
       
  6504             << qMakePair(&widget, QEvent::Polish)
       
  6505 #ifdef QT_HAS_QT3SUPPORT
       
  6506             << qMakePair(&widget, QEvent::ChildInserted)
       
  6507 #endif
       
  6508             << qMakePair(&widget, QEvent::ChildPolished)
       
  6509             << qMakePair(&widget, QEvent::Move)
       
  6510             << qMakePair(&widget, QEvent::Resize)
       
  6511             << qMakePair(&widget, QEvent::Show);
       
  6512 
       
  6513         if (accessibilityEnabled)
       
  6514             expected << qMakePair(&widget, QEvent::AccessibilityPrepare);
       
  6515         expected << qMakePair(&widget, QEvent::ShowToParent);
       
  6516         QCOMPARE(spy.eventList(), expected);
       
  6517         spy.clear();
       
  6518 
       
  6519         QCoreApplication::sendPostedEvents();
       
  6520         expected =
       
  6521             EventRecorder::EventList()
       
  6522 #ifdef QT_HAS_QT3SUPPORT
       
  6523             << qMakePair(&widget, QEvent::ChildInsertedRequest)
       
  6524 #endif
       
  6525             << qMakePair(&widget, QEvent::PolishRequest)
       
  6526             << qMakePair(&widget, QEvent::Type(QEvent::User + 1))
       
  6527             << qMakePair(&widget, QEvent::Type(QEvent::User + 2))
       
  6528 #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_S60)
       
  6529             << qMakePair(&widget, QEvent::UpdateRequest)
       
  6530 #endif
       
  6531             ;
       
  6532         QCOMPARE(spy.eventList(), expected);
       
  6533     }
       
  6534 }
       
  6535 
       
  6536 class RenderWidget : public QWidget
       
  6537 {
       
  6538 public:
       
  6539     RenderWidget(QWidget *source)
       
  6540         : source(source), ellipse(false) {}
       
  6541 
       
  6542     void setEllipseEnabled(bool enable = true)
       
  6543     {
       
  6544         ellipse = enable;
       
  6545         update();
       
  6546     }
       
  6547 
       
  6548 protected:
       
  6549     void paintEvent(QPaintEvent *)
       
  6550     {
       
  6551         if (ellipse) {
       
  6552             QPainter painter(this);
       
  6553             painter.fillRect(rect(), Qt::red);
       
  6554             painter.end();
       
  6555             QRegion regionToRender = QRegion(0, 0, source->width(), source->height() / 2,
       
  6556                                              QRegion::Ellipse);
       
  6557             source->render(this, QPoint(0, 30), regionToRender);
       
  6558         } else {
       
  6559             source->render(this);
       
  6560         }
       
  6561     }
       
  6562 
       
  6563 private:
       
  6564     QWidget *source;
       
  6565     bool ellipse;
       
  6566 };
       
  6567 
       
  6568 void tst_QWidget::render()
       
  6569 {
       
  6570     return;
       
  6571     QCalendarWidget source;
       
  6572     // disable anti-aliasing to eliminate potential differences when subpixel antialiasing
       
  6573     // is enabled on the screen
       
  6574     QFont f;
       
  6575     f.setStyleStrategy(QFont::NoAntialias);
       
  6576     source.setFont(f);
       
  6577     source.show();
       
  6578     QTest::qWaitForWindowShown(&source);
       
  6579 
       
  6580     // Render the entire source into target.
       
  6581     RenderWidget target(&source);
       
  6582     target.resize(source.size());
       
  6583     target.show();
       
  6584 
       
  6585     qApp->processEvents();
       
  6586     qApp->sendPostedEvents();
       
  6587     QTest::qWait(250);
       
  6588 
       
  6589     QImage sourceImage = QPixmap::grabWidget(&source).toImage();
       
  6590     qApp->processEvents();
       
  6591     QImage targetImage = QPixmap::grabWidget(&target).toImage();
       
  6592     qApp->processEvents();
       
  6593     QCOMPARE(sourceImage, targetImage);
       
  6594 
       
  6595     // Fill target.rect() will Qt::red and render
       
  6596     // QRegion(0, 0, source->width(), source->height() / 2, QRegion::Ellipse)
       
  6597     // of source into target with offset (0, 30).
       
  6598     target.setEllipseEnabled();
       
  6599     qApp->processEvents();
       
  6600     qApp->sendPostedEvents();
       
  6601 
       
  6602     targetImage = QPixmap::grabWidget(&target).toImage();
       
  6603     QVERIFY(sourceImage != targetImage);
       
  6604 
       
  6605     QCOMPARE(targetImage.pixel(target.width() / 2, 29), QColor(Qt::red).rgb());
       
  6606     QCOMPARE(targetImage.pixel(target.width() / 2, 30), sourceImage.pixel(source.width() / 2, 0));
       
  6607 
       
  6608     // Test that a child widget properly fills its background
       
  6609     {
       
  6610         QWidget window;
       
  6611         window.resize(100, 100);
       
  6612         // prevent custom styles
       
  6613         window.setStyle(new QWindowsStyle);
       
  6614         window.show();
       
  6615         QTest::qWaitForWindowShown(&window);
       
  6616         QWidget child(&window);
       
  6617         child.resize(window.size());
       
  6618         child.show();
       
  6619 
       
  6620         qApp->processEvents();
       
  6621         QCOMPARE(QPixmap::grabWidget(&child), QPixmap::grabWidget(&window));
       
  6622     }
       
  6623 
       
  6624     { // Check that the target offset is correct.
       
  6625         QWidget widget;
       
  6626         widget.resize(200, 200);
       
  6627         widget.setAutoFillBackground(true);
       
  6628         widget.setPalette(Qt::red);
       
  6629         // prevent custom styles
       
  6630         widget.setStyle(new QWindowsStyle);
       
  6631         widget.show();
       
  6632         QTest::qWaitForWindowShown(&widget);
       
  6633         QImage image(widget.size(), QImage::Format_RGB32);
       
  6634         image.fill(QColor(Qt::blue).rgb());
       
  6635 
       
  6636         // Target offset (0, 0)
       
  6637         widget.render(&image, QPoint(), QRect(20, 20, 100, 100));
       
  6638         QCOMPARE(image.pixel(0, 0), QColor(Qt::red).rgb());
       
  6639         QCOMPARE(image.pixel(99, 99), QColor(Qt::red).rgb());
       
  6640         QCOMPARE(image.pixel(100, 100), QColor(Qt::blue).rgb());
       
  6641 
       
  6642         // Target offset (20, 20).
       
  6643         image.fill(QColor(Qt::blue).rgb());
       
  6644         widget.render(&image, QPoint(20, 20), QRect(20, 20, 100, 100));
       
  6645         QCOMPARE(image.pixel(0, 0), QColor(Qt::blue).rgb());
       
  6646         QCOMPARE(image.pixel(19, 19), QColor(Qt::blue).rgb());
       
  6647         QCOMPARE(image.pixel(20, 20), QColor(Qt::red).rgb());
       
  6648         QCOMPARE(image.pixel(119, 119), QColor(Qt::red).rgb());
       
  6649         QCOMPARE(image.pixel(120, 120), QColor(Qt::blue).rgb());
       
  6650     }
       
  6651 }
       
  6652 
       
  6653 // On Windows the active palette is used instead of the inactive palette even
       
  6654 // though the widget is invisible. This is probably related to task 178507/168682,
       
  6655 // but for the renderInvisible test it doesn't matter, we're mostly interested
       
  6656 // in testing the geometry so just workaround the palette issue for now.
       
  6657 static void workaroundPaletteIssue(QWidget *widget)
       
  6658 {
       
  6659 #ifndef Q_WS_WIN
       
  6660     return;
       
  6661 #endif
       
  6662     if (!widget)
       
  6663         return;
       
  6664 
       
  6665     QWidget *navigationBar = qFindChild<QWidget *>(widget, QLatin1String("qt_calendar_navigationbar"));
       
  6666     QVERIFY(navigationBar);
       
  6667 
       
  6668     QPalette palette = navigationBar->palette();
       
  6669     const QColor background = palette.color(QPalette::Inactive, navigationBar->backgroundRole());
       
  6670     const QColor highlightedText = palette.color(QPalette::Inactive, QPalette::HighlightedText);
       
  6671     palette.setColor(QPalette::Active, navigationBar->backgroundRole(), background);
       
  6672     palette.setColor(QPalette::Active, QPalette::HighlightedText, highlightedText);
       
  6673     navigationBar->setPalette(palette);
       
  6674 }
       
  6675 
       
  6676 //#define RENDER_DEBUG
       
  6677 void tst_QWidget::renderInvisible()
       
  6678 {
       
  6679     QCalendarWidget *calendar = new QCalendarWidget;
       
  6680     // disable anti-aliasing to eliminate potential differences when subpixel antialiasing
       
  6681     // is enabled on the screen
       
  6682     QFont f;
       
  6683     f.setStyleStrategy(QFont::NoAntialias);
       
  6684     calendar->setFont(f);
       
  6685     calendar->show();
       
  6686     QTest::qWaitForWindowShown(calendar);
       
  6687 
       
  6688     // Create a dummy focus widget to get rid of focus rect in reference image.
       
  6689     QLineEdit dummyFocusWidget;
       
  6690     dummyFocusWidget.show();
       
  6691     QTest::qWaitForWindowShown(&dummyFocusWidget);
       
  6692     qApp->processEvents();
       
  6693     QTest::qWait(120);
       
  6694 
       
  6695     // Create normal reference image.
       
  6696     const QSize calendarSize = calendar->size();
       
  6697     QImage referenceImage(calendarSize, QImage::Format_ARGB32);
       
  6698     calendar->render(&referenceImage);
       
  6699 #ifdef RENDER_DEBUG
       
  6700     referenceImage.save("referenceImage.png");
       
  6701 #endif
       
  6702     QVERIFY(!referenceImage.isNull());
       
  6703 
       
  6704     // Create resized reference image.
       
  6705     const QSize calendarSizeResized = calendar->size() + QSize(50, 50);
       
  6706     calendar->resize(calendarSizeResized);
       
  6707     qApp->processEvents();
       
  6708     QTest::qWait(30);
       
  6709     QImage referenceImageResized(calendarSizeResized, QImage::Format_ARGB32);
       
  6710     calendar->render(&referenceImageResized);
       
  6711 #ifdef RENDER_DEBUG
       
  6712     referenceImageResized.save("referenceImageResized.png");
       
  6713 #endif
       
  6714     QVERIFY(!referenceImageResized.isNull());
       
  6715 
       
  6716     // Explicitly hide the calendar.
       
  6717     calendar->hide();
       
  6718     qApp->processEvents();
       
  6719     QTest::qWait(30);
       
  6720     workaroundPaletteIssue(calendar);
       
  6721 
       
  6722     { // Make sure we get the same image when the calendar is explicitly hidden.
       
  6723     QImage testImage(calendarSizeResized, QImage::Format_ARGB32);
       
  6724     calendar->render(&testImage);
       
  6725 #ifdef RENDER_DEBUG
       
  6726     testImage.save("explicitlyHiddenCalendarResized.png");
       
  6727 #endif
       
  6728     QCOMPARE(testImage, referenceImageResized);
       
  6729     }
       
  6730 
       
  6731     // Now that we have reference images we can delete the source and re-create
       
  6732     // the calendar and check that we get the same images from a calendar which has never
       
  6733     // been visible, laid out or created (Qt::WA_WState_Created).
       
  6734     delete calendar;
       
  6735     calendar = new QCalendarWidget;
       
  6736     calendar->setFont(f);
       
  6737     workaroundPaletteIssue(calendar);
       
  6738 
       
  6739     { // Never been visible, created or laid out.
       
  6740     QImage testImage(calendarSize, QImage::Format_ARGB32);
       
  6741     calendar->render(&testImage);
       
  6742 #ifdef RENDER_DEBUG
       
  6743     testImage.save("neverBeenVisibleCreatedOrLaidOut.png");
       
  6744 #endif
       
  6745     QCOMPARE(testImage, referenceImage);
       
  6746     }
       
  6747 
       
  6748     calendar->hide();
       
  6749     qApp->processEvents();
       
  6750     QTest::qWait(30);
       
  6751 
       
  6752     { // Calendar explicitly hidden.
       
  6753     QImage testImage(calendarSize, QImage::Format_ARGB32);
       
  6754     calendar->render(&testImage);
       
  6755 #ifdef RENDER_DEBUG
       
  6756     testImage.save("explicitlyHiddenCalendar.png");
       
  6757 #endif
       
  6758     QCOMPARE(testImage, referenceImage);
       
  6759     }
       
  6760 
       
  6761     // Get navigation bar and explicitly hide it.
       
  6762     QWidget *navigationBar = qFindChild<QWidget *>(calendar, QLatin1String("qt_calendar_navigationbar"));
       
  6763     QVERIFY(navigationBar);
       
  6764     navigationBar->hide();
       
  6765 
       
  6766     { // Check that the navigation bar isn't drawn when rendering the entire calendar.
       
  6767     QImage testImage(calendarSize, QImage::Format_ARGB32);
       
  6768     calendar->render(&testImage);
       
  6769 #ifdef RENDER_DEBUG
       
  6770     testImage.save("calendarWithoutNavigationBar.png");
       
  6771 #endif
       
  6772     QVERIFY(testImage != referenceImage);
       
  6773     }
       
  6774 
       
  6775     { // Make sure the navigation bar renders correctly even though it's hidden.
       
  6776     QImage testImage(navigationBar->size(), QImage::Format_ARGB32);
       
  6777     navigationBar->render(&testImage);
       
  6778 #ifdef RENDER_DEBUG
       
  6779     testImage.save("explicitlyHiddenNavigationBar.png");
       
  6780 #endif
       
  6781     QCOMPARE(testImage, referenceImage.copy(navigationBar->rect()));
       
  6782     }
       
  6783 
       
  6784     // Get next month button.
       
  6785     QWidget *nextMonthButton = qFindChild<QWidget *>(navigationBar, QLatin1String("qt_calendar_nextmonth"));
       
  6786     QVERIFY(nextMonthButton);
       
  6787 
       
  6788     { // Render next month button.
       
  6789     // Fill test image with correct background color.
       
  6790     QImage testImage(nextMonthButton->size(), QImage::Format_ARGB32);
       
  6791     navigationBar->render(&testImage, QPoint(), QRegion(), QWidget::RenderFlags());
       
  6792 #ifdef RENDER_DEBUG
       
  6793     testImage.save("nextMonthButtonBackground.png");
       
  6794 #endif
       
  6795 
       
  6796     // Set the button's background color to Qt::transparent; otherwise it will fill the
       
  6797     // background with QPalette::Window.
       
  6798     const QPalette originalPalette = nextMonthButton->palette();
       
  6799     QPalette palette = originalPalette;
       
  6800     palette.setColor(QPalette::Window, Qt::transparent);
       
  6801     nextMonthButton->setPalette(palette);
       
  6802 
       
  6803     // Render the button on top of the background.
       
  6804     nextMonthButton->render(&testImage);
       
  6805 #ifdef RENDER_DEBUG
       
  6806     testImage.save("nextMonthButton.png");
       
  6807 #endif
       
  6808     const QRect buttonRect(nextMonthButton->mapTo(calendar, QPoint()), nextMonthButton->size());
       
  6809     QCOMPARE(testImage, referenceImage.copy(buttonRect));
       
  6810 
       
  6811     // Restore palette.
       
  6812     nextMonthButton->setPalette(originalPalette);
       
  6813     }
       
  6814 
       
  6815     // Navigation bar isn't explicitly hidden anymore.
       
  6816     navigationBar->show();
       
  6817     qApp->processEvents();
       
  6818     QTest::qWait(30);
       
  6819     QVERIFY(!calendar->isVisible());
       
  6820 
       
  6821     // Now, completely mess up the layout. This will trigger an update on the layout
       
  6822     // when the calendar is visible or shown, but it's not. QWidget::render must therefore
       
  6823     // make sure the layout is activated before rendering.
       
  6824     QVERIFY(!calendar->isVisible());
       
  6825     calendar->resize(calendarSizeResized);
       
  6826     qApp->processEvents();
       
  6827 
       
  6828     { // Make sure we get an image equal to the resized reference image.
       
  6829     QImage testImage(calendarSizeResized, QImage::Format_ARGB32);
       
  6830     calendar->render(&testImage);
       
  6831 #ifdef RENDER_DEBUG
       
  6832     testImage.save("calendarResized.png");
       
  6833 #endif
       
  6834     QCOMPARE(testImage, referenceImageResized);
       
  6835     }
       
  6836 
       
  6837     { // Make sure we lay out the widget correctly the first time it's rendered.
       
  6838     QCalendarWidget calendar;
       
  6839     const QSize calendarSize = calendar.sizeHint();
       
  6840 
       
  6841     QImage image(2 * calendarSize, QImage::Format_ARGB32);
       
  6842     image.fill(QColor(Qt::red).rgb());
       
  6843     calendar.render(&image);
       
  6844 
       
  6845     for (int i = calendarSize.height(); i < 2 * calendarSize.height(); ++i)
       
  6846         for (int j = calendarSize.width(); j < 2 * calendarSize.width(); ++j)
       
  6847             QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  6848     }
       
  6849 
       
  6850     { // Ensure that we don't call adjustSize() on invisible top-levels if render() is called
       
  6851       // right after widgets have been added/removed to/from its layout.
       
  6852     QWidget topLevel;
       
  6853     topLevel.setLayout(new QVBoxLayout);
       
  6854 
       
  6855     QWidget *widget = new QLineEdit;
       
  6856     topLevel.layout()->addWidget(widget);
       
  6857 
       
  6858     const QSize initialSize = topLevel.size();
       
  6859     QPixmap pixmap(topLevel.sizeHint());
       
  6860     topLevel.render(&pixmap); // triggers adjustSize()
       
  6861     const QSize finalSize = topLevel.size();
       
  6862     QVERIFY(finalSize != initialSize);
       
  6863 
       
  6864     topLevel.layout()->removeWidget(widget);
       
  6865     QCOMPARE(topLevel.size(), finalSize);
       
  6866     topLevel.render(&pixmap);
       
  6867     QCOMPARE(topLevel.size(), finalSize);
       
  6868 
       
  6869     topLevel.layout()->addWidget(widget);
       
  6870     QCOMPARE(topLevel.size(), finalSize);
       
  6871     topLevel.render(&pixmap);
       
  6872     QCOMPARE(topLevel.size(), finalSize);
       
  6873     }
       
  6874 }
       
  6875 
       
  6876 void tst_QWidget::renderWithPainter()
       
  6877 {
       
  6878     QWidget widget;
       
  6879     // prevent custom styles
       
  6880     widget.setStyle(new QWindowsStyle);
       
  6881     widget.show();
       
  6882     widget.resize(70, 50);
       
  6883     widget.setAutoFillBackground(true);
       
  6884     widget.setPalette(Qt::black);
       
  6885 
       
  6886     // Render the entire widget onto the image.
       
  6887     QImage image(QSize(70, 50), QImage::Format_ARGB32);
       
  6888     image.fill(QColor(Qt::red).rgb());
       
  6889     QPainter painter(&image);
       
  6890     widget.render(&painter);
       
  6891 
       
  6892     for (int i = 0; i < image.height(); ++i) {
       
  6893         for (int j = 0; j < image.width(); ++j)
       
  6894             QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
       
  6895     }
       
  6896 
       
  6897     // Translate painter (10, 10).
       
  6898     painter.save();
       
  6899     image.fill(QColor(Qt::red).rgb());
       
  6900     painter.translate(10, 10);
       
  6901     widget.render(&painter);
       
  6902     painter.restore();
       
  6903 
       
  6904     for (int i = 0; i < image.height(); ++i) {
       
  6905         for (int j = 0; j < image.width(); ++j) {
       
  6906             if (i < 10 || j < 10)
       
  6907                 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  6908             else
       
  6909                 QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
       
  6910         }
       
  6911     }
       
  6912 
       
  6913     // Pass target offset (10, 10) (the same as QPainter::translate).
       
  6914     image.fill(QColor(Qt::red).rgb());
       
  6915     widget.render(&painter, QPoint(10, 10));
       
  6916 
       
  6917     for (int i = 0; i < image.height(); ++i) {
       
  6918         for (int j = 0; j < image.width(); ++j) {
       
  6919             if (i < 10 || j < 10)
       
  6920                 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  6921             else
       
  6922                 QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
       
  6923         }
       
  6924     }
       
  6925 
       
  6926     // Translate (10, 10) and pass target offset (10, 10).
       
  6927     painter.save();
       
  6928     image.fill(QColor(Qt::red).rgb());
       
  6929     painter.translate(10, 10);
       
  6930     widget.render(&painter, QPoint(10, 10));
       
  6931     painter.restore();
       
  6932 
       
  6933     for (int i = 0; i < image.height(); ++i) {
       
  6934         for (int j = 0; j < image.width(); ++j) {
       
  6935             if (i < 20 || j < 20)
       
  6936                 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  6937             else
       
  6938                 QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
       
  6939         }
       
  6940     }
       
  6941 
       
  6942     // Rotate painter 90 degrees.
       
  6943     painter.save();
       
  6944     image.fill(QColor(Qt::red).rgb());
       
  6945     painter.rotate(90);
       
  6946     widget.render(&painter);
       
  6947     painter.restore();
       
  6948 
       
  6949     for (int i = 0; i < image.height(); ++i) {
       
  6950         for (int j = 0; j < image.width(); ++j)
       
  6951             QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  6952     }
       
  6953 
       
  6954     // Translate and rotate.
       
  6955     image.fill(QColor(Qt::red).rgb());
       
  6956     widget.resize(40, 10);
       
  6957     painter.translate(10, 10);
       
  6958     painter.rotate(90);
       
  6959     widget.render(&painter);
       
  6960 
       
  6961     for (int i = 0; i < image.height(); ++i) {
       
  6962         for (int j = 0; j < image.width(); ++j) {
       
  6963             if (i >= 10 && j >= 0 && j < 10)
       
  6964                 QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
       
  6965             else
       
  6966                 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  6967         }
       
  6968     }
       
  6969 
       
  6970     // Make sure QWidget::render does not modify the render hints set on the painter.
       
  6971     painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform
       
  6972                            | QPainter::NonCosmeticDefaultPen | QPainter::TextAntialiasing);
       
  6973     QPainter::RenderHints oldRenderHints = painter.renderHints();
       
  6974     widget.render(&painter);
       
  6975     QCOMPARE(painter.renderHints(), oldRenderHints);
       
  6976 }
       
  6977 
       
  6978 void tst_QWidget::render_task188133()
       
  6979 {
       
  6980     QMainWindow mainWindow;
       
  6981 #if defined(QT3_SUPPORT)
       
  6982     mainWindow.setCentralWidget(new Q3TextEdit);
       
  6983 #endif
       
  6984     // Make sure QWidget::render does not trigger QWidget::repaint/update
       
  6985     // and asserts for Qt::WA_WState_Created.
       
  6986     QPixmap pixmap = QPixmap::grabWidget(&mainWindow);
       
  6987 }
       
  6988 
       
  6989 void tst_QWidget::render_task211796()
       
  6990 {
       
  6991     class MyWidget : public QWidget
       
  6992     {
       
  6993         void resizeEvent(QResizeEvent *)
       
  6994         {
       
  6995             QPixmap pixmap(size());
       
  6996             render(&pixmap);
       
  6997         }
       
  6998     };
       
  6999 
       
  7000     { // Please don't die in a resize recursion.
       
  7001         MyWidget widget;
       
  7002         widget.resize(200, 200);
       
  7003         widget.show();
       
  7004     }
       
  7005 
       
  7006     { // Same check with a deeper hierarchy.
       
  7007         QWidget widget;
       
  7008         widget.show();
       
  7009         QWidget child(&widget);
       
  7010         MyWidget grandChild;
       
  7011         grandChild.setParent(&child);
       
  7012         grandChild.resize(100, 100);
       
  7013         child.show();
       
  7014     }
       
  7015 }
       
  7016 
       
  7017 void tst_QWidget::render_task217815()
       
  7018 {
       
  7019     // Make sure we don't change the size of the widget when calling
       
  7020     // render() and the widget has an explicit size set.
       
  7021     // This was a problem on Windows because we called createWinId(),
       
  7022     // which in turn enforced the size to be bigger than the smallest
       
  7023     // possible native window size (which is (115,something) on WinXP).
       
  7024     QWidget widget;
       
  7025     const QSize explicitSize(80, 20);
       
  7026     widget.resize(explicitSize);
       
  7027     QCOMPARE(widget.size(), explicitSize);
       
  7028 
       
  7029     QPixmap pixmap(explicitSize);
       
  7030     widget.render(&pixmap);
       
  7031 
       
  7032     QCOMPARE(widget.size(), explicitSize);
       
  7033 }
       
  7034 
       
  7035 void tst_QWidget::render_windowOpacity()
       
  7036 {
       
  7037 #ifdef Q_OS_WINCE
       
  7038     QSKIP("Window Opacity is not supported on Windows CE", SkipAll);
       
  7039 #endif
       
  7040 
       
  7041     const qreal opacity = 0.5;
       
  7042 
       
  7043     { // Check that the painter opacity effects the widget drawing.
       
  7044     QWidget topLevel;
       
  7045     QWidget child(&topLevel);
       
  7046     child.resize(50, 50);
       
  7047     child.setPalette(Qt::red);
       
  7048     child.setAutoFillBackground(true);
       
  7049 
       
  7050     QPixmap expected(child.size());
       
  7051 #ifdef Q_WS_X11
       
  7052     if (expected.depth() < 24) {
       
  7053         QSKIP("This test won't give correct results with dithered pixmaps", SkipAll);
       
  7054     }
       
  7055 #endif
       
  7056     expected.fill(Qt::green);
       
  7057     QPainter painter(&expected);
       
  7058     painter.setOpacity(opacity);
       
  7059     painter.fillRect(QRect(QPoint(0, 0), child.size()), Qt::red);
       
  7060     painter.end();
       
  7061 
       
  7062     QPixmap result(child.size());
       
  7063     result.fill(Qt::green);
       
  7064     painter.begin(&result);
       
  7065     painter.setOpacity(opacity);
       
  7066     child.render(&painter);
       
  7067     painter.end();
       
  7068     QCOMPARE(result, expected);
       
  7069     }
       
  7070 
       
  7071     { // Combine the opacity set on the painter with the widget opacity.
       
  7072     class MyWidget : public QWidget
       
  7073     {
       
  7074     public:
       
  7075         void paintEvent(QPaintEvent *)
       
  7076         {
       
  7077             QPainter painter(this);
       
  7078             painter.setOpacity(opacity);
       
  7079             QCOMPARE(painter.opacity(), opacity);
       
  7080             painter.fillRect(rect(), Qt::red);
       
  7081         }
       
  7082         qreal opacity;
       
  7083     };
       
  7084 
       
  7085     MyWidget widget;
       
  7086     widget.resize(50, 50);
       
  7087     widget.opacity = opacity;
       
  7088     widget.setPalette(Qt::blue);
       
  7089     widget.setAutoFillBackground(true);
       
  7090 
       
  7091     QPixmap expected(widget.size());
       
  7092     expected.fill(Qt::green);
       
  7093     QPainter painter(&expected);
       
  7094     painter.setOpacity(opacity);
       
  7095     QPixmap pixmap(widget.size());
       
  7096     pixmap.fill(Qt::blue);
       
  7097     QPainter pixmapPainter(&pixmap);
       
  7098     pixmapPainter.setOpacity(opacity);
       
  7099     pixmapPainter.fillRect(QRect(QPoint(), widget.size()), Qt::red);
       
  7100     painter.drawPixmap(QPoint(), pixmap);
       
  7101     painter.end();
       
  7102 
       
  7103     QPixmap result(widget.size());
       
  7104     result.fill(Qt::green);
       
  7105     painter.begin(&result);
       
  7106     painter.setOpacity(opacity);
       
  7107     widget.render(&painter);
       
  7108     painter.end();
       
  7109     QCOMPARE(result, expected);
       
  7110     }
       
  7111 }
       
  7112 
       
  7113 void tst_QWidget::render_systemClip()
       
  7114 {
       
  7115     QWidget widget;
       
  7116     widget.setPalette(Qt::blue);
       
  7117     widget.resize(100, 100);
       
  7118 
       
  7119     QImage image(widget.size(), QImage::Format_RGB32);
       
  7120     image.fill(QColor(Qt::red).rgb());
       
  7121 
       
  7122     QPaintEngine *paintEngine = image.paintEngine();
       
  7123     QVERIFY(paintEngine);
       
  7124     paintEngine->setSystemClip(QRegion(0, 0, 50, 50));
       
  7125 
       
  7126     QPainter painter(&image);
       
  7127     // Make sure we're using the same paint engine and has the right clip set.
       
  7128     QCOMPARE(painter.paintEngine(), paintEngine);
       
  7129     QCOMPARE(paintEngine->systemClip(), QRegion(0, 0, 50, 50));
       
  7130 
       
  7131     // Translate painter outside system clip.
       
  7132     painter.translate(50, 0);
       
  7133     widget.render(&painter);
       
  7134 
       
  7135 #ifdef RENDER_DEBUG
       
  7136     image.save("outside_systemclip.png");
       
  7137 #endif
       
  7138 
       
  7139     // All pixels should be red.
       
  7140     for (int i = 0; i < image.height(); ++i) {
       
  7141         for (int j = 0; j < image.width(); ++j)
       
  7142             QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  7143     }
       
  7144 
       
  7145     // Restore painter and refill image with red.
       
  7146     image.fill(QColor(Qt::red).rgb());
       
  7147     painter.translate(-50, 0);
       
  7148 
       
  7149     // Set transform on the painter.
       
  7150     QTransform transform;
       
  7151     transform.shear(0, 1);
       
  7152     painter.setTransform(transform);
       
  7153     widget.render(&painter);
       
  7154 
       
  7155 #ifdef RENDER_DEBUG
       
  7156     image.save("blue_triangle.png");
       
  7157 #endif
       
  7158 
       
  7159     // We should now have a blue triangle starting at scan line 1, and the rest should be red.
       
  7160     // rrrrrrrrrr
       
  7161     // brrrrrrrrr
       
  7162     // bbrrrrrrrr
       
  7163     // bbbrrrrrrr
       
  7164     // bbbbrrrrrr
       
  7165     // rrrrrrrrrr
       
  7166     // ...
       
  7167 
       
  7168 #ifndef Q_WS_MAC
       
  7169     for (int i = 0; i < image.height(); ++i) {
       
  7170         for (int j = 0; j < image.width(); ++j) {
       
  7171             if (i < 50 && j < i)
       
  7172                 QCOMPARE(image.pixel(j, i), QColor(Qt::blue).rgb());
       
  7173             else
       
  7174                 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  7175         }
       
  7176     }
       
  7177 #else
       
  7178     // We don't paint directly on the image on the Mac, so we cannot do the pixel comparison
       
  7179     // as above due to QPainter::SmoothPixmapTransform. We therefore need to generate an
       
  7180     // expected image by first painting on a pixmap, and then draw the pixmap onto
       
  7181     // the image using QPainter::SmoothPixmapTransform. Then we can compare pixels :)
       
  7182     // The check is basically the same, except that it takes the smoothening into account.
       
  7183     QPixmap pixmap(50, 50);
       
  7184     const QRegion sysClip(0, 0, 50, 50);
       
  7185     widget.render(&pixmap, QPoint(), sysClip);
       
  7186 
       
  7187     QImage expectedImage(widget.size(), QImage::Format_RGB32);
       
  7188     expectedImage.fill(QColor(Qt::red).rgb());
       
  7189     expectedImage.paintEngine()->setSystemClip(sysClip);
       
  7190 
       
  7191     QPainter expectedImagePainter(&expectedImage);
       
  7192     expectedImagePainter.setTransform(QTransform().shear(0, 1));
       
  7193     // NB! This is the important part (SmoothPixmapTransform).
       
  7194     expectedImagePainter.setRenderHints(QPainter::SmoothPixmapTransform);
       
  7195     expectedImagePainter.drawPixmap(QPoint(0, 0), pixmap);
       
  7196     expectedImagePainter.end();
       
  7197 
       
  7198     QCOMPARE(image, expectedImage);
       
  7199 #endif
       
  7200 }
       
  7201 
       
  7202 void tst_QWidget::render_systemClip2_data()
       
  7203 {
       
  7204     QTest::addColumn<bool>("autoFillBackground");
       
  7205     QTest::addColumn<bool>("usePaintEvent");
       
  7206     QTest::addColumn<QColor>("expectedColor");
       
  7207 
       
  7208     QTest::newRow("Only auto-fill background") << true << false << QColor(Qt::blue);
       
  7209     QTest::newRow("Only draw in paintEvent") << false << true << QColor(Qt::green);
       
  7210     QTest::newRow("Auto-fill background and draw in paintEvent") << true << true << QColor(Qt::green);
       
  7211 }
       
  7212 
       
  7213 void tst_QWidget::render_systemClip2()
       
  7214 {
       
  7215     QFETCH(bool, autoFillBackground);
       
  7216     QFETCH(bool, usePaintEvent);
       
  7217     QFETCH(QColor, expectedColor);
       
  7218 
       
  7219     Q_ASSERT_X(expectedColor != QColor(Qt::red), Q_FUNC_INFO,
       
  7220                "Qt::red is the reference color for the image, pick another color");
       
  7221 
       
  7222     class MyWidget : public QWidget
       
  7223     {
       
  7224     public:
       
  7225         bool usePaintEvent;
       
  7226         void paintEvent(QPaintEvent *)
       
  7227         {
       
  7228             if (usePaintEvent)
       
  7229                 QPainter(this).fillRect(rect(), Qt::green);
       
  7230         }
       
  7231     };
       
  7232 
       
  7233     MyWidget widget;
       
  7234     widget.usePaintEvent = usePaintEvent;
       
  7235     widget.setPalette(Qt::blue);
       
  7236     // NB! widget.setAutoFillBackground(autoFillBackground) won't do the
       
  7237     // trick here since the widget is a top-level. The background is filled
       
  7238     // regardless, unless Qt::WA_OpaquePaintEvent or Qt::WA_NoSystemBackground
       
  7239     // is set. We therefore use the opaque attribute to turn off auto-fill.
       
  7240     if (!autoFillBackground)
       
  7241         widget.setAttribute(Qt::WA_OpaquePaintEvent);
       
  7242     widget.resize(100, 100);
       
  7243 
       
  7244     QImage image(widget.size(), QImage::Format_RGB32);
       
  7245     image.fill(QColor(Qt::red).rgb());
       
  7246 
       
  7247     QPaintEngine *paintEngine = image.paintEngine();
       
  7248     QVERIFY(paintEngine);
       
  7249 
       
  7250     QRegion systemClip(QRegion(50, 0, 50, 10));
       
  7251     systemClip += QRegion(90, 10, 10, 40);
       
  7252     paintEngine->setSystemClip(systemClip);
       
  7253 
       
  7254     // Render entire widget directly onto device.
       
  7255     widget.render(&image);
       
  7256 
       
  7257 #ifdef RENDER_DEBUG
       
  7258     image.save("systemclip_with_device.png");
       
  7259 #endif
       
  7260     // All pixels within the system clip should now be
       
  7261     // the expectedColor, and the rest should be red.
       
  7262     for (int i = 0; i < image.height(); ++i) {
       
  7263         for (int j = 0; j < image.width(); ++j) {
       
  7264             if (systemClip.contains(QPoint(j, i)))
       
  7265                 QCOMPARE(image.pixel(j, i), expectedColor.rgb());
       
  7266             else
       
  7267                 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  7268         }
       
  7269     }
       
  7270 
       
  7271     // Refill image with red.
       
  7272     image.fill(QColor(Qt::red).rgb());
       
  7273     paintEngine->setSystemClip(systemClip);
       
  7274 
       
  7275     // Do the same with an untransformed painter.
       
  7276     QPainter painter(&image);
       
  7277     //Make sure we're using the same paint engine and has the right clip set.
       
  7278     QCOMPARE(painter.paintEngine(), paintEngine);
       
  7279     QCOMPARE(paintEngine->systemClip(), systemClip);
       
  7280 
       
  7281     widget.render(&painter);
       
  7282 
       
  7283 #ifdef RENDER_DEBUG
       
  7284     image.save("systemclip_with_untransformed_painter.png");
       
  7285 #endif
       
  7286     // All pixels within the system clip should now be
       
  7287     // the expectedColor, and the rest should be red.
       
  7288     for (int i = 0; i < image.height(); ++i) {
       
  7289         for (int j = 0; j < image.width(); ++j) {
       
  7290             if (systemClip.contains(QPoint(j, i)))
       
  7291                 QCOMPARE(image.pixel(j, i), expectedColor.rgb());
       
  7292             else
       
  7293                 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  7294         }
       
  7295     }
       
  7296 }
       
  7297 
       
  7298 void tst_QWidget::render_systemClip3_data()
       
  7299 {
       
  7300     QTest::addColumn<QSize>("size");
       
  7301     QTest::addColumn<bool>("useSystemClip");
       
  7302 
       
  7303     // Reference: http://en.wikipedia.org/wiki/Flag_of_Norway
       
  7304     QTest::newRow("Norwegian Civil Flag") << QSize(220, 160) << false;
       
  7305     QTest::newRow("Norwegian War Flag") << QSize(270, 160) << true;
       
  7306 }
       
  7307 
       
  7308 // This test ensures that the current engine clip (systemClip + painter clip)
       
  7309 // is preserved after QPainter::setClipRegion(..., Qt::ReplaceClip);
       
  7310 void tst_QWidget::render_systemClip3()
       
  7311 {
       
  7312     QFETCH(QSize, size);
       
  7313     QFETCH(bool, useSystemClip);
       
  7314 
       
  7315     // Calculate the inner/outer cross of the flag.
       
  7316     QRegion outerCross(0, 0, size.width(), size.height());
       
  7317     outerCross -= QRect(0, 0, 60, 60);
       
  7318     outerCross -= QRect(100, 0, size.width() - 100, 60);
       
  7319     outerCross -= QRect(0, 100, 60, 60);
       
  7320     outerCross -= QRect(100, 100, size.width() - 100, 60);
       
  7321 
       
  7322     QRegion innerCross(0, 0, size.width(), size.height());
       
  7323     innerCross -= QRect(0, 0, 70, 70);
       
  7324     innerCross -= QRect(90, 0, size.width() - 90, 70);
       
  7325     innerCross -= QRect(0, 90, 70, 70);
       
  7326     innerCross -= QRect(90, 90, size.width() - 90, 70);
       
  7327 
       
  7328     const QRegion redArea(QRegion(0, 0, size.width(), size.height()) - outerCross);
       
  7329     const QRegion whiteArea(outerCross - innerCross);
       
  7330     const QRegion blueArea(innerCross);
       
  7331     QRegion systemClip;
       
  7332 
       
  7333     // Okay, here's the image that should look like a Norwegian civil/war flag in the end.
       
  7334     QImage flag(size, QImage::Format_ARGB32);
       
  7335     flag.fill(QColor(Qt::transparent).rgba());
       
  7336 
       
  7337     if (useSystemClip) {
       
  7338         QPainterPath warClip(QPoint(size.width(), 0));
       
  7339         warClip.lineTo(size.width() - 110, 60);
       
  7340         warClip.lineTo(size.width(), 80);
       
  7341         warClip.lineTo(size.width() - 110, 100);
       
  7342         warClip.lineTo(size.width(), 160);
       
  7343         warClip.closeSubpath();
       
  7344         systemClip = QRegion(0, 0, size.width(), size.height()) - QRegion(warClip.toFillPolygon().toPolygon());
       
  7345         flag.paintEngine()->setSystemClip(systemClip);
       
  7346     }
       
  7347 
       
  7348     QPainter painter(&flag);
       
  7349     painter.fillRect(QRect(QPoint(), size), Qt::red); // Fill image background with red.
       
  7350     painter.setClipRegion(outerCross); // Limit widget painting to inside the outer cross.
       
  7351 
       
  7352     // Here's the widget that's supposed to draw the inner/outer cross of the flag.
       
  7353     // The outer cross (white) should be drawn when the background is auto-filled, and
       
  7354     // the inner cross (blue) should be drawn in the paintEvent.
       
  7355     class MyWidget : public QWidget
       
  7356     { public:
       
  7357         void paintEvent(QPaintEvent *)
       
  7358         {
       
  7359             QPainter painter(this);
       
  7360             // Be evil and try to paint outside the outer cross. This should not be
       
  7361             // possible since the shared painter is clipped to the outer cross.
       
  7362             painter.setClipRect(0, 0, 60, 60, Qt::ReplaceClip);
       
  7363             painter.fillRect(rect(), Qt::green);
       
  7364             painter.setClipRegion(clip, Qt::ReplaceClip);
       
  7365             painter.fillRect(rect(), Qt::blue);
       
  7366         }
       
  7367         QRegion clip;
       
  7368     };
       
  7369 
       
  7370     MyWidget widget;
       
  7371     widget.clip = innerCross;
       
  7372     widget.setFixedSize(size);
       
  7373     widget.setPalette(Qt::white);
       
  7374     widget.setAutoFillBackground(true);
       
  7375     widget.render(&painter);
       
  7376 
       
  7377 #ifdef RENDER_DEBUG
       
  7378     flag.save("flag.png");
       
  7379 #endif
       
  7380 
       
  7381     // Let's make sure we got a Norwegian flag.
       
  7382     for (int i = 0; i < flag.height(); ++i) {
       
  7383         for (int j = 0; j < flag.width(); ++j) {
       
  7384             const QPoint pixel(j, i);
       
  7385             const QRgb pixelValue = flag.pixel(pixel);
       
  7386             if (useSystemClip && !systemClip.contains(pixel))
       
  7387                 QCOMPARE(pixelValue, QColor(Qt::transparent).rgba());
       
  7388             else if (redArea.contains(pixel))
       
  7389                 QCOMPARE(pixelValue, QColor(Qt::red).rgba());
       
  7390             else if (whiteArea.contains(pixel))
       
  7391                 QCOMPARE(pixelValue, QColor(Qt::white).rgba());
       
  7392             else
       
  7393                 QCOMPARE(pixelValue, QColor(Qt::blue).rgba());
       
  7394         }
       
  7395     }
       
  7396 }
       
  7397 
       
  7398 void tst_QWidget::render_task252837()
       
  7399 {
       
  7400     QWidget widget;
       
  7401     widget.resize(200, 200);
       
  7402 
       
  7403     QPixmap pixmap(widget.size());
       
  7404     QPainter painter(&pixmap);
       
  7405     // Please do not crash.
       
  7406     widget.render(&painter);
       
  7407 }
       
  7408 
       
  7409 void tst_QWidget::render_worldTransform()
       
  7410 {
       
  7411     class MyWidget : public QWidget
       
  7412     { public:
       
  7413         void paintEvent(QPaintEvent *)
       
  7414         {
       
  7415             QPainter painter(this);
       
  7416             // Make sure world transform is identity.
       
  7417             QCOMPARE(painter.worldTransform(), QTransform());
       
  7418 
       
  7419             // Make sure device transform is correct.
       
  7420             const QPoint widgetOffset = geometry().topLeft();
       
  7421             QTransform expectedDeviceTransform = QTransform::fromTranslate(105, 5);
       
  7422             expectedDeviceTransform.rotate(90);
       
  7423             expectedDeviceTransform.translate(widgetOffset.x(), widgetOffset.y());
       
  7424             QCOMPARE(painter.deviceTransform(), expectedDeviceTransform);
       
  7425 
       
  7426             // Set new world transform.
       
  7427             QTransform newWorldTransform = QTransform::fromTranslate(10, 10);
       
  7428             newWorldTransform.rotate(90);
       
  7429             painter.setWorldTransform(newWorldTransform);
       
  7430             QCOMPARE(painter.worldTransform(), newWorldTransform);
       
  7431 
       
  7432             // Again, check device transform.
       
  7433             expectedDeviceTransform.translate(10, 10);
       
  7434             expectedDeviceTransform.rotate(90);
       
  7435             QCOMPARE(painter.deviceTransform(), expectedDeviceTransform);
       
  7436 
       
  7437             painter.fillRect(QRect(0, 0, 20, 10), Qt::green);
       
  7438         }
       
  7439     };
       
  7440 
       
  7441     MyWidget widget;
       
  7442     widget.setFixedSize(100, 100);
       
  7443     widget.setPalette(Qt::red);
       
  7444     widget.setAutoFillBackground(true);
       
  7445 
       
  7446     MyWidget child;
       
  7447     child.setParent(&widget);
       
  7448     child.move(50, 50);
       
  7449     child.setFixedSize(50, 50);
       
  7450     child.setPalette(Qt::blue);
       
  7451     child.setAutoFillBackground(true);
       
  7452 
       
  7453     QImage image(QSize(110, 110), QImage::Format_RGB32);
       
  7454     image.fill(QColor(Qt::black).rgb());
       
  7455 
       
  7456     QPainter painter(&image);
       
  7457     painter.translate(105, 5);
       
  7458     painter.rotate(90);
       
  7459 
       
  7460     const QTransform worldTransform = painter.worldTransform();
       
  7461     const QTransform deviceTransform = painter.deviceTransform();
       
  7462 
       
  7463     // Render widgets onto image.
       
  7464     widget.render(&painter);
       
  7465 #ifdef RENDER_DEBUG
       
  7466     image.save("render_worldTransform_image.png");
       
  7467 #endif
       
  7468 
       
  7469     // Ensure the transforms are unchanged after render.
       
  7470     QCOMPARE(painter.worldTransform(), painter.worldTransform());
       
  7471     QCOMPARE(painter.deviceTransform(), painter.deviceTransform());
       
  7472     painter.end();
       
  7473 
       
  7474     // Paint expected image.
       
  7475     QImage expected(QSize(110, 110), QImage::Format_RGB32);
       
  7476     expected.fill(QColor(Qt::black).rgb());
       
  7477 
       
  7478     QPainter expectedPainter(&expected);
       
  7479     expectedPainter.translate(105, 5);
       
  7480     expectedPainter.rotate(90);
       
  7481     expectedPainter.save();
       
  7482     expectedPainter.fillRect(widget.rect(),Qt::red);
       
  7483     expectedPainter.translate(10, 10);
       
  7484     expectedPainter.rotate(90);
       
  7485     expectedPainter.fillRect(QRect(0, 0, 20, 10), Qt::green);
       
  7486     expectedPainter.restore();
       
  7487     expectedPainter.translate(50, 50);
       
  7488     expectedPainter.fillRect(child.rect(),Qt::blue);
       
  7489     expectedPainter.translate(10, 10);
       
  7490     expectedPainter.rotate(90);
       
  7491     expectedPainter.fillRect(QRect(0, 0, 20, 10), Qt::green);
       
  7492     expectedPainter.end();
       
  7493 
       
  7494 #ifdef RENDER_DEBUG
       
  7495     expected.save("render_worldTransform_expected.png");
       
  7496 #endif
       
  7497 
       
  7498     QCOMPARE(image, expected);
       
  7499 }
       
  7500 
       
  7501 void tst_QWidget::setContentsMargins()
       
  7502 {
       
  7503     QLabel label("why does it always rain on me?");
       
  7504     QSize oldSize = label.sizeHint();
       
  7505     label.setFrameStyle(QFrame::Sunken | QFrame::Box);
       
  7506     QSize newSize = label.sizeHint();
       
  7507     QVERIFY(oldSize != newSize);
       
  7508 
       
  7509     QLabel label2("why does it always rain on me?");
       
  7510     label2.show();
       
  7511     label2.setFrameStyle(QFrame::Sunken | QFrame::Box);
       
  7512     QCOMPARE(newSize, label2.sizeHint());
       
  7513 
       
  7514     QLabel label3("why does it always rain on me?");
       
  7515     label3.setFrameStyle(QFrame::Sunken | QFrame::Box);
       
  7516     QCOMPARE(newSize, label3.sizeHint());
       
  7517 }
       
  7518 
       
  7519 void tst_QWidget::moveWindowInShowEvent_data()
       
  7520 {
       
  7521     QTest::addColumn<QPoint>("initial");
       
  7522     QTest::addColumn<QPoint>("position");
       
  7523 
       
  7524     QPoint p = QApplication::desktop()->availableGeometry().topLeft();
       
  7525 
       
  7526     QTest::newRow("1") << p << (p + QPoint(10, 10));
       
  7527     QTest::newRow("2") << (p + QPoint(10,10)) << p;
       
  7528 }
       
  7529 
       
  7530 void tst_QWidget::moveWindowInShowEvent()
       
  7531 {
       
  7532 #ifdef Q_OS_IRIX
       
  7533     QSKIP("4DWM issues on IRIX makes this test fail", SkipAll);
       
  7534 #endif
       
  7535     QFETCH(QPoint, initial);
       
  7536     QFETCH(QPoint, position);
       
  7537 
       
  7538     class MoveWindowInShowEventWidget : public QWidget
       
  7539     {
       
  7540     public:
       
  7541         QPoint position;
       
  7542         void showEvent(QShowEvent *)
       
  7543         {
       
  7544             move(position);
       
  7545         }
       
  7546     };
       
  7547 
       
  7548     MoveWindowInShowEventWidget widget;
       
  7549     widget.resize(QSize(qApp->desktop()->availableGeometry().size() / 3).expandedTo(QSize(1, 1)));
       
  7550     // move to this position in showEvent()
       
  7551     widget.position = position;
       
  7552 
       
  7553     // put the widget in it's starting position
       
  7554     widget.move(initial);
       
  7555     QCOMPARE(widget.pos(), initial);
       
  7556 
       
  7557     // show it
       
  7558     widget.show();
       
  7559     #ifdef Q_WS_X11
       
  7560     qt_x11_wait_for_window_manager(&widget);
       
  7561     #endif
       
  7562     QTest::qWait(100);
       
  7563     // it should have moved
       
  7564     QCOMPARE(widget.pos(), position);
       
  7565 }
       
  7566 
       
  7567 void tst_QWidget::repaintWhenChildDeleted()
       
  7568 {
       
  7569 #ifdef Q_WS_WIN
       
  7570     if (QSysInfo::WindowsVersion & QSysInfo::WV_VISTA) {
       
  7571         QTest::qWait(1000);
       
  7572     }
       
  7573 #endif
       
  7574     ColorWidget w(0, Qt::red);
       
  7575 #if !defined(Q_OS_WINCE) && !defined(Q_WS_S60)
       
  7576     QPoint startPoint = QApplication::desktop()->availableGeometry(&w).topLeft();
       
  7577     startPoint.rx() += 50;
       
  7578     startPoint.ry() += 50;
       
  7579     w.setGeometry(QRect(startPoint, QSize(100, 100)));
       
  7580 #else
       
  7581     w.setGeometry(60, 60, 110, 110);
       
  7582 #endif
       
  7583     w.show();
       
  7584     QTest::qWaitForWindowShown(&w);
       
  7585     QTest::qWait(10);
       
  7586     QTRY_COMPARE(w.r, QRegion(w.rect()));
       
  7587     w.r = QRegion();
       
  7588 
       
  7589     {
       
  7590         const QPoint tlwOffset = w.geometry().topLeft();
       
  7591         ColorWidget child(&w, Qt::blue);
       
  7592         child.setGeometry(10, 10, 10, 10);
       
  7593         child.show();
       
  7594         QTest::qWait(10);
       
  7595         QTRY_COMPARE(child.r, QRegion(child.rect()));
       
  7596         w.r = QRegion();
       
  7597     }
       
  7598 
       
  7599     QTest::qWait(10);
       
  7600     QTRY_COMPARE(w.r, QRegion(10, 10, 10, 10));
       
  7601 }
       
  7602 
       
  7603 // task 175114
       
  7604 void tst_QWidget::hideOpaqueChildWhileHidden()
       
  7605 {
       
  7606     ColorWidget w(0, Qt::red);
       
  7607 #if !defined(Q_OS_WINCE) && !defined(Q_WS_S60)
       
  7608     QPoint startPoint = QApplication::desktop()->availableGeometry(&w).topLeft();
       
  7609     startPoint.rx() += 50;
       
  7610     startPoint.ry() += 50;
       
  7611     w.setGeometry(QRect(startPoint, QSize(100, 100)));
       
  7612 #else
       
  7613     w.setGeometry(60, 60, 110, 110);
       
  7614 #endif
       
  7615 
       
  7616     ColorWidget child(&w, Qt::blue);
       
  7617     child.setGeometry(10, 10, 80, 80);
       
  7618 
       
  7619     ColorWidget child2(&child, Qt::white);
       
  7620     child2.setGeometry(10, 10, 60, 60);
       
  7621 
       
  7622     w.show();
       
  7623     QTest::qWaitForWindowShown(&w);
       
  7624     QTest::qWait(10);
       
  7625     QTRY_COMPARE(child2.r, QRegion(child2.rect()));
       
  7626     child.r = QRegion();
       
  7627     child2.r = QRegion();
       
  7628     w.r = QRegion();
       
  7629 
       
  7630     child.hide();
       
  7631     child2.hide();
       
  7632     QTest::qWait(100);
       
  7633 
       
  7634     QCOMPARE(w.r, QRegion(child.geometry()));
       
  7635 
       
  7636     child.show();
       
  7637     QTest::qWait(100);
       
  7638     QCOMPARE(child.r, QRegion(child.rect()));
       
  7639     QCOMPARE(child2.r, QRegion());
       
  7640 }
       
  7641 
       
  7642 void tst_QWidget::updateWhileMinimized()
       
  7643 {
       
  7644 #if defined(Q_OS_WINCE) || defined(Q_WS_QWS)
       
  7645    QSKIP("This test doesn't make sense without support for showMinimized()", SkipAll);
       
  7646 #endif
       
  7647 
       
  7648     UpdateWidget widget;
       
  7649    // Filter out activation change and focus events to avoid update() calls in QWidget.
       
  7650     widget.updateOnActivationChangeAndFocusIn = false;
       
  7651     widget.reset();
       
  7652     widget.show();
       
  7653     QTest::qWaitForWindowShown(&widget);
       
  7654     QApplication::processEvents();
       
  7655     QTRY_VERIFY(widget.numPaintEvents > 0);
       
  7656     QTest::qWait(150);
       
  7657 
       
  7658     // Minimize window.
       
  7659     widget.showMinimized();
       
  7660     QTest::qWait(110);
       
  7661 
       
  7662     widget.reset();
       
  7663 
       
  7664     // The widget is not visible on the screen (but isVisible() still returns true).
       
  7665     // Make sure update requests are discarded until the widget is shown again.
       
  7666     widget.update(0, 0, 50, 50);
       
  7667     QTest::qWait(10);
       
  7668     QCOMPARE(widget.numPaintEvents, 0);
       
  7669 
       
  7670     // Restore window.
       
  7671     widget.showNormal();
       
  7672     QTest::qWait(30);
       
  7673     QTRY_COMPARE(widget.numPaintEvents, 1);
       
  7674     QCOMPARE(widget.paintedRegion, QRegion(0, 0, 50, 50));
       
  7675 }
       
  7676 
       
  7677 #if defined(Q_WS_WIN) || defined(Q_WS_X11)
       
  7678 class PaintOnScreenWidget: public QWidget
       
  7679 {
       
  7680 public:
       
  7681     PaintOnScreenWidget(QWidget *parent = 0, Qt::WindowFlags f = 0)
       
  7682         :QWidget(parent, f)
       
  7683     {
       
  7684     }
       
  7685 #if defined(Q_WS_WIN)
       
  7686     // This is the only way to enable PaintOnScreen on Windows.
       
  7687     QPaintEngine * paintEngine () const {return 0;}
       
  7688 #endif
       
  7689 };
       
  7690 
       
  7691 void tst_QWidget::alienWidgets()
       
  7692 {
       
  7693     qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
       
  7694     QWidget parent;
       
  7695     QWidget child(&parent);
       
  7696     QWidget grandChild(&child);
       
  7697     QWidget greatGrandChild(&grandChild);
       
  7698     parent.show();
       
  7699 
       
  7700 #ifdef Q_WS_X11
       
  7701     qt_x11_wait_for_window_manager(&parent);
       
  7702 #endif
       
  7703 
       
  7704     // Verify that the WA_WState_Created attribute is set
       
  7705     // and the top-level is the only native window.
       
  7706     QVERIFY(parent.testAttribute(Qt::WA_WState_Created));
       
  7707     QVERIFY(parent.internalWinId());
       
  7708 
       
  7709     QVERIFY(child.testAttribute(Qt::WA_WState_Created));
       
  7710     QVERIFY(!child.internalWinId());
       
  7711 
       
  7712     QVERIFY(grandChild.testAttribute(Qt::WA_WState_Created));
       
  7713     QVERIFY(!grandChild.internalWinId());
       
  7714 
       
  7715     QVERIFY(greatGrandChild.testAttribute(Qt::WA_WState_Created));
       
  7716     QVERIFY(!greatGrandChild.internalWinId());
       
  7717 
       
  7718     // Enforce native windows all the way up in the parent hierarchy
       
  7719     // if not WA_DontCreateNativeAncestors is set.
       
  7720     grandChild.setAttribute(Qt::WA_DontCreateNativeAncestors);
       
  7721     greatGrandChild.setAttribute(Qt::WA_NativeWindow);
       
  7722     QVERIFY(greatGrandChild.internalWinId());
       
  7723     QVERIFY(grandChild.internalWinId());
       
  7724     QVERIFY(!child.internalWinId());
       
  7725 
       
  7726     {
       
  7727         // Ensure that hide() on an ancestor of a widget with
       
  7728         // Qt::WA_DontCreateNativeAncestors still gets unmapped
       
  7729         QWidget window;
       
  7730         QWidget widget(&window);
       
  7731         QWidget child(&widget);
       
  7732         child.setAttribute(Qt::WA_NativeWindow);
       
  7733         child.setAttribute(Qt::WA_DontCreateNativeAncestors);
       
  7734         window.show();
       
  7735         QVERIFY(child.testAttribute(Qt::WA_Mapped));
       
  7736         widget.hide();
       
  7737         QVERIFY(!child.testAttribute(Qt::WA_Mapped));
       
  7738     }
       
  7739 
       
  7740     // Enforce a native window when calling QWidget::winId.
       
  7741     QVERIFY(child.winId());
       
  7742     QVERIFY(child.internalWinId());
       
  7743 
       
  7744     // Check that paint on screen widgets (incl. children) are native.
       
  7745     PaintOnScreenWidget paintOnScreen(&parent);
       
  7746     QWidget paintOnScreenChild(&paintOnScreen);
       
  7747     paintOnScreen.show();
       
  7748     QVERIFY(paintOnScreen.testAttribute(Qt::WA_WState_Created));
       
  7749     QVERIFY(!paintOnScreen.testAttribute(Qt::WA_NativeWindow));
       
  7750     QVERIFY(!paintOnScreen.internalWinId());
       
  7751     QVERIFY(!paintOnScreenChild.testAttribute(Qt::WA_NativeWindow));
       
  7752     QVERIFY(!paintOnScreenChild.internalWinId());
       
  7753 
       
  7754     paintOnScreen.setAttribute(Qt::WA_PaintOnScreen);
       
  7755     QVERIFY(paintOnScreen.testAttribute(Qt::WA_NativeWindow));
       
  7756     QVERIFY(paintOnScreen.internalWinId());
       
  7757     QVERIFY(paintOnScreenChild.testAttribute(Qt::WA_NativeWindow));
       
  7758     QVERIFY(paintOnScreenChild.internalWinId());
       
  7759 
       
  7760     // Check that widgets with the Qt::MSWindowsOwnDC attribute set
       
  7761     // are native.
       
  7762     QWidget msWindowsOwnDC(&parent, Qt::MSWindowsOwnDC);
       
  7763     msWindowsOwnDC.show();
       
  7764     QVERIFY(msWindowsOwnDC.testAttribute(Qt::WA_WState_Created));
       
  7765     QVERIFY(msWindowsOwnDC.testAttribute(Qt::WA_NativeWindow));
       
  7766     QVERIFY(msWindowsOwnDC.internalWinId());
       
  7767 
       
  7768     { // Enforce a native window when calling QWidget::handle() (on X11) or QWidget::getDC() (on Windows).
       
  7769         QWidget widget(&parent);
       
  7770         widget.show();
       
  7771         QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
       
  7772         QVERIFY(!widget.internalWinId());
       
  7773 #ifdef Q_WS_X11
       
  7774         widget.handle();
       
  7775 #else
       
  7776         widget.getDC();
       
  7777 #endif
       
  7778         QVERIFY(widget.internalWinId());
       
  7779     }
       
  7780 
       
  7781 #ifdef Q_WS_X11
       
  7782 #ifndef QT_NO_XRENDER
       
  7783     { // Enforce a native window when calling QWidget::x11PictureHandle().
       
  7784         QWidget widget(&parent);
       
  7785         widget.show();
       
  7786         QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
       
  7787         QVERIFY(!widget.internalWinId());
       
  7788         widget.x11PictureHandle();
       
  7789         QVERIFY(widget.internalWinId());
       
  7790     }
       
  7791 #endif
       
  7792 
       
  7793     { // Make sure we don't create native windows when setting Qt::WA_X11NetWmWindowType attributes
       
  7794       // on alien widgets (see task 194231).
       
  7795         QWidget dummy;
       
  7796         QVERIFY(dummy.winId());
       
  7797         QWidget widget(&dummy);
       
  7798         widget.setAttribute(Qt::WA_X11NetWmWindowTypeToolBar);
       
  7799         QVERIFY(!widget.internalWinId());
       
  7800     }
       
  7801 #endif
       
  7802 
       
  7803 
       
  7804     { // Make sure we create native ancestors when setting Qt::WA_PaintOnScreen before show().
       
  7805         QWidget topLevel;
       
  7806         QWidget child(&topLevel);
       
  7807         QWidget grandChild(&child);
       
  7808         PaintOnScreenWidget greatGrandChild(&grandChild);
       
  7809 
       
  7810         greatGrandChild.setAttribute(Qt::WA_PaintOnScreen);
       
  7811         QVERIFY(!child.internalWinId());
       
  7812         QVERIFY(!grandChild.internalWinId());
       
  7813         QVERIFY(!greatGrandChild.internalWinId());
       
  7814 
       
  7815         topLevel.show();
       
  7816         QVERIFY(child.internalWinId());
       
  7817         QVERIFY(grandChild.internalWinId());
       
  7818         QVERIFY(greatGrandChild.internalWinId());
       
  7819     }
       
  7820 
       
  7821     { // Ensure that widgets reparented into Qt::WA_PaintOnScreen widgets become native.
       
  7822         QWidget topLevel;
       
  7823         QWidget *widget = new PaintOnScreenWidget(&topLevel);
       
  7824         widget->setAttribute(Qt::WA_PaintOnScreen);
       
  7825         QWidget *child = new QWidget;
       
  7826         QWidget *dummy = new QWidget(child);
       
  7827         QWidget *grandChild = new QWidget(child);
       
  7828         QWidget *dummy2 = new QWidget(grandChild);
       
  7829 
       
  7830         child->setParent(widget);
       
  7831 
       
  7832         QVERIFY(!topLevel.internalWinId());
       
  7833         QVERIFY(!child->internalWinId());
       
  7834         QVERIFY(!dummy->internalWinId());
       
  7835         QVERIFY(!grandChild->internalWinId());
       
  7836         QVERIFY(!dummy2->internalWinId());
       
  7837 
       
  7838         topLevel.show();
       
  7839         QVERIFY(topLevel.internalWinId());
       
  7840         QVERIFY(widget->testAttribute(Qt::WA_NativeWindow));
       
  7841         QVERIFY(child->internalWinId());
       
  7842         QVERIFY(child->testAttribute(Qt::WA_NativeWindow));
       
  7843         QVERIFY(!child->testAttribute(Qt::WA_PaintOnScreen));
       
  7844         QVERIFY(!dummy->internalWinId());
       
  7845         QVERIFY(!dummy->testAttribute(Qt::WA_NativeWindow));
       
  7846         QVERIFY(!grandChild->internalWinId());
       
  7847         QVERIFY(!grandChild->testAttribute(Qt::WA_NativeWindow));
       
  7848         QVERIFY(!dummy2->internalWinId());
       
  7849         QVERIFY(!dummy2->testAttribute(Qt::WA_NativeWindow));
       
  7850     }
       
  7851 
       
  7852     { // Ensure that ancestors of a Qt::WA_PaintOnScreen widget stay native
       
  7853       // if they are re-created (typically in QWidgetPrivate::setParent_sys) (task 210822).
       
  7854         QWidget window;
       
  7855         QWidget child(&window);
       
  7856 
       
  7857         QWidget grandChild;
       
  7858         grandChild.setWindowTitle("This causes the widget to be created");
       
  7859 
       
  7860         PaintOnScreenWidget paintOnScreenWidget;
       
  7861         paintOnScreenWidget.setAttribute(Qt::WA_PaintOnScreen);
       
  7862         paintOnScreenWidget.setParent(&grandChild);
       
  7863 
       
  7864         grandChild.setParent(&child);
       
  7865 
       
  7866         window.show();
       
  7867 
       
  7868         QVERIFY(window.internalWinId());
       
  7869         QVERIFY(child.internalWinId());
       
  7870         QVERIFY(child.testAttribute(Qt::WA_NativeWindow));
       
  7871         QVERIFY(grandChild.internalWinId());
       
  7872         QVERIFY(grandChild.testAttribute(Qt::WA_NativeWindow));
       
  7873         QVERIFY(paintOnScreenWidget.internalWinId());
       
  7874         QVERIFY(paintOnScreenWidget.testAttribute(Qt::WA_NativeWindow));
       
  7875     }
       
  7876 
       
  7877     { // Ensure that all siblings are native unless Qt::AA_DontCreateNativeWidgetSiblings is set.
       
  7878         qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, false);
       
  7879         QWidget mainWindow;
       
  7880         QWidget *toolBar = new QWidget(&mainWindow);
       
  7881         QWidget *dockWidget = new QWidget(&mainWindow);
       
  7882         QWidget *centralWidget = new QWidget(&mainWindow);
       
  7883 
       
  7884         QWidget *button = new QWidget(centralWidget);
       
  7885         QWidget *mdiArea = new QWidget(centralWidget);
       
  7886 
       
  7887         QWidget *horizontalScroll = new QWidget(mdiArea);
       
  7888         QWidget *verticalScroll = new QWidget(mdiArea);
       
  7889         QWidget *viewport = new QWidget(mdiArea);
       
  7890 
       
  7891         viewport->setAttribute(Qt::WA_NativeWindow);
       
  7892         mainWindow.show();
       
  7893 
       
  7894         // Ensure that the viewport and its siblings are native:
       
  7895         QVERIFY(verticalScroll->testAttribute(Qt::WA_NativeWindow));
       
  7896         QVERIFY(verticalScroll->testAttribute(Qt::WA_NativeWindow));
       
  7897         QVERIFY(horizontalScroll->testAttribute(Qt::WA_NativeWindow));
       
  7898 
       
  7899         // Ensure that the mdi area and its siblings are native:
       
  7900         QVERIFY(mdiArea->testAttribute(Qt::WA_NativeWindow));
       
  7901         QVERIFY(button->testAttribute(Qt::WA_NativeWindow));
       
  7902 
       
  7903         // Ensure that the central widget and its siblings are native:
       
  7904         QVERIFY(centralWidget->testAttribute(Qt::WA_NativeWindow));
       
  7905         QVERIFY(dockWidget->testAttribute(Qt::WA_NativeWindow));
       
  7906         QVERIFY(toolBar->testAttribute(Qt::WA_NativeWindow));
       
  7907     }
       
  7908 }
       
  7909 #endif // Q_WS_WIN / Q_WS_X11
       
  7910 
       
  7911 class ASWidget : public QWidget
       
  7912 {
       
  7913 public:
       
  7914     ASWidget(QSize sizeHint, QSizePolicy sizePolicy, bool layout, bool hfwLayout, QWidget *parent = 0)
       
  7915         : QWidget(parent), mySizeHint(sizeHint)
       
  7916     {
       
  7917         setSizePolicy(sizePolicy);
       
  7918         if (layout) {
       
  7919             QSizePolicy sp = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
       
  7920             sp.setHeightForWidth(hfwLayout);
       
  7921 
       
  7922             QVBoxLayout *vbox = new QVBoxLayout;
       
  7923             vbox->setMargin(0);
       
  7924             vbox->addWidget(new ASWidget(sizeHint + QSize(30, 20), sp, false, false));
       
  7925             setLayout(vbox);
       
  7926         }
       
  7927     }
       
  7928 
       
  7929     QSize sizeHint() const {
       
  7930         if (layout())
       
  7931             return layout()->totalSizeHint();
       
  7932         return mySizeHint;
       
  7933     }
       
  7934     int heightForWidth(int width) const {
       
  7935         if (sizePolicy().hasHeightForWidth()) {
       
  7936             return width * 2;
       
  7937         } else {
       
  7938             return -1;
       
  7939         }
       
  7940     }
       
  7941 
       
  7942     QSize mySizeHint;
       
  7943 };
       
  7944 
       
  7945 void tst_QWidget::adjustSize_data()
       
  7946 {
       
  7947     const int MagicW = 200;
       
  7948     const int MagicH = 100;
       
  7949 
       
  7950     QTest::addColumn<QSize>("sizeHint");
       
  7951     QTest::addColumn<int>("hPolicy");
       
  7952     QTest::addColumn<int>("vPolicy");
       
  7953     QTest::addColumn<bool>("hfwSP");
       
  7954     QTest::addColumn<bool>("layout");
       
  7955     QTest::addColumn<bool>("hfwLayout");
       
  7956     QTest::addColumn<bool>("haveParent");
       
  7957     QTest::addColumn<QSize>("expectedSize");
       
  7958 
       
  7959     QTest::newRow("1") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7960         << false << false << false << false << QSize(5, qMax(6, MagicH));
       
  7961     QTest::newRow("2") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7962         << true << false << false << false << QSize(5, qMax(10, MagicH));
       
  7963     QTest::newRow("3") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7964         << false << true << false << false << QSize(35, 26);
       
  7965     QTest::newRow("4") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7966         << false << true << true << false << QSize(35, 70);
       
  7967     QTest::newRow("5") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7968         << false << false << false << false << QSize(100000, 100000);
       
  7969     QTest::newRow("6") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7970         << true << false << false << false << QSize(100000, 100000);
       
  7971     QTest::newRow("7") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7972         << false << true << false << false << QSize(100000, 100000);
       
  7973     QTest::newRow("8") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7974         << false << true << true << false << QSize(100000, 100000);
       
  7975     QTest::newRow("9") << QSize(5, 6) << int(QSizePolicy::Expanding) << int(QSizePolicy::Minimum)
       
  7976         << true << false << false << false << QSize(qMax(5, MagicW), 10);
       
  7977 
       
  7978     QTest::newRow("1c") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7979         << false << false << false << true << QSize(5, 6);
       
  7980     QTest::newRow("2c") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7981         << true << false << false << true << QSize(5, 6 /* or 10 would be OK too, since hfw contradicts sizeHint() */);
       
  7982     QTest::newRow("3c") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7983         << false << true << false << true << QSize(35, 26);
       
  7984     QTest::newRow("4c") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7985         << false << true << true << true << QSize(35, 70);
       
  7986     QTest::newRow("5c") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7987         << false << false << false << true << QSize(40001, 30001);
       
  7988     QTest::newRow("6c") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7989         << true << false << false << true << QSize(40001, 30001 /* or 80002 would be OK too, since hfw contradicts sizeHint() */);
       
  7990     QTest::newRow("7c") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7991         << false << true << false << true << QSize(40001 + 30, 30001 + 20);
       
  7992     QTest::newRow("8c") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
       
  7993         << false << true << true << true << QSize(40001 + 30, 80002 + 60);
       
  7994     QTest::newRow("9c") << QSize(5, 6) << int(QSizePolicy::Expanding) << int(QSizePolicy::Minimum)
       
  7995         << true << false << false << true << QSize(5, 6);
       
  7996 }
       
  7997 
       
  7998 void tst_QWidget::adjustSize()
       
  7999 {
       
  8000     QFETCH(QSize, sizeHint);
       
  8001     QFETCH(int, hPolicy);
       
  8002     QFETCH(int, vPolicy);
       
  8003     QFETCH(bool, hfwSP);
       
  8004     QFETCH(bool, layout);
       
  8005     QFETCH(bool, hfwLayout);
       
  8006     QFETCH(bool, haveParent);
       
  8007     QFETCH(QSize, expectedSize);
       
  8008 
       
  8009     QWidget *parent = new QWidget;
       
  8010 
       
  8011     QSizePolicy sp = QSizePolicy(QSizePolicy::Policy(hPolicy), QSizePolicy::Policy(vPolicy));
       
  8012     sp.setHeightForWidth(hfwSP);
       
  8013 
       
  8014     QWidget *child = new ASWidget(sizeHint, sp, layout, hfwLayout, haveParent ? parent : 0);
       
  8015     child->resize(123, 456);
       
  8016     child->adjustSize();
       
  8017     if (expectedSize == QSize(100000, 100000)) {
       
  8018         QVERIFY(child->size().width() < sizeHint.width());
       
  8019         QVERIFY(child->size().height() < sizeHint.height());
       
  8020     } else {
       
  8021 #if defined (Q_OS_WINCE)
       
  8022         if (!haveParent) {
       
  8023             const QRect& desktopRect = qApp->desktop()->availableGeometry();
       
  8024             expectedSize.setWidth(qMin(expectedSize.width(), desktopRect.width()));
       
  8025             expectedSize.setHeight(qMin(expectedSize.height(), desktopRect.height()));
       
  8026         }
       
  8027 #endif
       
  8028         QCOMPARE(child->size(), expectedSize);
       
  8029     }
       
  8030 
       
  8031     delete parent;
       
  8032 }
       
  8033 
       
  8034 class TestLayout : public QVBoxLayout
       
  8035 {
       
  8036     Q_OBJECT
       
  8037 public:
       
  8038     TestLayout(QWidget *w = 0) : QVBoxLayout(w)
       
  8039     {
       
  8040         invalidated = false;
       
  8041     }
       
  8042 
       
  8043     void invalidate()
       
  8044     {
       
  8045         invalidated = true;
       
  8046     }
       
  8047 
       
  8048     bool invalidated;
       
  8049 };
       
  8050 
       
  8051 void tst_QWidget::updateGeometry_data()
       
  8052 {
       
  8053     QTest::addColumn<QSize>("minSize");
       
  8054     QTest::addColumn<bool>("shouldInvalidate");
       
  8055     QTest::addColumn<QSize>("maxSize");
       
  8056     QTest::addColumn<bool>("shouldInvalidate2");
       
  8057     QTest::addColumn<int>("verticalSizePolicy");
       
  8058     QTest::addColumn<bool>("shouldInvalidate3");
       
  8059     QTest::addColumn<bool>("setVisible");
       
  8060     QTest::addColumn<bool>("shouldInvalidate4");
       
  8061 
       
  8062     QTest::newRow("setMinimumSize")
       
  8063         << QSize(100, 100) << true
       
  8064         << QSize() << false
       
  8065         << int(QSizePolicy::Preferred) << false
       
  8066         << true << false;
       
  8067     QTest::newRow("setMaximumSize")
       
  8068         << QSize() << false
       
  8069         << QSize(100, 100) << true
       
  8070         << int(QSizePolicy::Preferred) << false
       
  8071         << true << false;
       
  8072     QTest::newRow("setMinimumSize, then maximumSize to a different size")
       
  8073         << QSize(100, 100) << true
       
  8074         << QSize(300, 300) << true
       
  8075         << int(QSizePolicy::Preferred) << false
       
  8076         << true << false;
       
  8077     QTest::newRow("setMinimumSize, then maximumSize to the same size")
       
  8078         << QSize(100, 100) << true
       
  8079         << QSize(100, 100) << true
       
  8080         << int(QSizePolicy::Preferred) << false
       
  8081         << true << false;
       
  8082     QTest::newRow("setMinimumSize, then maximumSize to the same size and then hide it")
       
  8083         << QSize(100, 100) << true
       
  8084         << QSize(100, 100) << true
       
  8085         << int(QSizePolicy::Preferred) << false
       
  8086         << false << true;
       
  8087     QTest::newRow("Change sizePolicy")
       
  8088         << QSize() << false
       
  8089         << QSize() << false
       
  8090         << int(QSizePolicy::Minimum) << true
       
  8091         << true << false;
       
  8092 
       
  8093 }
       
  8094 
       
  8095 void tst_QWidget::updateGeometry()
       
  8096 {
       
  8097     QFETCH(QSize, minSize);
       
  8098     QFETCH(bool, shouldInvalidate);
       
  8099     QFETCH(QSize, maxSize);
       
  8100     QFETCH(bool, shouldInvalidate2);
       
  8101     QFETCH(int, verticalSizePolicy);
       
  8102     QFETCH(bool, shouldInvalidate3);
       
  8103     QFETCH(bool, setVisible);
       
  8104     QFETCH(bool, shouldInvalidate4);
       
  8105     QWidget parent;
       
  8106     parent.resize(200, 200);
       
  8107     TestLayout *lout = new TestLayout();
       
  8108     parent.setLayout(lout);
       
  8109     QWidget *child = new QWidget(&parent);
       
  8110     lout->addWidget(child);
       
  8111     parent.show();
       
  8112     QApplication::processEvents();
       
  8113 
       
  8114     lout->invalidated = false;
       
  8115     if (minSize.isValid())
       
  8116         child->setMinimumSize(minSize);
       
  8117     QCOMPARE(lout->invalidated, shouldInvalidate);
       
  8118 
       
  8119     lout->invalidated = false;
       
  8120     if (maxSize.isValid())
       
  8121         child->setMaximumSize(maxSize);
       
  8122     QCOMPARE(lout->invalidated, shouldInvalidate2);
       
  8123 
       
  8124     lout->invalidated = false;
       
  8125     child->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, (QSizePolicy::Policy)verticalSizePolicy));
       
  8126     if (shouldInvalidate3)
       
  8127         QCOMPARE(lout->invalidated, true);
       
  8128 
       
  8129     lout->invalidated = false;
       
  8130     if (!setVisible)
       
  8131         child->setVisible(false);
       
  8132     QCOMPARE(lout->invalidated, shouldInvalidate4);
       
  8133 }
       
  8134 
       
  8135 void tst_QWidget::sendUpdateRequestImmediately()
       
  8136 {
       
  8137 #ifdef Q_WS_MAC
       
  8138     if (!QApplicationPrivate::graphicsSystem())
       
  8139         QSKIP("We only send update requests on the Mac when passing -graphicssystem", SkipAll);
       
  8140 #endif
       
  8141 
       
  8142     UpdateWidget updateWidget;
       
  8143     updateWidget.show();
       
  8144 #ifdef Q_WS_X11
       
  8145     qt_x11_wait_for_window_manager(&updateWidget);
       
  8146 #endif
       
  8147 
       
  8148     qApp->processEvents();
       
  8149 #ifdef Q_WS_QWS
       
  8150     QApplication::sendPostedEvents(); //glib workaround
       
  8151 #endif
       
  8152     updateWidget.reset();
       
  8153 
       
  8154     QCOMPARE(updateWidget.numUpdateRequestEvents, 0);
       
  8155     updateWidget.repaint();
       
  8156     QCOMPARE(updateWidget.numUpdateRequestEvents, 1);
       
  8157 }
       
  8158 
       
  8159 class RedirectedWidget : public QWidget
       
  8160 {
       
  8161 protected:
       
  8162     void paintEvent(QPaintEvent *)
       
  8163     {
       
  8164         // Verify that the widget has a redirection set. The widget is redirected to
       
  8165         // the backing store on all platforms using it; otherwise to itself if the wrect
       
  8166         // does not start in (0, 0) or it has a mask set.
       
  8167         QPaintDevice *oldRedirection = QPainter::redirected(this);
       
  8168 #ifndef Q_WS_MAC
       
  8169         QVERIFY(oldRedirection);
       
  8170 #endif
       
  8171 
       
  8172         QImage image(size(), QImage::Format_RGB32);
       
  8173         image.fill(Qt::blue);
       
  8174 
       
  8175         {
       
  8176         QPainter painter(this);
       
  8177         QCOMPARE(painter.device(), static_cast<QPaintDevice *>(this));
       
  8178         }
       
  8179 
       
  8180         QPainter::setRedirected(this, &image);
       
  8181         QCOMPARE(QPainter::redirected(this), static_cast<QPaintDevice *>(&image));
       
  8182 
       
  8183         QPainter painter(this);
       
  8184         painter.fillRect(rect(), Qt::red);
       
  8185 
       
  8186         QPainter::restoreRedirected(this);
       
  8187         QCOMPARE(QPainter::redirected(this), oldRedirection);
       
  8188 
       
  8189         for (int i = 0; i < image.height(); ++i)
       
  8190             for (int j = 0; j < image.width(); ++j)
       
  8191                 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
       
  8192     }
       
  8193 
       
  8194 };
       
  8195 
       
  8196 // Test to make sure we're compatible in the particular case where QPainter::setRedirected
       
  8197 // actually works. It has been broken for all other cases since Qt 4.1.4 (backing store).
       
  8198 // QWidget::render is the modern and more powerful way of doing the same.
       
  8199 void tst_QWidget::painterRedirection()
       
  8200 {
       
  8201     RedirectedWidget widget;
       
  8202     // Set FramelessWindowHint and mask to trigger internal painter redirection on the Mac.
       
  8203     widget.setWindowFlags(widget.windowFlags() | Qt::FramelessWindowHint);
       
  8204     widget.setMask(QRect(10, 10, 50, 50));
       
  8205     widget.setFixedSize(100, 200);
       
  8206     widget.show();
       
  8207 #ifdef Q_WS_X11
       
  8208     qt_x11_wait_for_window_manager(&widget);
       
  8209 #endif
       
  8210     QPixmap pixmap(widget.size());
       
  8211     QPainter::setRedirected(&widget, &pixmap, QPoint());
       
  8212     widget.repaint();
       
  8213     QCOMPARE(QPainter::redirected(&widget), static_cast<QPaintDevice *>(&pixmap));
       
  8214 }
       
  8215 
       
  8216 
       
  8217 void tst_QWidget::doubleRepaint()
       
  8218 {
       
  8219 #ifdef Q_OS_IRIX
       
  8220    QSKIP("4DWM issues on IRIX makes this test fail", SkipAll);
       
  8221 #elif defined(Q_WS_MAC)
       
  8222     if (!macHasAccessToWindowsServer())
       
  8223         QSKIP("Not having window server access causes the wrong number of repaints to be issues", SkipAll);
       
  8224 #endif
       
  8225    UpdateWidget widget;
       
  8226    widget.setFocusPolicy(Qt::StrongFocus);
       
  8227    // Filter out activation change and focus events to avoid update() calls in QWidget.
       
  8228    widget.updateOnActivationChangeAndFocusIn = false;
       
  8229 
       
  8230    // Show: 1 repaint
       
  8231    int expectedRepaints = 1;
       
  8232    widget.show();
       
  8233    QTest::qWaitForWindowShown(&widget);
       
  8234    QTest::qWait(10);
       
  8235    QTRY_COMPARE(widget.numPaintEvents, expectedRepaints);
       
  8236    widget.numPaintEvents = 0;
       
  8237 
       
  8238    // Minmize: Should not trigger a repaint.
       
  8239    widget.showMinimized();
       
  8240    QTest::qWait(10);
       
  8241    QCOMPARE(widget.numPaintEvents, 0);
       
  8242    widget.numPaintEvents = 0;
       
  8243 
       
  8244    // Restore: Should not trigger a repaint.
       
  8245    widget.showNormal();
       
  8246    QTest::qWaitForWindowShown(&widget);
       
  8247    QTest::qWait(10);
       
  8248    QCOMPARE(widget.numPaintEvents, 0);
       
  8249 }
       
  8250 
       
  8251 #ifndef Q_WS_MAC
       
  8252 // This test only makes sense on the Mac when passing -graphicssystem.
       
  8253 void tst_QWidget::resizeInPaintEvent()
       
  8254 {
       
  8255     QWidget window;
       
  8256     UpdateWidget widget(&window);
       
  8257     window.show();
       
  8258     QTest::qWaitForWindowShown(&window);
       
  8259     QTRY_VERIFY(widget.numPaintEvents > 0);
       
  8260 
       
  8261     widget.reset();
       
  8262     QCOMPARE(widget.numPaintEvents, 0);
       
  8263 
       
  8264     widget.resizeInPaintEvent = true;
       
  8265     // This will call resize in the paintEvent, which in turn will call
       
  8266     // invalidateBuffer() and a new update request should be posted.
       
  8267     widget.repaint();
       
  8268     QCOMPARE(widget.numPaintEvents, 1);
       
  8269     widget.numPaintEvents = 0;
       
  8270 
       
  8271     QTest::qWait(10);
       
  8272     // Make sure the resize triggers another update.
       
  8273     QTRY_COMPARE(widget.numPaintEvents, 1);
       
  8274 }
       
  8275 #endif
       
  8276 
       
  8277 
       
  8278 class MaskSetWidget : public QWidget
       
  8279 {
       
  8280     Q_OBJECT
       
  8281 public:
       
  8282     MaskSetWidget(QWidget* p =0)
       
  8283             : QWidget(p) {}
       
  8284 
       
  8285     void paintEvent(QPaintEvent* event) {
       
  8286         QPainter p(this);
       
  8287 
       
  8288         paintedRegion += event->region();
       
  8289         foreach(QRect r, event->region().rects())
       
  8290             p.fillRect(r, Qt::red);
       
  8291     }
       
  8292 
       
  8293     void resizeEvent(QResizeEvent*) {
       
  8294         setMask(QRegion(QRect(0, 0, width(), 10).normalized()));
       
  8295     }
       
  8296 
       
  8297     QRegion paintedRegion;
       
  8298 
       
  8299 public slots:
       
  8300     void resizeDown() {
       
  8301         setGeometry(QRect(0, 50, 50, 50));
       
  8302     }
       
  8303 
       
  8304     void resizeUp() {
       
  8305         setGeometry(QRect(0, 50, 150, 50));
       
  8306     }
       
  8307 
       
  8308 };
       
  8309 
       
  8310 void tst_QWidget::setMaskInResizeEvent()
       
  8311 {
       
  8312     UpdateWidget w;
       
  8313     w.reset();
       
  8314     w.resize(200, 200);
       
  8315     w.setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
       
  8316     w.raise();
       
  8317 
       
  8318     MaskSetWidget testWidget(&w);
       
  8319     testWidget.setGeometry(0, 0, 100, 100);
       
  8320     testWidget.setMask(QRegion(QRect(0,0,100,10)));
       
  8321     testWidget.show();
       
  8322     w.show();
       
  8323     QTest::qWaitForWindowShown(&w);
       
  8324     QTest::qWait(30);
       
  8325     QTRY_VERIFY(w.numPaintEvents > 0);
       
  8326 
       
  8327     w.reset();
       
  8328     testWidget.paintedRegion = QRegion();
       
  8329     QTimer::singleShot(0, &testWidget, SLOT(resizeDown()));
       
  8330     QTest::qWait(100);
       
  8331 
       
  8332     QRegion expectedParentUpdate(0, 0, 100, 10); // Old testWidget area.
       
  8333     expectedParentUpdate += testWidget.geometry(); // New testWidget area.
       
  8334     QCOMPARE(w.paintedRegion, expectedParentUpdate);
       
  8335     QCOMPARE(testWidget.paintedRegion, testWidget.mask());
       
  8336 
       
  8337     testWidget.paintedRegion = QRegion();
       
  8338     // Now resize the widget again, but in the oposite direction
       
  8339     QTimer::singleShot(0, &testWidget, SLOT(resizeUp()));
       
  8340     QTest::qWait(100);
       
  8341 
       
  8342     QTRY_COMPARE(testWidget.paintedRegion, testWidget.mask());
       
  8343 }
       
  8344 
       
  8345 class MoveInResizeWidget : public QWidget
       
  8346 {
       
  8347     Q_OBJECT
       
  8348 public:
       
  8349     MoveInResizeWidget(QWidget* p = 0)
       
  8350         : QWidget(p)
       
  8351     {
       
  8352         setWindowFlags(Qt::FramelessWindowHint);
       
  8353     }
       
  8354 
       
  8355     void resizeEvent(QResizeEvent*) {
       
  8356 
       
  8357         move(QPoint(100,100));
       
  8358 
       
  8359         static bool firstTime = true;
       
  8360         if (firstTime)
       
  8361             QTimer::singleShot(250, this, SLOT(resizeMe()));
       
  8362 
       
  8363         firstTime = false;
       
  8364     }
       
  8365 
       
  8366 public slots:
       
  8367     void resizeMe() {
       
  8368         resize(100, 100);
       
  8369     }
       
  8370 };
       
  8371 
       
  8372 void tst_QWidget::moveInResizeEvent()
       
  8373 {
       
  8374     MoveInResizeWidget testWidget;
       
  8375     testWidget.setGeometry(50, 50, 200, 200);
       
  8376     testWidget.show();
       
  8377     QTest::qWaitForWindowShown(&testWidget);
       
  8378     QTest::qWait(300);
       
  8379 
       
  8380     QRect expectedGeometry(100,100, 100, 100);
       
  8381     QTRY_COMPARE(testWidget.geometry(), expectedGeometry);
       
  8382 }
       
  8383 
       
  8384 
       
  8385 #if defined(Q_WS_WIN) || defined(Q_WS_X11)
       
  8386 void tst_QWidget::immediateRepaintAfterShow()
       
  8387 {
       
  8388     UpdateWidget widget;
       
  8389     widget.show();
       
  8390     qApp->processEvents();
       
  8391     // On X11 in particular, we are now waiting for a MapNotify event before
       
  8392     // syncing the backing store. However, if someone request a repaint()
       
  8393     // we must repaint immediately regardless of the current state.
       
  8394     widget.numPaintEvents = 0;
       
  8395     widget.repaint();
       
  8396     QCOMPARE(widget.numPaintEvents, 1);
       
  8397 }
       
  8398 
       
  8399 void tst_QWidget::immediateRepaintAfterInvalidateBuffer()
       
  8400 {
       
  8401     QWidget *widget = new UpdateWidget;
       
  8402     widget->show();
       
  8403 #ifdef Q_WS_X11
       
  8404     qt_x11_wait_for_window_manager(widget);
       
  8405 #endif
       
  8406     QTest::qWait(200);
       
  8407 
       
  8408     static_cast<UpdateWidget *>(widget)->numPaintEvents = 0;
       
  8409 
       
  8410     // Marks the area covered by the widget as dirty in the backing store and
       
  8411     // posts an UpdateRequest event.
       
  8412     qt_widget_private(widget)->invalidateBuffer(widget->rect());
       
  8413     QCOMPARE(static_cast<UpdateWidget *>(widget)->numPaintEvents, 0);
       
  8414 
       
  8415     // The entire widget is already dirty, but this time we want to update immediately
       
  8416     // by calling repaint(), and thus we have to repaint the widget and not wait for
       
  8417     // the UpdateRequest to be sent when we get back to the event loop.
       
  8418     widget->repaint();
       
  8419     QCOMPARE(static_cast<UpdateWidget *>(widget)->numPaintEvents, 1);
       
  8420 
       
  8421     delete widget;
       
  8422 }
       
  8423 #endif
       
  8424 
       
  8425 void tst_QWidget::effectiveWinId()
       
  8426 {
       
  8427     QWidget parent;
       
  8428     QWidget child(&parent);
       
  8429 
       
  8430     // Shouldn't crash.
       
  8431     QVERIFY(!parent.effectiveWinId());
       
  8432     QVERIFY(!child.effectiveWinId());
       
  8433 
       
  8434     parent.show();
       
  8435 
       
  8436     QVERIFY(parent.effectiveWinId());
       
  8437     QVERIFY(child.effectiveWinId());
       
  8438 }
       
  8439 
       
  8440 class CustomWidget : public QWidget
       
  8441 {
       
  8442 public:
       
  8443     mutable int metricCallCount;
       
  8444 
       
  8445     CustomWidget(QWidget *parent = 0) : QWidget(parent), metricCallCount(0) {}
       
  8446 
       
  8447     virtual int metric(PaintDeviceMetric metric) const {
       
  8448         ++metricCallCount;
       
  8449         return QWidget::metric(metric);
       
  8450     }
       
  8451 };
       
  8452 
       
  8453 void tst_QWidget::customDpi()
       
  8454 {
       
  8455     QWidget *topLevel = new QWidget;
       
  8456     CustomWidget *custom = new CustomWidget(topLevel);
       
  8457     QWidget *child = new QWidget(custom);
       
  8458 
       
  8459     custom->metricCallCount = 0;
       
  8460     topLevel->logicalDpiX();
       
  8461     QCOMPARE(custom->metricCallCount, 0);
       
  8462     custom->logicalDpiX();
       
  8463     QCOMPARE(custom->metricCallCount, 1);
       
  8464     child->logicalDpiX();
       
  8465 #ifdef Q_WS_S60
       
  8466     // QWidget::metric is not recursive on Symbian
       
  8467     QCOMPARE(custom->metricCallCount, 1);
       
  8468 #else
       
  8469     QCOMPARE(custom->metricCallCount, 2);
       
  8470 #endif
       
  8471 
       
  8472     delete topLevel;
       
  8473 }
       
  8474 
       
  8475 void tst_QWidget::customDpiProperty()
       
  8476 {
       
  8477     QWidget *topLevel = new QWidget;
       
  8478     QWidget *middle = new CustomWidget(topLevel);
       
  8479     QWidget *child = new QWidget(middle);
       
  8480 
       
  8481     const int initialDpiX = topLevel->logicalDpiX();
       
  8482     const int initialDpiY = topLevel->logicalDpiY();
       
  8483 
       
  8484     middle->setProperty("_q_customDpiX", 300);
       
  8485     middle->setProperty("_q_customDpiY", 400);
       
  8486 
       
  8487     QCOMPARE(topLevel->logicalDpiX(), initialDpiX);
       
  8488     QCOMPARE(topLevel->logicalDpiY(), initialDpiY);
       
  8489 
       
  8490     QCOMPARE(middle->logicalDpiX(), 300);
       
  8491     QCOMPARE(middle->logicalDpiY(), 400);
       
  8492 
       
  8493     QCOMPARE(child->logicalDpiX(), 300);
       
  8494     QCOMPARE(child->logicalDpiY(), 400);
       
  8495 
       
  8496     middle->setProperty("_q_customDpiX", QVariant());
       
  8497     middle->setProperty("_q_customDpiY", QVariant());
       
  8498 
       
  8499     QCOMPARE(topLevel->logicalDpiX(), initialDpiX);
       
  8500     QCOMPARE(topLevel->logicalDpiY(), initialDpiY);
       
  8501 
       
  8502     QCOMPARE(middle->logicalDpiX(), initialDpiX);
       
  8503     QCOMPARE(middle->logicalDpiY(), initialDpiY);
       
  8504 
       
  8505     QCOMPARE(child->logicalDpiX(), initialDpiX);
       
  8506     QCOMPARE(child->logicalDpiY(), initialDpiY);
       
  8507 
       
  8508     delete topLevel;
       
  8509 }
       
  8510 
       
  8511 void tst_QWidget::quitOnCloseAttribute()
       
  8512 {
       
  8513     QWidget w;
       
  8514     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), true);
       
  8515     w.setAttribute(Qt::WA_QuitOnClose, false);
       
  8516     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
       
  8517 
       
  8518     w.setAttribute(Qt::WA_QuitOnClose);
       
  8519     w.setWindowFlags(Qt::Tool);
       
  8520     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
       
  8521 
       
  8522     w.setAttribute(Qt::WA_QuitOnClose);
       
  8523     w.setWindowFlags(Qt::Popup);
       
  8524     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
       
  8525 
       
  8526     w.setAttribute(Qt::WA_QuitOnClose);
       
  8527     w.setWindowFlags(Qt::ToolTip);
       
  8528     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
       
  8529 
       
  8530     w.setAttribute(Qt::WA_QuitOnClose);
       
  8531     w.setWindowFlags(Qt::SplashScreen);
       
  8532     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
       
  8533 
       
  8534     w.setAttribute(Qt::WA_QuitOnClose);
       
  8535     w.setWindowFlags(Qt::SubWindow);
       
  8536     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
       
  8537 
       
  8538     w.setAttribute(Qt::WA_QuitOnClose);
       
  8539     w.setWindowFlags(Qt::Dialog);
       
  8540     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), true);
       
  8541     w.show();
       
  8542     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), true);
       
  8543     w.setWindowFlags(Qt::Tool);
       
  8544     QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
       
  8545 }
       
  8546 
       
  8547 void tst_QWidget::moveRect()
       
  8548 {
       
  8549     QWidget widget;
       
  8550     widget.setUpdatesEnabled(false);
       
  8551     QWidget child(&widget);
       
  8552     child.setUpdatesEnabled(false);
       
  8553     child.setAttribute(Qt::WA_OpaquePaintEvent);
       
  8554     widget.show();
       
  8555     QTest::qWait(200);
       
  8556     child.move(10, 10); // Don't crash.
       
  8557 }
       
  8558 
       
  8559 #ifdef Q_WS_WIN
       
  8560 class GDIWidget : public QDialog
       
  8561 {
       
  8562 public:
       
  8563     GDIWidget() { setAttribute(Qt::WA_PaintOnScreen); }
       
  8564     QPaintEngine *paintEngine() const { return 0; }
       
  8565 
       
  8566 
       
  8567     void paintEvent(QPaintEvent *) {
       
  8568         HDC hdc = getDC();
       
  8569         SelectObject(hdc, CreateSolidBrush(RGB(255, 0, 0)));
       
  8570         Rectangle(hdc, 0, 0, 10, 10);
       
  8571 
       
  8572         releaseDC(hdc);
       
  8573 
       
  8574         QImage im = QPixmap::grabWindow(winId(), 0, 0, width(), height()).toImage();
       
  8575         color = im.pixel(1, 1);
       
  8576 
       
  8577         accept();
       
  8578     }
       
  8579 
       
  8580     QSize sizeHint() const {
       
  8581         return QSize(400, 300);
       
  8582     }
       
  8583 
       
  8584     QColor color;
       
  8585 };
       
  8586 
       
  8587 void tst_QWidget::gdiPainting()
       
  8588 {
       
  8589     GDIWidget w;
       
  8590     w.exec();
       
  8591 
       
  8592     QCOMPARE(w.color, QColor(255, 0, 0));
       
  8593 
       
  8594 }
       
  8595 
       
  8596 void tst_QWidget::paintOnScreenPossible()
       
  8597 {
       
  8598     QWidget w1;
       
  8599     w1.setAttribute(Qt::WA_PaintOnScreen);
       
  8600     QVERIFY(!w1.testAttribute(Qt::WA_PaintOnScreen));
       
  8601 
       
  8602     GDIWidget w2;
       
  8603     w2.setAttribute(Qt::WA_PaintOnScreen);
       
  8604     QVERIFY(w2.testAttribute(Qt::WA_PaintOnScreen));
       
  8605 }
       
  8606 #endif
       
  8607 
       
  8608 void tst_QWidget::reparentStaticWidget()
       
  8609 {
       
  8610     QWidget window1;
       
  8611 
       
  8612     QWidget *child = new QWidget(&window1);
       
  8613     child->setPalette(Qt::red);
       
  8614     child->setAutoFillBackground(true);
       
  8615     child->setAttribute(Qt::WA_StaticContents);
       
  8616     child->resize(100, 100);
       
  8617 
       
  8618     QWidget *grandChild = new QWidget(child);
       
  8619     grandChild->setPalette(Qt::blue);
       
  8620     grandChild->setAutoFillBackground(true);
       
  8621     grandChild->resize(50, 50);
       
  8622     grandChild->setAttribute(Qt::WA_StaticContents);
       
  8623     window1.show();
       
  8624     QTest::qWaitForWindowShown(&window1);
       
  8625 
       
  8626     QWidget window2;
       
  8627     window2.show();
       
  8628     QTest::qWaitForWindowShown(&window2);
       
  8629     QTest::qWait(20);
       
  8630 
       
  8631     // Reparent into another top-level.
       
  8632     child->setParent(&window2);
       
  8633     child->show();
       
  8634 
       
  8635     // Please don't crash.
       
  8636     window1.resize(window1.size() + QSize(2, 2));
       
  8637     QTest::qWait(20);
       
  8638 
       
  8639     // Make sure we move all static children even though
       
  8640     // the reparented widget itself is non-static.
       
  8641     child->setAttribute(Qt::WA_StaticContents, false);
       
  8642     child->setParent(&window1);
       
  8643     child->show();
       
  8644 
       
  8645     // Please don't crash.
       
  8646     window2.resize(window2.size() + QSize(2, 2));
       
  8647     QTest::qWait(20);
       
  8648 
       
  8649     child->setParent(0);
       
  8650     child->show();
       
  8651     QTest::qWait(20);
       
  8652 
       
  8653     // Please don't crash.
       
  8654     child->resize(child->size() + QSize(2, 2));
       
  8655     window2.resize(window2.size() + QSize(2, 2));
       
  8656     QTest::qWait(20);
       
  8657 
       
  8658     QWidget *siblingOfGrandChild = new QWidget(child);
       
  8659     siblingOfGrandChild->show();
       
  8660     QTest::qWait(20);
       
  8661 
       
  8662     // Nothing should happen when reparenting within the same top-level.
       
  8663     grandChild->setParent(siblingOfGrandChild);
       
  8664     grandChild->show();
       
  8665     QTest::qWait(20);
       
  8666 
       
  8667     QWidget paintOnScreen;
       
  8668     paintOnScreen.setAttribute(Qt::WA_PaintOnScreen);
       
  8669     paintOnScreen.show();
       
  8670     QTest::qWaitForWindowShown(&paintOnScreen);
       
  8671     QTest::qWait(20);
       
  8672 
       
  8673     child->setParent(&paintOnScreen);
       
  8674     child->show();
       
  8675     QTest::qWait(20);
       
  8676 
       
  8677     // Please don't crash.
       
  8678     paintOnScreen.resize(paintOnScreen.size() + QSize(2, 2));
       
  8679     QTest::qWait(20);
       
  8680 }
       
  8681 
       
  8682 #ifdef Q_WS_QWS
       
  8683 void tst_QWidget::updateOutsideSurfaceClip()
       
  8684 {
       
  8685     UpdateWidget widget;
       
  8686     widget.setWindowFlags(Qt::FramelessWindowHint);
       
  8687     widget.resize(100, 100);
       
  8688     widget.raise();
       
  8689     widget.show();
       
  8690     QTest::qWait(200);
       
  8691     widget.reset();
       
  8692 
       
  8693     // Move widget partially outside buffer and change the surface clip.
       
  8694     widget.move(-50, 0);
       
  8695     QTest::qWait(100);
       
  8696 
       
  8697     // Update region is outside the surface clip and should not trigger a repaint.
       
  8698     widget.update(0, 0, 20, 20);
       
  8699     QTest::qWait(100);
       
  8700     QCOMPARE(widget.numPaintEvents, 0);
       
  8701 
       
  8702     // Now, move the widget back so that the update region is inside the clip
       
  8703     // and make sure we get a repaint of the dirty area.
       
  8704     widget.move(0, 0);
       
  8705     QTest::qWait(100);
       
  8706     QCOMPARE(widget.numPaintEvents, 1);
       
  8707     QCOMPARE(widget.paintedRegion, QRegion(0, 0, 20, 20));
       
  8708 }
       
  8709 #endif
       
  8710 class ColorRedWidget : public QWidget
       
  8711 {
       
  8712 public:
       
  8713     ColorRedWidget(QWidget *parent = 0)
       
  8714         : QWidget(parent, Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::ToolTip)
       
  8715     {
       
  8716     }
       
  8717 
       
  8718     void paintEvent(QPaintEvent *) {
       
  8719         QPainter p(this);
       
  8720         p.fillRect(rect(),Qt::red);
       
  8721     }
       
  8722 };
       
  8723 
       
  8724 void tst_QWidget::translucentWidget()
       
  8725 {
       
  8726     QPixmap pm(16,16);
       
  8727     pm.fill(Qt::red);
       
  8728     ColorRedWidget label;
       
  8729     label.setFixedSize(16,16);
       
  8730     label.setAttribute(Qt::WA_TranslucentBackground);
       
  8731     label.move(qApp->desktop()->availableGeometry().topLeft());
       
  8732     label.show();
       
  8733 #ifdef Q_WS_X11
       
  8734     qt_x11_wait_for_window_manager(&label);
       
  8735 #endif
       
  8736     QTest::qWait(200);
       
  8737 
       
  8738     QPixmap widgetSnapshot = QPixmap::grabWindow(label.winId());
       
  8739     QImage actual = widgetSnapshot.toImage().convertToFormat(QImage::Format_RGB32);
       
  8740     QImage expected = pm.toImage().convertToFormat(QImage::Format_RGB32);
       
  8741     QCOMPARE(actual.size(),expected.size());
       
  8742     QCOMPARE(actual,expected);
       
  8743 }
       
  8744 
       
  8745 class MaskResizeTestWidget : public QWidget
       
  8746 {
       
  8747     Q_OBJECT
       
  8748 public:
       
  8749     MaskResizeTestWidget(QWidget* p =0)
       
  8750             : QWidget(p) {
       
  8751         setMask(QRegion(QRect(0, 0, 100, 100).normalized()));
       
  8752     }
       
  8753 
       
  8754     void paintEvent(QPaintEvent* event) {
       
  8755         QPainter p(this);
       
  8756 
       
  8757         paintedRegion += event->region();
       
  8758         foreach(QRect r, event->region().rects())
       
  8759             p.fillRect(r, Qt::red);
       
  8760     }
       
  8761 
       
  8762     QRegion paintedRegion;
       
  8763 
       
  8764 public slots:
       
  8765     void enlargeMask() {
       
  8766         QRegion newMask(QRect(0, 0, 150, 150).normalized());
       
  8767         setMask(newMask);
       
  8768     }
       
  8769 
       
  8770     void shrinkMask() {
       
  8771         QRegion newMask(QRect(0, 0, 50, 50).normalized());
       
  8772         setMask(newMask);
       
  8773     }
       
  8774 
       
  8775 };
       
  8776 
       
  8777 void tst_QWidget::setClearAndResizeMask()
       
  8778 {
       
  8779     UpdateWidget topLevel;
       
  8780     topLevel.resize(150, 150);
       
  8781     topLevel.show();
       
  8782     QTest::qWaitForWindowShown(&topLevel);
       
  8783     QTRY_VERIFY(topLevel.numPaintEvents > 0);
       
  8784     topLevel.reset();
       
  8785 
       
  8786     // Mask top-level widget
       
  8787     const QRegion topLevelMask(0, 0, 100, 100, QRegion::Ellipse);
       
  8788     topLevel.setMask(topLevelMask);
       
  8789     QCOMPARE(topLevel.mask(), topLevelMask);
       
  8790 #if defined(Q_WS_WIN) || defined(Q_WS_X11) // We don't control what's happening on other platforms.
       
  8791     // and ensure that the top-level doesn't get any update.
       
  8792     QCOMPARE(topLevel.numPaintEvents, 0);
       
  8793 #endif
       
  8794 
       
  8795     topLevel.reset();
       
  8796 
       
  8797     // Clear top-level mask
       
  8798     topLevel.clearMask();
       
  8799     QCOMPARE(topLevel.mask(), QRegion());
       
  8800     QTest::qWait(10);
       
  8801     QRegion outsideOldMask(topLevel.rect());
       
  8802     outsideOldMask -= topLevelMask;
       
  8803 #if defined(Q_WS_WIN) || defined(Q_WS_X11) // We don't control what's happening on other platforms.
       
  8804     // and ensure that the top-level gets an update for the area outside the old mask.
       
  8805     QTRY_VERIFY(topLevel.numPaintEvents > 0);
       
  8806     QTRY_COMPARE(topLevel.paintedRegion, outsideOldMask);
       
  8807 #endif
       
  8808 
       
  8809     UpdateWidget child(&topLevel);
       
  8810     child.setAutoFillBackground(true); // NB! Opaque child.
       
  8811     child.resize(100, 100);
       
  8812     child.show();
       
  8813     QTest::qWait(10);
       
  8814 
       
  8815     child.reset();
       
  8816     topLevel.reset();
       
  8817 
       
  8818     // Mask child widget with a mask that is smaller than the rect
       
  8819     const QRegion childMask(0, 0, 50, 50);
       
  8820     child.setMask(childMask);
       
  8821     QTRY_COMPARE(child.mask(), childMask);
       
  8822     QTest::qWait(50);
       
  8823     // and ensure that the child widget doesn't get any update.
       
  8824 #ifdef Q_WS_MAC
       
  8825     // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
       
  8826     QCOMPARE(child.numPaintEvents, 1);
       
  8827 #else
       
  8828     QCOMPARE(child.numPaintEvents, 0);
       
  8829 #endif
       
  8830     // and the parent widget gets an update for the newly exposed area.
       
  8831     QTRY_COMPARE(topLevel.numPaintEvents, 1);
       
  8832     QRegion expectedParentExpose(child.rect());
       
  8833     expectedParentExpose -= childMask;
       
  8834     QCOMPARE(topLevel.paintedRegion, expectedParentExpose);
       
  8835 
       
  8836     child.reset();
       
  8837     topLevel.reset();
       
  8838 
       
  8839     // Clear child widget mask
       
  8840     child.clearMask();
       
  8841     QTRY_COMPARE(child.mask(), QRegion());
       
  8842     QTest::qWait(10);
       
  8843     // and ensure that that the child widget gets an update for the area outside the old mask.
       
  8844     QTRY_COMPARE(child.numPaintEvents, 1);
       
  8845     outsideOldMask = child.rect();
       
  8846 #ifndef Q_WS_MAC
       
  8847     // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
       
  8848     outsideOldMask -= childMask;
       
  8849 #endif
       
  8850     QCOMPARE(child.paintedRegion, outsideOldMask);
       
  8851     // and the parent widget doesn't get any update.
       
  8852     QCOMPARE(topLevel.numPaintEvents, 0);
       
  8853 
       
  8854     child.reset();
       
  8855     topLevel.reset();
       
  8856 
       
  8857     // Mask child widget with a mask that is bigger than the rect
       
  8858     child.setMask(QRegion(0, 0, 1000, 1000));
       
  8859     QTest::qWait(100);
       
  8860 #ifdef Q_WS_MAC
       
  8861     // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
       
  8862     QTRY_COMPARE(child.numPaintEvents, 1);
       
  8863 #else
       
  8864     // and ensure that we don't get any updates at all.
       
  8865     QTRY_COMPARE(child.numPaintEvents, 0);
       
  8866 #endif
       
  8867     QCOMPARE(topLevel.numPaintEvents, 0);
       
  8868 
       
  8869     // ...and the same applies when clearing the mask.
       
  8870     child.clearMask();
       
  8871     QTest::qWait(100);
       
  8872 #ifdef Q_WS_MAC
       
  8873     // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
       
  8874     QTRY_VERIFY(child.numPaintEvents > 0);
       
  8875 #else
       
  8876     QCOMPARE(child.numPaintEvents, 0);
       
  8877 #endif
       
  8878     QCOMPARE(topLevel.numPaintEvents, 0);
       
  8879 
       
  8880     QWidget resizeParent;
       
  8881     MaskResizeTestWidget resizeChild(&resizeParent);
       
  8882 
       
  8883     resizeParent.resize(300,300);
       
  8884     resizeParent.raise();
       
  8885     resizeParent.setWindowFlags(Qt::WindowStaysOnTopHint);
       
  8886     resizeChild.setGeometry(50,50,200,200);
       
  8887     QPalette pal = resizeParent.palette();
       
  8888     pal.setColor(QPalette::Window, QColor(Qt::white));
       
  8889     resizeParent.setPalette(pal);
       
  8890 
       
  8891     resizeParent.show();
       
  8892     QTest::qWaitForWindowShown(&resizeParent);
       
  8893     // Disable the size grip on the Mac; otherwise it'll be included when grabbing the window.
       
  8894     resizeParent.setFixedSize(resizeParent.size());
       
  8895     resizeChild.show();
       
  8896     QTest::qWait(100);
       
  8897     resizeChild.paintedRegion = QRegion();
       
  8898 
       
  8899     QTimer::singleShot(100, &resizeChild, SLOT(shrinkMask()));
       
  8900     QTest::qWait(200);
       
  8901 #ifdef Q_WS_MAC
       
  8902     // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
       
  8903     QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask());
       
  8904 #else
       
  8905     QTRY_COMPARE(resizeChild.paintedRegion, QRegion());
       
  8906 #endif
       
  8907 
       
  8908     resizeChild.paintedRegion = QRegion();
       
  8909     const QRegion oldMask = resizeChild.mask();
       
  8910     QTimer::singleShot(0, &resizeChild, SLOT(enlargeMask()));
       
  8911     QTest::qWait(100);
       
  8912 #ifdef Q_WS_MAC
       
  8913     // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
       
  8914     QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask());
       
  8915 #else
       
  8916     QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask() - oldMask);
       
  8917 #endif
       
  8918 }
       
  8919 
       
  8920 void tst_QWidget::maskedUpdate()
       
  8921 {
       
  8922     UpdateWidget topLevel;
       
  8923     topLevel.resize(200, 200);
       
  8924     const QRegion topLevelMask(50, 50, 70, 70);
       
  8925     topLevel.setMask(topLevelMask);
       
  8926 
       
  8927     UpdateWidget child(&topLevel);
       
  8928     child.setGeometry(20, 20, 180, 180);
       
  8929     const QRegion childMask(60, 60, 30, 30);
       
  8930     child.setMask(childMask);
       
  8931 
       
  8932     UpdateWidget grandChild(&child);
       
  8933     grandChild.setGeometry(50, 50, 100, 100);
       
  8934     const QRegion grandChildMask(20, 20, 10, 10);
       
  8935     grandChild.setMask(grandChildMask);
       
  8936 
       
  8937     topLevel.show();
       
  8938     QTest::qWaitForWindowShown(&topLevel);
       
  8939     QTRY_VERIFY(topLevel.numPaintEvents > 0);
       
  8940 
       
  8941 
       
  8942 #define RESET_WIDGETS \
       
  8943     topLevel.reset(); \
       
  8944     child.reset(); \
       
  8945     grandChild.reset();
       
  8946 
       
  8947 #define CLEAR_MASK(widget) \
       
  8948     widget.clearMask(); \
       
  8949     QTest::qWait(100); \
       
  8950     RESET_WIDGETS;
       
  8951 
       
  8952     // All widgets are transparent at this point, so any call to update() will result
       
  8953     // in composition, i.e. the update propagates to ancestors and children.
       
  8954 
       
  8955     // TopLevel update.
       
  8956     RESET_WIDGETS;
       
  8957     topLevel.update();
       
  8958     QTest::qWait(10);
       
  8959 
       
  8960     QTRY_COMPARE(topLevel.paintedRegion, topLevelMask);
       
  8961     QTRY_COMPARE(child.paintedRegion, childMask);
       
  8962     QTRY_COMPARE(grandChild.paintedRegion, grandChildMask);
       
  8963 
       
  8964     // Child update.
       
  8965     RESET_WIDGETS;
       
  8966     child.update();
       
  8967     QTest::qWait(10);
       
  8968 
       
  8969     QTRY_COMPARE(topLevel.paintedRegion, childMask.translated(child.pos()));
       
  8970     QTRY_COMPARE(child.paintedRegion, childMask);
       
  8971     QTRY_COMPARE(grandChild.paintedRegion, grandChildMask);
       
  8972 
       
  8973     // GrandChild update.
       
  8974     RESET_WIDGETS;
       
  8975     grandChild.update();
       
  8976     QTest::qWait(10);
       
  8977 
       
  8978     QTRY_COMPARE(topLevel.paintedRegion, grandChildMask.translated(grandChild.mapTo(&topLevel, QPoint())));
       
  8979     QTRY_COMPARE(child.paintedRegion, grandChildMask.translated(grandChild.pos()));
       
  8980     QTRY_COMPARE(grandChild.paintedRegion, grandChildMask);
       
  8981 
       
  8982     topLevel.setAttribute(Qt::WA_OpaquePaintEvent);
       
  8983     child.setAttribute(Qt::WA_OpaquePaintEvent);
       
  8984     grandChild.setAttribute(Qt::WA_OpaquePaintEvent);
       
  8985 
       
  8986     // All widgets are now opaque, which means no composition, i.e.
       
  8987     // the update does not propate to ancestors and children.
       
  8988 
       
  8989     // TopLevel update.
       
  8990     RESET_WIDGETS;
       
  8991     topLevel.update();
       
  8992     QTest::qWait(10);
       
  8993 
       
  8994     QRegion expectedTopLevelUpdate = topLevelMask;
       
  8995     expectedTopLevelUpdate -= childMask.translated(child.pos()); // Subtract opaque children.
       
  8996     QTRY_COMPARE(topLevel.paintedRegion, expectedTopLevelUpdate);
       
  8997     QTRY_COMPARE(child.paintedRegion, QRegion());
       
  8998     QTRY_COMPARE(grandChild.paintedRegion, QRegion());
       
  8999 
       
  9000     // Child update.
       
  9001     RESET_WIDGETS;
       
  9002     child.update();
       
  9003     QTest::qWait(10);
       
  9004 
       
  9005     QTRY_COMPARE(topLevel.paintedRegion, QRegion());
       
  9006     QRegion expectedChildUpdate = childMask;
       
  9007     expectedChildUpdate -= grandChildMask.translated(grandChild.pos()); // Subtract oapque children.
       
  9008     QTRY_COMPARE(child.paintedRegion, expectedChildUpdate);
       
  9009     QTRY_COMPARE(grandChild.paintedRegion, QRegion());
       
  9010 
       
  9011     // GrandChild update.
       
  9012     RESET_WIDGETS;
       
  9013     grandChild.update();
       
  9014     QTest::qWait(10);
       
  9015 
       
  9016     QTRY_COMPARE(topLevel.paintedRegion, QRegion());
       
  9017     QTRY_COMPARE(child.paintedRegion, QRegion());
       
  9018     QTRY_COMPARE(grandChild.paintedRegion, grandChildMask);
       
  9019 
       
  9020     // GrandChild update.
       
  9021     CLEAR_MASK(grandChild);
       
  9022     grandChild.update();
       
  9023     QTest::qWait(10);
       
  9024 
       
  9025     QTRY_COMPARE(topLevel.paintedRegion, QRegion());
       
  9026     QTRY_COMPARE(child.paintedRegion, QRegion());
       
  9027     QRegion expectedGrandChildUpdate = grandChild.rect();
       
  9028     // Clip with parent's mask.
       
  9029     expectedGrandChildUpdate &= childMask.translated(-grandChild.pos());
       
  9030     QCOMPARE(grandChild.paintedRegion, expectedGrandChildUpdate);
       
  9031 
       
  9032     // GrandChild update.
       
  9033     CLEAR_MASK(child);
       
  9034     grandChild.update();
       
  9035     QTest::qWait(10);
       
  9036 
       
  9037     QTRY_COMPARE(topLevel.paintedRegion, QRegion());
       
  9038     QTRY_COMPARE(child.paintedRegion, QRegion());
       
  9039     expectedGrandChildUpdate = grandChild.rect();
       
  9040     // Clip with parent's mask.
       
  9041     expectedGrandChildUpdate &= topLevelMask.translated(-grandChild.mapTo(&topLevel, QPoint()));
       
  9042     QTRY_COMPARE(grandChild.paintedRegion, expectedGrandChildUpdate);
       
  9043 
       
  9044     // Child update.
       
  9045     RESET_WIDGETS;
       
  9046     child.update();
       
  9047     QTest::qWait(10);
       
  9048 
       
  9049     QTRY_COMPARE(topLevel.paintedRegion, QRegion());
       
  9050     expectedChildUpdate = child.rect();
       
  9051     // Clip with parent's mask.
       
  9052     expectedChildUpdate &= topLevelMask.translated(-child.pos());
       
  9053     expectedChildUpdate -= grandChild.geometry(); // Subtract opaque children.
       
  9054     QTRY_COMPARE(child.paintedRegion, expectedChildUpdate);
       
  9055     QTRY_COMPARE(grandChild.paintedRegion, QRegion());
       
  9056 
       
  9057     // GrandChild update.
       
  9058     CLEAR_MASK(topLevel);
       
  9059     grandChild.update();
       
  9060     QTest::qWait(10);
       
  9061 
       
  9062     QTRY_COMPARE(topLevel.paintedRegion, QRegion());
       
  9063     QTRY_COMPARE(child.paintedRegion, QRegion());
       
  9064     QTRY_COMPARE(grandChild.paintedRegion, QRegion(grandChild.rect())); // Full update.
       
  9065 }
       
  9066 
       
  9067 #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS)
       
  9068 void tst_QWidget::syntheticEnterLeave()
       
  9069 {
       
  9070     class MyWidget : public QWidget
       
  9071     {
       
  9072     public:
       
  9073         MyWidget(QWidget *parent = 0) : QWidget(parent), numEnterEvents(0), numLeaveEvents(0) {}
       
  9074         void enterEvent(QEvent *) { ++numEnterEvents; }
       
  9075         void leaveEvent(QEvent *) { ++numLeaveEvents; }
       
  9076         int numEnterEvents;
       
  9077         int numLeaveEvents;
       
  9078     };
       
  9079 
       
  9080     QCursor::setPos(QPoint(0,0));
       
  9081 
       
  9082     MyWidget window;
       
  9083     window.setWindowFlags(Qt::WindowStaysOnTopHint);
       
  9084     window.resize(200, 200);
       
  9085 
       
  9086     MyWidget *child1 = new MyWidget(&window);
       
  9087     child1->setPalette(Qt::blue);
       
  9088     child1->setAutoFillBackground(true);
       
  9089     child1->resize(200, 200);
       
  9090     child1->setCursor(Qt::OpenHandCursor);
       
  9091 
       
  9092     MyWidget *child2 = new MyWidget(&window);
       
  9093     child2->resize(200, 200);
       
  9094 
       
  9095     MyWidget *grandChild = new MyWidget(child2);
       
  9096     grandChild->setPalette(Qt::red);
       
  9097     grandChild->setAutoFillBackground(true);
       
  9098     grandChild->resize(200, 200);
       
  9099     grandChild->setCursor(Qt::WaitCursor);
       
  9100 
       
  9101     window.show();
       
  9102     window.raise();
       
  9103 #ifdef Q_WS_X11
       
  9104     qt_x11_wait_for_window_manager(&window);
       
  9105 #endif
       
  9106     QTest::qWait(300);
       
  9107 
       
  9108 #define RESET_EVENT_COUNTS \
       
  9109     window.numEnterEvents = 0; \
       
  9110     window.numLeaveEvents = 0; \
       
  9111     child1->numEnterEvents = 0; \
       
  9112     child1->numLeaveEvents = 0; \
       
  9113     child2->numEnterEvents = 0; \
       
  9114     child2->numLeaveEvents = 0; \
       
  9115     grandChild->numEnterEvents = 0; \
       
  9116     grandChild->numLeaveEvents = 0;
       
  9117 
       
  9118     // Position the cursor in the middle of the window.
       
  9119     const QPoint globalPos = window.mapToGlobal(QPoint(100, 100));
       
  9120     QCursor::setPos(globalPos); // Enter child2 and grandChild.
       
  9121     QTest::qWait(300);
       
  9122 
       
  9123 #ifdef Q_OS_WINCE_WM
       
  9124     QSKIP("Windows Mobile has no proper cursor support", SkipAll);
       
  9125 #endif
       
  9126 
       
  9127     QCOMPARE(window.numLeaveEvents, 0);
       
  9128     QCOMPARE(child2->numLeaveEvents, 0);
       
  9129     QCOMPARE(grandChild->numLeaveEvents, 0);
       
  9130     QCOMPARE(child1->numLeaveEvents, 0);
       
  9131 
       
  9132     QCOMPARE(window.numEnterEvents, 1);
       
  9133     QCOMPARE(child2->numEnterEvents, 1);
       
  9134     QCOMPARE(grandChild->numEnterEvents, 1);
       
  9135     QCOMPARE(child1->numEnterEvents, 0);
       
  9136 
       
  9137     RESET_EVENT_COUNTS;
       
  9138     child2->hide(); // Leave child2 and grandChild, enter child1.
       
  9139 
       
  9140     QCOMPARE(window.numLeaveEvents, 0);
       
  9141     QCOMPARE(child2->numLeaveEvents, 1);
       
  9142     QCOMPARE(grandChild->numLeaveEvents, 1);
       
  9143     QCOMPARE(child1->numLeaveEvents, 0);
       
  9144 
       
  9145     QCOMPARE(window.numEnterEvents, 0);
       
  9146     QCOMPARE(child2->numEnterEvents, 0);
       
  9147     QCOMPARE(grandChild->numEnterEvents, 0);
       
  9148     QCOMPARE(child1->numEnterEvents, 1);
       
  9149 
       
  9150     RESET_EVENT_COUNTS;
       
  9151     child2->show(); // Leave child1, enter child2 and grandChild.
       
  9152 
       
  9153     QCOMPARE(window.numLeaveEvents, 0);
       
  9154     QCOMPARE(child2->numLeaveEvents, 0);
       
  9155     QCOMPARE(grandChild->numLeaveEvents, 0);
       
  9156     QCOMPARE(child1->numLeaveEvents, 1);
       
  9157 
       
  9158     QCOMPARE(window.numEnterEvents, 0);
       
  9159     QCOMPARE(child2->numEnterEvents, 1);
       
  9160     QCOMPARE(grandChild->numEnterEvents, 1);
       
  9161     QCOMPARE(child1->numEnterEvents, 0);
       
  9162 
       
  9163     RESET_EVENT_COUNTS;
       
  9164     delete child2; // Enter child1 (and do not send leave events to child2 and grandChild).
       
  9165 
       
  9166     QCOMPARE(window.numLeaveEvents, 0);
       
  9167     QCOMPARE(child1->numLeaveEvents, 0);
       
  9168 
       
  9169     QCOMPARE(window.numEnterEvents, 0);
       
  9170     QCOMPARE(child1->numEnterEvents, 1);
       
  9171 }
       
  9172 
       
  9173 void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
       
  9174 {
       
  9175 #ifdef Q_OS_WINCE_WM
       
  9176     QSKIP("Windows Mobile has no proper cursor support", SkipAll);
       
  9177 #endif
       
  9178     class SELParent : public QWidget
       
  9179     {
       
  9180     public:
       
  9181         SELParent(QWidget *parent = 0): QWidget(parent) { }
       
  9182 
       
  9183         void mousePressEvent(QMouseEvent *) { child->show(); }
       
  9184         QWidget *child;
       
  9185     };
       
  9186 
       
  9187     class SELChild : public QWidget
       
  9188      {
       
  9189      public:
       
  9190          SELChild(QWidget *parent = 0) : QWidget(parent), numEnterEvents(0), numMouseMoveEvents(0) {}
       
  9191          void enterEvent(QEvent *) { ++numEnterEvents; }
       
  9192          void mouseMoveEvent(QMouseEvent *event)
       
  9193          {
       
  9194              QCOMPARE(event->button(), Qt::NoButton);
       
  9195              QCOMPARE(event->buttons(), Qt::MouseButtons(Qt::NoButton));
       
  9196              ++numMouseMoveEvents;
       
  9197          }
       
  9198          void reset() { numEnterEvents = numMouseMoveEvents = 0; }
       
  9199          int numEnterEvents, numMouseMoveEvents;
       
  9200      };
       
  9201 
       
  9202     QCursor::setPos(QPoint(0,0));
       
  9203 
       
  9204      SELParent parent;
       
  9205      parent.resize(200, 200);
       
  9206      SELChild child(&parent);
       
  9207      child.resize(200, 200);
       
  9208      parent.show();
       
  9209  #ifdef Q_WS_X11
       
  9210      qt_x11_wait_for_window_manager(&parent);
       
  9211  #endif
       
  9212      QTest::qWait(150);
       
  9213 
       
  9214      QCursor::setPos(child.mapToGlobal(QPoint(100, 100)));
       
  9215      // Make sure the cursor has entered the child.
       
  9216      QTRY_VERIFY(child.numEnterEvents > 0);
       
  9217 
       
  9218      child.hide();
       
  9219      child.reset();
       
  9220      child.show();
       
  9221 
       
  9222      // Make sure the child gets enter event and no mouse move event.
       
  9223      QCOMPARE(child.numEnterEvents, 1);
       
  9224      QCOMPARE(child.numMouseMoveEvents, 0);
       
  9225 
       
  9226      child.hide();
       
  9227      child.reset();
       
  9228      child.setMouseTracking(true);
       
  9229      child.show();
       
  9230 
       
  9231      // Make sure the child gets enter event and mouse move event.
       
  9232      // Note that we verify event->button() and event->buttons()
       
  9233      // in SELChild::mouseMoveEvent().
       
  9234      QCOMPARE(child.numEnterEvents, 1);
       
  9235      QCOMPARE(child.numMouseMoveEvents, 1);
       
  9236 
       
  9237      // Sending synthetic enter/leave trough the parent's mousePressEvent handler.
       
  9238      parent.child = &child;
       
  9239 
       
  9240      child.hide();
       
  9241      child.reset();
       
  9242      QTest::mouseClick(&parent, Qt::LeftButton);
       
  9243 
       
  9244      // Make sure the child gets enter event and one mouse move event.
       
  9245      QCOMPARE(child.numEnterEvents, 1);
       
  9246      QCOMPARE(child.numMouseMoveEvents, 1);
       
  9247 
       
  9248      child.hide();
       
  9249      child.reset();
       
  9250      child.setMouseTracking(false);
       
  9251      QTest::mouseClick(&parent, Qt::LeftButton);
       
  9252 
       
  9253      // Make sure the child gets enter event and no mouse move event.
       
  9254      QCOMPARE(child.numEnterEvents, 1);
       
  9255      QCOMPARE(child.numMouseMoveEvents, 0);
       
  9256  }
       
  9257 #endif
       
  9258 
       
  9259 void tst_QWidget::windowFlags()
       
  9260 {
       
  9261     QWidget w;
       
  9262     w.setWindowFlags(w.windowFlags() | Qt::FramelessWindowHint);
       
  9263     QVERIFY(w.windowFlags() & Qt::FramelessWindowHint);
       
  9264 }
       
  9265 
       
  9266 void tst_QWidget::initialPosForDontShowOnScreenWidgets()
       
  9267 {
       
  9268     { // Check default position.
       
  9269         const QPoint expectedPos(0, 0);
       
  9270         QWidget widget;
       
  9271         widget.setAttribute(Qt::WA_DontShowOnScreen);
       
  9272         widget.winId(); // Make sure create_sys is called.
       
  9273         QCOMPARE(widget.pos(), expectedPos);
       
  9274         QCOMPARE(widget.geometry().topLeft(), expectedPos);
       
  9275     }
       
  9276 
       
  9277     { // Explicitly move to a position.
       
  9278         const QPoint expectedPos(100, 100);
       
  9279         QWidget widget;
       
  9280         widget.setAttribute(Qt::WA_DontShowOnScreen);
       
  9281         widget.move(expectedPos);
       
  9282         widget.winId(); // Make sure create_sys is called.
       
  9283         QCOMPARE(widget.pos(), expectedPos);
       
  9284         QCOMPARE(widget.geometry().topLeft(), expectedPos);
       
  9285     }
       
  9286 }
       
  9287 
       
  9288 #ifdef Q_WS_X11
       
  9289 void tst_QWidget::paintOutsidePaintEvent()
       
  9290 {
       
  9291     QWidget widget;
       
  9292     widget.resize(200, 200);
       
  9293 
       
  9294     QWidget child1(&widget);
       
  9295     child1.resize(100, 100);
       
  9296     child1.setPalette(Qt::red);
       
  9297     child1.setAutoFillBackground(true);
       
  9298 
       
  9299     QWidget child2(&widget);
       
  9300     child2.setGeometry(50, 50, 100, 100);
       
  9301     child2.setPalette(Qt::blue);
       
  9302     child2.setAutoFillBackground(true);
       
  9303 
       
  9304     widget.show();
       
  9305     QTest::qWaitForWindowShown(&widget);
       
  9306     QTest::qWait(60);
       
  9307 
       
  9308     const QPixmap before = QPixmap::grabWindow(widget.winId());
       
  9309 
       
  9310     // Child 1 should be clipped by child 2, so nothing should change.
       
  9311     child1.setAttribute(Qt::WA_PaintOutsidePaintEvent);
       
  9312     QPainter painter(&child1);
       
  9313     painter.fillRect(child1.rect(), Qt::red);
       
  9314     painter.end();
       
  9315     XSync(QX11Info::display(), false); // Flush output buffer.
       
  9316     QTest::qWait(60);
       
  9317 
       
  9318     const QPixmap after = QPixmap::grabWindow(widget.winId());
       
  9319 
       
  9320     QCOMPARE(before, after);
       
  9321 }
       
  9322 #endif
       
  9323 
       
  9324 class MyEvilObject : public QObject
       
  9325 {
       
  9326     Q_OBJECT
       
  9327 public:
       
  9328     MyEvilObject(QWidget *widgetToCrash) : QObject(), widget(widgetToCrash)
       
  9329     {
       
  9330         connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(beEvil(QObject *)));
       
  9331         delete widget;
       
  9332     }
       
  9333     QWidget *widget;
       
  9334 
       
  9335 private slots:
       
  9336     void beEvil(QObject *) { widget->update(0, 0, 150, 150); }
       
  9337 };
       
  9338 
       
  9339 void tst_QWidget::updateOnDestroyedSignal()
       
  9340 {
       
  9341     QWidget widget;
       
  9342 
       
  9343     QWidget *child = new QWidget(&widget);
       
  9344     child->resize(100, 100);
       
  9345     child->setAutoFillBackground(true);
       
  9346     child->setPalette(Qt::red);
       
  9347 
       
  9348     widget.show();
       
  9349 #ifdef Q_WS_X11
       
  9350     qt_x11_wait_for_window_manager(&widget);
       
  9351 #endif
       
  9352     QTest::qWait(200);
       
  9353 
       
  9354     // Please do not crash.
       
  9355     MyEvilObject evil(child);
       
  9356     QTest::qWait(200);
       
  9357 }
       
  9358 
       
  9359 void tst_QWidget::toplevelLineEditFocus()
       
  9360 {
       
  9361     testWidget->hide();
       
  9362 
       
  9363     QLineEdit w;
       
  9364     w.show();
       
  9365     QTest::qWaitForWindowShown(&w);
       
  9366     QTest::qWait(20);
       
  9367 
       
  9368     QTRY_COMPARE(QApplication::activeWindow(), (QWidget*)&w);
       
  9369     QTRY_COMPARE(QApplication::focusWidget(), (QWidget*)&w);
       
  9370 }
       
  9371 
       
  9372 void tst_QWidget::focusWidget_task254563()
       
  9373 {
       
  9374     //having different visibility for widget is important
       
  9375     QWidget top;
       
  9376     top.show();
       
  9377     QWidget container(&top);
       
  9378     QWidget *widget = new QWidget(&container);
       
  9379     widget->show();
       
  9380 
       
  9381     widget->setFocus(); //set focus (will set the focus widget up to the toplevel to be 'widget')
       
  9382     container.setFocus();
       
  9383     delete widget; // will call clearFocus but that doesn't help
       
  9384     QVERIFY(top.focusWidget() != widget); //dangling pointer
       
  9385 }
       
  9386 
       
  9387 void tst_QWidget::destroyBackingStore()
       
  9388 {
       
  9389 #ifdef QT_BUILD_INTERNAL
       
  9390     UpdateWidget w;
       
  9391     w.reset();
       
  9392     w.show();
       
  9393 
       
  9394     QTest::qWaitForWindowShown(&w);
       
  9395     QApplication::processEvents();
       
  9396     QTRY_VERIFY(w.numPaintEvents > 0);
       
  9397     w.reset();
       
  9398     w.update();
       
  9399     delete qt_widget_private(&w)->topData()->backingStore;
       
  9400     qt_widget_private(&w)->topData()->backingStore = 0;
       
  9401     qt_widget_private(&w)->topData()->backingStore = new QWidgetBackingStore(&w);
       
  9402 
       
  9403     w.update();
       
  9404     QApplication::processEvents();
       
  9405 #ifdef Q_WS_QWS
       
  9406     QApplication::processEvents();
       
  9407 #endif
       
  9408     QCOMPARE(w.numPaintEvents, 1);
       
  9409 
       
  9410     // Check one more time, because the second time around does more caching.
       
  9411     w.update();
       
  9412     QApplication::processEvents();
       
  9413     QCOMPARE(w.numPaintEvents, 2);
       
  9414 #endif
       
  9415 }
       
  9416 
       
  9417 void tst_QWidget::rectOutsideCoordinatesLimit_task144779()
       
  9418 {
       
  9419 #ifdef Q_OS_WINCE_WM
       
  9420     QSKIP( "Tables of 5000 elements do not make sense on Windows Mobile.", SkipAll);
       
  9421 #endif
       
  9422     QApplication::setOverrideCursor(Qt::BlankCursor); //keep the cursor out of screen grabs
       
  9423     QWidget main(0,Qt::FramelessWindowHint); //don't get confused by the size of the window frame
       
  9424     QPalette palette;
       
  9425     palette.setColor(QPalette::Window, Qt::red);
       
  9426     main.setPalette(palette);
       
  9427 
       
  9428     QDesktopWidget desktop;
       
  9429     QRect desktopDimensions = desktop.availableGeometry(&main);
       
  9430     QSize mainSize(400, 400);
       
  9431     mainSize = mainSize.boundedTo(desktopDimensions.size());
       
  9432     main.resize(mainSize);
       
  9433 
       
  9434     QWidget *offsetWidget = new QWidget(&main);
       
  9435     offsetWidget->setGeometry(0, -(15000 - mainSize.height()), mainSize.width(), 15000);
       
  9436 
       
  9437     // big widget is too big for the coordinates, it must be limited by wrect
       
  9438     // if wrect is not at the right position because of offsetWidget, bigwidget
       
  9439     // is not painted correctly
       
  9440     QWidget *bigWidget = new QWidget(offsetWidget);
       
  9441     bigWidget->setGeometry(0, 0, mainSize.width(), 50000);
       
  9442     palette.setColor(QPalette::Window, Qt::green);
       
  9443     bigWidget->setPalette(palette);
       
  9444     bigWidget->setAutoFillBackground(true);
       
  9445 
       
  9446     main.show();
       
  9447     QTest::qWaitForWindowShown(&main);
       
  9448 
       
  9449     QPixmap correct(main.size());
       
  9450     correct.fill(Qt::green);
       
  9451 
       
  9452     QTRY_COMPARE(QPixmap::grabWindow(main.winId()).toImage().convertToFormat(QImage::Format_RGB32),
       
  9453                  correct.toImage().convertToFormat(QImage::Format_RGB32));
       
  9454     QApplication::restoreOverrideCursor();
       
  9455 }
       
  9456 
       
  9457 void tst_QWidget::inputFocus_task257832()
       
  9458 {
       
  9459       QLineEdit *widget = new QLineEdit;
       
  9460       QInputContext *context = widget->inputContext();
       
  9461       if (!context)
       
  9462             QSKIP("No input context", SkipSingle);
       
  9463       widget->setFocus();
       
  9464       widget->winId();    // make sure, widget has been created
       
  9465       context->setFocusWidget(widget);
       
  9466       QCOMPARE(context->focusWidget(), static_cast<QWidget*>(widget));
       
  9467       widget->setReadOnly(true);
       
  9468       QVERIFY(!context->focusWidget());
       
  9469       delete widget;
       
  9470 }
       
  9471 
       
  9472 void tst_QWidget::setGraphicsEffect()
       
  9473 {
       
  9474     // Check that we don't have any effect by default.
       
  9475     QWidget *widget = new QWidget;
       
  9476     QVERIFY(!widget->graphicsEffect());
       
  9477 
       
  9478     // SetGet check.
       
  9479     QPointer<QGraphicsEffect> blurEffect = new QGraphicsBlurEffect;
       
  9480     widget->setGraphicsEffect(blurEffect);
       
  9481     QCOMPARE(widget->graphicsEffect(), static_cast<QGraphicsEffect *>(blurEffect));
       
  9482 
       
  9483     // Ensure the existing effect is deleted when setting a new one.
       
  9484     QPointer<QGraphicsEffect> shadowEffect = new QGraphicsDropShadowEffect;
       
  9485     widget->setGraphicsEffect(shadowEffect);
       
  9486     QVERIFY(!blurEffect);
       
  9487     QCOMPARE(widget->graphicsEffect(), static_cast<QGraphicsEffect *>(shadowEffect));
       
  9488     blurEffect = new QGraphicsBlurEffect;
       
  9489 
       
  9490     // Ensure the effect is uninstalled when setting it on a new target.
       
  9491     QWidget *anotherWidget = new QWidget;
       
  9492     anotherWidget->setGraphicsEffect(blurEffect);
       
  9493     widget->setGraphicsEffect(blurEffect);
       
  9494     QVERIFY(!anotherWidget->graphicsEffect());
       
  9495     QVERIFY(!shadowEffect);
       
  9496 
       
  9497     // Ensure the existing effect is deleted when deleting the widget.
       
  9498     delete widget;
       
  9499     QVERIFY(!blurEffect);
       
  9500     delete anotherWidget;
       
  9501 }
       
  9502 
       
  9503 void tst_QWidget::activateWindow()
       
  9504 {
       
  9505     // Test case for task 260685
       
  9506 
       
  9507     // Create first mainwindow and set it active
       
  9508     QMainWindow* mainwindow = new QMainWindow();
       
  9509     QLabel* label = new QLabel(mainwindow);
       
  9510     mainwindow->setCentralWidget(label);
       
  9511     mainwindow->setVisible(true);
       
  9512     mainwindow->activateWindow();
       
  9513     QTest::qWaitForWindowShown(mainwindow);
       
  9514     qApp->processEvents();
       
  9515 
       
  9516     QTRY_VERIFY(mainwindow->isActiveWindow());
       
  9517 
       
  9518     // Create second mainwindow and set it active
       
  9519     QMainWindow* mainwindow2 = new QMainWindow();
       
  9520     QLabel* label2 = new QLabel(mainwindow2);
       
  9521     mainwindow2->setCentralWidget(label2);
       
  9522     mainwindow2->setVisible(true);
       
  9523     mainwindow2->activateWindow();
       
  9524     qApp->processEvents();
       
  9525 
       
  9526     QTRY_VERIFY(!mainwindow->isActiveWindow());
       
  9527     QTRY_VERIFY(mainwindow2->isActiveWindow());
       
  9528 
       
  9529     // Revert first mainwindow back to visible active
       
  9530     mainwindow->setVisible(true);
       
  9531     mainwindow->activateWindow();
       
  9532     qApp->processEvents();
       
  9533 
       
  9534     QTRY_VERIFY(mainwindow->isActiveWindow());
       
  9535     QTRY_VERIFY(!mainwindow2->isActiveWindow());
       
  9536 }
       
  9537 
       
  9538 #ifdef Q_OS_SYMBIAN
       
  9539 void tst_QWidget::cbaVisibility()
       
  9540 {
       
  9541     // Test case for task 261048
       
  9542 
       
  9543     // Create first mainwindow in fullsreen and activate it
       
  9544     QMainWindow* mainwindow = new QMainWindow();
       
  9545     QLabel* label = new QLabel(mainwindow);
       
  9546     mainwindow->setCentralWidget(label);
       
  9547     mainwindow->setWindowState(Qt::WindowFullScreen);
       
  9548     mainwindow->setVisible(true);
       
  9549     mainwindow->activateWindow();
       
  9550     qApp->processEvents();
       
  9551 
       
  9552     QVERIFY(mainwindow->isActiveWindow());
       
  9553     QVERIFY(QDesktopWidget().availableGeometry().size() == mainwindow->size());
       
  9554 
       
  9555     // Create second mainwindow in maximized and activate it
       
  9556     QMainWindow* mainwindow2 = new QMainWindow();
       
  9557     QLabel* label2 = new QLabel(mainwindow2);
       
  9558     mainwindow2->setCentralWidget(label2);
       
  9559     mainwindow2->setWindowState(Qt::WindowMaximized);
       
  9560     mainwindow2->setVisible(true);
       
  9561     mainwindow2->activateWindow();
       
  9562     qApp->processEvents();
       
  9563 
       
  9564     QVERIFY(!mainwindow->isActiveWindow());
       
  9565     QVERIFY(mainwindow2->isActiveWindow());
       
  9566     QVERIFY(QDesktopWidget().availableGeometry().size() == mainwindow2->size());
       
  9567 
       
  9568     // Verify window decorations i.e. status pane and CBA are visible.
       
  9569     CEikStatusPane* statusPane = CEikonEnv::Static()->AppUiFactory()->StatusPane();
       
  9570     QVERIFY(statusPane->IsVisible());
       
  9571     CEikButtonGroupContainer* buttonGroup = CEikonEnv::Static()->AppUiFactory()->Cba();
       
  9572     QVERIFY(buttonGroup->IsVisible());
       
  9573 }
       
  9574 #endif
       
  9575 
       
  9576 QTEST_MAIN(tst_QWidget)
       
  9577 #include "tst_qwidget.moc"