1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <qboxlayout.h>
44 #include <qapplication.h>
47 #include <qeventloop.h>
50 #include <qlineedit.h>
51 #include <qlistview.h>
52 #include <qmessagebox.h>
55 #include <qpushbutton.h>
58 #include <qwindowsstyle.h>
59 #include <qdesktopwidget.h>
60 #include <private/qwidget_p.h>
61 #include <private/qapplication_p.h>
62 #include <qcalendarwidget.h>
63 #include <qmainwindow.h>
64 #include <qdockwidget.h>
66 #include <QtGui/qpaintengine.h>
67 #include <QtGui/qbackingstore.h>
68 #include <QtGui/qguiapplication.h>
70 #include <qtableview.h>
71 #include <qtreewidget.h>
73 #include <QtWidgets/QGraphicsView>
74 #include <QtWidgets/QGraphicsProxyWidget>
77 # include <qscreen_qws.h>
81 #include "tst_qwidget_mac_helpers.h" // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile.
84 #include <QtTest/QtTest>
87 # include <QtCore/qt_windows.h>
88 # include <QtGui/private/qguiapplication_p.h>
89 # include <QtGui/QPlatformNativeInterface>
90 # include <QtGui/QPlatformIntegration>
92 static HWND winHandleOf(const QWidget *w)
94 static QPlatformNativeInterface *nativeInterface
95 = QGuiApplicationPrivate::instance()->platformIntegration()->nativeInterface();
96 if (void *handle = nativeInterface->nativeResourceForWindow("handle", w->window()->windowHandle()))
97 return reinterpret_cast<HWND>(handle);
98 qWarning() << "Cannot obtain native handle for " << w;
103 #if defined(Q_WS_WIN)
104 # include <qt_windows.h>
105 # if !defined(Q_OS_WINCE)
106 #define Q_CHECK_PAINTEVENTS \
107 if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
108 QSKIP("desktop is not visible, this test would fail");
110 # define Q_CHECK_PAINTEVENTS
112 #elif defined(Q_WS_X11)
113 # include <private/qt_x11_p.h>
114 # include <qx11info_x11.h>
115 #elif defined(Q_WS_QWS)
116 # include <qwindowsystem_qws.h>
119 #if !defined(Q_WS_WIN)
120 #define Q_CHECK_PAINTEVENTS
123 #if defined(Q_OS_WINCE_WM)
124 #include <qguifunctions_wince.h>
125 // taken from qguifunctions_wce.cpp
126 #define SPI_GETPLATFORMTYPE 257
127 bool qt_wince_is_platform(const QString &platformString) {
128 wchar_t tszPlatform[64];
129 if (SystemParametersInfo(SPI_GETPLATFORMTYPE,
130 sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0))
131 if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform))
135 bool qt_wince_is_smartphone() {
136 return qt_wince_is_platform(QString::fromLatin1("Smartphone"));
141 #include <Security/AuthSession.h>
142 bool macHasAccessToWindowsServer()
144 SecuritySessionId mySession;
145 SessionAttributeBits sessionInfo;
146 SessionGetInfo(callerSecuritySession, &mySession, &sessionInfo);
147 return (sessionInfo & sessionHasGraphicAccess);
156 class tst_QWidget : public QObject
162 virtual ~tst_QWidget();
166 void cleanupTestCase();
171 void fontPropagation();
172 void fontPropagation2();
173 void palettePropagation();
174 void palettePropagation2();
175 void enabledPropagation();
176 #ifndef QT_NO_DRAGANDDROP
177 void acceptDropsPropagation();
181 void visible_setWindowOpacity();
185 void mapFromAndTo_data();
187 void focusChainOnHide();
188 void focusChainOnReparent();
197 void showMaximized();
198 void showFullScreen();
199 void showMinimized();
200 void showMinimizedKeepsFocus();
204 void hideWhenFocusWidgetIsChild();
206 void normalGeometry();
210 void windowOpacity();
214 #ifndef QT_MAC_USE_COCOA
217 void testContentsPropagation();
219 void saveRestoreGeometry();
220 void restoreVersion1Geometry_data();
221 void restoreVersion1Geometry();
229 void optimizedResizeMove();
230 void optimizedResize_topLevel();
234 void testDeletionInEventHandlers();
236 void childDeletesItsSibling();
238 void setMinimumSize();
239 void setMaximumSize();
242 void ensureCreated();
243 void winIdChangeEvent();
244 void persistentWinId();
245 void showNativeChild();
246 void qobject_castInDestroyedSlot();
248 void showHideEvent_data();
249 void showHideEvent();
251 void lostUpdatesOnHide();
261 // tests QWidget::setGeometry()
262 void setWindowGeometry_data();
263 void setWindowGeometry();
266 #if !defined(Q_WS_X11) && !defined(Q_OS_IRIX)
267 // tests QWidget::move() and resize()
268 void windowMoveResize_data();
269 void windowMoveResize();
272 void moveChild_data();
274 void showAndMoveChild();
276 #ifndef QT_MAC_USE_COCOA
277 void subtractOpaqueSiblings();
283 void setGeometry_win();
289 void multipleToplevelFocusCheck();
293 void testWindowIconChangeEventPropagation();
295 void minAndMaxSizeWithX11BypassWindowManagerHint();
297 void clean_qt_x11_enforce_cursor();
302 void renderInvisible();
303 void renderWithPainter();
304 void render_task188133();
305 void render_task211796();
306 void render_task217815();
308 void render_windowOpacity();
310 void render_systemClip();
311 void render_systemClip2_data();
312 void render_systemClip2();
313 void render_systemClip3_data();
314 void render_systemClip3();
315 void render_task252837();
316 void render_worldTransform();
318 void setContentsMargins();
321 void moveWindowInShowEvent_data();
322 void moveWindowInShowEvent();
325 void repaintWhenChildDeleted();
326 void hideOpaqueChildWhileHidden();
327 #if !defined(Q_OS_WINCE) && !defined(Q_WS_QWS)
328 void updateWhileMinimized();
330 #if defined(Q_WS_WIN) || defined(Q_WS_X11)
334 void adjustSize_data();
335 void updateGeometry();
336 void updateGeometry_data();
337 void sendUpdateRequestImmediately();
339 void doubleRepaint();
341 void resizeInPaintEvent();
342 void opaqueChildren();
344 void setMaskInResizeEvent();
345 void moveInResizeEvent();
347 #if defined(Q_WS_WIN) || defined(Q_WS_X11)
348 // We don't support immediate repaint right after show on
349 // other platforms. Must be compatible with Qt 4.3.
350 void immediateRepaintAfterShow();
351 void immediateRepaintAfterInvalidateBuffer();
353 void effectiveWinId();
354 void effectiveWinId2();
356 void customDpiProperty();
358 void quitOnCloseAttribute();
361 #if defined (Q_WS_WIN)
363 void paintOnScreenPossible();
365 void reparentStaticWidget();
366 void QTBUG6883_reparentStaticWidget2();
368 void updateOutsideSurfaceClip();
370 void translucentWidget();
372 void setClearAndResizeMask();
374 #if !defined(Q_OS_WINCE_WM)
375 void syntheticEnterLeave();
376 void taskQTBUG_4055_sendSyntheticEnterLeave();
379 void initialPosForDontShowOnScreenWidgets();
380 void updateOnDestroyedSignal();
381 void toplevelLineEditFocus();
382 void inputFocus_task257832();
384 void focusWidget_task254563();
385 #ifndef Q_OS_WINCE_WM
386 void rectOutsideCoordinatesLimit_task144779();
388 void setGraphicsEffect();
390 #ifdef QT_BUILD_INTERNAL
391 void destroyBackingStore();
394 void activateWindow();
396 void openModal_taskQTBUG_5804();
398 void focusProxyAndInputMethods();
399 #ifdef QT_BUILD_INTERNAL
400 void scrollWithoutBackingStore();
403 void taskQTBUG_7532_tabOrderWithFocusProxy();
404 void movedAndResizedAttributes();
407 void childAt_unifiedToolBar();
408 void taskQTBUG_11373();
410 void taskQTBUG_17333_ResizeInfiniteRecursion();
412 void nativeChildFocus();
416 bool ensureScreenSize(int width, int height);
420 bool tst_QWidget::ensureScreenSize(int width, int height)
424 available = QDesktopWidget().availableGeometry().size();
425 if (available.width() < width || available.height() < height) {
426 QScreen *screen = QScreen::instance();
429 screen->setMode(width, height, screen->depth());
433 available = QDesktopWidget().availableGeometry().size();
434 return (available.width() >= width && available.height() >= height);
437 // Testing get/set functions
438 void tst_QWidget::getSetCheck()
441 QWidget child1(&obj1);
442 // QStyle * QWidget::style()
443 // void QWidget::setStyle(QStyle *)
444 QWindowsStyle *var1 = new QWindowsStyle;
446 QCOMPARE(static_cast<QStyle *>(var1), obj1.style());
447 obj1.setStyle((QStyle *)0);
448 QVERIFY(var1 != obj1.style());
449 QVERIFY(0 != obj1.style()); // style can never be 0 for a widget
451 // int QWidget::minimumWidth()
452 // void QWidget::setMinimumWidth(int)
453 obj1.setMinimumWidth(0);
454 QCOMPARE(obj1.minimumWidth(), 0);
455 obj1.setMinimumWidth(INT_MIN);
456 QCOMPARE(obj1.minimumWidth(), 0); // A widgets width can never be less than 0
457 obj1.setMinimumWidth(INT_MAX);
458 #ifndef Q_WS_QWS //QWS doesn't allow toplevels to be bigger than the screen
459 QCOMPARE(obj1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
462 child1.setMinimumWidth(0);
463 QCOMPARE(child1.minimumWidth(), 0);
464 child1.setMinimumWidth(INT_MIN);
465 QCOMPARE(child1.minimumWidth(), 0); // A widgets width can never be less than 0
466 child1.setMinimumWidth(INT_MAX);
467 QCOMPARE(child1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
469 // int QWidget::minimumHeight()
470 // void QWidget::setMinimumHeight(int)
471 obj1.setMinimumHeight(0);
472 QCOMPARE(obj1.minimumHeight(), 0);
473 obj1.setMinimumHeight(INT_MIN);
474 QCOMPARE(obj1.minimumHeight(), 0); // A widgets height can never be less than 0
475 obj1.setMinimumHeight(INT_MAX);
476 #ifndef Q_WS_QWS //QWS doesn't allow toplevels to be bigger than the screen
477 QCOMPARE(obj1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
480 child1.setMinimumHeight(0);
481 QCOMPARE(child1.minimumHeight(), 0);
482 child1.setMinimumHeight(INT_MIN);
483 QCOMPARE(child1.minimumHeight(), 0); // A widgets height can never be less than 0
484 child1.setMinimumHeight(INT_MAX);
485 QCOMPARE(child1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium
487 // int QWidget::maximumWidth()
488 // void QWidget::setMaximumWidth(int)
489 obj1.setMaximumWidth(0);
490 QCOMPARE(obj1.maximumWidth(), 0);
491 obj1.setMaximumWidth(INT_MIN);
492 QCOMPARE(obj1.maximumWidth(), 0); // A widgets width can never be less than 0
493 obj1.setMaximumWidth(INT_MAX);
494 QCOMPARE(obj1.maximumWidth(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
496 // int QWidget::maximumHeight()
497 // void QWidget::setMaximumHeight(int)
498 obj1.setMaximumHeight(0);
499 QCOMPARE(obj1.maximumHeight(), 0);
500 obj1.setMaximumHeight(INT_MIN);
501 QCOMPARE(obj1.maximumHeight(), 0); // A widgets height can never be less than 0
502 obj1.setMaximumHeight(INT_MAX);
503 QCOMPARE(obj1.maximumHeight(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX
506 obj1.setMinimumWidth(0);
507 obj1.setMinimumHeight(0);
508 obj1.setMaximumWidth(QWIDGETSIZE_MAX);
509 obj1.setMaximumHeight(QWIDGETSIZE_MAX);
511 // const QPalette & QWidget::palette()
512 // void QWidget::setPalette(const QPalette &)
514 obj1.setPalette(var6);
515 QCOMPARE(var6, obj1.palette());
516 obj1.setPalette(QPalette());
517 QCOMPARE(QPalette(), obj1.palette());
519 // const QFont & QWidget::font()
520 // void QWidget::setFont(const QFont &)
523 QCOMPARE(var7, obj1.font());
524 obj1.setFont(QFont());
525 QCOMPARE(QFont(), obj1.font());
527 // qreal QWidget::windowOpacity()
528 // void QWidget::setWindowOpacity(qreal)
529 obj1.setWindowOpacity(0.0);
530 QCOMPARE(0.0, obj1.windowOpacity());
531 obj1.setWindowOpacity(1.1f);
532 QCOMPARE(1.0, obj1.windowOpacity()); // 1.0 is the fullest opacity possible
534 // QWidget * QWidget::focusProxy()
535 // void QWidget::setFocusProxy(QWidget *)
536 QWidget *var9 = new QWidget();
537 obj1.setFocusProxy(var9);
538 QCOMPARE(var9, obj1.focusProxy());
539 obj1.setFocusProxy((QWidget *)0);
540 QCOMPARE((QWidget *)0, obj1.focusProxy());
543 // const QRect & QWidget::geometry()
544 // void QWidget::setGeometry(const QRect &)
545 qApp->processEvents();
546 QRect var10(10, 10, 100, 100);
547 obj1.setGeometry(var10);
548 qApp->processEvents();
549 qDebug() << obj1.geometry();
550 QCOMPARE(var10, obj1.geometry());
551 obj1.setGeometry(QRect(0,0,0,0));
552 qDebug() << obj1.geometry();
553 QCOMPARE(QRect(0,0,0,0), obj1.geometry());
555 // QLayout * QWidget::layout()
556 // void QWidget::setLayout(QLayout *)
557 QBoxLayout *var11 = new QBoxLayout(QBoxLayout::LeftToRight);
558 obj1.setLayout(var11);
559 QCOMPARE(static_cast<QLayout *>(var11), obj1.layout());
560 obj1.setLayout((QLayout *)0);
561 QCOMPARE(static_cast<QLayout *>(var11), obj1.layout()); // You cannot set a 0-pointer layout, that keeps the current
562 delete var11; // This will remove the layout from the widget
563 QCOMPARE((QLayout *)0, obj1.layout());
565 // bool QWidget::acceptDrops()
566 // void QWidget::setAcceptDrops(bool)
567 obj1.setAcceptDrops(false);
568 QCOMPARE(false, obj1.acceptDrops());
569 obj1.setAcceptDrops(true);
570 QCOMPARE(true, obj1.acceptDrops());
572 // bool QWidget::autoFillBackground()
573 // void QWidget::setAutoFillBackground(bool)
574 obj1.setAutoFillBackground(false);
575 QCOMPARE(false, obj1.autoFillBackground());
576 obj1.setAutoFillBackground(true);
577 QCOMPARE(true, obj1.autoFillBackground());
580 #if defined (Q_WS_WIN) && !defined(Q_OS_WINCE)
581 obj1.setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
582 HWND handle = obj1.winId();
583 long flags = GetWindowLong(handle, GWL_STYLE);
584 QVERIFY(flags & WS_POPUP);
588 tst_QWidget::tst_QWidget()
592 font.setPointSize(42);
593 qApp->setFont(font, "QPropagationTestWidget");
596 palette.setColor(QPalette::ToolTipBase, QColor(12, 13, 14));
597 palette.setColor(QPalette::Text, QColor(21, 22, 23));
598 qApp->setPalette(palette, "QPropagationTestWidget");
603 tst_QWidget::~tst_QWidget()
607 class BezierViewer : public QWidget {
609 BezierViewer( QWidget* parent=0, const char* name=0 );
610 void paintEvent( QPaintEvent* );
611 void setPoints( const QPolygonF& poly );
617 void tst_QWidget::initTestCase()
619 #ifdef Q_OS_WINCE //disable magic for WindowsCE
620 qApp->setAutoMaximizeThreshold(-1);
622 // Create the test class
623 testWidget = new BezierViewer( 0, "testObject");
624 testWidget->resize(200,200);
626 QTest::qWaitForWindowShown(testWidget);
630 void tst_QWidget::cleanupTestCase()
636 void tst_QWidget::init()
638 // TODO: Add initialization code here.
639 // This will be executed immediately before each test is run.
640 testWidget->setFont(QFont());
641 testWidget->setPalette(QPalette());
644 void tst_QWidget::cleanup()
650 BezierViewer::BezierViewer( QWidget* parent, const char* name )
655 pal.setColor(backgroundRole(), Qt::white);
660 void BezierViewer::setPoints( const QPolygonF& a )
665 #include "private/qbezier_p.h"
666 void BezierViewer::paintEvent( QPaintEvent* )
668 if ( points.size() != 4 ) {
669 #if defined(QT_CHECK_RANGE)
670 qWarning( "QPolygon::bezier: The array must have 4 control points" );
675 /* Calculate Bezier curve */
676 QPolygonF bezier = QBezier::fromPoints(points.at(0),points.at(1),points.at(2),points.at(3)).toPolygon();
678 QPainter painter( this );
680 /* Calculate scale to fit in window */
681 QRectF br = bezier.boundingRect() | points.boundingRect();
683 int scl = qMax( qMin(pr.width()/br.width(), pr.height()/br.height()), qreal(1.) );
686 /* Scale Bezier curve vertices */
687 for ( QPolygonF::Iterator it = bezier.begin(); it != bezier.end(); ++it ) {
688 it->setX( (it->x()-br.x()) * scl + border );
689 it->setY( (it->y()-br.y()) * scl + border );
693 painter.setPen( Qt::lightGray );
695 for ( i = border; i <= pr.width(); i += scl ) {
696 painter.drawLine( i, 0, i, pr.height() );
698 for ( int j = border; j <= pr.height(); j += scl ) {
699 painter.drawLine( 0, j, pr.width(), j );
702 /* Write number of vertices */
703 painter.setPen( Qt::red );
704 painter.setFont( QFont("Helvetica", 14, QFont::DemiBold, true ) );
706 caption.setNum( bezier.size() );
707 caption += QString::fromLatin1( " vertices" );
708 painter.drawText( 10, pr.height()-10, caption );
710 /* Draw Bezier curve */
711 painter.setPen( Qt::black );
712 painter.drawPolyline( bezier );
714 /* Scale and draw control points */
715 painter.setPen( Qt::darkGreen );
716 for ( QPolygonF::Iterator p1 = points.begin(); p1 != points.end(); ++p1 ) {
717 int x = (p1->x()-br.x()) * scl + border;
718 int y = (p1->y()-br.y()) * scl + border;
719 painter.drawLine( x-4, y-4, x+4, y+4 );
720 painter.drawLine( x+4, y-4, x-4, y+4 );
724 painter.setPen( Qt::red );
725 painter.setBrush( Qt::red );
726 for ( QPolygonF::Iterator p2 = bezier.begin(); p2 != bezier.end(); ++p2 )
727 painter.drawEllipse( p2->x()-1, p2->y()-1, 3, 3 );
730 void tst_QWidget::fontPropagation()
732 QFont font = testWidget->font();
733 QWidget* childWidget = new QWidget( testWidget );
735 QCOMPARE( font, childWidget->font() );
737 font.setBold( true );
738 testWidget->setFont( font );
739 QCOMPARE( font, testWidget->font() );
740 QCOMPARE( font, childWidget->font() );
742 QFont newFont = font;
743 newFont.setItalic( true );
744 childWidget->setFont( newFont );
745 QWidget* grandChildWidget = new QWidget( childWidget );
746 QCOMPARE( font, testWidget->font() );
747 QCOMPARE( newFont, grandChildWidget->font() );
749 font.setUnderline( true );
750 testWidget->setFont( font );
752 // the child and grand child should now have merged bold and
754 newFont.setUnderline( true );
756 QCOMPARE( newFont, childWidget->font() );
757 QCOMPARE( newFont, grandChildWidget->font() );
759 // make sure font propagation continues working after reparenting
760 font = testWidget->font();
761 font.setPointSize(font.pointSize() + 2);
762 testWidget->setFont(font);
764 QWidget *one = new QWidget(testWidget);
765 QWidget *two = new QWidget(one);
766 QWidget *three = new QWidget(two);
767 QWidget *four = new QWidget(two);
769 four->setParent(three);
770 four->move(QPoint(0,0));
772 font.setPointSize(font.pointSize() + 2);
773 testWidget->setFont(font);
775 QCOMPARE(testWidget->font(), one->font());
776 QCOMPARE(one->font(), two->font());
777 QCOMPARE(two->font(), three->font());
778 QCOMPARE(three->font(), four->font());
780 QVERIFY(testWidget->testAttribute(Qt::WA_SetFont));
781 QVERIFY(! one->testAttribute(Qt::WA_SetFont));
782 QVERIFY(! two->testAttribute(Qt::WA_SetFont));
783 QVERIFY(! three->testAttribute(Qt::WA_SetFont));
784 QVERIFY(! four->testAttribute(Qt::WA_SetFont));
786 font.setPointSize(font.pointSize() + 2);
789 QCOMPARE(one->font(), two->font());
790 QCOMPARE(two->font(), three->font());
791 QCOMPARE(three->font(), four->font());
793 QVERIFY(one->testAttribute(Qt::WA_SetFont));
794 QVERIFY(! two->testAttribute(Qt::WA_SetFont));
795 QVERIFY(! three->testAttribute(Qt::WA_SetFont));
796 QVERIFY(! four->testAttribute(Qt::WA_SetFont));
798 font.setPointSize(font.pointSize() + 2);
801 QCOMPARE(two->font(), three->font());
802 QCOMPARE(three->font(), four->font());
804 QVERIFY(two->testAttribute(Qt::WA_SetFont));
805 QVERIFY(! three->testAttribute(Qt::WA_SetFont));
806 QVERIFY(! four->testAttribute(Qt::WA_SetFont));
808 font.setPointSize(font.pointSize() + 2);
809 three->setFont(font);
811 QCOMPARE(three->font(), four->font());
813 QVERIFY(three->testAttribute(Qt::WA_SetFont));
814 QVERIFY(! four->testAttribute(Qt::WA_SetFont));
816 font.setPointSize(font.pointSize() + 2);
819 QVERIFY(four->testAttribute(Qt::WA_SetFont));
822 class QPropagationTestWidget : public QWidget
826 QPropagationTestWidget(QWidget *parent = 0)
831 void tst_QWidget::fontPropagation2()
833 // ! Note, the code below is executed in tst_QWidget's constructor.
835 // font.setBold(true);
836 // font.setPointSize(42);
837 // qApp->setFont(font, "QPropagationTestWidget");
839 QWidget *root = new QWidget;
840 QWidget *child0 = new QWidget(root);
841 QWidget *child1 = new QWidget(child0);
842 QWidget *child2 = new QPropagationTestWidget(child1);
843 QWidget *child3 = new QWidget(child2);
844 QWidget *child4 = new QWidget(child3);
845 QWidget *child5 = new QWidget(child4);
848 // Check that only the application fonts apply.
849 QCOMPARE(root->font(), QApplication::font());
850 QCOMPARE(child0->font(), QApplication::font());
851 QCOMPARE(child1->font(), QApplication::font());
852 QCOMPARE(child2->font().pointSize(), 42);
853 QVERIFY(child2->font().bold());
854 QCOMPARE(child3->font().pointSize(), 42);
855 QVERIFY(child3->font().bold());
856 QCOMPARE(child4->font().pointSize(), 42);
857 QVERIFY(child4->font().bold());
858 QCOMPARE(child5->font().pointSize(), 42);
859 QVERIFY(child5->font().bold());
861 // Set child0's font size to 15, and remove bold on child4.
863 font.setPointSize(15);
864 child0->setFont(font);
866 unboldFont.setBold(false);
867 child4->setFont(unboldFont);
869 // Check that the above settings propagate correctly.
870 QCOMPARE(root->font(), QApplication::font());
871 QCOMPARE(child0->font().pointSize(), 15);
872 QVERIFY(!child0->font().bold());
873 QCOMPARE(child1->font().pointSize(), 15);
874 QVERIFY(!child1->font().bold());
875 QCOMPARE(child2->font().pointSize(), 15);
876 QVERIFY(child2->font().bold());
877 QCOMPARE(child3->font().pointSize(), 15);
878 QVERIFY(child3->font().bold());
879 QCOMPARE(child4->font().pointSize(), 15);
880 QVERIFY(!child4->font().bold());
881 QCOMPARE(child5->font().pointSize(), 15);
882 QVERIFY(!child5->font().bold());
884 // Replace the app font for child2. Italic should propagate
885 // but the size should still be ignored. The previous bold
887 QFont italicSizeFont;
888 italicSizeFont.setItalic(true);
889 italicSizeFont.setPointSize(33);
890 qApp->setFont(italicSizeFont, "QPropagationTestWidget");
892 // Check that this propagates correctly.
893 QCOMPARE(root->font(), QApplication::font());
894 QCOMPARE(child0->font().pointSize(), 15);
895 QVERIFY(!child0->font().bold());
896 QVERIFY(!child0->font().italic());
897 QCOMPARE(child1->font().pointSize(), 15);
898 QVERIFY(!child1->font().bold());
899 QVERIFY(!child1->font().italic());
900 QCOMPARE(child2->font().pointSize(), 15);
901 QVERIFY(!child2->font().bold());
902 QVERIFY(child2->font().italic());
903 QCOMPARE(child3->font().pointSize(), 15);
904 QVERIFY(!child3->font().bold());
905 QVERIFY(child3->font().italic());
906 QCOMPARE(child4->font().pointSize(), 15);
907 QVERIFY(!child4->font().bold());
908 QVERIFY(child4->font().italic());
909 QCOMPARE(child5->font().pointSize(), 15);
910 QVERIFY(!child5->font().bold());
911 QVERIFY(child5->font().italic());
914 void tst_QWidget::palettePropagation()
916 QPalette palette = testWidget->palette();
917 QWidget* childWidget = new QWidget( testWidget );
919 QCOMPARE( palette, childWidget->palette() );
921 palette.setColor( QPalette::Base, Qt::red );
922 testWidget->setPalette( palette );
923 QCOMPARE( palette, testWidget->palette() );
924 QCOMPARE( palette, childWidget->palette() );
926 QPalette newPalette = palette;
927 newPalette.setColor( QPalette::Highlight, Qt::green );
928 childWidget->setPalette( newPalette );
929 QWidget* grandChildWidget = new QWidget( childWidget );
930 QCOMPARE( palette, testWidget->palette() );
931 QCOMPARE( newPalette, grandChildWidget->palette() );
933 palette.setColor( QPalette::Text, Qt::blue );
934 testWidget->setPalette( palette );
936 // the child and grand child should now have merged green
937 // highlight and blue text
938 newPalette.setColor( QPalette::Text, Qt::blue);
940 QCOMPARE( newPalette, childWidget->palette() );
941 QCOMPARE( newPalette, grandChildWidget->palette() );
944 void tst_QWidget::palettePropagation2()
946 // ! Note, the code below is executed in tst_QWidget's constructor.
948 // font.setColor(QPalette::ToolTipBase, QColor(12, 13, 14));
949 // font.setColor(QPalette::Text, QColor(21, 22, 23));
950 // qApp->setPalette(palette, "QPropagationTestWidget");
952 QWidget *root = new QWidget;
953 QWidget *child0 = new QWidget(root);
954 QWidget *child1 = new QWidget(child0);
955 QWidget *child2 = new QPropagationTestWidget(child1);
956 QWidget *child3 = new QWidget(child2);
957 QWidget *child4 = new QWidget(child3);
958 QWidget *child5 = new QWidget(child4);
962 // These colors are unlikely to be imposed on the default palette of
964 QColor sysPalText(21, 22, 23);
965 QColor sysPalToolTipBase(12, 13, 14);
966 QColor overridePalText(42, 43, 44);
967 QColor overridePalToolTipBase(45, 46, 47);
968 QColor sysPalButton(99, 98, 97);
970 // Check that only the application fonts apply.
971 QPalette appPal = QApplication::palette();
972 QCOMPARE(root->palette(), appPal);
973 QCOMPARE(child0->palette(), appPal);
974 QCOMPARE(child1->palette(), appPal);
975 QCOMPARE(child2->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
976 QCOMPARE(child2->palette().color(QPalette::Text), sysPalText);
977 QCOMPARE(child2->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
978 QCOMPARE(child3->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
979 QCOMPARE(child3->palette().color(QPalette::Text), sysPalText);
980 QCOMPARE(child3->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
981 QCOMPARE(child4->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
982 QCOMPARE(child4->palette().color(QPalette::Text), sysPalText);
983 QCOMPARE(child4->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
984 QCOMPARE(child5->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
985 QCOMPARE(child5->palette().color(QPalette::Text), sysPalText);
986 QCOMPARE(child5->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
988 // Set child0's Text, and set ToolTipBase on child4.
989 QPalette textPalette;
990 textPalette.setColor(QPalette::Text, overridePalText);
991 child0->setPalette(textPalette);
992 QPalette toolTipPalette;
993 toolTipPalette.setColor(QPalette::ToolTipBase, overridePalToolTipBase);
994 child4->setPalette(toolTipPalette);
996 // Check that the above settings propagate correctly.
997 QCOMPARE(root->palette(), appPal);
998 QCOMPARE(child0->palette().color(QPalette::Text), overridePalText);
999 QCOMPARE(child0->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
1000 QCOMPARE(child0->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
1001 QCOMPARE(child1->palette().color(QPalette::Text), overridePalText);
1002 QCOMPARE(child1->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
1003 QCOMPARE(child1->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
1004 QCOMPARE(child2->palette().color(QPalette::Text), overridePalText);
1005 QCOMPARE(child2->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
1006 QCOMPARE(child2->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
1007 QCOMPARE(child3->palette().color(QPalette::Text), overridePalText);
1008 QCOMPARE(child3->palette().color(QPalette::ToolTipBase), sysPalToolTipBase);
1009 QCOMPARE(child3->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
1010 QCOMPARE(child4->palette().color(QPalette::Text), overridePalText);
1011 QCOMPARE(child4->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
1012 QCOMPARE(child4->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
1013 QCOMPARE(child5->palette().color(QPalette::Text), overridePalText);
1014 QCOMPARE(child5->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
1015 QCOMPARE(child5->palette().color(QPalette::ToolTipText), appPal.color(QPalette::ToolTipText));
1017 // Replace the app palette for child2. Button should propagate but Text
1018 // should still be ignored. The previous ToolTipBase setting is gone.
1019 QPalette buttonPalette;
1020 buttonPalette.setColor(QPalette::ToolTipText, sysPalButton);
1021 qApp->setPalette(buttonPalette, "QPropagationTestWidget");
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), appPal.color(QPalette::ToolTipBase));
1033 QCOMPARE(child2->palette().color(QPalette::ToolTipText), sysPalButton);
1034 QCOMPARE(child3->palette().color(QPalette::Text), overridePalText);
1035 QCOMPARE(child3->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
1036 QCOMPARE(child3->palette().color(QPalette::ToolTipText), sysPalButton);
1037 QCOMPARE(child4->palette().color(QPalette::Text), overridePalText);
1038 QCOMPARE(child4->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
1039 QCOMPARE(child4->palette().color(QPalette::ToolTipText), sysPalButton);
1040 QCOMPARE(child5->palette().color(QPalette::Text), overridePalText);
1041 QCOMPARE(child5->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
1042 QCOMPARE(child5->palette().color(QPalette::ToolTipText), sysPalButton);
1045 void tst_QWidget::enabledPropagation()
1047 QWidget* childWidget = new QWidget( testWidget );
1048 childWidget->show();
1049 QVERIFY( testWidget->isEnabled() );
1050 QVERIFY( childWidget->isEnabled() );
1052 testWidget->setEnabled( false );
1053 QVERIFY( !testWidget->isEnabled() );
1054 QVERIFY( !childWidget->isEnabled() );
1056 testWidget->setDisabled( false );
1057 QVERIFY( testWidget->isEnabled() );
1058 QVERIFY( childWidget->isEnabled() );
1060 QWidget* grandChildWidget = new QWidget( childWidget );
1061 QVERIFY( grandChildWidget->isEnabled() );
1063 testWidget->setDisabled( true );
1064 QVERIFY( !testWidget->isEnabled() );
1065 QVERIFY( !childWidget->isEnabled() );
1066 QVERIFY( !grandChildWidget->isEnabled() );
1068 grandChildWidget->setEnabled( false );
1069 testWidget->setEnabled( true );
1070 QVERIFY( testWidget->isEnabled() );
1071 QVERIFY( childWidget->isEnabled() );
1072 QVERIFY( !grandChildWidget->isEnabled() );
1074 grandChildWidget->setEnabled( true );
1075 testWidget->setEnabled( false );
1076 childWidget->setDisabled( true );
1077 testWidget->setEnabled( true );
1078 QVERIFY( testWidget->isEnabled() );
1079 QVERIFY( !childWidget->isEnabled() );
1080 QVERIFY( !grandChildWidget->isEnabled() );
1083 // Drag'n drop disabled in this build.
1084 #ifndef QT_NO_DRAGANDDROP
1085 void tst_QWidget::acceptDropsPropagation()
1087 QWidget *childWidget = new QWidget(testWidget);
1088 childWidget->show();
1089 QVERIFY(!testWidget->acceptDrops());
1090 QVERIFY(!childWidget->acceptDrops());
1092 testWidget->setAcceptDrops(true);
1093 QVERIFY(testWidget->acceptDrops());
1094 QVERIFY(!childWidget->acceptDrops());
1095 QVERIFY(childWidget->testAttribute(Qt::WA_DropSiteRegistered));
1097 testWidget->setAcceptDrops(false);
1098 QVERIFY(!testWidget->acceptDrops());
1099 QVERIFY(!childWidget->acceptDrops());
1100 QVERIFY(!childWidget->testAttribute(Qt::WA_DropSiteRegistered));
1102 QWidget *grandChildWidget = new QWidget(childWidget);
1103 QVERIFY(!grandChildWidget->acceptDrops());
1104 QVERIFY(!grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
1106 testWidget->setAcceptDrops(true);
1107 QVERIFY(testWidget->acceptDrops());
1108 QVERIFY(!childWidget->acceptDrops());
1109 QVERIFY(childWidget->testAttribute(Qt::WA_DropSiteRegistered));
1110 QVERIFY(!grandChildWidget->acceptDrops());
1111 QVERIFY(grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
1113 grandChildWidget->setAcceptDrops(true);
1114 testWidget->setAcceptDrops(false);
1115 QVERIFY(!testWidget->acceptDrops());
1116 QVERIFY(!childWidget->acceptDrops());
1117 QVERIFY(grandChildWidget->acceptDrops());
1118 QVERIFY(grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
1120 grandChildWidget->setAcceptDrops(false);
1121 QVERIFY(!grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
1122 testWidget->setAcceptDrops(true);
1123 childWidget->setAcceptDrops(true);
1124 testWidget->setAcceptDrops(false);
1125 QVERIFY(!testWidget->acceptDrops());
1126 QVERIFY(childWidget->acceptDrops());
1127 QVERIFY(!grandChildWidget->acceptDrops());
1128 QVERIFY(grandChildWidget->testAttribute(Qt::WA_DropSiteRegistered));
1132 void tst_QWidget::isEnabledTo()
1134 QWidget* childWidget = new QWidget( testWidget );
1135 QWidget* grandChildWidget = new QWidget( childWidget );
1137 QVERIFY( childWidget->isEnabledTo( testWidget ) );
1138 QVERIFY( grandChildWidget->isEnabledTo( testWidget ) );
1140 childWidget->setEnabled( false );
1141 QVERIFY( !childWidget->isEnabledTo( testWidget ) );
1142 QVERIFY( grandChildWidget->isEnabledTo( childWidget ) );
1143 QVERIFY( !grandChildWidget->isEnabledTo( testWidget ) );
1146 void tst_QWidget::visible()
1148 // Ensure that the testWidget is hidden for this test at the
1152 QVERIFY( !testWidget->isVisible() );
1153 QWidget* childWidget = new QWidget( testWidget );
1154 QVERIFY( !childWidget->isVisible() );
1157 QVERIFY( testWidget->isVisible() );
1158 QVERIFY( childWidget->isVisible() );
1160 QWidget* grandChildWidget = new QWidget( childWidget );
1161 QVERIFY( !grandChildWidget->isVisible() );
1162 grandChildWidget->show();
1163 QVERIFY( grandChildWidget->isVisible() );
1165 grandChildWidget->hide();
1168 QVERIFY( !grandChildWidget->isVisible() );
1169 QVERIFY( testWidget->isVisible() );
1170 QVERIFY( childWidget->isVisible() );
1172 grandChildWidget->show();
1173 childWidget->hide();
1176 QVERIFY( testWidget->isVisible() );
1177 QVERIFY( !childWidget->isVisible() );
1178 QVERIFY( !grandChildWidget->isVisible() );
1180 grandChildWidget->show();
1181 QVERIFY( !grandChildWidget->isVisible() );
1184 void tst_QWidget::setLocale()
1187 QCOMPARE(w.locale(), QLocale());
1189 w.setLocale(QLocale::Italian);
1190 QCOMPARE(w.locale(), QLocale(QLocale::Italian));
1193 QCOMPARE(child1.locale(), QLocale(QLocale::Italian));
1196 QCOMPARE(w.locale(), QLocale());
1197 QCOMPARE(child1.locale(), QLocale());
1199 w.setLocale(QLocale::French);
1200 QCOMPARE(w.locale(), QLocale(QLocale::French));
1201 QCOMPARE(child1.locale(), QLocale(QLocale::French));
1203 child1.setLocale(QLocale::Italian);
1204 QCOMPARE(w.locale(), QLocale(QLocale::French));
1205 QCOMPARE(child1.locale(), QLocale(QLocale::Italian));
1207 child1.unsetLocale();
1208 QCOMPARE(w.locale(), QLocale(QLocale::French));
1209 QCOMPARE(child1.locale(), QLocale(QLocale::French));
1212 QCOMPARE(child2.locale(), QLocale());
1213 child2.setParent(&w);
1214 QCOMPARE(child2.locale(), QLocale(QLocale::French));
1217 void tst_QWidget::visible_setWindowOpacity()
1220 QVERIFY( !testWidget->isVisible() );
1221 testWidget->setWindowOpacity(0.5);
1223 QVERIFY(!::IsWindowVisible(winHandleOf(testWidget)));
1225 testWidget->setWindowOpacity(1.0);
1228 void tst_QWidget::isVisibleTo()
1230 // Ensure that the testWidget is hidden for this test at the
1234 QWidget* childWidget = new QWidget( testWidget );
1235 QVERIFY( childWidget->isVisibleTo( testWidget ) );
1236 childWidget->hide();
1237 QVERIFY( !childWidget->isVisibleTo( testWidget ) );
1239 QWidget* grandChildWidget = new QWidget( childWidget );
1240 QVERIFY( !grandChildWidget->isVisibleTo( testWidget ) );
1241 QVERIFY( grandChildWidget->isVisibleTo( childWidget ) );
1244 childWidget->show();
1246 QVERIFY( childWidget->isVisibleTo( testWidget ) );
1247 grandChildWidget->hide();
1248 QVERIFY( !grandChildWidget->isVisibleTo( childWidget ) );
1249 QVERIFY( !grandChildWidget->isVisibleTo( testWidget ) );
1253 void tst_QWidget::isHidden()
1255 // Ensure that the testWidget is hidden for this test at the
1259 QVERIFY( testWidget->isHidden() );
1260 QWidget* childWidget = new QWidget( testWidget );
1261 QVERIFY( !childWidget->isHidden() );
1264 QVERIFY( !testWidget->isHidden() );
1265 QVERIFY( !childWidget->isHidden() );
1267 QWidget* grandChildWidget = new QWidget( childWidget );
1268 QVERIFY( grandChildWidget->isHidden() );
1269 grandChildWidget->show();
1270 QVERIFY( !grandChildWidget->isHidden() );
1272 grandChildWidget->hide();
1275 QVERIFY( grandChildWidget->isHidden() );
1276 QVERIFY( !testWidget->isHidden() );
1277 QVERIFY( !childWidget->isHidden() );
1279 grandChildWidget->show();
1280 childWidget->hide();
1283 QVERIFY( !testWidget->isHidden() );
1284 QVERIFY( childWidget->isHidden() );
1285 QVERIFY( !grandChildWidget->isHidden() );
1287 grandChildWidget->show();
1288 QVERIFY( !grandChildWidget->isHidden() );
1291 void tst_QWidget::fonts()
1293 // Tests setFont(), ownFont() and unsetFont()
1294 QWidget* cleanTestWidget = new QWidget( testWidget );
1295 QFont originalFont = cleanTestWidget->font();
1297 QVERIFY( !cleanTestWidget->testAttribute(Qt::WA_SetFont) );
1298 cleanTestWidget->setFont(QFont());
1299 QVERIFY( !cleanTestWidget->testAttribute(Qt::WA_SetFont) );
1301 QFont newFont( "times", 18 );
1302 cleanTestWidget->setFont( newFont );
1303 newFont = newFont.resolve( testWidget->font() );
1305 QVERIFY( cleanTestWidget->testAttribute(Qt::WA_SetFont) );
1306 QVERIFY( cleanTestWidget->font() == newFont );
1308 cleanTestWidget->setFont(QFont());
1309 QVERIFY( !cleanTestWidget->testAttribute(Qt::WA_SetFont) );
1310 QVERIFY( cleanTestWidget->font() == originalFont );
1313 void tst_QWidget::mapFromAndTo_data()
1315 QTest::addColumn<bool>("windowHidden");
1316 QTest::addColumn<bool>("subWindow1Hidden");
1317 QTest::addColumn<bool>("subWindow2Hidden");
1318 QTest::addColumn<bool>("subSubWindowHidden");
1319 QTest::addColumn<bool>("windowMinimized");
1320 QTest::addColumn<bool>("subWindow1Minimized");
1322 QTest::newRow("window 1 sub1 1 sub2 1 subsub 1") << false << false << false << false << false << false;
1323 QTest::newRow("window 0 sub1 1 sub2 1 subsub 1") << true << false << false << false << false << false;
1324 QTest::newRow("window 1 sub1 0 sub2 1 subsub 1") << false << true << false << false << false << false;
1325 QTest::newRow("window 0 sub1 0 sub2 1 subsub 1") << true << true << false << false << false << false;
1326 QTest::newRow("window 1 sub1 1 sub2 0 subsub 1") << false << false << true << false << false << false;
1327 QTest::newRow("window 0 sub1 1 sub2 0 subsub 1") << true << false << true << false << false << false;
1328 QTest::newRow("window 1 sub1 0 sub2 0 subsub 1") << false << true << true << false << false << false;
1329 QTest::newRow("window 0 sub1 0 sub2 0 subsub 1") << true << true << true << false << false << false;
1330 QTest::newRow("window 1 sub1 1 sub2 1 subsub 0") << false << false << false << true << false << false;
1331 QTest::newRow("window 0 sub1 1 sub2 1 subsub 0") << true << false << false << true << false << false;
1332 QTest::newRow("window 1 sub1 0 sub2 1 subsub 0") << false << true << false << true << false << false;
1333 QTest::newRow("window 0 sub1 0 sub2 1 subsub 0") << true << true << false << true << false << false;
1334 QTest::newRow("window 1 sub1 1 sub2 0 subsub 0") << false << false << true << true << false << false;
1335 QTest::newRow("window 0 sub1 1 sub2 0 subsub 0") << true << false << true << true << false << false;
1336 QTest::newRow("window 1 sub1 0 sub2 0 subsub 0") << false << true << true << true << false << false;
1337 QTest::newRow("window 0 sub1 0 sub2 0 subsub 0") << true << true << true << true << false << false;
1338 QTest::newRow("window 1 sub1 1 sub2 1 subsub 1 windowMinimized") << false << false << false << false << true << false;
1339 QTest::newRow("window 0 sub1 1 sub2 1 subsub 1 windowMinimized") << true << false << false << false << true << false;
1340 QTest::newRow("window 1 sub1 0 sub2 1 subsub 1 windowMinimized") << false << true << false << false << true << false;
1341 QTest::newRow("window 0 sub1 0 sub2 1 subsub 1 windowMinimized") << true << true << false << false << true << false;
1342 QTest::newRow("window 1 sub1 1 sub2 0 subsub 1 windowMinimized") << false << false << true << false << true << false;
1343 QTest::newRow("window 0 sub1 1 sub2 0 subsub 1 windowMinimized") << true << false << true << false << true << false;
1344 QTest::newRow("window 1 sub1 0 sub2 0 subsub 1 windowMinimized") << false << true << true << false << true << false;
1345 QTest::newRow("window 0 sub1 0 sub2 0 subsub 1 windowMinimized") << true << true << true << false << true << false;
1346 QTest::newRow("window 1 sub1 1 sub2 1 subsub 0 windowMinimized") << false << false << false << true << true << false;
1347 QTest::newRow("window 0 sub1 1 sub2 1 subsub 0 windowMinimized") << true << false << false << true << true << false;
1348 QTest::newRow("window 1 sub1 0 sub2 1 subsub 0 windowMinimized") << false << true << false << true << true << false;
1349 QTest::newRow("window 0 sub1 0 sub2 1 subsub 0 windowMinimized") << true << true << false << true << true << false;
1350 QTest::newRow("window 1 sub1 1 sub2 0 subsub 0 windowMinimized") << false << false << true << true << true << false;
1351 QTest::newRow("window 0 sub1 1 sub2 0 subsub 0 windowMinimized") << true << false << true << true << true << false;
1352 QTest::newRow("window 1 sub1 0 sub2 0 subsub 0 windowMinimized") << false << true << true << true << true << false;
1353 QTest::newRow("window 0 sub1 0 sub2 0 subsub 0 windowMinimized") << true << true << true << true << true << false;
1354 QTest::newRow("window 1 sub1 1 sub2 1 subsub 1 subWindow1Minimized") << false << false << false << false << false << true;
1355 QTest::newRow("window 0 sub1 1 sub2 1 subsub 1 subWindow1Minimized") << true << false << false << false << false << true;
1356 QTest::newRow("window 1 sub1 0 sub2 1 subsub 1 subWindow1Minimized") << false << true << false << false << false << true;
1357 QTest::newRow("window 0 sub1 0 sub2 1 subsub 1 subWindow1Minimized") << true << true << false << false << false << true;
1358 QTest::newRow("window 1 sub1 1 sub2 0 subsub 1 subWindow1Minimized") << false << false << true << false << false << true;
1359 QTest::newRow("window 0 sub1 1 sub2 0 subsub 1 subWindow1Minimized") << true << false << true << false << false << true;
1360 QTest::newRow("window 1 sub1 0 sub2 0 subsub 1 subWindow1Minimized") << false << true << true << false << false << true;
1361 QTest::newRow("window 0 sub1 0 sub2 0 subsub 1 subWindow1Minimized") << true << true << true << false << false << true;
1362 QTest::newRow("window 1 sub1 1 sub2 1 subsub 0 subWindow1Minimized") << false << false << false << true << false << true;
1363 QTest::newRow("window 0 sub1 1 sub2 1 subsub 0 subWindow1Minimized") << true << false << false << true << false << true;
1364 QTest::newRow("window 1 sub1 0 sub2 1 subsub 0 subWindow1Minimized") << false << true << false << true << false << true;
1365 QTest::newRow("window 0 sub1 0 sub2 1 subsub 0 subWindow1Minimized") << true << true << false << true << false << true;
1366 QTest::newRow("window 1 sub1 1 sub2 0 subsub 0 subWindow1Minimized") << false << false << true << true << false << true;
1367 QTest::newRow("window 0 sub1 1 sub2 0 subsub 0 subWindow1Minimized") << true << false << true << true << false << true;
1368 QTest::newRow("window 1 sub1 0 sub2 0 subsub 0 subWindow1Minimized") << false << true << true << true << false << true;
1369 QTest::newRow("window 0 sub1 0 sub2 0 subsub 0 subWindow1Minimized") << true << true << true << true << false << true;
1374 void tst_QWidget::mapFromAndTo()
1376 QFETCH(bool, windowHidden);
1377 QFETCH(bool, subWindow1Hidden);
1378 QFETCH(bool, subWindow2Hidden);
1379 QFETCH(bool, subSubWindowHidden);
1380 QFETCH(bool, windowMinimized);
1381 QFETCH(bool, subWindow1Minimized);
1383 // create a toplevel and two overlapping siblings
1385 window.setWindowFlags(window.windowFlags() | Qt::X11BypassWindowManagerHint);
1386 QWidget *subWindow1 = new QWidget(&window);
1387 QWidget *subWindow2 = new QWidget(&window);
1388 QWidget *subSubWindow = new QWidget(subWindow1);
1390 // set their geometries
1391 window.setGeometry(100, 100, 100, 100);
1392 subWindow1->setGeometry(50, 50, 100, 100);
1393 subWindow2->setGeometry(75, 75, 100, 100);
1394 subSubWindow->setGeometry(10, 10, 10, 10);
1396 #if !defined (Q_OS_WINCE) //still no proper minimizing
1398 if (windowMinimized) {
1399 if (!windowHidden) {
1400 window.showMinimized();
1401 QVERIFY(window.isMinimized());
1404 window.setVisible(!windowHidden);
1406 if (subWindow1Minimized) {
1408 subWindow1->showMinimized();
1409 QVERIFY(subWindow1->isMinimized());
1411 subWindow1->setVisible(!subWindow1Hidden);
1414 Q_UNUSED(windowHidden);
1415 Q_UNUSED(subWindow1Hidden);
1416 Q_UNUSED(windowMinimized);
1417 Q_UNUSED(subWindow1Minimized);
1420 subWindow2->setVisible(!subWindow2Hidden);
1421 subSubWindow->setVisible(!subSubWindowHidden);
1424 QCOMPARE(window.mapToGlobal(QPoint(0, 0)), QPoint(100, 100));
1425 QCOMPARE(window.mapToGlobal(QPoint(10, 0)), QPoint(110, 100));
1426 QCOMPARE(window.mapToGlobal(QPoint(0, 10)), QPoint(100, 110));
1427 QCOMPARE(window.mapToGlobal(QPoint(-10, 0)), QPoint(90, 100));
1428 QCOMPARE(window.mapToGlobal(QPoint(0, -10)), QPoint(100, 90));
1429 QCOMPARE(window.mapToGlobal(QPoint(100, 100)), QPoint(200, 200));
1430 QCOMPARE(window.mapToGlobal(QPoint(110, 100)), QPoint(210, 200));
1431 QCOMPARE(window.mapToGlobal(QPoint(100, 110)), QPoint(200, 210));
1432 QCOMPARE(window.mapFromGlobal(QPoint(100, 100)), QPoint(0, 0));
1433 QCOMPARE(window.mapFromGlobal(QPoint(110, 100)), QPoint(10, 0));
1434 QCOMPARE(window.mapFromGlobal(QPoint(100, 110)), QPoint(0, 10));
1435 QCOMPARE(window.mapFromGlobal(QPoint(90, 100)), QPoint(-10, 0));
1436 QCOMPARE(window.mapFromGlobal(QPoint(100, 90)), QPoint(0, -10));
1437 QCOMPARE(window.mapFromGlobal(QPoint(200, 200)), QPoint(100, 100));
1438 QCOMPARE(window.mapFromGlobal(QPoint(210, 200)), QPoint(110, 100));
1439 QCOMPARE(window.mapFromGlobal(QPoint(200, 210)), QPoint(100, 110));
1440 QCOMPARE(window.mapToParent(QPoint(0, 0)), QPoint(100, 100));
1441 QCOMPARE(window.mapToParent(QPoint(10, 0)), QPoint(110, 100));
1442 QCOMPARE(window.mapToParent(QPoint(0, 10)), QPoint(100, 110));
1443 QCOMPARE(window.mapToParent(QPoint(-10, 0)), QPoint(90, 100));
1444 QCOMPARE(window.mapToParent(QPoint(0, -10)), QPoint(100, 90));
1445 QCOMPARE(window.mapToParent(QPoint(100, 100)), QPoint(200, 200));
1446 QCOMPARE(window.mapToParent(QPoint(110, 100)), QPoint(210, 200));
1447 QCOMPARE(window.mapToParent(QPoint(100, 110)), QPoint(200, 210));
1448 QCOMPARE(window.mapFromParent(QPoint(100, 100)), QPoint(0, 0));
1449 QCOMPARE(window.mapFromParent(QPoint(110, 100)), QPoint(10, 0));
1450 QCOMPARE(window.mapFromParent(QPoint(100, 110)), QPoint(0, 10));
1451 QCOMPARE(window.mapFromParent(QPoint(90, 100)), QPoint(-10, 0));
1452 QCOMPARE(window.mapFromParent(QPoint(100, 90)), QPoint(0, -10));
1453 QCOMPARE(window.mapFromParent(QPoint(200, 200)), QPoint(100, 100));
1454 QCOMPARE(window.mapFromParent(QPoint(210, 200)), QPoint(110, 100));
1455 QCOMPARE(window.mapFromParent(QPoint(200, 210)), QPoint(100, 110));
1458 QCOMPARE(subWindow1->mapToGlobal(QPoint(0, 0)), QPoint(150, 150));
1459 QCOMPARE(subWindow1->mapToGlobal(QPoint(10, 0)), QPoint(160, 150));
1460 QCOMPARE(subWindow1->mapToGlobal(QPoint(0, 10)), QPoint(150, 160));
1461 QCOMPARE(subWindow1->mapToGlobal(QPoint(-10, 0)), QPoint(140, 150));
1462 QCOMPARE(subWindow1->mapToGlobal(QPoint(0, -10)), QPoint(150, 140));
1463 QCOMPARE(subWindow1->mapToGlobal(QPoint(100, 100)), QPoint(250, 250));
1464 QCOMPARE(subWindow1->mapToGlobal(QPoint(110, 100)), QPoint(260, 250));
1465 QCOMPARE(subWindow1->mapToGlobal(QPoint(100, 110)), QPoint(250, 260));
1466 QCOMPARE(subWindow1->mapFromGlobal(QPoint(150, 150)), QPoint(0, 0));
1467 QCOMPARE(subWindow1->mapFromGlobal(QPoint(160, 150)), QPoint(10, 0));
1468 QCOMPARE(subWindow1->mapFromGlobal(QPoint(150, 160)), QPoint(0, 10));
1469 QCOMPARE(subWindow1->mapFromGlobal(QPoint(140, 150)), QPoint(-10, 0));
1470 QCOMPARE(subWindow1->mapFromGlobal(QPoint(150, 140)), QPoint(0, -10));
1471 QCOMPARE(subWindow1->mapFromGlobal(QPoint(250, 250)), QPoint(100, 100));
1472 QCOMPARE(subWindow1->mapFromGlobal(QPoint(260, 250)), QPoint(110, 100));
1473 QCOMPARE(subWindow1->mapFromGlobal(QPoint(250, 260)), QPoint(100, 110));
1474 QCOMPARE(subWindow1->mapToParent(QPoint(0, 0)), QPoint(50, 50));
1475 QCOMPARE(subWindow1->mapToParent(QPoint(10, 0)), QPoint(60, 50));
1476 QCOMPARE(subWindow1->mapToParent(QPoint(0, 10)), QPoint(50, 60));
1477 QCOMPARE(subWindow1->mapToParent(QPoint(-10, 0)), QPoint(40, 50));
1478 QCOMPARE(subWindow1->mapToParent(QPoint(0, -10)), QPoint(50, 40));
1479 QCOMPARE(subWindow1->mapToParent(QPoint(100, 100)), QPoint(150, 150));
1480 QCOMPARE(subWindow1->mapToParent(QPoint(110, 100)), QPoint(160, 150));
1481 QCOMPARE(subWindow1->mapToParent(QPoint(100, 110)), QPoint(150, 160));
1482 QCOMPARE(subWindow1->mapFromParent(QPoint(50, 50)), QPoint(0, 0));
1483 QCOMPARE(subWindow1->mapFromParent(QPoint(60, 50)), QPoint(10, 0));
1484 QCOMPARE(subWindow1->mapFromParent(QPoint(50, 60)), QPoint(0, 10));
1485 QCOMPARE(subWindow1->mapFromParent(QPoint(40, 50)), QPoint(-10, 0));
1486 QCOMPARE(subWindow1->mapFromParent(QPoint(50, 40)), QPoint(0, -10));
1487 QCOMPARE(subWindow1->mapFromParent(QPoint(150, 150)), QPoint(100, 100));
1488 QCOMPARE(subWindow1->mapFromParent(QPoint(160, 150)), QPoint(110, 100));
1489 QCOMPARE(subWindow1->mapFromParent(QPoint(150, 160)), QPoint(100, 110));
1492 QCOMPARE(subSubWindow->mapToGlobal(QPoint(0, 0)), QPoint(160, 160));
1493 QCOMPARE(subSubWindow->mapToGlobal(QPoint(10, 0)), QPoint(170, 160));
1494 QCOMPARE(subSubWindow->mapToGlobal(QPoint(0, 10)), QPoint(160, 170));
1495 QCOMPARE(subSubWindow->mapToGlobal(QPoint(-10, 0)), QPoint(150, 160));
1496 QCOMPARE(subSubWindow->mapToGlobal(QPoint(0, -10)), QPoint(160, 150));
1497 QCOMPARE(subSubWindow->mapToGlobal(QPoint(100, 100)), QPoint(260, 260));
1498 QCOMPARE(subSubWindow->mapToGlobal(QPoint(110, 100)), QPoint(270, 260));
1499 QCOMPARE(subSubWindow->mapToGlobal(QPoint(100, 110)), QPoint(260, 270));
1500 QCOMPARE(subSubWindow->mapFromGlobal(QPoint(160, 160)), QPoint(0, 0));
1501 QCOMPARE(subSubWindow->mapFromGlobal(QPoint(170, 160)), QPoint(10, 0));
1502 QCOMPARE(subSubWindow->mapFromGlobal(QPoint(160, 170)), QPoint(0, 10));
1503 QCOMPARE(subSubWindow->mapFromGlobal(QPoint(150, 160)), QPoint(-10, 0));
1504 QCOMPARE(subSubWindow->mapFromGlobal(QPoint(160, 150)), QPoint(0, -10));
1505 QCOMPARE(subSubWindow->mapFromGlobal(QPoint(260, 260)), QPoint(100, 100));
1506 QCOMPARE(subSubWindow->mapFromGlobal(QPoint(270, 260)), QPoint(110, 100));
1507 QCOMPARE(subSubWindow->mapFromGlobal(QPoint(260, 270)), QPoint(100, 110));
1508 QCOMPARE(subSubWindow->mapToParent(QPoint(0, 0)), QPoint(10, 10));
1509 QCOMPARE(subSubWindow->mapToParent(QPoint(10, 0)), QPoint(20, 10));
1510 QCOMPARE(subSubWindow->mapToParent(QPoint(0, 10)), QPoint(10, 20));
1511 QCOMPARE(subSubWindow->mapToParent(QPoint(-10, 0)), QPoint(0, 10));
1512 QCOMPARE(subSubWindow->mapToParent(QPoint(0, -10)), QPoint(10, 0));
1513 QCOMPARE(subSubWindow->mapToParent(QPoint(100, 100)), QPoint(110, 110));
1514 QCOMPARE(subSubWindow->mapToParent(QPoint(110, 100)), QPoint(120, 110));
1515 QCOMPARE(subSubWindow->mapToParent(QPoint(100, 110)), QPoint(110, 120));
1516 QCOMPARE(subSubWindow->mapFromParent(QPoint(10, 10)), QPoint(0, 0));
1517 QCOMPARE(subSubWindow->mapFromParent(QPoint(20, 10)), QPoint(10, 0));
1518 QCOMPARE(subSubWindow->mapFromParent(QPoint(10, 20)), QPoint(0, 10));
1519 QCOMPARE(subSubWindow->mapFromParent(QPoint(0, 10)), QPoint(-10, 0));
1520 QCOMPARE(subSubWindow->mapFromParent(QPoint(10, 0)), QPoint(0, -10));
1521 QCOMPARE(subSubWindow->mapFromParent(QPoint(110, 110)), QPoint(100, 100));
1522 QCOMPARE(subSubWindow->mapFromParent(QPoint(120, 110)), QPoint(110, 100));
1523 QCOMPARE(subSubWindow->mapFromParent(QPoint(110, 120)), QPoint(100, 110));
1526 void tst_QWidget::focusChainOnReparent()
1529 QWidget *child1 = new QWidget(&window);
1530 QWidget *child2 = new QWidget(&window);
1531 QWidget *child3 = new QWidget(&window);
1532 QWidget *child21 = new QWidget(child2);
1533 QWidget *child22 = new QWidget(child2);
1534 QWidget *child4 = new QWidget(&window);
1536 QWidget *expectedOriginalChain[8] = {&window, child1, child2, child3, child21, child22, child4, &window};
1537 QWidget *w = &window;
1538 for (int i = 0; i <8; ++i) {
1539 QCOMPARE(w, expectedOriginalChain[i]);
1540 w = w->nextInFocusChain();
1542 for (int i = 7; i >= 0; --i) {
1543 w = w->previousInFocusChain();
1544 QCOMPARE(w, expectedOriginalChain[i]);
1548 child2->setParent(&window2);
1550 QWidget *expectedNewChain[5] = {&window2, child2, child21, child22, &window2};
1552 for (int i = 0; i <5; ++i) {
1553 QCOMPARE(w, expectedNewChain[i]);
1554 w = w->nextInFocusChain();
1556 for (int i = 4; i >= 0; --i) {
1557 w = w->previousInFocusChain();
1558 QCOMPARE(w, expectedNewChain[i]);
1561 QWidget *expectedOldChain[5] = {&window, child1, child3, child4, &window};
1563 for (int i = 0; i <5; ++i) {
1564 QCOMPARE(w, expectedOldChain[i]);
1565 w = w->nextInFocusChain();
1567 for (int i = 4; i >= 0; --i) {
1568 w = w->previousInFocusChain();
1569 QCOMPARE(w, expectedOldChain[i]);
1574 void tst_QWidget::focusChainOnHide()
1576 testWidget->hide(); // We do not want to get disturbed by other widgets
1577 // focus should move to the next widget in the focus chain when we hide it.
1578 QWidget *parent = new QWidget();
1579 parent->setObjectName(QLatin1String("Parent"));
1580 parent->setFocusPolicy(Qt::StrongFocus);
1581 QWidget *child = new QWidget(parent);
1582 child->setObjectName(QLatin1String("child"));
1583 child->setFocusPolicy(Qt::StrongFocus);
1584 QWidget::setTabOrder(child, parent);
1587 qApp->setActiveWindow(parent->window());
1588 child->activateWindow();
1590 qApp->processEvents();
1592 QTRY_COMPARE(child->hasFocus(), true);
1594 qApp->processEvents();
1596 QTRY_COMPARE(parent->hasFocus(), true);
1597 QCOMPARE(parent, qApp->focusWidget());
1600 testWidget->show(); //don't disturb later tests
1603 class Container : public QWidget
1610 box = new QVBoxLayout(this);
1611 //(new QVBoxLayout(this))->setAutoAdd(true);
1616 focusNextPrevChild(true);
1621 focusNextPrevChild(false);
1625 class Composite : public QFrame
1628 Composite(QWidget* parent = 0, const char* name = 0)
1631 setObjectName(name);
1632 //QHBoxLayout* hbox = new QHBoxLayout(this, 2, 0);
1633 //hbox->setAutoAdd(true);
1634 QHBoxLayout* hbox = new QHBoxLayout(this);
1636 lineEdit = new QLineEdit(this);
1637 hbox->addWidget(lineEdit);
1639 button = new QPushButton(this);
1640 hbox->addWidget(button);
1641 button->setFocusPolicy( Qt::NoFocus );
1643 setFocusProxy( lineEdit );
1644 setFocusPolicy( Qt::StrongFocus );
1646 setTabOrder(lineEdit, button);
1650 QLineEdit* lineEdit;
1651 QPushButton* button;
1654 #define NUM_WIDGETS 4
1656 void tst_QWidget::setTabOrder()
1660 Container container;
1662 Composite* comp[NUM_WIDGETS];
1664 QLineEdit *firstEdit = new QLineEdit(&container);
1665 container.box->addWidget(firstEdit);
1668 for(i = 0; i < NUM_WIDGETS; i++) {
1669 comp[i] = new Composite(&container);
1670 container.box->addWidget(comp[i]);
1673 QLineEdit *lastEdit = new QLineEdit(&container);
1674 container.box->addWidget(lastEdit);
1676 container.setTabOrder(lastEdit, comp[NUM_WIDGETS-1]);
1677 for(i = NUM_WIDGETS-1; i > 0; i--) {
1678 container.setTabOrder(comp[i], comp[i-1]);
1680 container.setTabOrder(comp[0], firstEdit);
1682 int current = NUM_WIDGETS-1;
1683 lastEdit->setFocus();
1686 container.activateWindow();
1687 qApp->setActiveWindow(&container);
1689 QTest::qWaitForWindowShown(&container);
1695 QTRY_VERIFY(lastEdit->hasFocus());
1698 QVERIFY(comp[current]->focusProxy()->hasFocus());
1701 } while (current >= 0);
1703 QVERIFY(firstEdit->hasFocus());
1707 void tst_QWidget::activation()
1711 #if defined(Q_OS_WINCE)
1712 int waitTime = 1000;
1718 qApp->processEvents();
1721 widget1.setWindowTitle("Widget1");
1724 widget2.setWindowTitle("Widget2");
1729 QTest::qWait(waitTime);
1730 QVERIFY(qApp->activeWindow() == &widget2);
1731 widget2.showMinimized();
1732 QTest::qWait(waitTime);
1734 QVERIFY(qApp->activeWindow() == &widget1);
1735 widget2.showMaximized();
1736 QTest::qWait(waitTime);
1737 QVERIFY(qApp->activeWindow() == &widget2);
1738 widget2.showMinimized();
1739 QTest::qWait(waitTime);
1740 QVERIFY(qApp->activeWindow() == &widget1);
1741 widget2.showNormal();
1742 QTest::qWait(waitTime);
1743 #if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
1744 if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
1745 QEXPECT_FAIL("", "MS introduced new behavior after XP", Continue);
1747 QTest::qWait(waitTime);
1748 QVERIFY(qApp->activeWindow() == &widget2);
1750 QTest::qWait(waitTime);
1751 QVERIFY(qApp->activeWindow() == &widget1);
1755 // Many window managers do not support window state properly, which causes this test to fail.
1757 void tst_QWidget::windowState()
1759 #ifdef Q_OS_WINCE_WM
1760 QPoint pos(500, 500);
1761 QSize size(200, 200);
1762 if (qt_wince_is_smartphone()) { //small screen
1763 pos = QPoint(10,10);
1764 size = QSize(100,100);
1767 const QPoint pos(500, 500);
1768 const QSize size(200, 200);
1773 widget1.resize(size);
1774 QCOMPARE(widget1.pos(), pos);
1775 QCOMPARE(widget1.size(), size);
1777 widget1.setWindowTitle("Widget1");
1778 QCOMPARE(widget1.pos(), pos);
1779 QCOMPARE(widget1.size(), size);
1781 #define VERIFY_STATE(s) QCOMPARE(int(widget1.windowState() & stateMask), int(s))
1783 const int stateMask = Qt::WindowMaximized|Qt::WindowMinimized|Qt::WindowFullScreen;
1785 widget1.setWindowState(Qt::WindowMaximized);
1787 VERIFY_STATE(Qt::WindowMaximized);
1788 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowMaximized);
1792 VERIFY_STATE(Qt::WindowMaximized);
1793 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowMaximized);
1795 widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
1797 QVERIFY(!(widget1.windowState() & Qt::WindowMaximized));
1798 QTRY_COMPARE(widget1.pos(), pos);
1799 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState);
1801 widget1.setWindowState(Qt::WindowMinimized);
1803 VERIFY_STATE(Qt::WindowMinimized);
1804 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowMinimized);
1806 widget1.setWindowState(widget1.windowState() | Qt::WindowMaximized);
1808 VERIFY_STATE((Qt::WindowMinimized|Qt::WindowMaximized));
1809 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowMinimized);
1811 widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
1813 VERIFY_STATE(Qt::WindowMaximized);
1814 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowMaximized);
1816 widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
1818 QVERIFY(!(widget1.windowState() & (Qt::WindowMinimized|Qt::WindowMaximized)));
1819 QTRY_COMPARE(widget1.pos(), pos);
1820 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState);
1822 widget1.setWindowState(Qt::WindowFullScreen);
1824 VERIFY_STATE(Qt::WindowFullScreen);
1825 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowFullScreen);
1827 widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
1829 VERIFY_STATE((Qt::WindowFullScreen|Qt::WindowMinimized));
1830 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowMinimized);
1832 widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
1834 VERIFY_STATE(Qt::WindowFullScreen);
1835 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowFullScreen);
1837 widget1.setWindowState(Qt::WindowNoState);
1839 VERIFY_STATE(Qt::WindowNoState);
1840 QTRY_COMPARE(widget1.pos(), pos);
1841 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState);
1843 widget1.setWindowState(Qt::WindowFullScreen);
1845 VERIFY_STATE(Qt::WindowFullScreen);
1846 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowFullScreen);
1848 widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
1850 VERIFY_STATE((Qt::WindowFullScreen|Qt::WindowMaximized));
1851 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowFullScreen);
1853 widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
1855 VERIFY_STATE((Qt::WindowFullScreen|Qt::WindowMaximized|Qt::WindowMinimized));
1856 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowMinimized);
1858 widget1.setWindowState(widget1.windowState() ^ Qt::WindowMinimized);
1860 VERIFY_STATE((Qt::WindowFullScreen|Qt::WindowMaximized));
1861 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowFullScreen);
1863 widget1.setWindowState(widget1.windowState() ^ Qt::WindowFullScreen);
1865 VERIFY_STATE(Qt::WindowMaximized);
1866 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowMaximized);
1868 widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
1870 QVERIFY(!(widget1.windowState() & stateMask));
1871 QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState);
1873 QTRY_COMPARE(widget1.pos(), pos);
1874 QTRY_COMPARE(widget1.size(), size);
1878 void tst_QWidget::showMaximized()
1881 QHBoxLayout *layout;
1882 layout = new QHBoxLayout;
1888 layout->addWidget(&le);
1889 layout->addWidget(&le2);
1890 layout->addWidget(&le3);
1892 layouted.setLayout(layout);
1894 plain.showMaximized();
1895 QVERIFY(plain.windowState() & Qt::WindowMaximized);
1898 QVERIFY(!(plain.windowState() & Qt::WindowMaximized));
1900 layouted.showMaximized();
1901 QVERIFY(layouted.windowState() & Qt::WindowMaximized);
1903 layouted.showNormal();
1904 QVERIFY(!(layouted.windowState() & Qt::WindowMaximized));
1906 // ### fixme: embedded may choose a different size to fit on the screen.
1907 if (layouted.size() != layouted.sizeHint())
1908 QEXPECT_FAIL("", "QTBUG-22326", Continue);
1909 QCOMPARE(layouted.size(), layouted.sizeHint());
1911 layouted.showMaximized();
1912 QVERIFY(layouted.isMaximized());
1913 QVERIFY(layouted.isVisible());
1916 QVERIFY(layouted.isMaximized());
1917 QVERIFY(!layouted.isVisible());
1919 layouted.showMaximized();
1920 QVERIFY(layouted.isMaximized());
1921 QVERIFY(layouted.isVisible());
1923 layouted.showMinimized();
1924 QVERIFY(layouted.isMinimized());
1925 QVERIFY(layouted.isMaximized());
1927 layouted.showMaximized();
1928 QVERIFY(!layouted.isMinimized());
1929 QVERIFY(layouted.isMaximized());
1930 QVERIFY(layouted.isVisible());
1932 layouted.showMinimized();
1933 QVERIFY(layouted.isMinimized());
1934 QVERIFY(layouted.isMaximized());
1936 layouted.showMaximized();
1937 QVERIFY(!layouted.isMinimized());
1938 QVERIFY(layouted.isMaximized());
1939 QVERIFY(layouted.isVisible());
1943 QWidget widget(&frame);
1944 widget.showMaximized();
1945 QVERIFY(widget.isMaximized());
1950 widget.setGeometry(0, 0, 10, 10);
1951 widget.showMaximized();
1952 QTRY_VERIFY(widget.size().width() > 20 && widget.size().height() > 20);
1956 void tst_QWidget::showFullScreen()
1959 QHBoxLayout *layout;
1964 layout = new QHBoxLayout;
1966 layout->addWidget(&le);
1967 layout->addWidget(&le2);
1968 layout->addWidget(&le3);
1970 layouted.setLayout(layout);
1972 plain.showFullScreen();
1973 QVERIFY(plain.windowState() & Qt::WindowFullScreen);
1976 QVERIFY(!(plain.windowState() & Qt::WindowFullScreen));
1978 layouted.showFullScreen();
1979 QVERIFY(layouted.windowState() & Qt::WindowFullScreen);
1981 layouted.showNormal();
1982 QVERIFY(!(layouted.windowState() & Qt::WindowFullScreen));
1984 // ### fixme: embedded may choose a different size to fit on the screen.
1985 if (layouted.size() != layouted.sizeHint())
1986 QEXPECT_FAIL("", "QTBUG-22326", Continue);
1987 QCOMPARE(layouted.size(), layouted.sizeHint());
1989 layouted.showFullScreen();
1990 QVERIFY(layouted.isFullScreen());
1991 QVERIFY(layouted.isVisible());
1994 QVERIFY(layouted.isFullScreen());
1995 QVERIFY(!layouted.isVisible());
1997 layouted.showFullScreen();
1998 QVERIFY(layouted.isFullScreen());
1999 QVERIFY(layouted.isVisible());
2001 layouted.showMinimized();
2002 QVERIFY(layouted.isMinimized());
2003 QVERIFY(layouted.isFullScreen());
2005 layouted.showFullScreen();
2006 QVERIFY(!layouted.isMinimized());
2007 QVERIFY(layouted.isFullScreen());
2008 QVERIFY(layouted.isVisible());
2010 layouted.showMinimized();
2011 QVERIFY(layouted.isMinimized());
2012 QVERIFY(layouted.isFullScreen());
2014 layouted.showFullScreen();
2015 QVERIFY(!layouted.isMinimized());
2016 QVERIFY(layouted.isFullScreen());
2017 QVERIFY(layouted.isVisible());
2021 QWidget widget(&frame);
2022 widget.showFullScreen();
2023 QVERIFY(widget.isFullScreen());
2027 class ResizeWidget : public QWidget {
2029 ResizeWidget(QWidget *p = 0) : QWidget(p)
2031 m_resizeEventCount = 0;
2034 void resizeEvent(QResizeEvent *e){
2035 QCOMPARE(size(), e->size());
2036 ++m_resizeEventCount;
2040 int m_resizeEventCount;
2043 void tst_QWidget::resizeEvent()
2047 ResizeWidget wChild(&wParent);
2049 QCOMPARE (wChild.m_resizeEventCount, 1); // initial resize event before paint
2051 QSize safeSize(640,480);
2052 if (wChild.size() == safeSize)
2053 safeSize.setWidth(639);
2054 wChild.resize(safeSize);
2055 QCOMPARE (wChild.m_resizeEventCount, 1);
2057 QCOMPARE (wChild.m_resizeEventCount, 2);
2061 ResizeWidget wTopLevel;
2063 QCOMPARE (wTopLevel.m_resizeEventCount, 1); // initial resize event before paint for toplevels
2065 QSize safeSize(640,480);
2066 if (wTopLevel.size() == safeSize)
2067 safeSize.setWidth(639);
2068 wTopLevel.resize(safeSize);
2069 QCOMPARE (wTopLevel.m_resizeEventCount, 1);
2071 QCOMPARE (wTopLevel.m_resizeEventCount, 2);
2075 void tst_QWidget::showMinimized()
2078 plain.move(100, 100);
2079 plain.resize(200, 200);
2080 QPoint pos = plain.pos();
2082 plain.showMinimized();
2083 QVERIFY(plain.isMinimized());
2084 QVERIFY(plain.isVisible());
2085 QCOMPARE(plain.pos(), pos);
2088 QVERIFY(!plain.isMinimized());
2089 QVERIFY(plain.isVisible());
2090 QCOMPARE(plain.pos(), pos);
2092 plain.showMinimized();
2093 QVERIFY(plain.isMinimized());
2094 QVERIFY(plain.isVisible());
2095 QCOMPARE(plain.pos(), pos);
2098 QVERIFY(plain.isMinimized());
2099 QVERIFY(!plain.isVisible());
2101 plain.showMinimized();
2102 QVERIFY(plain.isMinimized());
2103 QVERIFY(plain.isVisible());
2105 plain.setGeometry(200, 200, 300, 300);
2107 QCOMPARE(plain.geometry(), QRect(200, 200, 300, 300));
2111 QWidget widget(&frame);
2112 widget.showMinimized();
2113 QVERIFY(widget.isMinimized());
2117 void tst_QWidget::showMinimizedKeepsFocus()
2119 //here we test that minimizing a widget and restoring it doesn't change the focus inside of it
2122 QWidget child1(&window), child2(&window);
2123 child1.setFocusPolicy(Qt::StrongFocus);
2124 child2.setFocusPolicy(Qt::StrongFocus);
2126 qApp->setActiveWindow(&window);
2127 QTest::qWaitForWindowShown(&window);
2131 QTRY_COMPARE(window.focusWidget(), &child2);
2132 QTRY_COMPARE(qApp->focusWidget(), &child2);
2134 window.showMinimized();
2136 QTRY_VERIFY(window.isMinimized());
2137 QTRY_COMPARE(window.focusWidget(), &child2);
2139 window.showNormal();
2141 QTRY_COMPARE(window.focusWidget(), &child2);
2144 //testing deletion of the focusWidget
2147 QWidget *child = new QWidget(&window);
2148 child->setFocusPolicy(Qt::StrongFocus);
2150 qApp->setActiveWindow(&window);
2151 QTest::qWaitForWindowShown(&window);
2154 QTRY_COMPARE(window.focusWidget(), child);
2155 QTRY_COMPARE(qApp->focusWidget(), child);
2158 QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
2159 QCOMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
2162 //testing reparenting the focus widget
2165 QWidget *child = new QWidget(&window);
2166 child->setFocusPolicy(Qt::StrongFocus);
2168 qApp->setActiveWindow(&window);
2169 QTest::qWaitForWindowShown(&window);
2172 QTRY_COMPARE(window.focusWidget(), child);
2173 QTRY_COMPARE(qApp->focusWidget(), child);
2175 child->setParent(0);
2176 QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
2177 QCOMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
2180 //testing setEnabled(false)
2183 QWidget *child = new QWidget(&window);
2184 child->setFocusPolicy(Qt::StrongFocus);
2186 qApp->setActiveWindow(&window);
2187 QTest::qWaitForWindowShown(&window);
2190 QTRY_COMPARE(window.focusWidget(), child);
2191 QTRY_COMPARE(qApp->focusWidget(), child);
2193 child->setEnabled(false);
2194 QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
2195 QCOMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
2198 //testing clearFocus
2201 QWidget *firstchild = new QWidget(&window);
2202 firstchild->setFocusPolicy(Qt::StrongFocus);
2203 QWidget *child = new QWidget(&window);
2204 child->setFocusPolicy(Qt::StrongFocus);
2206 qApp->setActiveWindow(&window);
2207 QTest::qWaitForWindowShown(&window);
2210 QTRY_COMPARE(window.focusWidget(), child);
2211 QTRY_COMPARE(qApp->focusWidget(), child);
2213 child->clearFocus();
2214 QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
2215 QCOMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
2217 window.showMinimized();
2219 QTRY_VERIFY(window.isMinimized());
2221 QEXPECT_FAIL("", "QWS does not implement showMinimized()", Continue);
2223 QCOMPARE(window.focusWidget(), static_cast<QWidget*>(0));
2225 QEXPECT_FAIL("", "QWS does not implement showMinimized()", Continue);
2227 QTRY_COMPARE(qApp->focusWidget(), static_cast<QWidget*>(0));
2229 window.showNormal();
2230 qApp->setActiveWindow(&window);
2231 QTest::qWaitForWindowShown(&window);
2234 if (!macHasAccessToWindowsServer())
2235 QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
2237 QTRY_COMPARE(window.focusWidget(), firstchild);
2239 if (!macHasAccessToWindowsServer())
2240 QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
2242 QTRY_COMPARE(qApp->focusWidget(), firstchild);
2247 void tst_QWidget::reparent()
2250 parent.setWindowTitle("Toplevel");
2251 parent.setGeometry(300, 300, 200, 150);
2254 child.setObjectName("child");
2255 child.setGeometry(10, 10, 180, 130);
2257 pal1.setColor(child.backgroundRole(), Qt::white);
2258 child.setPalette(pal1);
2260 QWidget childTLW(&child, Qt::Window);
2261 childTLW.setObjectName("childTLW");
2262 childTLW.setGeometry(100, 100, 50, 50);
2264 pal2.setColor(childTLW.backgroundRole(), Qt::yellow);
2265 childTLW.setPalette(pal2);
2269 QTest::qWaitForWindowShown(&parent);
2272 parent.move(50, 50);
2274 parent.move(300, 300);
2277 QPoint childPos = parent.mapToGlobal(child.pos());
2278 QPoint tlwPos = childTLW.pos();
2280 child.setParent(0, child.windowFlags() & ~Qt::WindowType_Mask);
2281 child.setGeometry(childPos.x(), childPos.y(), child.width(), child.height());
2285 // On X11, the window manager will apply NorthWestGravity rules to 'child', which
2286 // means the top-left corner of the window frame will be placed at 'childPos',
2287 // causing this test to fail
2289 QCOMPARE(child.geometry().topLeft(), childPos);
2291 QTRY_COMPARE(childTLW.pos(), tlwPos);
2293 // This following part of the test only makes sense on Windows.
2295 QWidget childTLWChild(&childTLW);
2296 childTLWChild.setObjectName("childTLWChild");
2298 QWidget grandChild(&child);
2299 grandChild.setObjectName("grandChild");
2300 grandChild.setGeometry(10, 10, 160, 110);
2302 pal3.setColor(grandChild.backgroundRole(), Qt::red);
2303 grandChild.setPalette(pal3);
2304 //grandChild.setPaletteBackgroundColor(Qt::red);
2306 QWidget grandChildTLW(&grandChild, Qt::Window);
2307 grandChildTLW.setObjectName("grandChildTLW");
2308 grandChildTLW.setGeometry(200, 200, 50, 50);
2310 pal4.setColor(grandChildTLW.backgroundRole(), Qt::yellow);
2311 grandChildTLW.setPalette(pal4);
2312 //grandChildTLW.setPaletteBackgroundColor(Qt::yellow);
2314 QWidget grandChildTLWChild(&grandChildTLW);
2315 grandChildTLWChild.setObjectName("grandChildTLWChild");
2317 QVERIFY(IsWindow(childTLW.winId()));
2318 QVERIFY(IsWindow(childTLWChild.winId()));
2319 QVERIFY(IsWindow(grandChildTLW.winId()));
2320 QVERIFY(IsWindow(grandChildTLWChild.winId()));
2324 QVERIFY(IsWindow(childTLW.winId()));
2325 QVERIFY(IsWindow(childTLWChild.winId()));
2326 QVERIFY(IsWindow(grandChildTLW.winId()));
2327 QVERIFY(IsWindow(grandChildTLWChild.winId()));
2329 child.setParent(&parent);
2333 // this appears to stabelize results
2334 qApp->processEvents();
2336 QVERIFY(IsWindow(childTLW.winId()));
2337 QVERIFY(IsWindow(childTLWChild.winId()));
2339 QVERIFY(IsWindow(grandChildTLW.winId()));
2340 QVERIFY(IsWindow(grandChildTLWChild.winId()));
2344 // Qt/Embedded does it differently.
2346 void tst_QWidget::icon()
2350 testWidget->setWindowIcon(p);
2352 QVERIFY(!testWidget->windowIcon().isNull());
2354 QVERIFY(!testWidget->windowIcon().isNull());
2355 testWidget->showFullScreen();
2356 QVERIFY(!testWidget->windowIcon().isNull());
2357 testWidget->showNormal();
2358 QVERIFY(!testWidget->windowIcon().isNull());
2362 void tst_QWidget::hideWhenFocusWidgetIsChild()
2364 testWidget->activateWindow();
2365 QWidget *parentWidget = new QWidget(testWidget);
2366 parentWidget->setObjectName("parentWidget");
2367 parentWidget->setGeometry(0, 0, 100, 100);
2368 QLineEdit *edit = new QLineEdit(parentWidget);
2369 edit->setObjectName("edit1");
2370 QLineEdit *edit3 = new QLineEdit(parentWidget);
2371 edit3->setObjectName("edit3");
2373 parentWidget->show();
2374 QLineEdit *edit2 = new QLineEdit(testWidget);
2375 edit2->setObjectName("edit2");
2377 edit2->move(110, 100);
2379 qApp->processEvents();
2380 QString actualFocusWidget, expectedFocusWidget;
2382 if (!qApp->focusWidget())
2383 QSKIP("Your window manager is too broken for this test");
2385 QVERIFY(qApp->focusWidget());
2386 actualFocusWidget.sprintf("%p %s %s", qApp->focusWidget(), qApp->focusWidget()->objectName().toLatin1().constData(), qApp->focusWidget()->metaObject()->className());
2387 expectedFocusWidget.sprintf("%p %s %s", edit, edit->objectName().toLatin1().constData(), edit->metaObject()->className());
2388 QCOMPARE(actualFocusWidget, expectedFocusWidget);
2390 parentWidget->hide();
2391 qApp->processEvents();
2392 actualFocusWidget.sprintf("%p %s %s", qApp->focusWidget(), qApp->focusWidget()->objectName().toLatin1().constData(), qApp->focusWidget()->metaObject()->className());
2393 expectedFocusWidget.sprintf("%p %s %s", edit2, edit2->objectName().toLatin1().constData(), edit2->metaObject()->className());
2394 QCOMPARE(actualFocusWidget, expectedFocusWidget);
2397 delete parentWidget;
2400 // 4DWM issues on IRIX makes this test fail.
2402 void tst_QWidget::normalGeometry()
2405 parent.setWindowTitle("NormalGeometry parent");
2406 QWidget *child = new QWidget(&parent);
2408 QCOMPARE(parent.normalGeometry(), parent.geometry());
2409 QCOMPARE(child->normalGeometry(), QRect());
2411 parent.setGeometry(100, 100, 200, 200);
2413 QTest::qWaitForWindowShown(&parent);
2414 QApplication::processEvents();
2416 QRect geom = parent.geometry();
2417 // ### the window manager places the top-left corner at
2418 // ### 100,100... making geom something like 102,124 (offset by
2419 // ### the frame/frame)... this indicates a rather large different
2420 // ### between how X11 and Windows works
2421 // QCOMPARE(geom, QRect(100, 100, 200, 200));
2422 QCOMPARE(parent.normalGeometry(), geom);
2424 parent.setWindowState(parent.windowState() ^ Qt::WindowMaximized);
2426 QTRY_VERIFY(parent.windowState() & Qt::WindowMaximized);
2427 QTRY_VERIFY(parent.geometry() != geom);
2428 QTRY_COMPARE(parent.normalGeometry(), geom);
2430 parent.setWindowState(parent.windowState() ^ Qt::WindowMaximized);
2432 QTRY_VERIFY(!(parent.windowState() & Qt::WindowMaximized));
2433 QTRY_COMPARE(parent.geometry(), geom);
2434 QTRY_COMPARE(parent.normalGeometry(), geom);
2436 parent.showMaximized();
2438 QTRY_VERIFY(parent.windowState() & Qt::WindowMaximized);
2439 QTRY_VERIFY(parent.geometry() != geom);
2440 QCOMPARE(parent.normalGeometry(), geom);
2442 parent.showNormal();
2444 QTRY_VERIFY(!(parent.windowState() & Qt::WindowMaximized));
2445 QTRY_COMPARE(parent.geometry(), geom);
2446 QCOMPARE(parent.normalGeometry(), geom);
2448 parent.setWindowState(parent.windowState() ^ Qt::WindowMinimized);
2450 parent.setWindowState(parent.windowState() ^ Qt::WindowMaximized);
2452 QTRY_VERIFY(parent.windowState() & (Qt::WindowMinimized|Qt::WindowMaximized));
2453 // ### when minimized and maximized at the same time, the geometry
2454 // ### does *NOT* have to be the normal geometry, it could be the
2455 // ### maximized geometry.
2456 // QCOMPARE(parent.geometry(), geom);
2457 QTRY_COMPARE(parent.normalGeometry(), geom);
2459 parent.setWindowState(parent.windowState() ^ Qt::WindowMinimized);
2461 QTRY_VERIFY(!(parent.windowState() & Qt::WindowMinimized));
2462 QTRY_VERIFY(parent.windowState() & Qt::WindowMaximized);
2463 QTRY_VERIFY(parent.geometry() != geom);
2464 QTRY_COMPARE(parent.normalGeometry(), geom);
2466 parent.setWindowState(parent.windowState() ^ Qt::WindowMaximized);
2468 QTRY_VERIFY(!(parent.windowState() & Qt::WindowMaximized));
2469 QTRY_COMPARE(parent.geometry(), geom);
2470 QTRY_COMPARE(parent.normalGeometry(), geom);
2472 parent.setWindowState(parent.windowState() ^ Qt::WindowFullScreen);
2474 QTRY_VERIFY(parent.windowState() & Qt::WindowFullScreen);
2475 QTRY_VERIFY(parent.geometry() != geom);
2476 QTRY_COMPARE(parent.normalGeometry(), geom);
2478 parent.setWindowState(parent.windowState() ^ Qt::WindowFullScreen);
2480 QVERIFY(!(parent.windowState() & Qt::WindowFullScreen));
2481 QTRY_COMPARE(parent.geometry(), geom);
2482 QTRY_COMPARE(parent.normalGeometry(), geom);
2484 parent.showFullScreen();
2486 QTRY_VERIFY(parent.windowState() & Qt::WindowFullScreen);
2487 QTRY_VERIFY(parent.geometry() != geom);
2488 QTRY_COMPARE(parent.normalGeometry(), geom);
2490 parent.showNormal();
2492 QTRY_VERIFY(!(parent.windowState() & Qt::WindowFullScreen));
2493 QTRY_COMPARE(parent.geometry(), geom);
2494 QTRY_COMPARE(parent.normalGeometry(), geom);
2496 parent.showNormal();
2497 parent.setWindowState(Qt:: WindowFullScreen | Qt::WindowMaximized);
2498 parent.setWindowState(Qt::WindowMinimized | Qt:: WindowFullScreen | Qt::WindowMaximized);
2499 parent.setWindowState(Qt:: WindowFullScreen | Qt::WindowMaximized);
2501 QTRY_COMPARE(parent.normalGeometry(), geom);
2505 void tst_QWidget::setGeometry()
2508 QWidget child(&tlw);
2510 QRect tr(100,100,200,200);
2511 QRect cr(50,50,50,50);
2512 tlw.setGeometry(tr);
2513 child.setGeometry(cr);
2516 QCOMPARE(tlw.geometry().size(), tr.size());
2517 QCOMPARE(child.geometry(), cr);
2519 tlw.setParent(0, Qt::Window|Qt::FramelessWindowHint);
2520 tr = QRect(0,0,100,100);
2521 tr.moveTopLeft(QApplication::desktop()->availableGeometry().topLeft());
2522 tlw.setGeometry(tr);
2523 QCOMPARE(tlw.geometry(), tr);
2526 if (tlw.frameGeometry() != tlw.geometry())
2527 QSKIP("Your window manager is too broken for this test");
2528 QCOMPARE(tlw.geometry(), tr);
2532 // Windows CE does not support windowOpacity.
2534 void tst_QWidget::windowOpacity()
2537 QWidget child(&widget);
2539 // Initial value should be 1.0
2540 QCOMPARE(widget.windowOpacity(), 1.0);
2541 // children should always return 1.0
2542 QCOMPARE(child.windowOpacity(), 1.0);
2544 widget.setWindowOpacity(0.0);
2545 QCOMPARE(widget.windowOpacity(), 0.0);
2546 child.setWindowOpacity(0.0);
2547 QCOMPARE(child.windowOpacity(), 1.0);
2549 widget.setWindowOpacity(1.0);
2550 QCOMPARE(widget.windowOpacity(), 1.0);
2551 child.setWindowOpacity(1.0);
2552 QCOMPARE(child.windowOpacity(), 1.0);
2554 widget.setWindowOpacity(2.0);
2555 QCOMPARE(widget.windowOpacity(), 1.0);
2556 child.setWindowOpacity(2.0);
2557 QCOMPARE(child.windowOpacity(), 1.0);
2559 widget.setWindowOpacity(-1.0);
2560 QCOMPARE(widget.windowOpacity(), 0.0);
2561 child.setWindowOpacity(-1.0);
2562 QCOMPARE(child.windowOpacity(), 1.0);
2566 class UpdateWidget : public QWidget
2569 UpdateWidget(QWidget *parent = 0) : QWidget(parent) {
2573 void paintEvent(QPaintEvent *e) {
2574 paintedRegion += e->region();
2576 if (resizeInPaintEvent) {
2577 resizeInPaintEvent = false;
2578 resize(size() + QSize(2, 2));
2582 bool event(QEvent *event)
2584 switch (event->type()) {
2585 case QEvent::ZOrderChange:
2586 ++numZOrderChangeEvents;
2588 case QEvent::UpdateRequest:
2589 ++numUpdateRequestEvents;
2591 case QEvent::ActivationChange:
2592 case QEvent::FocusIn:
2593 case QEvent::FocusOut:
2594 case QEvent::WindowActivate:
2595 case QEvent::WindowDeactivate:
2596 if (!updateOnActivationChangeAndFocusIn)
2597 return true; // Filter out to avoid update() calls in QWidget.
2602 return QWidget::event(event);
2607 numZOrderChangeEvents = 0;
2608 numUpdateRequestEvents = 0;
2609 updateOnActivationChangeAndFocusIn = false;
2610 resizeInPaintEvent = false;
2611 paintedRegion = QRegion();
2615 int numZOrderChangeEvents;
2616 int numUpdateRequestEvents;
2617 bool updateOnActivationChangeAndFocusIn;
2618 bool resizeInPaintEvent;
2619 QRegion paintedRegion;
2622 void tst_QWidget::lostUpdatesOnHide()
2625 UpdateWidget widget;
2626 widget.setAttribute(Qt::WA_DontShowOnScreen);
2633 QCOMPARE(widget.numPaintEvents, 1);
2637 void tst_QWidget::raise()
2640 QWidget *parent = new QWidget(0);
2641 QList<UpdateWidget *> allChildren;
2643 UpdateWidget *child1 = new UpdateWidget(parent);
2644 child1->setAutoFillBackground(true);
2645 allChildren.append(child1);
2647 UpdateWidget *child2 = new UpdateWidget(parent);
2648 child2->setAutoFillBackground(true);
2649 allChildren.append(child2);
2651 UpdateWidget *child3 = new UpdateWidget(parent);
2652 child3->setAutoFillBackground(true);
2653 allChildren.append(child3);
2655 UpdateWidget *child4 = new UpdateWidget(parent);
2656 child4->setAutoFillBackground(true);
2657 allChildren.append(child4);
2660 QTest::qWaitForWindowShown(parent);
2664 if (child1->internalWinId()) {
2665 QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events.");
2669 QList<QObject *> list1;
2670 list1 << child1 << child2 << child3 << child4;
2671 QVERIFY(parent->children() == list1);
2672 QCOMPARE(allChildren.count(), list1.count());
2674 foreach (UpdateWidget *child, allChildren) {
2675 int expectedPaintEvents = child == child4 ? 1 : 0;
2676 if (expectedPaintEvents == 0) {
2677 QVERIFY(child->numPaintEvents == 0);
2679 // show() issues multiple paint events on some window managers
2680 QTRY_VERIFY(child->numPaintEvents >= expectedPaintEvents);
2682 QCOMPARE(child->numZOrderChangeEvents, 0);
2686 for (int i = 0; i < 5; ++i)
2690 foreach (UpdateWidget *child, allChildren) {
2691 int expectedPaintEvents = child == child2 ? 1 : 0;
2692 int expectedZOrderChangeEvents = child == child2 ? 1 : 0;
2694 QSKIP("Not yet sure why this fails.");
2696 QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
2697 QCOMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
2701 QList<QObject *> list2;
2702 list2 << child1 << child3 << child4 << child2;
2703 QVERIFY(parent->children() == list2);
2705 // Creates a widget on top of all the children and checks that raising one of
2706 // the children underneath doesn't trigger a repaint on the covering widget.
2708 parent->setParent(&topLevel);
2710 QTest::qWaitForWindowShown(&topLevel);
2713 UpdateWidget *onTop = new UpdateWidget(&topLevel);
2715 onTop->resize(topLevel.size());
2716 onTop->setAutoFillBackground(true);
2719 QTRY_VERIFY(onTop->numPaintEvents > 0);
2722 // Reset all the children.
2723 foreach (UpdateWidget *child, allChildren)
2726 for (int i = 0; i < 5; ++i)
2730 QCOMPARE(onTop->numPaintEvents, 0);
2731 QCOMPARE(onTop->numZOrderChangeEvents, 0);
2733 QList<QObject *> list3;
2734 list3 << child1 << child4 << child2 << child3;
2735 QVERIFY(parent->children() == list3);
2737 foreach (UpdateWidget *child, allChildren) {
2738 int expectedPaintEvents = 0;
2739 int expectedZOrderChangeEvents = child == child3 ? 1 : 0;
2740 QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
2741 QCOMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
2746 // Cocoa has no Z-Order for views, we hack it, but it results in paint events.
2748 void tst_QWidget::lower()
2750 QWidget *parent = new QWidget(0);
2751 QList<UpdateWidget *> allChildren;
2753 UpdateWidget *child1 = new UpdateWidget(parent);
2754 child1->setAutoFillBackground(true);
2755 allChildren.append(child1);
2757 UpdateWidget *child2 = new UpdateWidget(parent);
2758 child2->setAutoFillBackground(true);
2759 allChildren.append(child2);
2761 UpdateWidget *child3 = new UpdateWidget(parent);
2762 child3->setAutoFillBackground(true);
2763 allChildren.append(child3);
2765 UpdateWidget *child4 = new UpdateWidget(parent);
2766 child4->setAutoFillBackground(true);
2767 allChildren.append(child4);
2770 QTest::qWaitForWindowShown(parent);
2773 QList<QObject *> list1;
2774 list1 << child1 << child2 << child3 << child4;
2775 QVERIFY(parent->children() == list1);
2776 QCOMPARE(allChildren.count(), list1.count());
2778 foreach (UpdateWidget *child, allChildren) {
2779 int expectedPaintEvents = child == child4 ? 1 : 0;
2780 if (expectedPaintEvents == 0) {
2781 QVERIFY(child->numPaintEvents == 0);
2783 // show() issues multiple paint events on some window managers
2784 QTRY_VERIFY(child->numPaintEvents >= expectedPaintEvents);
2786 QCOMPARE(child->numZOrderChangeEvents, 0);
2790 for (int i = 0; i < 5; ++i)
2795 foreach (UpdateWidget *child, allChildren) {
2796 int expectedPaintEvents = child == child3 ? 1 : 0;
2797 int expectedZOrderChangeEvents = child == child4 ? 1 : 0;
2798 QTRY_COMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
2799 QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
2803 QList<QObject *> list2;
2804 list2 << child4 << child1 << child2 << child3;
2805 QVERIFY(parent->children() == list2);
2811 // Cocoa has no Z-Order for views, we hack it, but it results in paint events.
2813 void tst_QWidget::stackUnder()
2816 QWidget *parent = new QWidget(0);
2817 QList<UpdateWidget *> allChildren;
2819 UpdateWidget *child1 = new UpdateWidget(parent);
2820 child1->setAutoFillBackground(true);
2821 allChildren.append(child1);
2823 UpdateWidget *child2 = new UpdateWidget(parent);
2824 child2->setAutoFillBackground(true);
2825 allChildren.append(child2);
2827 UpdateWidget *child3 = new UpdateWidget(parent);
2828 child3->setAutoFillBackground(true);
2829 allChildren.append(child3);
2831 UpdateWidget *child4 = new UpdateWidget(parent);
2832 child4->setAutoFillBackground(true);
2833 allChildren.append(child4);
2836 QTest::qWaitForWindowShown(parent);
2839 QApplication::sendPostedEvents(); //glib workaround
2842 QList<QObject *> list1;
2843 list1 << child1 << child2 << child3 << child4;
2844 QVERIFY(parent->children() == list1);
2846 foreach (UpdateWidget *child, allChildren) {
2847 int expectedPaintEvents = child == child4 ? 1 : 0;
2848 #if defined(Q_WS_WIN) || defined(Q_OS_MAC)
2849 if (expectedPaintEvents == 1 && child->numPaintEvents == 2)
2850 QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue);
2852 QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
2853 QCOMPARE(child->numZOrderChangeEvents, 0);
2857 for (int i = 0; i < 5; ++i)
2858 child4->stackUnder(child2);
2861 QList<QObject *> list2;
2862 list2 << child1 << child4 << child2 << child3;
2863 QVERIFY(parent->children() == list2);
2865 foreach (UpdateWidget *child, allChildren) {
2866 int expectedPaintEvents = child == child3 ? 1 : 0;
2867 int expectedZOrderChangeEvents = child == child4 ? 1 : 0;
2868 QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents);
2869 QTRY_COMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
2873 for (int i = 0; i < 5; ++i)
2874 child1->stackUnder(child3);
2877 QList<QObject *> list3;
2878 list3 << child4 << child2 << child1 << child3;
2879 QVERIFY(parent->children() == list3);
2881 foreach (UpdateWidget *child, allChildren) {
2882 int expectedZOrderChangeEvents = child == child1 ? 1 : 0;
2883 if (child == child3) {
2885 qApp->processEvents();
2888 QEXPECT_FAIL(0, "See QTBUG-493", Continue);
2890 QCOMPARE(child->numPaintEvents, 0);
2892 QCOMPARE(child->numPaintEvents, 0);
2894 QTRY_COMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents);
2902 void drawPolygon(QPaintDevice *dev, int w, int h)
2905 p.fillRect(0, 0, w, h, Qt::white);
2908 a << QPoint(0, 0) << QPoint(w/2, h/2) << QPoint(w, 0)
2909 << QPoint(w/2, h) << QPoint(0, 0);
2911 p.setPen(QPen(Qt::black, 1));
2912 p.setBrush(Qt::DiagCrossPattern);
2916 class ContentsPropagationWidget : public QWidget
2920 ContentsPropagationWidget(QWidget *parent = 0) : QWidget(parent)
2922 QWidget *child = this;
2923 for (int i=0; i<32; ++i) {
2924 child = new QWidget(child);
2925 child->setGeometry(i, i, 400 - i*2, 400 - i*2);
2929 void setContentsPropagation(bool enable) {
2930 foreach (QObject *child, children())
2931 qobject_cast<QWidget *>(child)->setAutoFillBackground(!enable);
2935 void paintEvent(QPaintEvent *)
2937 int w = width(), h = height();
2938 drawPolygon(this, w, h);
2941 QSize sizeHint() const { return QSize(500, 500); }
2944 void tst_QWidget::testContentsPropagation()
2946 ContentsPropagationWidget widget;
2948 widget.resize(500,500);
2950 widget.setFixedSize(500, 500);
2952 widget.setContentsPropagation(false);
2953 QPixmap widgetSnapshot = QPixmap::grabWidget(&widget);
2955 QPixmap correct(500, 500);
2956 drawPolygon(&correct, 500, 500);
2957 //correct.save("correct.png", "PNG");
2959 //widgetSnapshot.save("snap1.png", "PNG");
2960 QVERIFY(widgetSnapshot.toImage() != correct.toImage());
2962 widget.setContentsPropagation(true);
2963 widgetSnapshot = QPixmap::grabWidget(&widget);
2964 //widgetSnapshot.save("snap2.png", "PNG");
2966 QCOMPARE(widgetSnapshot, correct);
2970 Test that saving and restoring window geometry with
2971 saveGeometry() and restoreGeometry() works.
2973 // 4DWM issues on IRIX makes this test fail.
2975 void tst_QWidget::saveRestoreGeometry()
2977 const QPoint position(100, 100);
2978 const QSize size(200, 200);
2980 QByteArray savedGeometry;
2984 widget.move(position);
2985 widget.resize(size);
2987 QTest::qWaitForWindowShown(&widget);
2988 QApplication::processEvents();
2990 QTRY_COMPARE(widget.pos(), position);
2991 QCOMPARE(widget.size(), size);
2992 savedGeometry = widget.saveGeometry();
2998 const QByteArray empty;
2999 const QByteArray one("a");
3000 const QByteArray two("ab");
3001 const QByteArray three("abc");
3002 const QByteArray four("abca");
3003 const QByteArray garbage("abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc");
3005 QVERIFY(widget.restoreGeometry(empty) == false);
3006 QVERIFY(widget.restoreGeometry(one) == false);
3007 QVERIFY(widget.restoreGeometry(two) == false);
3008 QVERIFY(widget.restoreGeometry(three) == false);
3009 QVERIFY(widget.restoreGeometry(four) == false);
3010 QVERIFY(widget.restoreGeometry(garbage) == false);
3012 QVERIFY(widget.restoreGeometry(savedGeometry));
3014 QTest::qWaitForWindowShown(&widget);
3015 QApplication::processEvents();
3017 QTRY_COMPARE(widget.pos(), position);
3018 QCOMPARE(widget.size(), size);
3020 QCOMPARE(widget.pos(), position);
3021 QCOMPARE(widget.size(), size);
3026 widget.move(position);
3027 widget.resize(size);
3029 QTest::qWaitForWindowShown(&widget);
3031 QTRY_COMPARE(widget.geometry().size(), size);
3035 //Restore from Full screen
3036 savedGeometry = widget.saveGeometry();
3037 geom = widget.geometry();
3038 widget.setWindowState(widget.windowState() | Qt::WindowFullScreen);
3039 QTRY_VERIFY((widget.windowState() & Qt::WindowFullScreen));
3041 QVERIFY(widget.restoreGeometry(savedGeometry));
3043 QTRY_VERIFY(!(widget.windowState() & Qt::WindowFullScreen));
3044 QTRY_COMPARE(widget.geometry(), geom);
3046 //Restore to full screen
3047 widget.setWindowState(widget.windowState() | Qt::WindowFullScreen);
3049 QTRY_VERIFY((widget.windowState() & Qt::WindowFullScreen));
3051 savedGeometry = widget.saveGeometry();
3052 geom = widget.geometry();
3053 widget.setWindowState(widget.windowState() ^ Qt::WindowFullScreen);
3055 QTRY_VERIFY(!(widget.windowState() & Qt::WindowFullScreen));
3057 QVERIFY(widget.restoreGeometry(savedGeometry));
3059 QTRY_VERIFY((widget.windowState() & Qt::WindowFullScreen));
3060 QTRY_COMPARE(widget.geometry(), geom);
3061 QVERIFY((widget.windowState() & Qt::WindowFullScreen));
3062 widget.setWindowState(widget.windowState() ^ Qt::WindowFullScreen);
3064 QTRY_VERIFY(!(widget.windowState() & Qt::WindowFullScreen));
3067 //Restore from Maximised
3068 widget.move(position);
3069 widget.resize(size);
3071 QTRY_COMPARE(widget.size(), size);
3073 savedGeometry = widget.saveGeometry();
3074 geom = widget.geometry();
3075 widget.setWindowState(widget.windowState() | Qt::WindowMaximized);
3077 QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized));
3078 QTRY_VERIFY(widget.geometry() != geom);
3080 QVERIFY(widget.restoreGeometry(savedGeometry));
3082 QTRY_COMPARE(widget.geometry(), geom);
3084 QVERIFY(!(widget.windowState() & Qt::WindowMaximized));
3086 //Restore to maximised
3087 widget.setWindowState(widget.windowState() | Qt::WindowMaximized);
3089 QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized));
3091 geom = widget.geometry();
3092 savedGeometry = widget.saveGeometry();
3093 widget.setWindowState(widget.windowState() ^ Qt::WindowMaximized);
3095 QTRY_VERIFY(!(widget.windowState() & Qt::WindowMaximized));
3097 QVERIFY(widget.restoreGeometry(savedGeometry));
3099 QTRY_VERIFY((widget.windowState() & Qt::WindowMaximized));
3100 QTRY_COMPARE(widget.geometry(), geom);
3105 // 4DWM issues on IRIX makes this test fail.
3107 void tst_QWidget::restoreVersion1Geometry_data()
3109 QTest::addColumn<QString>("fileName");
3110 QTest::addColumn<uint>("expectedWindowState");
3111 QTest::addColumn<QPoint>("expectedPosition");
3112 QTest::addColumn<QSize>("expectedSize");
3113 QTest::addColumn<QRect>("expectedNormalGeometry");
3114 const QPoint position(100, 100);
3115 const QSize size(200, 200);
3116 const QRect normalGeometry(102, 124, 200, 200);
3118 QTest::newRow("geometry.dat") << ":geometry.dat" << uint(Qt::WindowNoState) << position << size << normalGeometry;
3119 QTest::newRow("geometry-maximized.dat") << ":geometry-maximized.dat" << uint(Qt::WindowMaximized) << position << size << normalGeometry;
3120 QTest::newRow("geometry-fullscreen.dat") << ":geometry-fullscreen.dat" << uint(Qt::WindowFullScreen) << position << size << normalGeometry;
3124 Test that the current version of restoreGeometry() can restore geometry
3125 saved width saveGeometry() version 1.0.
3127 void tst_QWidget::restoreVersion1Geometry()
3129 QFETCH(QString, fileName);
3130 QFETCH(uint, expectedWindowState);
3131 QFETCH(QPoint, expectedPosition);
3132 QFETCH(QSize, expectedSize);
3133 QFETCH(QRect, expectedNormalGeometry);
3135 // WindowActive is uninteresting for this test
3136 const uint WindowStateMask = Qt::WindowFullScreen | Qt::WindowMaximized | Qt::WindowMinimized;
3139 QVERIFY(f.exists());
3140 f.open(QIODevice::ReadOnly);
3141 const QByteArray savedGeometry = f.readAll();
3142 QCOMPARE(savedGeometry.count(), 46);
3147 QVERIFY(widget.restoreGeometry(savedGeometry));
3149 QCOMPARE(uint(widget.windowState() & WindowStateMask), expectedWindowState);
3150 if (expectedWindowState == Qt::WindowNoState) {
3151 QCOMPARE(widget.pos(), expectedPosition);
3152 QCOMPARE(widget.size(), expectedSize);
3155 QTest::qWaitForWindowShown(&widget);
3158 if (expectedWindowState == Qt::WindowNoState) {
3159 QTRY_COMPARE(widget.pos(), expectedPosition);
3160 QTRY_COMPARE(widget.size(), expectedSize);
3163 widget.showNormal();
3166 if (expectedWindowState != Qt::WindowNoState) {
3167 // restoring from maximized or fullscreen, we can only restore to the normal geometry
3168 QTRY_COMPARE(widget.geometry(), expectedNormalGeometry);
3170 QTRY_COMPARE(widget.pos(), expectedPosition);
3171 QTRY_COMPARE(widget.size(), expectedSize);
3175 // Code for saving a new geometry*.dat files
3177 QWidget widgetToSave;
3178 widgetToSave.move(expectedPosition);
3179 widgetToSave.resize(expectedSize);
3180 widgetToSave.show();
3182 qt_x11_wait_for_window_manager(&widget);
3184 QTest::qWait(500); // stabilize
3185 widgetToSave.setWindowState(Qt::WindowStates(expectedWindowState));
3186 QTest::qWait(500); // stabilize
3188 QByteArray geometryToSave = widgetToSave.saveGeometry();
3190 // Code for saving a new geometry.dat file.
3191 f.setFileName(fileName.mid(1));
3192 QVERIFY(f.open(QIODevice::WriteOnly)); // did you forget to 'p4 edit *.dat'? :)
3193 f.write(geometryToSave);
3200 void tst_QWidget::widgetAt()
3204 QWidget *w1 = new QWidget(0, Qt::X11BypassWindowManagerHint);
3205 w1->setGeometry(0,0,150,150);
3206 w1->setObjectName("w1");
3208 QWidget *w2 = new QWidget(0, Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint);
3209 w2->setGeometry(50,50,100,100);
3210 w2->setObjectName("w2");
3212 QTest::qWaitForWindowShown(w1);
3213 qApp->processEvents();
3215 QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)));
3216 QCOMPARE(wr->objectName(), QString("w1"));
3219 QTest::qWaitForWindowShown(w2);
3220 qApp->processEvents();
3221 qApp->processEvents();
3222 qApp->processEvents();
3223 QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)));
3224 QCOMPARE(wr->objectName(), QString("w2"));
3227 qApp->processEvents();
3228 QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)) && wr->objectName() == QString("w1"));
3231 qApp->processEvents();
3232 QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)) && wr->objectName() == QString("w2"));
3234 QWidget *w3 = new QWidget(w2);
3235 w3->setGeometry(10,10,50,50);
3236 w3->setObjectName("w3");
3238 qApp->processEvents();
3239 QTRY_VERIFY((wr = QApplication::widgetAt(100,100)) && wr->objectName() == QString("w3"));
3241 w3->setAttribute(Qt::WA_TransparentForMouseEvents);
3242 qApp->processEvents();
3243 QTRY_VERIFY((wr = QApplication::widgetAt(100, 100)) && wr->objectName() == QString("w2"));
3245 QRegion rgn = QRect(QPoint(0,0), w2->size());
3246 QPoint point = w2->mapFromGlobal(QPoint(100,100));
3247 rgn -= QRect(point, QSize(1,1));
3249 qApp->processEvents();
3251 #if defined(Q_OS_WINCE)
3252 QEXPECT_FAIL("", "Windows CE does only support rectangular regions", Continue); //See also task 147191
3254 /// ### fixme: Check platforms
3255 QEXPECT_FAIL("", "Window mask not implemented on Lighthouse QTBUG-22326", Continue);
3257 QTRY_COMPARE(QApplication::widgetAt(100,100)->objectName(), w1->objectName());
3258 QTRY_COMPARE(QApplication::widgetAt(101,101)->objectName(), w2->objectName());
3260 QBitmap bitmap(w2->size());
3261 QPainter p(&bitmap);
3262 p.fillRect(bitmap.rect(), Qt::color1);
3263 p.setPen(Qt::color0);
3264 p.drawPoint(w2->mapFromGlobal(QPoint(100,100)));
3266 w2->setMask(bitmap);
3267 qApp->processEvents();
3269 #if defined(Q_OS_WINCE)
3270 QEXPECT_FAIL("", "Windows CE does only support rectangular regions", Continue); //See also task 147191
3272 /// ### fixme: Check platforms
3273 QEXPECT_FAIL("", "Window mask not implemented on Lighthouse QTBUG-22326", Continue);
3274 QTRY_VERIFY(QApplication::widgetAt(100,100) == w1);
3275 QTRY_VERIFY(QApplication::widgetAt(101,101) == w2);
3281 #if defined(Q_WS_X11)
3282 bool getProperty(Display *display, Window target, Atom type, Atom property,
3283 unsigned char** data, unsigned long* count)
3287 unsigned long nitems, bytes_left;
3289 int ret = XGetWindowProperty(display, target, property,
3291 type, &atom_return, &size,
3292 &nitems, &bytes_left, data);
3293 if (ret != Success || nitems < 1)
3296 if (bytes_left != 0) {
3298 unsigned long remain = ((size / 8) * nitems) + bytes_left;
3299 ret = XGetWindowProperty(display, target,
3300 property, 0l, remain, false,
3301 type, &atom_return, &size,
3302 &nitems, &bytes_left, data);
3311 QString textPropertyToString(Display *display, XTextProperty& text_prop)
3314 if (text_prop.value && text_prop.nitems > 0) {
3315 if (text_prop.encoding == XA_STRING) {
3316 ret = reinterpret_cast<char *>(text_prop.value);
3318 text_prop.nitems = strlen(reinterpret_cast<char *>(text_prop.value));
3321 if (XmbTextPropertyToTextList(display, &text_prop, &list, &num) == Success
3322 && num > 0 && *list) {
3323 ret = QString::fromLocal8Bit(*list);
3324 XFreeStringList(list);
3332 void tst_QWidget::task110173()
3336 QPushButton *pb1 = new QPushButton("click", &w);
3337 pb1->setFocusPolicy(Qt::ClickFocus);
3338 pb1->move(100, 100);
3340 QPushButton *pb2 = new QPushButton("push", &w);
3341 pb2->setFocusPolicy(Qt::ClickFocus);
3342 pb2->move(300, 300);
3344 QTest::keyClick( &w, Qt::Key_Tab );
3346 QTest::qWaitForWindowShown(&w);
3350 class Widget : public QWidget
3353 Widget() : deleteThis(false) { setFocusPolicy(Qt::StrongFocus); }
3354 void actionEvent(QActionEvent *) { if (deleteThis) delete this; }
3355 void changeEvent(QEvent *) { if (deleteThis) delete this; }
3356 void closeEvent(QCloseEvent *) { if (deleteThis) delete this; }
3357 void hideEvent(QHideEvent *) { if (deleteThis) delete this; }
3358 void focusOutEvent(QFocusEvent *) { if (deleteThis) delete this; }
3359 void keyPressEvent(QKeyEvent *) { if (deleteThis) delete this; }
3360 void keyReleaseEvent(QKeyEvent *) { if (deleteThis) delete this; }
3361 void mouseDoubleClickEvent(QMouseEvent *) { if (deleteThis) delete this; }
3362 void mousePressEvent(QMouseEvent *) { if (deleteThis) delete this; }
3363 void mouseReleaseEvent(QMouseEvent *) { if (deleteThis) delete this; }
3364 void mouseMoveEvent(QMouseEvent *) { if (deleteThis) delete this; }
3369 void tst_QWidget::testDeletionInEventHandlers()
3372 QPointer<Widget> w = new Widget;
3373 w->deleteThis = true;
3378 // focusOut (crashes)
3382 //QVERIFY(qApp->focusWidget() == w);
3383 //w->deleteThis = true;
3390 w->deleteThis = true;
3391 QTest::keyPress(w, Qt::Key_A);
3398 w->deleteThis = true;
3399 QTest::keyRelease(w, Qt::Key_A);
3406 w->deleteThis = true;
3407 QTest::mousePress(w, Qt::LeftButton);
3414 w->deleteThis = true;
3415 QTest::mouseRelease(w, Qt::LeftButton);
3419 // mouse double click
3422 w->deleteThis = true;
3423 QTest::mouseDClick(w, Qt::LeftButton);
3427 // hide event (crashes)
3430 //w->deleteThis = true;
3436 w->deleteThis = true;
3437 w->addAction(new QAction(w));
3444 w->deleteThis = true;
3445 w->setMouseTracking(true);
3450 w->setMouseTracking(true);
3452 w->deleteThis = true;
3453 QMouseEvent me(QEvent::MouseMove, QPoint(0, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
3454 QApplication::sendEvent(w, &me);
3460 void tst_QWidget::sheetOpacity()
3463 QWidget sheet(&tmpWindow, Qt::Sheet);
3466 QCOMPARE(int(sheet.windowOpacity() * 255), 242); // 95%
3467 sheet.setParent(0, Qt::Dialog);
3468 QCOMPARE(int(sheet.windowOpacity() * 255), 255);
3471 class MaskedPainter : public QWidget
3477 : mask(20, 20, 50, 50)
3482 void paintEvent(QPaintEvent *)
3485 p.fillRect(mask, QColor(Qt::red));
3490 Verifies that the entire area inside the mask is painted red.
3492 bool verifyWidgetMask(QWidget *widget, QRect mask)
3494 const QImage image = QPixmap::grabWindow(widget->winId()).toImage();
3496 const QImage masked = image.copy(mask);
3498 red.fill(QColor(Qt::red).rgb());
3500 return (masked == red);
3503 void tst_QWidget::setMask()
3505 testWidget->hide(); // get this out of the way.
3512 QVERIFY(verifyWidgetMask(&w, w.mask));
3517 w.setWindowFlags(w.windowFlags() | Qt::FramelessWindowHint);
3520 QRect mask = w.mask;
3522 QVERIFY(verifyWidgetMask(&w, mask));
3527 class StaticWidget : public QWidget
3533 QRegion paintedRegion;
3535 StaticWidget(QWidget *parent = 0)
3538 setAttribute(Qt::WA_StaticContents);
3539 setAttribute(Qt::WA_OpaquePaintEvent);
3540 setPalette(Qt::red); // Make sure we have an opaque palette.
3541 setAutoFillBackground(true);
3542 gotPaintEvent = false;
3545 void paintEvent(QPaintEvent *e)
3547 paintedRegion += e->region();
3548 gotPaintEvent = true;
3549 // qDebug() << "paint" << e->region();
3550 // Look for a full update, set partial to false if found.
3551 foreach(QRect r, e->region().rects()) {
3552 partial = (r != rect());
3553 if (partial == false)
3560 Test that widget resizes and moves can be done with minimal repaints when WA_StaticContents
3561 and WA_OpaquePaintEvent is set. Test is mac-only for now.
3563 void tst_QWidget::optimizedResizeMove()
3566 parent.resize(400, 400);
3568 StaticWidget staticWidget(&parent);
3569 staticWidget.gotPaintEvent = false;
3570 staticWidget.move(150, 150);
3571 staticWidget.resize(150, 150);
3573 QTest::qWaitForWindowShown(&parent);
3575 QTRY_COMPARE(staticWidget.gotPaintEvent, true);
3577 staticWidget.gotPaintEvent = false;
3578 staticWidget.move(staticWidget.pos() + QPoint(10, 10));
3580 QCOMPARE(staticWidget.gotPaintEvent, false);
3582 staticWidget.gotPaintEvent = false;
3583 staticWidget.move(staticWidget.pos() + QPoint(-10, -10));
3585 QCOMPARE(staticWidget.gotPaintEvent, false);
3587 staticWidget.gotPaintEvent = false;
3588 staticWidget.move(staticWidget.pos() + QPoint(-10, 10));
3590 QCOMPARE(staticWidget.gotPaintEvent, false);
3592 staticWidget.gotPaintEvent = false;
3593 staticWidget.resize(staticWidget.size() + QSize(10, 10));
3595 QCOMPARE(staticWidget.gotPaintEvent, true);
3596 QCOMPARE(staticWidget.partial, true);
3598 staticWidget.gotPaintEvent = false;
3599 staticWidget.resize(staticWidget.size() + QSize(-10, -10));
3601 QCOMPARE(staticWidget.gotPaintEvent, false);
3603 staticWidget.gotPaintEvent = false;
3604 staticWidget.resize(staticWidget.size() + QSize(10, -10));
3606 QCOMPARE(staticWidget.gotPaintEvent, true);
3607 QCOMPARE(staticWidget.partial, true);
3609 staticWidget.gotPaintEvent = false;
3610 staticWidget.move(staticWidget.pos() + QPoint(10, 10));
3611 staticWidget.resize(staticWidget.size() + QSize(-10, -10));
3613 QCOMPARE(staticWidget.gotPaintEvent, false);
3615 staticWidget.gotPaintEvent = false;
3616 staticWidget.move(staticWidget.pos() + QPoint(10, 10));
3617 staticWidget.resize(staticWidget.size() + QSize(10, 10));
3619 QCOMPARE(staticWidget.gotPaintEvent, true);
3620 QCOMPARE(staticWidget.partial, true);
3622 staticWidget.gotPaintEvent = false;
3623 staticWidget.move(staticWidget.pos() + QPoint(-10, -10));
3624 staticWidget.resize(staticWidget.size() + QSize(-10, -10));
3626 QCOMPARE(staticWidget.gotPaintEvent, false);
3628 staticWidget.setAttribute(Qt::WA_StaticContents, false);
3629 staticWidget.gotPaintEvent = false;
3630 staticWidget.move(staticWidget.pos() + QPoint(-10, -10));
3631 staticWidget.resize(staticWidget.size() + QSize(-10, -10));
3633 QCOMPARE(staticWidget.gotPaintEvent, true);
3634 QCOMPARE(staticWidget.partial, false);
3635 staticWidget.setAttribute(Qt::WA_StaticContents, true);
3637 staticWidget.setAttribute(Qt::WA_StaticContents, false);
3638 staticWidget.gotPaintEvent = false;
3639 staticWidget.move(staticWidget.pos() + QPoint(10, 10));
3641 QCOMPARE(staticWidget.gotPaintEvent, false);
3642 staticWidget.setAttribute(Qt::WA_StaticContents, true);
3645 void tst_QWidget::optimizedResize_topLevel()
3647 #if defined(Q_OS_MAC) || defined(Q_WS_QWS)
3648 QSKIP("We do not yet have static contents support for *top-levels* on this platform");
3651 StaticWidget topLevel;
3652 topLevel.gotPaintEvent = false;
3654 QTest::qWaitForWindowShown(&topLevel);
3656 QTRY_COMPARE(topLevel.gotPaintEvent, true);
3658 topLevel.gotPaintEvent = false;
3659 topLevel.partial = false;
3660 topLevel.paintedRegion = QRegion();
3663 topLevel.resize(topLevel.size() + QSize(10, 10));
3665 // Static contents does not work when programmatically resizing
3666 // top-levels with QWidget::resize. We do some funky stuff in
3667 // setGeometry_sys. However, resizing it with the mouse or with
3668 // a native function call works (it basically has to go through
3669 // WM_RESIZE in QApplication). This is a corner case, though.
3671 const QRect frame = topLevel.frameGeometry();
3672 MoveWindow(topLevel.winId(), frame.x(), frame.y(),
3673 frame.width() + 10, frame.height() + 10,
3679 // Expected update region: New rect - old rect.
3680 QRegion expectedUpdateRegion(topLevel.rect());
3681 expectedUpdateRegion -= QRect(QPoint(), topLevel.size() - QSize(10, 10));
3683 QTRY_COMPARE(topLevel.gotPaintEvent, true);
3684 QCOMPARE(topLevel.partial, true);
3685 QCOMPARE(topLevel.paintedRegion, expectedUpdateRegion);
3688 class SiblingDeleter : public QWidget
3691 inline SiblingDeleter(QWidget *sibling, QWidget *parent)
3692 : QWidget(parent), sibling(sibling) {}
3693 inline virtual ~SiblingDeleter() { delete sibling; }
3696 QPointer<QWidget> sibling;
3700 void tst_QWidget::childDeletesItsSibling()
3702 QWidget *commonParent = new QWidget(0);
3703 QPointer<QWidget> child = new QWidget(0);
3704 QPointer<QWidget> siblingDeleter = new SiblingDeleter(child, commonParent);
3705 child->setParent(commonParent);
3706 delete commonParent; // don't crash
3708 QVERIFY(!siblingDeleter);
3713 # define SET_SAFE_SIZE(w) \
3715 QSize safeSize(qt_screen->width() - 250, qt_screen->height() - 250); \
3716 if (!safeSize.isValid()) \
3717 QSKIP("Screen size too small"); \
3718 if (defaultSize.width() > safeSize.width() || defaultSize.height() > safeSize.height()) { \
3719 defaultSize = safeSize; \
3720 w.resize(defaultSize); \
3721 w.setAttribute(Qt::WA_Resized, false); \
3725 # define SET_SAFE_SIZE(w)
3729 void tst_QWidget::setMinimumSize()
3732 QSize defaultSize = w.size();
3735 w.setMinimumSize(defaultSize + QSize(100, 100));
3736 QCOMPARE(w.size(), defaultSize + QSize(100, 100));
3737 QVERIFY(!w.testAttribute(Qt::WA_Resized));
3739 w.setMinimumSize(defaultSize + QSize(50, 50));
3740 QCOMPARE(w.size(), defaultSize + QSize(100, 100));
3741 QVERIFY(!w.testAttribute(Qt::WA_Resized));
3743 w.setMinimumSize(defaultSize + QSize(200, 200));
3744 QCOMPARE(w.size(), defaultSize + QSize(200, 200));
3745 QVERIFY(!w.testAttribute(Qt::WA_Resized));
3747 // Setting a minimum size larger than the desktop does not work on WinCE,
3748 // so skip this part of the test.
3750 QSize nonDefaultSize = defaultSize + QSize(5,5);
3751 w.setMinimumSize(nonDefaultSize);
3754 QVERIFY(w.height() >= nonDefaultSize.height());
3755 QVERIFY(w.width() >= nonDefaultSize.width());
3759 void tst_QWidget::setMaximumSize()
3762 QSize defaultSize = w.size();
3765 w.setMinimumSize(defaultSize + QSize(100, 100));
3766 QCOMPARE(w.size(), defaultSize + QSize(100, 100));
3767 QVERIFY(!w.testAttribute(Qt::WA_Resized));
3768 w.setMinimumSize(defaultSize);
3770 w.setMaximumSize(defaultSize + QSize(200, 200));
3771 QCOMPARE(w.size(), defaultSize + QSize(100, 100));
3772 QVERIFY(!w.testAttribute(Qt::WA_Resized));
3774 w.setMaximumSize(defaultSize + QSize(50, 50));
3775 QCOMPARE(w.size(), defaultSize + QSize(50, 50));
3776 QVERIFY(!w.testAttribute(Qt::WA_Resized));
3779 void tst_QWidget::setFixedSize()
3782 QSize defaultSize = w.size();
3785 w.setFixedSize(defaultSize + QSize(100, 100));
3786 QCOMPARE(w.size(), defaultSize + QSize(100, 100));
3787 QVERIFY(w.testAttribute(Qt::WA_Resized));
3789 w.setFixedSize(defaultSize + QSize(200, 200));
3791 QCOMPARE(w.minimumSize(), defaultSize + QSize(200,200));
3792 QCOMPARE(w.maximumSize(), defaultSize + QSize(200,200));
3793 QCOMPARE(w.size(), defaultSize + QSize(200, 200));
3794 QVERIFY(w.testAttribute(Qt::WA_Resized));
3796 w.setFixedSize(defaultSize + QSize(50, 50));
3797 QCOMPARE(w.size(), defaultSize + QSize(50, 50));
3798 QVERIFY(w.testAttribute(Qt::WA_Resized));
3800 w.setAttribute(Qt::WA_Resized, false);
3801 w.setFixedSize(defaultSize + QSize(50, 50));
3802 QVERIFY(!w.testAttribute(Qt::WA_Resized));
3804 w.setFixedSize(defaultSize + QSize(150, 150));
3807 QVERIFY(w.size() == defaultSize + QSize(150,150));
3810 void tst_QWidget::ensureCreated()
3814 WId widgetWinId = widget.winId();
3815 Q_UNUSED(widgetWinId);
3816 QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
3822 QDialog dialog(&window);
3823 dialog.setWindowModality(Qt::NonModal);
3825 WId dialogWinId = dialog.winId();
3826 Q_UNUSED(dialogWinId);
3827 QVERIFY(dialog.testAttribute(Qt::WA_WState_Created));
3828 QVERIFY(window.testAttribute(Qt::WA_WState_Created));
3834 QDialog dialog(&window);
3835 dialog.setWindowModality(Qt::WindowModal);
3837 WId dialogWinId = dialog.winId();
3838 Q_UNUSED(dialogWinId);
3839 QVERIFY(dialog.testAttribute(Qt::WA_WState_Created));
3840 QVERIFY(window.testAttribute(Qt::WA_WState_Created));
3846 QDialog dialog(&window);
3847 dialog.setWindowModality(Qt::ApplicationModal);
3849 WId dialogWinId = dialog.winId();
3850 Q_UNUSED(dialogWinId);
3851 QVERIFY(dialog.testAttribute(Qt::WA_WState_Created));
3852 QVERIFY(window.testAttribute(Qt::WA_WState_Created));
3856 class WinIdChangeWidget : public QWidget {
3858 WinIdChangeWidget(QWidget *p = 0)
3864 bool event(QEvent *e)
3866 if (e->type() == QEvent::WinIdChange) {
3867 m_winIdList.append(internalWinId());
3870 return QWidget::event(e);
3873 QList<WId> m_winIdList;
3874 int winIdChangeEventCount() const { return m_winIdList.count(); }
3877 void tst_QWidget::winIdChangeEvent()
3880 // Transforming an alien widget into a native widget
3881 WinIdChangeWidget widget;
3882 const WId winIdBefore = widget.internalWinId();
3883 const WId winIdAfter = widget.winId();
3884 QVERIFY(winIdBefore != winIdAfter);
3885 QCOMPARE(widget.winIdChangeEventCount(), 1);
3889 // Changing parent of a native widget
3890 // Should cause winId of child to change, on all platforms
3891 QWidget parent1, parent2;
3892 WinIdChangeWidget child(&parent1);
3893 const WId winIdBefore = child.winId();
3894 QCOMPARE(child.winIdChangeEventCount(), 1);
3895 child.setParent(&parent2);
3896 const WId winIdAfter = child.internalWinId();
3897 QVERIFY(winIdBefore != winIdAfter);
3898 QCOMPARE(child.winIdChangeEventCount(), 3);
3899 // winId is set to zero during reparenting
3900 QVERIFY(0 == child.m_winIdList[1]);
3904 // Changing grandparent of a native widget
3905 QWidget grandparent1, grandparent2;
3906 QWidget parent(&grandparent1);
3907 WinIdChangeWidget child(&parent);
3908 const WId winIdBefore = child.winId();
3909 QCOMPARE(child.winIdChangeEventCount(), 1);
3910 parent.setParent(&grandparent2);
3911 const WId winIdAfter = child.internalWinId();
3912 QCOMPARE(winIdBefore, winIdAfter);
3913 QCOMPARE(child.winIdChangeEventCount(), 1);
3917 // Changing parent of an alien widget
3918 QWidget parent1, parent2;
3919 WinIdChangeWidget child(&parent1);
3920 const WId winIdBefore = child.internalWinId();
3921 child.setParent(&parent2);
3922 const WId winIdAfter = child.internalWinId();
3923 QCOMPARE(winIdBefore, winIdAfter);
3924 QCOMPARE(child.winIdChangeEventCount(), 0);
3928 // Making native child widget into a top-level window
3930 WinIdChangeWidget child(&parent);
3932 const WId winIdBefore = child.internalWinId();
3933 QCOMPARE(child.winIdChangeEventCount(), 1);
3934 const Qt::WindowFlags flags = child.windowFlags();
3935 child.setWindowFlags(flags | Qt::Window);
3936 const WId winIdAfter = child.internalWinId();
3937 QVERIFY(winIdBefore != winIdAfter);
3938 QCOMPARE(child.winIdChangeEventCount(), 3);
3939 // winId is set to zero during reparenting
3940 QVERIFY(0 == child.m_winIdList[1]);
3944 void tst_QWidget::persistentWinId()
3946 QWidget *parent = new QWidget;
3947 QWidget *w1 = new QWidget;
3948 QWidget *w2 = new QWidget;
3949 QWidget *w3 = new QWidget;
3950 w1->setParent(parent);
3954 WId winId1 = w1->winId();
3955 WId winId2 = w2->winId();
3956 WId winId3 = w3->winId();
3958 // reparenting should change the winId of the widget being reparented, but not of its children
3960 QVERIFY(w1->winId() != winId1);
3961 winId1 = w1->winId();
3962 QCOMPARE(w2->winId(), winId2);
3963 QCOMPARE(w3->winId(), winId3);
3965 w1->setParent(parent);
3966 QVERIFY(w1->winId() != winId1);
3967 winId1 = w1->winId();
3968 QCOMPARE(w2->winId(), winId2);
3969 QCOMPARE(w3->winId(), winId3);
3972 QVERIFY(w2->winId() != winId2);
3973 winId2 = w2->winId();
3974 QCOMPARE(w3->winId(), winId3);
3976 w2->setParent(parent);
3977 QVERIFY(w2->winId() != winId2);
3978 winId2 = w2->winId();
3979 QCOMPARE(w3->winId(), winId3);
3982 QVERIFY(w2->winId() != winId2);
3983 winId2 = w2->winId();
3984 QCOMPARE(w3->winId(), winId3);
3987 QVERIFY(w3->winId() != winId3);
3988 winId3 = w3->winId();
3991 QVERIFY(w3->winId() != winId3);
3992 winId3 = w3->winId();
3995 QVERIFY(w3->winId() != winId3);
3996 winId3 = w3->winId();
4001 void tst_QWidget::showNativeChild()
4004 topLevel.setGeometry(0, 0, 100, 100);
4005 QWidget child(&topLevel);
4008 QTest::qWaitForWindowShown(&topLevel);
4011 class ShowHideEventWidget : public QWidget
4014 int numberOfShowEvents, numberOfHideEvents;
4016 ShowHideEventWidget(QWidget *parent = 0)
4017 : QWidget(parent), numberOfShowEvents(0), numberOfHideEvents(0)
4021 { QWidget::create(); }
4023 void showEvent(QShowEvent *)
4024 { ++numberOfShowEvents; }
4026 void hideEvent(QHideEvent *)
4027 { ++numberOfHideEvents; }
4030 void tst_QWidget::showHideEvent_data()
4032 QTest::addColumn<bool>("show");
4033 QTest::addColumn<bool>("hide");
4034 QTest::addColumn<bool>("create");
4035 QTest::addColumn<int>("expectedShowEvents");
4036 QTest::addColumn<int>("expectedHideEvents");
4038 QTest::newRow("window: only show")
4044 QTest::newRow("window: show/hide")
4050 QTest::newRow("window: show/hide/create")
4056 QTest::newRow("window: hide/create")
4062 QTest::newRow("window: only hide")
4068 QTest::newRow("window: nothing")
4076 void tst_QWidget::showHideEvent()
4080 QFETCH(bool, create);
4081 QFETCH(int, expectedShowEvents);
4082 QFETCH(int, expectedHideEvents);
4084 ShowHideEventWidget widget;
4089 if (create && !widget.testAttribute(Qt::WA_WState_Created))
4092 QCOMPARE(widget.numberOfShowEvents, expectedShowEvents);
4093 QCOMPARE(widget.numberOfHideEvents, expectedHideEvents);
4096 void tst_QWidget::update()
4098 QTest::qWait(10); // Wait for the initStuff to do it's stuff.
4102 w.setGeometry(50, 50, 100, 100);
4104 QTest::qWaitForWindowShown(&w);
4106 QApplication::processEvents();
4107 QApplication::processEvents();
4110 QEXPECT_FAIL(0, "Cocoa compositor says to paint this twice.", Continue);
4112 QTRY_COMPARE(w.numPaintEvents, 1);
4114 QCOMPARE(w.visibleRegion(), QRegion(w.rect()));
4115 QCOMPARE(w.paintedRegion, w.visibleRegion());
4118 UpdateWidget child(&w);
4119 child.setGeometry(10, 10, 80, 80);
4122 QPoint childOffset = child.mapToParent(QPoint());
4124 // widgets are transparent by default, so both should get repaints
4126 QApplication::processEvents();
4127 QApplication::processEvents();
4128 QCOMPARE(child.numPaintEvents, 1);
4129 QCOMPARE(child.visibleRegion(), QRegion(child.rect()));
4130 QCOMPARE(child.paintedRegion, child.visibleRegion());
4131 QCOMPARE(w.numPaintEvents, 1);
4132 QCOMPARE(w.visibleRegion(), QRegion(w.rect()));
4133 QCOMPARE(w.paintedRegion, child.visibleRegion().translated(childOffset));
4139 QApplication::processEvents();
4140 QApplication::processEvents();
4141 QCOMPARE(child.numPaintEvents, 1);
4142 QCOMPARE(child.visibleRegion(), QRegion(child.rect()));
4143 QCOMPARE(child.paintedRegion, child.visibleRegion());
4144 QCOMPARE(w.numPaintEvents, 1);
4145 QCOMPARE(w.visibleRegion(), QRegion(w.rect()));
4146 QCOMPARE(w.paintedRegion, w.visibleRegion());
4149 QPalette opaquePalette = child.palette();
4150 opaquePalette.setColor(child.backgroundRole(), QColor(Qt::red));
4152 // setting an opaque background on the child should prevent paint-events
4153 // for the parent in the child area
4155 child.setPalette(opaquePalette);
4156 child.setAutoFillBackground(true);
4157 QApplication::processEvents();
4163 QApplication::processEvents();
4164 QApplication::processEvents();
4166 QCOMPARE(w.numPaintEvents, 1);
4167 QRegion expectedVisible = QRegion(w.rect())
4168 - child.visibleRegion().translated(childOffset);
4169 QCOMPARE(w.visibleRegion(), expectedVisible);
4170 QCOMPARE(w.paintedRegion, expectedVisible);
4171 QCOMPARE(child.numPaintEvents, 0);
4177 QApplication::processEvents();
4178 QApplication::processEvents();
4180 QCOMPARE(w.numPaintEvents, 0);
4181 QCOMPARE(child.numPaintEvents, 1);
4182 QCOMPARE(child.paintedRegion, child.visibleRegion());
4188 // overlapping sibling
4189 UpdateWidget sibling(&w);
4190 child.setGeometry(10, 10, 20, 20);
4191 sibling.setGeometry(15, 15, 20, 20);
4194 QApplication::processEvents();
4199 const QPoint siblingOffset = sibling.mapToParent(QPoint());
4202 QApplication::processEvents();
4203 QApplication::processEvents();
4205 // child is opaque, sibling transparent
4207 QCOMPARE(sibling.numPaintEvents, 1);
4208 QCOMPARE(sibling.paintedRegion, sibling.visibleRegion());
4210 QCOMPARE(child.numPaintEvents, 1);
4211 QCOMPARE(child.paintedRegion.translated(childOffset),
4212 child.visibleRegion().translated(childOffset)
4213 & sibling.visibleRegion().translated(siblingOffset));
4215 QCOMPARE(w.numPaintEvents, 1);
4216 QCOMPARE(w.paintedRegion,
4217 w.visibleRegion() & sibling.visibleRegion().translated(siblingOffset));
4218 QCOMPARE(w.paintedRegion,
4219 (w.visibleRegion() - child.visibleRegion().translated(childOffset))
4220 & sibling.visibleRegion().translated(siblingOffset));
4227 sibling.setPalette(opaquePalette);
4228 sibling.setAutoFillBackground(true);
4231 QApplication::processEvents();
4232 QApplication::processEvents();
4234 // child opaque, sibling opaque
4236 QCOMPARE(sibling.numPaintEvents, 1);
4237 QCOMPARE(sibling.paintedRegion, sibling.visibleRegion());
4240 if (child.internalWinId()) // child is native
4241 QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue);
4243 QCOMPARE(child.numPaintEvents, 0);
4244 QCOMPARE(child.visibleRegion(),
4245 QRegion(child.rect())
4246 - sibling.visibleRegion().translated(siblingOffset - childOffset));
4248 QCOMPARE(w.numPaintEvents, 0);
4249 QCOMPARE(w.visibleRegion(),
4251 - child.visibleRegion().translated(childOffset)
4252 - sibling.visibleRegion().translated(siblingOffset));
4256 static inline bool isOpaque(QWidget *widget)
4260 return qt_widget_private(widget)->isOpaque;
4263 void tst_QWidget::isOpaque()
4267 QVERIFY(::isOpaque(&w));
4270 QVERIFY(!::isOpaque(&child));
4272 child.setAutoFillBackground(true);
4273 QVERIFY(::isOpaque(&child));
4279 palette = child.palette();
4280 palette.setColor(child.backgroundRole(), QColor(255, 0, 0, 127));
4281 child.setPalette(palette);
4282 QVERIFY(!::isOpaque(&child));
4284 palette.setColor(child.backgroundRole(), QColor(255, 0, 0, 255));
4285 child.setPalette(palette);
4286 QVERIFY(::isOpaque(&child));
4288 palette.setColor(QPalette::Window, QColor(0, 0, 255, 127));
4289 w.setPalette(palette);
4291 QVERIFY(!::isOpaque(&w));
4293 child.setAutoFillBackground(false);
4294 QVERIFY(!::isOpaque(&child));
4296 // Qt::WA_OpaquePaintEvent
4298 child.setAttribute(Qt::WA_OpaquePaintEvent);
4299 QVERIFY(::isOpaque(&child));
4301 child.setAttribute(Qt::WA_OpaquePaintEvent, false);
4302 QVERIFY(!::isOpaque(&child));
4304 // Qt::WA_NoSystemBackground
4306 child.setAttribute(Qt::WA_NoSystemBackground);
4307 QVERIFY(!::isOpaque(&child));
4309 child.setAttribute(Qt::WA_NoSystemBackground, false);
4310 QVERIFY(!::isOpaque(&child));
4312 palette.setColor(QPalette::Window, QColor(0, 0, 255, 255));
4313 w.setPalette(palette);
4314 QVERIFY(::isOpaque(&w));
4316 w.setAttribute(Qt::WA_NoSystemBackground);
4317 QVERIFY(!::isOpaque(&w));
4319 w.setAttribute(Qt::WA_NoSystemBackground, false);
4320 QVERIFY(::isOpaque(&w));
4323 QPalette palette = QApplication::palette();
4324 QPalette old = palette;
4325 palette.setColor(QPalette::Window, Qt::transparent);
4326 QApplication::setPalette(palette);
4329 QVERIFY(!::isOpaque(&widget));
4331 QApplication::setPalette(old);
4332 QCOMPARE(::isOpaque(&widget), old.color(QPalette::Window).alpha() == 255);
4339 Test that scrolling of a widget invalidates the correct regions
4341 void tst_QWidget::scroll()
4343 UpdateWidget updateWidget;
4344 updateWidget.resize(500, 500);
4345 updateWidget.reset();
4346 updateWidget.show();
4347 QTest::qWaitForWindowShown(&updateWidget);
4349 qApp->processEvents();
4350 QTRY_VERIFY(updateWidget.numPaintEvents > 0);
4353 updateWidget.reset();
4354 updateWidget.scroll(10, 10);
4355 qApp->processEvents();
4356 QRegion dirty(QRect(0, 0, 500, 10));
4357 dirty += QRegion(QRect(0, 10, 10, 490));
4358 QCOMPARE(updateWidget.paintedRegion, dirty);
4362 updateWidget.reset();
4363 updateWidget.update(0, 0, 10, 10);
4364 updateWidget.scroll(0, 10);
4365 qApp->processEvents();
4366 QRegion dirty(QRect(0, 0, 500, 10));
4367 dirty += QRegion(QRect(0, 10, 10, 10));
4368 QCOMPARE(updateWidget.paintedRegion, dirty);
4372 updateWidget.reset();
4373 updateWidget.update(0, 0, 100, 100);
4374 updateWidget.scroll(10, 10, QRect(50, 50, 100, 100));
4375 qApp->processEvents();
4376 QRegion dirty(QRect(0, 0, 100, 50));
4377 dirty += QRegion(QRect(0, 50, 150, 10));
4378 dirty += QRegion(QRect(0, 60, 110, 40));
4379 dirty += QRegion(QRect(50, 100, 60, 10));
4380 dirty += QRegion(QRect(50, 110, 10, 40));
4381 QCOMPARE(updateWidget.paintedRegion, dirty);
4385 updateWidget.reset();
4386 updateWidget.update(0, 0, 100, 100);
4387 updateWidget.scroll(10, 10, QRect(100, 100, 100, 100));
4388 qApp->processEvents();
4389 QRegion dirty(QRect(0, 0, 100, 100));
4390 dirty += QRegion(QRect(100, 100, 100, 10));
4391 dirty += QRegion(QRect(100, 110, 10, 90));
4392 QCOMPARE(updateWidget.paintedRegion, dirty);
4397 class DestroyedSlotChecker : public QObject
4404 DestroyedSlotChecker()
4410 void destroyedSlot(QObject *object)
4412 wasQWidget = (qobject_cast<QWidget *>(object) != 0 || object->isWidgetType());
4417 Test that qobject_cast<QWidget*> returns 0 in a slot
4418 connected to QObject::destroyed.
4420 void tst_QWidget::qobject_castInDestroyedSlot()
4422 DestroyedSlotChecker checker;
4423 QWidget *widget = new QWidget();
4425 QObject::connect(widget, SIGNAL(destroyed(QObject *)), &checker, SLOT(destroyedSlot(QObject *)));
4428 QVERIFY(checker.wasQWidget == true);
4431 Q_DECLARE_METATYPE(QList<QRect>)
4433 // Since X11 WindowManager operations are all async, and we have no way to know if the window
4434 // manager has finished playing with the window geometry, this test can't be reliable on X11.
4436 void tst_QWidget::setWindowGeometry_data()
4438 QTest::addColumn<QList<QRect> >("rects");
4439 QTest::addColumn<int>("windowFlags");
4441 QList<QList<QRect> > rects;
4442 rects << (QList<QRect>()
4443 << QRect(100, 100, 200, 200)
4444 << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100)
4445 << QRect(130, 100, 0, 200)
4446 << QRect(100, 50, 200, 0)
4447 << QRect(130, 50, 0, 0))
4449 << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100)
4450 << QRect(130, 100, 0, 200)
4451 << QRect(100, 50, 200, 0)
4452 << QRect(130, 50, 0, 0)
4453 << QRect(100, 100, 200, 200))
4455 << QRect(130, 100, 0, 200)
4456 << QRect(100, 50, 200, 0)
4457 << QRect(130, 50, 0, 0)
4458 << QRect(100, 100, 200, 200)
4459 << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100))
4461 << QRect(100, 50, 200, 0)
4462 << QRect(130, 50, 0, 0)
4463 << QRect(100, 100, 200, 200)
4464 << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100)
4465 << QRect(130, 100, 0, 200))
4467 << QRect(130, 50, 0, 0)
4468 << QRect(100, 100, 200, 200)
4469 << QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100)
4470 << QRect(130, 100, 0, 200)
4471 << QRect(100, 50, 200, 0));
4473 QList<int> windowFlags;
4474 windowFlags << 0 << Qt::FramelessWindowHint;
4476 foreach (QList<QRect> l, rects) {
4477 QRect rect = l.first();
4478 foreach (int windowFlag, windowFlags) {
4479 QTest::newRow(QString("%1,%2 %3x%4, flags %5")
4484 .arg(windowFlag, 0, 16).toAscii())
4491 void tst_QWidget::setWindowGeometry()
4493 QFETCH(QList<QRect>, rects);
4494 QFETCH(int, windowFlags);
4495 QRect rect = rects.takeFirst();
4498 // test setGeometry() without actually showing the window
4500 if (windowFlags != 0)
4501 widget.setWindowFlags(Qt::WindowFlags(windowFlags));
4503 widget.setGeometry(rect);
4505 QCOMPARE(widget.geometry(), rect);
4507 // setGeometry() without showing
4508 foreach (QRect r, rects) {
4509 widget.setGeometry(r);
4511 QCOMPARE(widget.geometry(), r);
4516 // setGeometry() first, then show()
4518 if (windowFlags != 0)
4519 widget.setWindowFlags(Qt::WindowFlags(windowFlags));
4521 widget.setGeometry(rect);
4523 QTest::qWaitForWindowShown(&widget);
4525 QTRY_COMPARE(widget.geometry(), rect);
4527 // setGeometry() while shown
4528 foreach (QRect r, rects) {
4529 widget.setGeometry(r);
4531 QTRY_COMPARE(widget.geometry(), r);
4533 widget.setGeometry(rect);
4535 QTRY_COMPARE(widget.geometry(), rect);
4540 QTRY_COMPARE(widget.geometry(), rect);
4542 // setGeometry() after hide()
4543 foreach (QRect r, rects) {
4544 widget.setGeometry(r);
4546 QTRY_COMPARE(widget.geometry(), r);
4548 widget.setGeometry(rect);
4550 QTRY_COMPARE(widget.geometry(), rect);
4552 // show() again, geometry() should still be the same
4554 QTest::qWaitForWindowShown(&widget);
4556 QTRY_COMPARE(widget.geometry(), rect);
4558 // final hide(), again geometry() should be unchanged
4561 QTRY_COMPARE(widget.geometry(), rect);
4565 // show() first, then setGeometry()
4567 if (windowFlags != 0)
4568 widget.setWindowFlags(Qt::WindowFlags(windowFlags));
4571 QTest::qWaitForWindowShown(&widget);
4572 widget.setGeometry(rect);
4574 QTRY_COMPARE(widget.geometry(), rect);
4576 // setGeometry() while shown
4577 foreach (QRect r, rects) {
4578 widget.setGeometry(r);
4580 QTRY_COMPARE(widget.geometry(), r);
4582 widget.setGeometry(rect);
4584 QTRY_COMPARE(widget.geometry(), rect);
4589 QTRY_COMPARE(widget.geometry(), rect);
4591 // setGeometry() after hide()
4592 foreach (QRect r, rects) {
4593 widget.setGeometry(r);
4595 QTRY_COMPARE(widget.geometry(), r);
4597 widget.setGeometry(rect);
4599 QTRY_COMPARE(widget.geometry(), rect);
4601 // show() again, geometry() should still be the same
4603 QTest::qWaitForWindowShown(&widget);
4605 QTRY_COMPARE(widget.geometry(), rect);
4607 // final hide(), again geometry() should be unchanged
4610 QTRY_COMPARE(widget.geometry(), rect);
4615 #if defined (Q_WS_WIN) && !defined(Q_OS_WINCE)
4616 void tst_QWidget::setGeometry_win()
4619 widget.setGeometry(0, 600, 100,100);
4621 widget.setWindowState(widget.windowState() | Qt::WindowMaximized);
4622 QRect geom = widget.normalGeometry();
4624 widget.setGeometry(geom);
4625 widget.setWindowState(widget.windowState() | Qt::WindowMaximized);
4628 ::GetWindowRect(widget.internalWinId(), &rt);
4629 QVERIFY(rt.left <= 0);
4630 QVERIFY(rt.top <= 0);
4634 // Since X11 WindowManager operation are all async, and we have no way to know if the window
4635 // manager has finished playing with the window geometry, this test can't be reliable on X11.
4636 // 4DWM issues on IRIX also makes this test fail.
4637 #if !defined(Q_WS_X11) && !defined(Q_OS_IRIX)
4638 void tst_QWidget::windowMoveResize_data()
4640 setWindowGeometry_data();
4643 void tst_QWidget::windowMoveResize()
4645 QFETCH(QList<QRect>, rects);
4646 QFETCH(int, windowFlags);
4648 QRect rect = rects.takeFirst();
4651 // test setGeometry() without actually showing the window
4653 if (windowFlags != 0)
4654 widget.setWindowFlags(Qt::WindowFlags(windowFlags));
4656 widget.move(rect.topLeft());
4657 widget.resize(rect.size());
4659 QTRY_COMPARE(widget.pos(), rect.topLeft());
4660 QTRY_COMPARE(widget.size(), rect.size());
4662 // move() without showing
4663 foreach (QRect r, rects) {
4664 widget.move(r.topLeft());
4665 widget.resize(r.size());
4666 QApplication::processEvents();
4667 QTRY_COMPARE(widget.pos(), r.topLeft());
4668 QTRY_COMPARE(widget.size(), r.size());
4673 // move() first, then show()
4675 if (windowFlags != 0)
4676 widget.setWindowFlags(Qt::WindowFlags(windowFlags));
4678 widget.move(rect.topLeft());
4679 widget.resize(rect.size());
4683 QTRY_COMPARE(widget.pos(), rect.topLeft());
4684 QTRY_COMPARE(widget.size(), rect.size());
4686 // move() while shown
4687 foreach (QRect r, rects) {
4689 if ((widget.width() == 0 || widget.height() == 0) && r.width() != 0 && r.height() != 0) {
4690 QEXPECT_FAIL("130,100 0x200, flags 0",
4691 "First resize after show of zero-sized gets wrong win_gravity.",
4693 QEXPECT_FAIL("100,50 200x0, flags 0",
4694 "First resize after show of zero-sized gets wrong win_gravity.",
4696 QEXPECT_FAIL("130,50 0x0, flags 0",
4697 "First resize after show of zero-sized gets wrong win_gravity.",
4701 widget.move(r.topLeft());
4702 widget.resize(r.size());
4703 QApplication::processEvents();
4704 QTRY_COMPARE(widget.pos(), r.topLeft());
4705 QTRY_COMPARE(widget.size(), r.size());
4707 widget.move(rect.topLeft());
4708 widget.resize(rect.size());
4709 QApplication::processEvents();
4710 QTRY_COMPARE(widget.pos(), rect.topLeft());
4711 QTRY_COMPARE(widget.size(), rect.size());
4716 QTRY_COMPARE(widget.pos(), rect.topLeft());
4717 QTRY_COMPARE(widget.size(), rect.size());
4719 // move() after hide()
4720 foreach (QRect r, rects) {
4721 widget.move(r.topLeft());
4722 widget.resize(r.size());
4723 QApplication::processEvents();
4724 #if defined(Q_OS_MAC)
4725 if (r.width() == 0 && r.height() > 0) {
4726 widget.move(r.topLeft());
4727 widget.resize(r.size());
4730 QTRY_COMPARE(widget.pos(), r.topLeft());
4731 QTRY_COMPARE(widget.size(), r.size());
4733 widget.move(rect.topLeft());
4734 widget.resize(rect.size());
4736 QTRY_COMPARE(widget.pos(), rect.topLeft());
4737 QTRY_COMPARE(widget.size(), rect.size());
4739 // show() again, pos() should be the same
4741 QTest::qWaitForWindowShown(&widget);
4742 QApplication::processEvents();
4743 QTRY_COMPARE(widget.pos(), rect.topLeft());
4744 QTRY_COMPARE(widget.size(), rect.size());
4746 // final hide(), again pos() should be unchanged
4748 QApplication::processEvents();
4749 QTRY_COMPARE(widget.pos(), rect.topLeft());
4750 QTRY_COMPARE(widget.size(), rect.size());
4754 // show() first, then move()
4756 if (windowFlags != 0)
4757 widget.setWindowFlags(Qt::WindowFlags(windowFlags));
4760 QTest::qWaitForWindowShown(&widget);
4761 QApplication::processEvents();
4762 widget.move(rect.topLeft());
4763 widget.resize(rect.size());
4764 QApplication::processEvents();
4765 QTRY_COMPARE(widget.pos(), rect.topLeft());
4766 QTRY_COMPARE(widget.size(), rect.size());
4768 // move() while shown
4769 foreach (QRect r, rects) {
4770 widget.move(r.topLeft());
4771 widget.resize(r.size());
4772 QApplication::processEvents();
4773 QTRY_COMPARE(widget.pos(), r.topLeft());
4774 QTRY_COMPARE(widget.size(), r.size());
4776 widget.move(rect.topLeft());
4777 widget.resize(rect.size());
4778 QApplication::processEvents();
4779 QTRY_COMPARE(widget.pos(), rect.topLeft());
4780 QTRY_COMPARE(widget.size(), rect.size());
4784 QApplication::processEvents();
4785 QTRY_COMPARE(widget.pos(), rect.topLeft());
4786 QTRY_COMPARE(widget.size(), rect.size());
4788 // move() after hide()
4789 foreach (QRect r, rects) {
4790 widget.move(r.topLeft());
4791 widget.resize(r.size());
4792 QApplication::processEvents();
4793 #if defined(Q_OS_MAC)
4794 if (r.width() == 0 && r.height() > 0) {
4795 widget.move(r.topLeft());
4796 widget.resize(r.size());
4799 QTRY_COMPARE(widget.pos(), r.topLeft());
4800 QTRY_COMPARE(widget.size(), r.size());
4802 widget.move(rect.topLeft());
4803 widget.resize(rect.size());
4804 QApplication::processEvents();
4805 QTRY_COMPARE(widget.pos(), rect.topLeft());
4806 QTRY_COMPARE(widget.size(), rect.size());
4808 // show() again, pos() should be the same
4810 QTest::qWaitForWindowShown(&widget);
4812 QTRY_COMPARE(widget.pos(), rect.topLeft());
4813 QTRY_COMPARE(widget.size(), rect.size());
4815 // final hide(), again pos() should be unchanged
4818 QTRY_COMPARE(widget.pos(), rect.topLeft());
4819 QTRY_COMPARE(widget.size(), rect.size());
4824 class ColorWidget : public QWidget
4827 ColorWidget(QWidget *parent = 0, const QColor &c = QColor(Qt::red))
4828 : QWidget(parent, Qt::FramelessWindowHint), color(c)
4830 QPalette opaquePalette = palette();
4831 opaquePalette.setColor(backgroundRole(), color);
4832 setPalette(opaquePalette);
4833 setAutoFillBackground(true);
4836 void paintEvent(QPaintEvent *e) {
4848 #define VERIFY_COLOR(region, color) { \
4849 const QRegion r = QRegion(region); \
4850 for (int i = 0; i < r.rects().size(); ++i) { \
4851 const QRect rect = r.rects().at(i); \
4852 for (int t = 0; t < 5; t++) { \
4853 const QPixmap pixmap = QPixmap::grabWindow(QDesktopWidget().winId(), \
4854 rect.left(), rect.top(), \
4855 rect.width(), rect.height()); \
4856 QCOMPARE(pixmap.size(), rect.size()); \
4857 QPixmap expectedPixmap(pixmap); /* ensure equal formats */ \
4858 expectedPixmap.detach(); \
4859 expectedPixmap.fill(color); \
4860 QImage image = pixmap.toImage(); \
4861 uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0; \
4862 uint firstPixel = image.pixel(0,0) | alphaCorrection; \
4863 if ( firstPixel != QColor(color).rgb() && t < 4 ) \
4864 { QTest::qWait(200); continue; } \
4865 QCOMPARE(firstPixel, QColor(color).rgb()); \
4866 QCOMPARE(pixmap, expectedPixmap); \
4872 void tst_QWidget::moveChild_data()
4874 QTest::addColumn<QPoint>("offset");
4876 QTest::newRow("right") << QPoint(20, 0);
4877 QTest::newRow("down") << QPoint(0, 20);
4878 QTest::newRow("left") << QPoint(-20, 0);
4879 QTest::newRow("up") << QPoint(0, -20);
4882 void tst_QWidget::moveChild()
4884 QFETCH(QPoint, offset);
4887 // prevent custom styles
4888 parent.setStyle(new QWindowsStyle);
4889 ColorWidget child(&parent, Qt::blue);
4892 parent.setGeometry(QRect(QPoint(QApplication::desktop()->availableGeometry(&parent).topLeft()),
4895 parent.setGeometry(60, 60, 150, 150);
4897 child.setGeometry(25, 25, 50, 50);
4899 QTest::qWaitForWindowShown(&parent);
4901 const QPoint tlwOffset = parent.geometry().topLeft();
4903 QTRY_COMPARE(parent.r, QRegion(parent.rect()) - child.geometry());
4904 QTRY_COMPARE(child.r, QRegion(child.rect()));
4905 VERIFY_COLOR(child.geometry().translated(tlwOffset),
4907 VERIFY_COLOR(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset),
4914 const QRect oldGeometry = child.geometry();
4916 QPoint pos = child.pos() + offset;
4919 QTRY_COMPARE(pos, child.pos());
4921 QCOMPARE(parent.r, QRegion(oldGeometry) - child.geometry());
4922 #if !defined(Q_OS_MAC)
4923 // should be scrolled in backingstore
4924 QCOMPARE(child.r, QRegion());
4926 VERIFY_COLOR(child.geometry().translated(tlwOffset),
4928 VERIFY_COLOR(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset),
4932 void tst_QWidget::showAndMoveChild()
4934 QWidget parent(0, Qt::FramelessWindowHint);
4935 // prevent custom styles
4936 parent.setStyle(new QWindowsStyle);
4938 QDesktopWidget desktop;
4939 QRect desktopDimensions = desktop.availableGeometry(&parent);
4940 desktopDimensions = desktopDimensions.adjusted(64, 64, -64, -64);
4942 parent.setGeometry(desktopDimensions);
4943 parent.setPalette(Qt::red);
4945 QTest::qWaitForWindowShown(&parent);
4948 const QPoint tlwOffset = parent.geometry().topLeft();
4949 QWidget child(&parent);
4950 child.resize(desktopDimensions.width()/2, desktopDimensions.height()/2);
4951 child.setPalette(Qt::blue);
4952 child.setAutoFillBackground(true);
4954 // Ensure that the child is repainted correctly when moved right after show.
4955 // NB! Do NOT processEvents() (or qWait()) in between show() and move().
4957 child.move(desktopDimensions.width()/2, desktopDimensions.height()/2);
4958 qApp->processEvents();
4960 VERIFY_COLOR(child.geometry().translated(tlwOffset), Qt::blue);
4961 VERIFY_COLOR(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), Qt::red);
4964 // Cocoa only has rect granularity.
4966 void tst_QWidget::subtractOpaqueSiblings()
4969 w.setGeometry(50, 50, 300, 300);
4971 ColorWidget *large = new ColorWidget(&w, Qt::red);
4972 large->setGeometry(50, 50, 200, 200);
4974 ColorWidget *medium = new ColorWidget(large, Qt::gray);
4975 medium->setGeometry(50, 50, 100, 100);
4977 ColorWidget *tall = new ColorWidget(&w, Qt::blue);
4978 tall->setGeometry(100, 30, 50, 100);
4981 QTest::qWaitForWindowShown(&w);
4991 // QWidgetPrivate::subtractOpaqueSiblings() should prevent parts of medium
4992 // to be repainted and tall from be repainted at all.
4994 QTRY_COMPARE(large->r, QRegion());
4995 QTRY_COMPARE(tall->r, QRegion());
4996 QTRY_COMPARE(medium->r.translated(medium->mapTo(&w, QPoint())),
4997 QRegion(medium->geometry().translated(large->pos()))
4998 - tall->geometry());
5002 void tst_QWidget::deleteStyle()
5005 widget.setStyle(new QWindowsStyle);
5007 delete widget.style();
5008 qApp->processEvents();
5012 void tst_QWidget::getDC()
5015 widget.setGeometry(0, 0, 2, 4);
5017 HDC dc = widget.getDC();
5020 widget.releaseDC(dc);
5024 class TopLevelFocusCheck: public QWidget
5029 TopLevelFocusCheck(QWidget* parent = 0) : QWidget(parent)
5031 edit = new QLineEdit(this);
5033 edit->installEventFilter(this);
5037 void mouseDoubleClickEvent ( QMouseEvent * /*event*/ )
5040 edit->setFocus(Qt::OtherFocusReason);
5041 qApp->processEvents();
5043 bool eventFilter(QObject *obj, QEvent *event)
5045 if (obj == edit && event->type()== QEvent::FocusOut) {
5053 void tst_QWidget::multipleToplevelFocusCheck()
5055 TopLevelFocusCheck w1;
5056 TopLevelFocusCheck w2;
5058 w1.resize(200, 200);
5060 QTest::qWaitForWindowShown(&w1);
5063 QTest::qWaitForWindowShown(&w2);
5067 QApplication::setActiveWindow(&w1);
5068 w1.activateWindow();
5069 QApplication::processEvents();
5070 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1));
5072 QTest::mouseDClick(&w1, Qt::LeftButton);
5073 QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit));
5075 w2.activateWindow();
5076 QApplication::setActiveWindow(&w2);
5077 QApplication::processEvents();
5078 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2));
5079 QTest::mouseClick(&w2, Qt::LeftButton);
5081 QEXPECT_FAIL("", "embedded toplevels take focus anyway", Continue);
5083 QTRY_COMPARE(QApplication::focusWidget(), (QWidget *)0);
5085 QTest::mouseDClick(&w2, Qt::LeftButton);
5086 QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w2.edit));
5088 w1.activateWindow();
5089 QApplication::setActiveWindow(&w1);
5090 QApplication::processEvents();
5091 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1));
5092 QTest::mouseDClick(&w1, Qt::LeftButton);
5093 QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit));
5095 w2.activateWindow();
5096 QApplication::setActiveWindow(&w2);
5097 QApplication::processEvents();
5098 QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2));
5099 QTest::mouseClick(&w2, Qt::LeftButton);
5100 QTRY_COMPARE(QApplication::focusWidget(), (QWidget *)0);
5103 class FocusWidget: public QWidget
5106 virtual bool event(QEvent *ev)
5108 if (ev->type() == QEvent::FocusAboutToChange)
5109 widgetDuringFocusAboutToChange = qApp->focusWidget();
5110 return QWidget::event(ev);
5112 virtual void focusOutEvent(QFocusEvent *)
5114 widgetDuringFocusOut = qApp->focusWidget();
5118 FocusWidget(QWidget *parent) : QWidget(parent), widgetDuringFocusAboutToChange(0), widgetDuringFocusOut(0) {}
5120 QWidget *widgetDuringFocusAboutToChange;
5121 QWidget *widgetDuringFocusOut;
5124 void tst_QWidget::setFocus()
5127 // move focus to another window
5128 testWidget->activateWindow();
5129 QApplication::setActiveWindow(testWidget);
5130 if (testWidget->focusWidget())
5131 testWidget->focusWidget()->clearFocus();
5133 testWidget->clearFocus();
5135 // window and children never shown, nobody gets focus
5138 QWidget child1(&window);
5139 child1.setFocusPolicy(Qt::StrongFocus);
5141 QWidget child2(&window);
5142 child2.setFocusPolicy(Qt::StrongFocus);
5145 QVERIFY(!child1.hasFocus());
5146 QCOMPARE(window.focusWidget(), &child1);
5147 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5150 QVERIFY(!child2.hasFocus());
5151 QCOMPARE(window.focusWidget(), &child2);
5152 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5156 // window and children show, but window not active, nobody gets focus
5159 QWidget child1(&window);
5160 child1.setFocusPolicy(Qt::StrongFocus);
5162 QWidget child2(&window);
5163 child2.setFocusPolicy(Qt::StrongFocus);
5167 // note: window may be active, but we don't want it to be
5168 testWidget->activateWindow();
5169 QApplication::setActiveWindow(testWidget);
5170 if (testWidget->focusWidget())
5171 testWidget->focusWidget()->clearFocus();
5173 testWidget->clearFocus();
5176 QVERIFY(!child1.hasFocus());
5177 QCOMPARE(window.focusWidget(), &child1);
5178 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5181 QVERIFY(!child2.hasFocus());
5182 QCOMPARE(window.focusWidget(), &child2);
5183 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5187 // window and children show, but window *is* active, children get focus
5190 FocusWidget child1(&window);
5191 child1.setFocusPolicy(Qt::StrongFocus);
5193 QWidget child2(&window);
5194 child2.setFocusPolicy(Qt::StrongFocus);
5197 window.activateWindow();
5198 QTest::qWaitForWindowShown(&window);
5199 QTRY_VERIFY(qGuiApp->focusWindow());
5202 QTRY_VERIFY(child1.hasFocus());
5203 QCOMPARE(window.focusWidget(), &child1);
5204 QCOMPARE(QApplication::focusWidget(), &child1);
5207 QVERIFY(child2.hasFocus());
5208 QCOMPARE(window.focusWidget(), &child2);
5209 QCOMPARE(QApplication::focusWidget(), &child2);
5211 // focus changed in between the events
5212 QCOMPARE(child1.widgetDuringFocusAboutToChange, &child1);
5213 QCOMPARE(child1.widgetDuringFocusOut, &child2);
5217 // window shown and active, children created, don't get focus, but get focus when shown
5221 window.activateWindow();
5222 QTest::qWaitForWindowShown(&window);
5223 QTRY_VERIFY(qGuiApp->focusWindow());
5225 QWidget child1(&window);
5226 child1.setFocusPolicy(Qt::StrongFocus);
5228 QWidget child2(&window);
5229 child2.setFocusPolicy(Qt::StrongFocus);
5232 QVERIFY(!child1.hasFocus());
5233 QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
5234 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5237 QApplication::processEvents();
5238 QTRY_VERIFY(child1.hasFocus());
5239 QCOMPARE(window.focusWidget(), &child1);
5240 QCOMPARE(QApplication::focusWidget(), &child1);
5243 QVERIFY(!child2.hasFocus());
5244 QCOMPARE(window.focusWidget(), &child1);
5245 QCOMPARE(QApplication::focusWidget(), &child1);
5248 QVERIFY(child2.hasFocus());
5249 QCOMPARE(window.focusWidget(), &child2);
5250 QCOMPARE(QApplication::focusWidget(), &child2);
5254 // window shown and active, children created, don't get focus,
5255 // even after setFocus(), hide(), then show()
5259 window.activateWindow();
5260 QTest::qWaitForWindowShown(&window);
5261 QTRY_VERIFY(qGuiApp->focusWindow());
5263 QWidget child1(&window);
5264 child1.setFocusPolicy(Qt::StrongFocus);
5266 QWidget child2(&window);
5267 child2.setFocusPolicy(Qt::StrongFocus);
5270 QVERIFY(!child1.hasFocus());
5271 QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
5272 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5275 QVERIFY(!child1.hasFocus());
5276 QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
5277 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5280 QVERIFY(!child1.hasFocus());
5281 QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
5282 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5285 QVERIFY(!child2.hasFocus());
5286 QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
5287 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5290 QVERIFY(!child2.hasFocus());
5291 QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
5292 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5295 QVERIFY(!child2.hasFocus());
5296 QCOMPARE(window.focusWidget(), static_cast<QWidget *>(0));
5297 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget *>(0));
5301 class EventSpy : public QObject
5304 EventSpy(QWidget *widget, QEvent::Type event)
5305 : m_widget(widget), eventToSpy(event), m_count(0)
5308 m_widget->installEventFilter(this);
5311 QWidget *widget() const { return m_widget; }
5312 int count() const { return m_count; }
5313 void clear() { m_count = 0; }
5316 bool eventFilter(QObject *object, QEvent *event)
5318 if (event->type() == eventToSpy)
5320 return QObject::eventFilter(object, event);
5325 QEvent::Type eventToSpy;
5329 void tst_QWidget::setCursor()
5331 #ifndef QT_NO_CURSOR
5334 QWidget child(&window);
5336 QVERIFY(!window.testAttribute(Qt::WA_SetCursor));
5337 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5339 window.setCursor(window.cursor());
5340 QVERIFY(window.testAttribute(Qt::WA_SetCursor));
5341 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5342 QCOMPARE(child.cursor().shape(), window.cursor().shape());
5345 // do it again, but with window show()n
5348 QWidget child(&window);
5351 QVERIFY(!window.testAttribute(Qt::WA_SetCursor));
5352 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5354 window.setCursor(window.cursor());
5355 QVERIFY(window.testAttribute(Qt::WA_SetCursor));
5356 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5357 QCOMPARE(child.cursor().shape(), window.cursor().shape());
5363 QWidget child(&window);
5365 window.setCursor(Qt::WaitCursor);
5366 QVERIFY(window.testAttribute(Qt::WA_SetCursor));
5367 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5368 QCOMPARE(child.cursor().shape(), window.cursor().shape());
5371 // same thing again, just with window show()n
5374 QWidget child(&window);
5377 window.setCursor(Qt::WaitCursor);
5378 QVERIFY(window.testAttribute(Qt::WA_SetCursor));
5379 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5380 QCOMPARE(child.cursor().shape(), window.cursor().shape());
5383 // reparenting child should not cause the WA_SetCursor to become set
5387 QWidget child(&window);
5389 window.setCursor(Qt::WaitCursor);
5392 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5393 QCOMPARE(child.cursor().shape(), QCursor().shape());
5395 child.setParent(&window2);
5396 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5397 QCOMPARE(child.cursor().shape(), window2.cursor().shape());
5399 window2.setCursor(Qt::WaitCursor);
5400 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5401 QCOMPARE(child.cursor().shape(), window2.cursor().shape());
5404 // again, with windows show()n
5408 QWidget child(&window);
5410 window.setCursor(Qt::WaitCursor);
5414 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5415 QCOMPARE(child.cursor().shape(), QCursor().shape());
5417 child.setParent(&window2);
5418 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5419 QCOMPARE(child.cursor().shape(), window2.cursor().shape());
5422 window2.setCursor(Qt::WaitCursor);
5423 QVERIFY(!child.testAttribute(Qt::WA_SetCursor));
5424 QCOMPARE(child.cursor().shape(), window2.cursor().shape());
5427 // test if CursorChange is sent
5430 EventSpy spy(&widget, QEvent::CursorChange);
5431 QCOMPARE(spy.count(), 0);
5432 widget.setCursor(QCursor(Qt::WaitCursor));
5433 QCOMPARE(spy.count(), 1);
5434 widget.unsetCursor();
5435 QCOMPARE(spy.count(), 2);
5440 void tst_QWidget::setToolTip()
5443 EventSpy spy(&widget, QEvent::ToolTipChange);
5444 QCOMPARE(spy.count(), 0);
5446 QCOMPARE(widget.toolTip(), QString());
5447 widget.setToolTip(QString("Hello"));
5448 QCOMPARE(widget.toolTip(), QString("Hello"));
5449 QCOMPARE(spy.count(), 1);
5450 widget.setToolTip(QString());
5451 QCOMPARE(widget.toolTip(), QString());
5452 QCOMPARE(spy.count(), 2);
5454 // Mouse over doesn't work on Windows mobile, so skip the rest of the test for that platform.
5455 #ifndef Q_OS_WINCE_WM
5456 for (int pass = 0; pass < 2; ++pass) {
5457 QWidget *popup = new QWidget(0, Qt::Popup);
5458 popup->resize(150, 50);
5459 QFrame *frame = new QFrame(popup);
5460 frame->setGeometry(0, 0, 50, 50);
5461 frame->setFrameStyle(QFrame::Box | QFrame::Plain);
5462 EventSpy spy1(frame, QEvent::ToolTip);
5463 EventSpy spy2(popup, QEvent::ToolTip);
5464 frame->setMouseTracking(pass == 0 ? false : true);
5465 frame->setToolTip(QLatin1String("TOOLTIP FRAME"));
5466 popup->setToolTip(QLatin1String("TOOLTIP POPUP"));
5468 QTest::qWaitForWindowShown(popup);
5470 QTest::mouseMove(frame);
5471 QTest::qWait(900); // delay is 700
5473 QCOMPARE(spy1.count(), 1);
5474 QCOMPARE(spy2.count(), 0);
5476 QTest::qWait(2200); // delay is 2000
5477 QTest::mouseMove(popup);
5483 void tst_QWidget::testWindowIconChangeEventPropagation()
5485 // Create widget hierarchy.
5486 QWidget topLevelWidget;
5487 QWidget topLevelChild(&topLevelWidget);
5489 QDialog dialog(&topLevelWidget);
5490 QWidget dialogChild(&dialog);
5492 QWidgetList widgets;
5493 widgets << &topLevelWidget << &topLevelChild
5494 << &dialog << &dialogChild;
5495 QCOMPARE(widgets.count(), 4);
5497 // Create spy lists.
5498 QList <EventSpy *> applicationEventSpies;
5499 QList <EventSpy *> widgetEventSpies;
5500 foreach (QWidget *widget, widgets) {
5501 applicationEventSpies.append(new EventSpy(widget, QEvent::ApplicationWindowIconChange));
5502 widgetEventSpies.append(new EventSpy(widget, QEvent::WindowIconChange));
5505 // QApplication::setWindowIcon
5506 const QIcon windowIcon = qApp->style()->standardIcon(QStyle::SP_TitleBarMenuButton);
5507 qApp->setWindowIcon(windowIcon);
5509 for (int i = 0; i < widgets.count(); ++i) {
5510 // Check QEvent::ApplicationWindowIconChange
5511 EventSpy *spy = applicationEventSpies.at(i);
5512 QWidget *widget = spy->widget();
5513 if (widget->isWindow()) {
5514 QCOMPARE(spy->count(), 1);
5515 QCOMPARE(widget->windowIcon(), windowIcon);
5517 QCOMPARE(spy->count(), 0);
5521 // Check QEvent::WindowIconChange
5522 spy = widgetEventSpies.at(i);
5523 QCOMPARE(spy->count(), 1);
5527 // Set icon on a top-level widget.
5528 topLevelWidget.setWindowIcon(*new QIcon);
5530 for (int i = 0; i < widgets.count(); ++i) {
5531 // Check QEvent::ApplicationWindowIconChange
5532 EventSpy *spy = applicationEventSpies.at(i);
5533 QCOMPARE(spy->count(), 0);
5536 // Check QEvent::WindowIconChange
5537 spy = widgetEventSpies.at(i);
5538 QWidget *widget = spy->widget();
5539 if (widget == &topLevelWidget) {
5540 QCOMPARE(widget->windowIcon(), QIcon());
5541 QCOMPARE(spy->count(), 1);
5542 } else if (topLevelWidget.isAncestorOf(widget)) {
5543 QCOMPARE(spy->count(), 1);
5545 QCOMPARE(spy->count(), 0);
5551 for (int i = 0; i < widgets.count(); ++i) {
5552 delete applicationEventSpies.at(i);
5553 delete widgetEventSpies.at(i);
5555 qApp->setWindowIcon(QIcon());
5559 void tst_QWidget::minAndMaxSizeWithX11BypassWindowManagerHint()
5561 // Same size as in QWidget::create_sys().
5562 const QSize desktopSize = QApplication::desktop()->size();
5563 const QSize originalSize(desktopSize.width() / 2, desktopSize.height() * 4 / 10);
5566 QWidget widget(0, Qt::X11BypassWindowManagerHint);
5568 const QSize newMaximumSize = widget.size().boundedTo(originalSize) - QSize(10, 10);
5569 widget.setMaximumSize(newMaximumSize);
5570 QCOMPARE(widget.size(), newMaximumSize);
5573 qt_x11_wait_for_window_manager(&widget);
5574 QCOMPARE(widget.size(), newMaximumSize);
5578 QWidget widget(0, Qt::X11BypassWindowManagerHint);
5580 const QSize newMinimumSize = widget.size().expandedTo(originalSize) + QSize(10, 10);
5581 widget.setMinimumSize(newMinimumSize);
5582 QCOMPARE(widget.size(), newMinimumSize);
5585 qt_x11_wait_for_window_manager(&widget);
5586 QCOMPARE(widget.size(), newMinimumSize);
5590 class ShowHideShowWidget : public QWidget
5596 bool gotExpectedMapNotify;
5598 ShowHideShowWidget()
5599 : state(0), gotExpectedMapNotify(false)
5604 void timerEvent(QTimerEvent *)
5616 bool x11Event(XEvent *event)
5618 if (state == 1 && event->type == MapNotify)
5619 gotExpectedMapNotify = true;
5627 void tst_QWidget::showHideShow()
5629 ShowHideShowWidget w;
5633 QEventLoop eventLoop;
5634 connect(&w, SIGNAL(done()), &eventLoop, SLOT(quit()));
5637 QVERIFY(w.gotExpectedMapNotify);
5640 void tst_QWidget::clean_qt_x11_enforce_cursor()
5644 QWidget *w = new QWidget(&window);
5645 QWidget *child = new QWidget(w);
5646 child->setAttribute(Qt::WA_SetCursor, true);
5649 QApplication::setActiveWindow(&window);
5650 QTest::qWaitForWindowShown(&window);
5652 QCursor::setPos(window.geometry().center());
5656 QApplication::processEvents();
5662 QGraphicsScene scene;
5663 QLineEdit *edit = new QLineEdit;
5664 scene.addWidget(edit);
5666 // If the test didn't crash, then it passed.
5670 class EventRecorder : public QObject
5675 typedef QList<QPair<QWidget *, QEvent::Type> > EventList;
5677 EventRecorder(QObject *parent = 0)
5681 EventList eventList()
5691 bool eventFilter(QObject *object, QEvent *event)
5693 QWidget *widget = qobject_cast<QWidget *>(object);
5694 if (widget && !event->spontaneous())
5695 events.append(qMakePair(widget, event->type()));
5703 void tst_QWidget::childEvents()
5705 EventRecorder::EventList expected;
5707 // Move away the cursor; otherwise it might result in an enter event if it's
5708 // inside the widget when the widget is shown.
5709 QCursor::setPos(qApp->desktop()->availableGeometry().bottomRight());
5713 // no children created, not shown
5716 widget.installEventFilter(&spy);
5718 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
5720 QCoreApplication::sendPostedEvents();
5723 EventRecorder::EventList()
5724 << qMakePair(&widget, QEvent::PolishRequest)
5725 << qMakePair(&widget, QEvent::Polish)
5726 << qMakePair(&widget, QEvent::Type(QEvent::User + 1));
5727 QCOMPARE(spy.eventList(), expected);
5731 // no children, shown
5734 widget.installEventFilter(&spy);
5736 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
5740 EventRecorder::EventList()
5741 << qMakePair(&widget, QEvent::WinIdChange)
5742 << qMakePair(&widget, QEvent::Polish)
5743 << qMakePair(&widget, QEvent::Move)
5744 << qMakePair(&widget, QEvent::Resize)
5745 << qMakePair(&widget, QEvent::Show);
5747 expected << qMakePair(&widget, QEvent::ShowToParent);
5748 QCOMPARE(spy.eventList(), expected);
5751 QCoreApplication::sendPostedEvents();
5753 EventRecorder::EventList()
5754 << qMakePair(&widget, QEvent::PolishRequest)
5755 << qMakePair(&widget, QEvent::Type(QEvent::User + 1));
5758 expected << qMakePair(&widget, QEvent::UpdateLater);
5760 expected << qMakePair(&widget, QEvent::UpdateRequest);
5762 QCOMPARE(spy.eventList(), expected);
5766 // 2 children, not shown
5769 widget.installEventFilter(&spy);
5771 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
5773 QWidget child1(&widget);
5775 child2.setParent(&widget);
5777 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 2)));
5780 EventRecorder::EventList()
5781 << qMakePair(&widget, QEvent::ChildAdded)
5782 << qMakePair(&widget, QEvent::ChildAdded);
5783 QCOMPARE(spy.eventList(), expected);
5786 QCoreApplication::sendPostedEvents();
5788 EventRecorder::EventList()
5789 << qMakePair(&widget, QEvent::PolishRequest)
5790 << qMakePair(&widget, QEvent::Polish)
5791 << qMakePair(&widget, QEvent::ChildPolished)
5792 << qMakePair(&widget, QEvent::ChildPolished)
5793 << qMakePair(&widget, QEvent::Type(QEvent::User + 1))
5794 << qMakePair(&widget, QEvent::Type(QEvent::User + 2));
5795 QCOMPARE(spy.eventList(), expected);
5799 // 2 children, widget shown
5802 widget.installEventFilter(&spy);
5804 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
5806 QWidget child1(&widget);
5808 child2.setParent(&widget);
5810 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 2)));
5813 EventRecorder::EventList()
5814 << qMakePair(&widget, QEvent::ChildAdded)
5815 << qMakePair(&widget, QEvent::ChildAdded);
5816 QCOMPARE(spy.eventList(), expected);
5821 EventRecorder::EventList()
5822 << qMakePair(&widget, QEvent::WinIdChange)
5823 << qMakePair(&widget, QEvent::Polish)
5824 << qMakePair(&widget, QEvent::ChildPolished)
5825 << qMakePair(&widget, QEvent::ChildPolished)
5826 << qMakePair(&widget, QEvent::Move)
5827 << qMakePair(&widget, QEvent::Resize)
5828 << qMakePair(&widget, QEvent::Show);
5830 expected << qMakePair(&widget, QEvent::ShowToParent);
5831 QCOMPARE(spy.eventList(), expected);
5834 QCoreApplication::sendPostedEvents();
5836 EventRecorder::EventList()
5837 << qMakePair(&widget, QEvent::PolishRequest)
5838 << qMakePair(&widget, QEvent::Type(QEvent::User + 1))
5839 << qMakePair(&widget, QEvent::Type(QEvent::User + 2));
5842 expected << qMakePair(&widget, QEvent::UpdateLater);
5844 expected << qMakePair(&widget, QEvent::UpdateRequest);
5846 QCOMPARE(spy.eventList(), expected);
5850 // 2 children, but one is reparented away, not shown
5853 widget.installEventFilter(&spy);
5855 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
5857 QWidget child1(&widget);
5859 child2.setParent(&widget);
5860 child2.setParent(0);
5862 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 2)));
5865 EventRecorder::EventList()
5866 << qMakePair(&widget, QEvent::ChildAdded)
5867 << qMakePair(&widget, QEvent::ChildAdded)
5868 << qMakePair(&widget, QEvent::ChildRemoved);
5869 QCOMPARE(spy.eventList(), expected);
5872 QCoreApplication::sendPostedEvents();
5874 EventRecorder::EventList()
5875 << qMakePair(&widget, QEvent::PolishRequest)
5876 << qMakePair(&widget, QEvent::Polish)
5877 << qMakePair(&widget, QEvent::ChildPolished)
5878 << qMakePair(&widget, QEvent::Type(QEvent::User + 1))
5879 << qMakePair(&widget, QEvent::Type(QEvent::User + 2));
5880 QCOMPARE(spy.eventList(), expected);
5884 // 2 children, but one is reparented away, then widget is shown
5887 widget.installEventFilter(&spy);
5889 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 1)));
5891 QWidget child1(&widget);
5893 child2.setParent(&widget);
5894 child2.setParent(0);
5896 QCoreApplication::postEvent(&widget, new QEvent(QEvent::Type(QEvent::User + 2)));
5899 EventRecorder::EventList()
5900 << qMakePair(&widget, QEvent::ChildAdded)
5901 << qMakePair(&widget, QEvent::ChildAdded)
5902 << qMakePair(&widget, QEvent::ChildRemoved);
5903 QCOMPARE(spy.eventList(), expected);
5908 EventRecorder::EventList()
5909 << qMakePair(&widget, QEvent::WinIdChange)
5910 << qMakePair(&widget, QEvent::Polish)
5911 << qMakePair(&widget, QEvent::ChildPolished)
5912 << qMakePair(&widget, QEvent::Move)
5913 << qMakePair(&widget, QEvent::Resize)
5914 << qMakePair(&widget, QEvent::Show);
5916 expected << qMakePair(&widget, QEvent::ShowToParent);
5917 QCOMPARE(spy.eventList(), expected);
5920 QCoreApplication::sendPostedEvents();
5922 EventRecorder::EventList()
5923 << qMakePair(&widget, QEvent::PolishRequest)
5924 << qMakePair(&widget, QEvent::Type(QEvent::User + 1))
5925 << qMakePair(&widget, QEvent::Type(QEvent::User + 2));
5928 expected << qMakePair(&widget, QEvent::UpdateLater);
5930 expected << qMakePair(&widget, QEvent::UpdateRequest);
5932 QCOMPARE(spy.eventList(), expected);
5936 class RenderWidget : public QWidget
5939 RenderWidget(QWidget *source)
5940 : source(source), ellipse(false) {}
5942 void setEllipseEnabled(bool enable = true)
5949 void paintEvent(QPaintEvent *)
5952 QPainter painter(this);
5953 painter.fillRect(rect(), Qt::red);
5955 QRegion regionToRender = QRegion(0, 0, source->width(), source->height() / 2,
5957 source->render(this, QPoint(0, 30), regionToRender);
5959 source->render(this);
5968 void tst_QWidget::render()
5971 QCalendarWidget source;
5972 // disable anti-aliasing to eliminate potential differences when subpixel antialiasing
5973 // is enabled on the screen
5975 f.setStyleStrategy(QFont::NoAntialias);
5978 QTest::qWaitForWindowShown(&source);
5980 // Render the entire source into target.
5981 RenderWidget target(&source);
5982 target.resize(source.size());
5985 qApp->processEvents();
5986 qApp->sendPostedEvents();
5989 QImage sourceImage = QPixmap::grabWidget(&source).toImage();
5990 qApp->processEvents();
5991 QImage targetImage = QPixmap::grabWidget(&target).toImage();
5992 qApp->processEvents();
5993 QCOMPARE(sourceImage, targetImage);
5995 // Fill target.rect() will Qt::red and render
5996 // QRegion(0, 0, source->width(), source->height() / 2, QRegion::Ellipse)
5997 // of source into target with offset (0, 30).
5998 target.setEllipseEnabled();
5999 qApp->processEvents();
6000 qApp->sendPostedEvents();
6002 targetImage = QPixmap::grabWidget(&target).toImage();
6003 QVERIFY(sourceImage != targetImage);
6005 QCOMPARE(targetImage.pixel(target.width() / 2, 29), QColor(Qt::red).rgb());
6006 QCOMPARE(targetImage.pixel(target.width() / 2, 30), sourceImage.pixel(source.width() / 2, 0));
6008 // Test that a child widget properly fills its background
6011 window.resize(100, 100);
6012 // prevent custom styles
6013 window.setStyle(new QWindowsStyle);
6015 QTest::qWaitForWindowShown(&window);
6016 QWidget child(&window);
6017 child.resize(window.size());
6020 qApp->processEvents();
6021 QCOMPARE(QPixmap::grabWidget(&child), QPixmap::grabWidget(&window));
6024 { // Check that the target offset is correct.
6026 widget.resize(200, 200);
6027 widget.setAutoFillBackground(true);
6028 widget.setPalette(Qt::red);
6029 // prevent custom styles
6030 widget.setStyle(new QWindowsStyle);
6032 QTest::qWaitForWindowShown(&widget);
6033 QImage image(widget.size(), QImage::Format_RGB32);
6034 image.fill(QColor(Qt::blue).rgb());
6036 // Target offset (0, 0)
6037 widget.render(&image, QPoint(), QRect(20, 20, 100, 100));
6038 QCOMPARE(image.pixel(0, 0), QColor(Qt::red).rgb());
6039 QCOMPARE(image.pixel(99, 99), QColor(Qt::red).rgb());
6040 QCOMPARE(image.pixel(100, 100), QColor(Qt::blue).rgb());
6042 // Target offset (20, 20).
6043 image.fill(QColor(Qt::blue).rgb());
6044 widget.render(&image, QPoint(20, 20), QRect(20, 20, 100, 100));
6045 QCOMPARE(image.pixel(0, 0), QColor(Qt::blue).rgb());
6046 QCOMPARE(image.pixel(19, 19), QColor(Qt::blue).rgb());
6047 QCOMPARE(image.pixel(20, 20), QColor(Qt::red).rgb());
6048 QCOMPARE(image.pixel(119, 119), QColor(Qt::red).rgb());
6049 QCOMPARE(image.pixel(120, 120), QColor(Qt::blue).rgb());
6053 // On Windows the active palette is used instead of the inactive palette even
6054 // though the widget is invisible. This is probably related to task 178507/168682,
6055 // but for the renderInvisible test it doesn't matter, we're mostly interested
6056 // in testing the geometry so just workaround the palette issue for now.
6057 static void workaroundPaletteIssue(QWidget *widget)
6065 QWidget *navigationBar = qFindChild<QWidget *>(widget, QLatin1String("qt_calendar_navigationbar"));
6066 QVERIFY(navigationBar);
6068 QPalette palette = navigationBar->palette();
6069 const QColor background = palette.color(QPalette::Inactive, navigationBar->backgroundRole());
6070 const QColor highlightedText = palette.color(QPalette::Inactive, QPalette::HighlightedText);
6071 palette.setColor(QPalette::Active, navigationBar->backgroundRole(), background);
6072 palette.setColor(QPalette::Active, QPalette::HighlightedText, highlightedText);
6073 navigationBar->setPalette(palette);
6076 //#define RENDER_DEBUG
6077 void tst_QWidget::renderInvisible()
6079 QCalendarWidget *calendar = new QCalendarWidget;
6080 // disable anti-aliasing to eliminate potential differences when subpixel antialiasing
6081 // is enabled on the screen
6083 f.setStyleStrategy(QFont::NoAntialias);
6084 calendar->setFont(f);
6086 QTest::qWaitForWindowShown(calendar);
6088 // Create a dummy focus widget to get rid of focus rect in reference image.
6089 QLineEdit dummyFocusWidget;
6090 dummyFocusWidget.show();
6091 QTest::qWaitForWindowShown(&dummyFocusWidget);
6092 qApp->processEvents();
6095 // Create normal reference image.
6096 const QSize calendarSize = calendar->size();
6097 QImage referenceImage(calendarSize, QImage::Format_ARGB32);
6098 calendar->render(&referenceImage);
6100 referenceImage.save("referenceImage.png");
6102 QVERIFY(!referenceImage.isNull());
6104 // Create resized reference image.
6105 const QSize calendarSizeResized = calendar->size() + QSize(50, 50);
6106 calendar->resize(calendarSizeResized);
6107 qApp->processEvents();
6109 QImage referenceImageResized(calendarSizeResized, QImage::Format_ARGB32);
6110 calendar->render(&referenceImageResized);
6112 referenceImageResized.save("referenceImageResized.png");
6114 QVERIFY(!referenceImageResized.isNull());
6116 // Explicitly hide the calendar.
6118 qApp->processEvents();
6120 workaroundPaletteIssue(calendar);
6122 { // Make sure we get the same image when the calendar is explicitly hidden.
6123 QImage testImage(calendarSizeResized, QImage::Format_ARGB32);
6124 calendar->render(&testImage);
6126 testImage.save("explicitlyHiddenCalendarResized.png");
6128 QCOMPARE(testImage, referenceImageResized);
6131 // Now that we have reference images we can delete the source and re-create
6132 // the calendar and check that we get the same images from a calendar which has never
6133 // been visible, laid out or created (Qt::WA_WState_Created).
6135 calendar = new QCalendarWidget;
6136 calendar->setFont(f);
6137 workaroundPaletteIssue(calendar);
6139 { // Never been visible, created or laid out.
6140 QImage testImage(calendarSize, QImage::Format_ARGB32);
6141 calendar->render(&testImage);
6143 testImage.save("neverBeenVisibleCreatedOrLaidOut.png");
6145 QCOMPARE(testImage, referenceImage);
6149 qApp->processEvents();
6152 { // Calendar explicitly hidden.
6153 QImage testImage(calendarSize, QImage::Format_ARGB32);
6154 calendar->render(&testImage);
6156 testImage.save("explicitlyHiddenCalendar.png");
6158 QCOMPARE(testImage, referenceImage);
6161 // Get navigation bar and explicitly hide it.
6162 QWidget *navigationBar = qFindChild<QWidget *>(calendar, QLatin1String("qt_calendar_navigationbar"));
6163 QVERIFY(navigationBar);
6164 navigationBar->hide();
6166 { // Check that the navigation bar isn't drawn when rendering the entire calendar.
6167 QImage testImage(calendarSize, QImage::Format_ARGB32);
6168 calendar->render(&testImage);
6170 testImage.save("calendarWithoutNavigationBar.png");
6172 QVERIFY(testImage != referenceImage);
6175 { // Make sure the navigation bar renders correctly even though it's hidden.
6176 QImage testImage(navigationBar->size(), QImage::Format_ARGB32);
6177 navigationBar->render(&testImage);
6179 testImage.save("explicitlyHiddenNavigationBar.png");
6181 QCOMPARE(testImage, referenceImage.copy(navigationBar->rect()));
6184 // Get next month button.
6185 QWidget *nextMonthButton = qFindChild<QWidget *>(navigationBar, QLatin1String("qt_calendar_nextmonth"));
6186 QVERIFY(nextMonthButton);
6188 { // Render next month button.
6189 // Fill test image with correct background color.
6190 QImage testImage(nextMonthButton->size(), QImage::Format_ARGB32);
6191 navigationBar->render(&testImage, QPoint(), QRegion(), QWidget::RenderFlags());
6193 testImage.save("nextMonthButtonBackground.png");
6196 // Set the button's background color to Qt::transparent; otherwise it will fill the
6197 // background with QPalette::Window.
6198 const QPalette originalPalette = nextMonthButton->palette();
6199 QPalette palette = originalPalette;
6200 palette.setColor(QPalette::Window, Qt::transparent);
6201 nextMonthButton->setPalette(palette);
6203 // Render the button on top of the background.
6204 nextMonthButton->render(&testImage);
6206 testImage.save("nextMonthButton.png");
6208 const QRect buttonRect(nextMonthButton->mapTo(calendar, QPoint()), nextMonthButton->size());
6209 QCOMPARE(testImage, referenceImage.copy(buttonRect));
6212 nextMonthButton->setPalette(originalPalette);
6215 // Navigation bar isn't explicitly hidden anymore.
6216 navigationBar->show();
6217 qApp->processEvents();
6219 QVERIFY(!calendar->isVisible());
6221 // Now, completely mess up the layout. This will trigger an update on the layout
6222 // when the calendar is visible or shown, but it's not. QWidget::render must therefore
6223 // make sure the layout is activated before rendering.
6224 QVERIFY(!calendar->isVisible());
6225 calendar->resize(calendarSizeResized);
6226 qApp->processEvents();
6228 { // Make sure we get an image equal to the resized reference image.
6229 QImage testImage(calendarSizeResized, QImage::Format_ARGB32);
6230 calendar->render(&testImage);
6232 testImage.save("calendarResized.png");
6234 QCOMPARE(testImage, referenceImageResized);
6237 { // Make sure we lay out the widget correctly the first time it's rendered.
6238 QCalendarWidget calendar;
6239 const QSize calendarSize = calendar.sizeHint();
6241 QImage image(2 * calendarSize, QImage::Format_ARGB32);
6242 image.fill(QColor(Qt::red).rgb());
6243 calendar.render(&image);
6245 for (int i = calendarSize.height(); i < 2 * calendarSize.height(); ++i)
6246 for (int j = calendarSize.width(); j < 2 * calendarSize.width(); ++j)
6247 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6250 { // Ensure that we don't call adjustSize() on invisible top-levels if render() is called
6251 // right after widgets have been added/removed to/from its layout.
6253 topLevel.setLayout(new QVBoxLayout);
6255 QWidget *widget = new QLineEdit;
6256 topLevel.layout()->addWidget(widget);
6258 const QSize initialSize = topLevel.size();
6259 QPixmap pixmap(topLevel.sizeHint());
6260 topLevel.render(&pixmap); // triggers adjustSize()
6261 const QSize finalSize = topLevel.size();
6262 QVERIFY(finalSize != initialSize);
6264 topLevel.layout()->removeWidget(widget);
6265 QCOMPARE(topLevel.size(), finalSize);
6266 topLevel.render(&pixmap);
6267 QCOMPARE(topLevel.size(), finalSize);
6269 topLevel.layout()->addWidget(widget);
6270 QCOMPARE(topLevel.size(), finalSize);
6271 topLevel.render(&pixmap);
6272 QCOMPARE(topLevel.size(), finalSize);
6276 void tst_QWidget::renderWithPainter()
6279 // prevent custom styles
6280 widget.setStyle(new QWindowsStyle);
6282 widget.resize(70, 50);
6283 widget.setAutoFillBackground(true);
6284 widget.setPalette(Qt::black);
6286 // Render the entire widget onto the image.
6287 QImage image(QSize(70, 50), QImage::Format_ARGB32);
6288 image.fill(QColor(Qt::red).rgb());
6289 QPainter painter(&image);
6290 widget.render(&painter);
6292 for (int i = 0; i < image.height(); ++i) {
6293 for (int j = 0; j < image.width(); ++j)
6294 QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
6297 // Translate painter (10, 10).
6299 image.fill(QColor(Qt::red).rgb());
6300 painter.translate(10, 10);
6301 widget.render(&painter);
6304 for (int i = 0; i < image.height(); ++i) {
6305 for (int j = 0; j < image.width(); ++j) {
6306 if (i < 10 || j < 10)
6307 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6309 QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
6313 // Pass target offset (10, 10) (the same as QPainter::translate).
6314 image.fill(QColor(Qt::red).rgb());
6315 widget.render(&painter, QPoint(10, 10));
6317 for (int i = 0; i < image.height(); ++i) {
6318 for (int j = 0; j < image.width(); ++j) {
6319 if (i < 10 || j < 10)
6320 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6322 QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
6326 // Translate (10, 10) and pass target offset (10, 10).
6328 image.fill(QColor(Qt::red).rgb());
6329 painter.translate(10, 10);
6330 widget.render(&painter, QPoint(10, 10));
6333 for (int i = 0; i < image.height(); ++i) {
6334 for (int j = 0; j < image.width(); ++j) {
6335 if (i < 20 || j < 20)
6336 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6338 QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
6342 // Rotate painter 90 degrees.
6344 image.fill(QColor(Qt::red).rgb());
6346 widget.render(&painter);
6349 for (int i = 0; i < image.height(); ++i) {
6350 for (int j = 0; j < image.width(); ++j)
6351 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6354 // Translate and rotate.
6355 image.fill(QColor(Qt::red).rgb());
6356 widget.resize(40, 10);
6357 painter.translate(10, 10);
6359 widget.render(&painter);
6361 for (int i = 0; i < image.height(); ++i) {
6362 for (int j = 0; j < image.width(); ++j) {
6363 if (i >= 10 && j >= 0 && j < 10)
6364 QCOMPARE(image.pixel(j, i), QColor(Qt::black).rgb());
6366 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6370 // Make sure QWidget::render does not modify the render hints set on the painter.
6371 painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform
6372 | QPainter::NonCosmeticDefaultPen | QPainter::TextAntialiasing);
6373 QPainter::RenderHints oldRenderHints = painter.renderHints();
6374 widget.render(&painter);
6375 QCOMPARE(painter.renderHints(), oldRenderHints);
6378 void tst_QWidget::render_task188133()
6380 QMainWindow mainWindow;
6382 // Make sure QWidget::render does not trigger QWidget::repaint/update
6383 // and asserts for Qt::WA_WState_Created.
6384 QPixmap pixmap = QPixmap::grabWidget(&mainWindow);
6387 void tst_QWidget::render_task211796()
6389 class MyWidget : public QWidget
6391 void resizeEvent(QResizeEvent *)
6393 QPixmap pixmap(size());
6398 { // Please don't die in a resize recursion.
6400 widget.resize(200, 200);
6404 { // Same check with a deeper hierarchy.
6407 QWidget child(&widget);
6408 MyWidget grandChild;
6409 grandChild.setParent(&child);
6410 grandChild.resize(100, 100);
6415 void tst_QWidget::render_task217815()
6417 // Make sure we don't change the size of the widget when calling
6418 // render() and the widget has an explicit size set.
6419 // This was a problem on Windows because we called createWinId(),
6420 // which in turn enforced the size to be bigger than the smallest
6421 // possible native window size (which is (115,something) on WinXP).
6423 const QSize explicitSize(80, 20);
6424 widget.resize(explicitSize);
6425 QCOMPARE(widget.size(), explicitSize);
6427 QPixmap pixmap(explicitSize);
6428 widget.render(&pixmap);
6430 QCOMPARE(widget.size(), explicitSize);
6433 // Window Opacity is not supported on Windows CE.
6435 void tst_QWidget::render_windowOpacity()
6437 const qreal opacity = 0.5;
6439 { // Check that the painter opacity effects the widget drawing.
6441 QWidget child(&topLevel);
6442 child.resize(50, 50);
6443 child.setPalette(Qt::red);
6444 child.setAutoFillBackground(true);
6446 QPixmap expected(child.size());
6448 if (expected.depth() < 24)
6449 QSKIP("This test won't give correct results with dithered pixmaps");
6451 expected.fill(Qt::green);
6452 QPainter painter(&expected);
6453 painter.setOpacity(opacity);
6454 painter.fillRect(QRect(QPoint(0, 0), child.size()), Qt::red);
6457 QPixmap result(child.size());
6458 result.fill(Qt::green);
6459 painter.begin(&result);
6460 painter.setOpacity(opacity);
6461 child.render(&painter);
6463 QCOMPARE(result, expected);
6466 { // Combine the opacity set on the painter with the widget opacity.
6467 class MyWidget : public QWidget
6470 void paintEvent(QPaintEvent *)
6472 QPainter painter(this);
6473 painter.setOpacity(opacity);
6474 QCOMPARE(painter.opacity(), opacity);
6475 painter.fillRect(rect(), Qt::red);
6481 widget.resize(50, 50);
6482 widget.opacity = opacity;
6483 widget.setPalette(Qt::blue);
6484 widget.setAutoFillBackground(true);
6486 QPixmap expected(widget.size());
6487 expected.fill(Qt::green);
6488 QPainter painter(&expected);
6489 painter.setOpacity(opacity);
6490 QPixmap pixmap(widget.size());
6491 pixmap.fill(Qt::blue);
6492 QPainter pixmapPainter(&pixmap);
6493 pixmapPainter.setOpacity(opacity);
6494 pixmapPainter.fillRect(QRect(QPoint(), widget.size()), Qt::red);
6495 painter.drawPixmap(QPoint(), pixmap);
6498 QPixmap result(widget.size());
6499 result.fill(Qt::green);
6500 painter.begin(&result);
6501 painter.setOpacity(opacity);
6502 widget.render(&painter);
6504 QCOMPARE(result, expected);
6509 void tst_QWidget::render_systemClip()
6512 widget.setPalette(Qt::blue);
6513 widget.resize(100, 100);
6515 QImage image(widget.size(), QImage::Format_RGB32);
6516 image.fill(QColor(Qt::red).rgb());
6518 QPaintEngine *paintEngine = image.paintEngine();
6519 QVERIFY(paintEngine);
6520 paintEngine->setSystemClip(QRegion(0, 0, 50, 50));
6522 QPainter painter(&image);
6523 // Make sure we're using the same paint engine and has the right clip set.
6524 QCOMPARE(painter.paintEngine(), paintEngine);
6525 QCOMPARE(paintEngine->systemClip(), QRegion(0, 0, 50, 50));
6527 // Translate painter outside system clip.
6528 painter.translate(50, 0);
6529 widget.render(&painter);
6532 image.save("outside_systemclip.png");
6535 // All pixels should be red.
6536 for (int i = 0; i < image.height(); ++i) {
6537 for (int j = 0; j < image.width(); ++j)
6538 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6541 // Restore painter and refill image with red.
6542 image.fill(QColor(Qt::red).rgb());
6543 painter.translate(-50, 0);
6545 // Set transform on the painter.
6546 QTransform transform;
6547 transform.shear(0, 1);
6548 painter.setTransform(transform);
6549 widget.render(&painter);
6552 image.save("blue_triangle.png");
6555 // We should now have a blue triangle starting at scan line 1, and the rest should be red.
6565 for (int i = 0; i < image.height(); ++i) {
6566 for (int j = 0; j < image.width(); ++j) {
6567 if (i < 50 && j < i)
6568 QCOMPARE(image.pixel(j, i), QColor(Qt::blue).rgb());
6570 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6574 // We don't paint directly on the image on the Mac, so we cannot do the pixel comparison
6575 // as above due to QPainter::SmoothPixmapTransform. We therefore need to generate an
6576 // expected image by first painting on a pixmap, and then draw the pixmap onto
6577 // the image using QPainter::SmoothPixmapTransform. Then we can compare pixels :)
6578 // The check is basically the same, except that it takes the smoothening into account.
6579 QPixmap pixmap(50, 50);
6580 const QRegion sysClip(0, 0, 50, 50);
6581 widget.render(&pixmap, QPoint(), sysClip);
6583 QImage expectedImage(widget.size(), QImage::Format_RGB32);
6584 expectedImage.fill(QColor(Qt::red).rgb());
6585 expectedImage.paintEngine()->setSystemClip(sysClip);
6587 QPainter expectedImagePainter(&expectedImage);
6588 expectedImagePainter.setTransform(QTransform().shear(0, 1));
6589 // NB! This is the important part (SmoothPixmapTransform).
6590 expectedImagePainter.setRenderHints(QPainter::SmoothPixmapTransform);
6591 expectedImagePainter.drawPixmap(QPoint(0, 0), pixmap);
6592 expectedImagePainter.end();
6594 QCOMPARE(image, expectedImage);
6598 void tst_QWidget::render_systemClip2_data()
6600 QTest::addColumn<bool>("autoFillBackground");
6601 QTest::addColumn<bool>("usePaintEvent");
6602 QTest::addColumn<QColor>("expectedColor");
6604 QTest::newRow("Only auto-fill background") << true << false << QColor(Qt::blue);
6605 QTest::newRow("Only draw in paintEvent") << false << true << QColor(Qt::green);
6606 QTest::newRow("Auto-fill background and draw in paintEvent") << true << true << QColor(Qt::green);
6609 void tst_QWidget::render_systemClip2()
6611 QFETCH(bool, autoFillBackground);
6612 QFETCH(bool, usePaintEvent);
6613 QFETCH(QColor, expectedColor);
6615 QVERIFY2(expectedColor != QColor(Qt::red), "Qt::red is the reference color for the image, pick another color");
6617 class MyWidget : public QWidget
6621 void paintEvent(QPaintEvent *)
6624 QPainter(this).fillRect(rect(), Qt::green);
6629 widget.usePaintEvent = usePaintEvent;
6630 widget.setPalette(Qt::blue);
6631 // NB! widget.setAutoFillBackground(autoFillBackground) won't do the
6632 // trick here since the widget is a top-level. The background is filled
6633 // regardless, unless Qt::WA_OpaquePaintEvent or Qt::WA_NoSystemBackground
6634 // is set. We therefore use the opaque attribute to turn off auto-fill.
6635 if (!autoFillBackground)
6636 widget.setAttribute(Qt::WA_OpaquePaintEvent);
6637 widget.resize(100, 100);
6639 QImage image(widget.size(), QImage::Format_RGB32);
6640 image.fill(QColor(Qt::red).rgb());
6642 QPaintEngine *paintEngine = image.paintEngine();
6643 QVERIFY(paintEngine);
6645 QRegion systemClip(QRegion(50, 0, 50, 10));
6646 systemClip += QRegion(90, 10, 10, 40);
6647 paintEngine->setSystemClip(systemClip);
6649 // Render entire widget directly onto device.
6650 widget.render(&image);
6653 image.save("systemclip_with_device.png");
6655 // All pixels within the system clip should now be
6656 // the expectedColor, and the rest should be red.
6657 for (int i = 0; i < image.height(); ++i) {
6658 for (int j = 0; j < image.width(); ++j) {
6659 if (systemClip.contains(QPoint(j, i)))
6660 QCOMPARE(image.pixel(j, i), expectedColor.rgb());
6662 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6666 // Refill image with red.
6667 image.fill(QColor(Qt::red).rgb());
6668 paintEngine->setSystemClip(systemClip);
6670 // Do the same with an untransformed painter.
6671 QPainter painter(&image);
6672 //Make sure we're using the same paint engine and has the right clip set.
6673 QCOMPARE(painter.paintEngine(), paintEngine);
6674 QCOMPARE(paintEngine->systemClip(), systemClip);
6676 widget.render(&painter);
6679 image.save("systemclip_with_untransformed_painter.png");
6681 // All pixels within the system clip should now be
6682 // the expectedColor, and the rest should be red.
6683 for (int i = 0; i < image.height(); ++i) {
6684 for (int j = 0; j < image.width(); ++j) {
6685 if (systemClip.contains(QPoint(j, i)))
6686 QCOMPARE(image.pixel(j, i), expectedColor.rgb());
6688 QCOMPARE(image.pixel(j, i), QColor(Qt::red).rgb());
6693 void tst_QWidget::render_systemClip3_data()
6695 QTest::addColumn<QSize>("size");
6696 QTest::addColumn<bool>("useSystemClip");
6698 // Reference: http://en.wikipedia.org/wiki/Flag_of_Norway
6699 QTest::newRow("Norwegian Civil Flag") << QSize(220, 160) << false;
6700 QTest::newRow("Norwegian War Flag") << QSize(270, 160) << true;
6703 // This test ensures that the current engine clip (systemClip + painter clip)
6704 // is preserved after QPainter::setClipRegion(..., Qt::ReplaceClip);
6705 void tst_QWidget::render_systemClip3()
6707 QFETCH(QSize, size);
6708 QFETCH(bool, useSystemClip);
6710 // Calculate the inner/outer cross of the flag.
6711 QRegion outerCross(0, 0, size.width(), size.height());
6712 outerCross -= QRect(0, 0, 60, 60);
6713 outerCross -= QRect(100, 0, size.width() - 100, 60);
6714 outerCross -= QRect(0, 100, 60, 60);
6715 outerCross -= QRect(100, 100, size.width() - 100, 60);
6717 QRegion innerCross(0, 0, size.width(), size.height());
6718 innerCross -= QRect(0, 0, 70, 70);
6719 innerCross -= QRect(90, 0, size.width() - 90, 70);
6720 innerCross -= QRect(0, 90, 70, 70);
6721 innerCross -= QRect(90, 90, size.width() - 90, 70);
6723 const QRegion redArea(QRegion(0, 0, size.width(), size.height()) - outerCross);
6724 const QRegion whiteArea(outerCross - innerCross);
6725 const QRegion blueArea(innerCross);
6728 // Okay, here's the image that should look like a Norwegian civil/war flag in the end.
6729 QImage flag(size, QImage::Format_ARGB32);
6730 flag.fill(QColor(Qt::transparent).rgba());
6732 if (useSystemClip) {
6733 QPainterPath warClip(QPoint(size.width(), 0));
6734 warClip.lineTo(size.width() - 110, 60);
6735 warClip.lineTo(size.width(), 80);
6736 warClip.lineTo(size.width() - 110, 100);
6737 warClip.lineTo(size.width(), 160);
6738 warClip.closeSubpath();
6739 systemClip = QRegion(0, 0, size.width(), size.height()) - QRegion(warClip.toFillPolygon().toPolygon());
6740 flag.paintEngine()->setSystemClip(systemClip);
6743 QPainter painter(&flag);
6744 painter.fillRect(QRect(QPoint(), size), Qt::red); // Fill image background with red.
6745 painter.setClipRegion(outerCross); // Limit widget painting to inside the outer cross.
6747 // Here's the widget that's supposed to draw the inner/outer cross of the flag.
6748 // The outer cross (white) should be drawn when the background is auto-filled, and
6749 // the inner cross (blue) should be drawn in the paintEvent.
6750 class MyWidget : public QWidget
6752 void paintEvent(QPaintEvent *)
6754 QPainter painter(this);
6755 // Be evil and try to paint outside the outer cross. This should not be
6756 // possible since the shared painter is clipped to the outer cross.
6757 painter.setClipRect(0, 0, 60, 60, Qt::ReplaceClip);
6758 painter.fillRect(rect(), Qt::green);
6759 painter.setClipRegion(clip, Qt::ReplaceClip);
6760 painter.fillRect(rect(), Qt::blue);
6766 widget.clip = innerCross;
6767 widget.setFixedSize(size);
6768 widget.setPalette(Qt::white);
6769 widget.setAutoFillBackground(true);
6770 widget.render(&painter);
6773 flag.save("flag.png");
6776 // Let's make sure we got a Norwegian flag.
6777 for (int i = 0; i < flag.height(); ++i) {
6778 for (int j = 0; j < flag.width(); ++j) {
6779 const QPoint pixel(j, i);
6780 const QRgb pixelValue = flag.pixel(pixel);
6781 if (useSystemClip && !systemClip.contains(pixel))
6782 QCOMPARE(pixelValue, QColor(Qt::transparent).rgba());
6783 else if (redArea.contains(pixel))
6784 QCOMPARE(pixelValue, QColor(Qt::red).rgba());
6785 else if (whiteArea.contains(pixel))
6786 QCOMPARE(pixelValue, QColor(Qt::white).rgba());
6788 QCOMPARE(pixelValue, QColor(Qt::blue).rgba());
6793 void tst_QWidget::render_task252837()
6796 widget.resize(200, 200);
6798 QPixmap pixmap(widget.size());
6799 QPainter painter(&pixmap);
6800 // Please do not crash.
6801 widget.render(&painter);
6804 void tst_QWidget::render_worldTransform()
6806 class MyWidget : public QWidget
6808 void paintEvent(QPaintEvent *)
6810 QPainter painter(this);
6811 // Make sure world transform is identity.
6812 QCOMPARE(painter.worldTransform(), QTransform());
6814 // Make sure device transform is correct.
6815 const QPoint widgetOffset = geometry().topLeft();
6816 QTransform expectedDeviceTransform = QTransform::fromTranslate(105, 5);
6817 expectedDeviceTransform.rotate(90);
6818 expectedDeviceTransform.translate(widgetOffset.x(), widgetOffset.y());
6819 QCOMPARE(painter.deviceTransform(), expectedDeviceTransform);
6821 // Set new world transform.
6822 QTransform newWorldTransform = QTransform::fromTranslate(10, 10);
6823 newWorldTransform.rotate(90);
6824 painter.setWorldTransform(newWorldTransform);
6825 QCOMPARE(painter.worldTransform(), newWorldTransform);
6827 // Again, check device transform.
6828 expectedDeviceTransform.translate(10, 10);
6829 expectedDeviceTransform.rotate(90);
6830 QCOMPARE(painter.deviceTransform(), expectedDeviceTransform);
6832 painter.fillRect(QRect(0, 0, 20, 10), Qt::green);
6837 widget.setFixedSize(100, 100);
6838 widget.setPalette(Qt::red);
6839 widget.setAutoFillBackground(true);
6842 child.setParent(&widget);
6844 child.setFixedSize(50, 50);
6845 child.setPalette(Qt::blue);
6846 child.setAutoFillBackground(true);
6848 QImage image(QSize(110, 110), QImage::Format_RGB32);
6849 image.fill(QColor(Qt::black).rgb());
6851 QPainter painter(&image);
6852 painter.translate(105, 5);
6855 // Render widgets onto image.
6856 widget.render(&painter);
6858 image.save("render_worldTransform_image.png");
6861 // Ensure the transforms are unchanged after render.
6862 QCOMPARE(painter.worldTransform(), painter.worldTransform());
6863 QCOMPARE(painter.deviceTransform(), painter.deviceTransform());
6866 // Paint expected image.
6867 QImage expected(QSize(110, 110), QImage::Format_RGB32);
6868 expected.fill(QColor(Qt::black).rgb());
6870 QPainter expectedPainter(&expected);
6871 expectedPainter.translate(105, 5);
6872 expectedPainter.rotate(90);
6873 expectedPainter.save();
6874 expectedPainter.fillRect(widget.rect(),Qt::red);
6875 expectedPainter.translate(10, 10);
6876 expectedPainter.rotate(90);
6877 expectedPainter.fillRect(QRect(0, 0, 20, 10), Qt::green);
6878 expectedPainter.restore();
6879 expectedPainter.translate(50, 50);
6880 expectedPainter.fillRect(child.rect(),Qt::blue);
6881 expectedPainter.translate(10, 10);
6882 expectedPainter.rotate(90);
6883 expectedPainter.fillRect(QRect(0, 0, 20, 10), Qt::green);
6884 expectedPainter.end();
6887 expected.save("render_worldTransform_expected.png");
6890 QCOMPARE(image, expected);
6893 void tst_QWidget::setContentsMargins()
6895 QLabel label("why does it always rain on me?");
6896 QSize oldSize = label.sizeHint();
6897 label.setFrameStyle(QFrame::Sunken | QFrame::Box);
6898 QSize newSize = label.sizeHint();
6899 QVERIFY(oldSize != newSize);
6901 QLabel label2("why does it always rain on me?");
6903 label2.setFrameStyle(QFrame::Sunken | QFrame::Box);
6904 QCOMPARE(newSize, label2.sizeHint());
6906 QLabel label3("why does it always rain on me?");
6907 label3.setFrameStyle(QFrame::Sunken | QFrame::Box);
6908 QCOMPARE(newSize, label3.sizeHint());
6911 // 4DWM issues on IRIX makes this test fail.
6913 void tst_QWidget::moveWindowInShowEvent_data()
6915 QTest::addColumn<QPoint>("initial");
6916 QTest::addColumn<QPoint>("position");
6918 QPoint p = QApplication::desktop()->availableGeometry().topLeft();
6920 QTest::newRow("1") << p << (p + QPoint(10, 10));
6921 QTest::newRow("2") << (p + QPoint(10,10)) << p;
6924 void tst_QWidget::moveWindowInShowEvent()
6926 QFETCH(QPoint, initial);
6927 QFETCH(QPoint, position);
6929 class MoveWindowInShowEventWidget : public QWidget
6933 void showEvent(QShowEvent *)
6939 MoveWindowInShowEventWidget widget;
6940 widget.resize(QSize(qApp->desktop()->availableGeometry().size() / 3).expandedTo(QSize(1, 1)));
6941 // move to this position in showEvent()
6942 widget.position = position;
6944 // put the widget in it's starting position
6945 widget.move(initial);
6946 QCOMPARE(widget.pos(), initial);
6951 qt_x11_wait_for_window_manager(&widget);
6954 // it should have moved
6955 QCOMPARE(widget.pos(), position);
6959 void tst_QWidget::repaintWhenChildDeleted()
6962 if (QSysInfo::WindowsVersion & QSysInfo::WV_VISTA) {
6966 ColorWidget w(0, Qt::red);
6967 #if !defined(Q_OS_WINCE)
6968 QPoint startPoint = QApplication::desktop()->availableGeometry(&w).topLeft();
6969 startPoint.rx() += 50;
6970 startPoint.ry() += 50;
6971 w.setGeometry(QRect(startPoint, QSize(100, 100)));
6973 w.setGeometry(60, 60, 110, 110);
6976 QTest::qWaitForWindowShown(&w);
6978 QTRY_COMPARE(w.r, QRegion(w.rect()));
6982 ColorWidget child(&w, Qt::blue);
6983 child.setGeometry(10, 10, 10, 10);
6986 QTRY_COMPARE(child.r, QRegion(child.rect()));
6991 QTRY_COMPARE(w.r, QRegion(10, 10, 10, 10));
6995 void tst_QWidget::hideOpaqueChildWhileHidden()
6997 ColorWidget w(0, Qt::red);
6998 #if !defined(Q_OS_WINCE)
6999 QPoint startPoint = QApplication::desktop()->availableGeometry(&w).topLeft();
7000 startPoint.rx() += 50;
7001 startPoint.ry() += 50;
7002 w.setGeometry(QRect(startPoint, QSize(100, 100)));
7004 w.setGeometry(60, 60, 110, 110);
7007 ColorWidget child(&w, Qt::blue);
7008 child.setGeometry(10, 10, 80, 80);
7010 ColorWidget child2(&child, Qt::white);
7011 child2.setGeometry(10, 10, 60, 60);
7014 QTest::qWaitForWindowShown(&w);
7016 QTRY_COMPARE(child2.r, QRegion(child2.rect()));
7017 child.r = QRegion();
7018 child2.r = QRegion();
7025 QCOMPARE(w.r, QRegion(child.geometry()));
7029 QCOMPARE(child.r, QRegion(child.rect()));
7030 QCOMPARE(child2.r, QRegion());
7033 // This test doesn't make sense without support for showMinimized().
7034 #if !defined(Q_OS_WINCE) && !defined(Q_WS_QWS)
7035 void tst_QWidget::updateWhileMinimized()
7037 UpdateWidget widget;
7038 // Filter out activation change and focus events to avoid update() calls in QWidget.
7039 widget.updateOnActivationChangeAndFocusIn = false;
7042 QTest::qWaitForWindowShown(&widget);
7043 QApplication::processEvents();
7044 QTRY_VERIFY(widget.numPaintEvents > 0);
7048 widget.showMinimized();
7053 // The widget is not visible on the screen (but isVisible() still returns true).
7054 // Make sure update requests are discarded until the widget is shown again.
7055 widget.update(0, 0, 50, 50);
7057 QCOMPARE(widget.numPaintEvents, 0);
7060 widget.showNormal();
7062 QTRY_COMPARE(widget.numPaintEvents, 1);
7063 QCOMPARE(widget.paintedRegion, QRegion(0, 0, 50, 50));
7067 #if defined(Q_WS_WIN) || defined(Q_WS_X11)
7068 class PaintOnScreenWidget: public QWidget
7071 PaintOnScreenWidget(QWidget *parent = 0, Qt::WindowFlags f = 0)
7075 #if defined(Q_WS_WIN)
7076 // This is the only way to enable PaintOnScreen on Windows.
7077 QPaintEngine * paintEngine () const {return 0;}
7081 void tst_QWidget::alienWidgets()
7083 qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
7085 QWidget child(&parent);
7086 QWidget grandChild(&child);
7087 QWidget greatGrandChild(&grandChild);
7091 qt_x11_wait_for_window_manager(&parent);
7094 // Verify that the WA_WState_Created attribute is set
7095 // and the top-level is the only native window.
7096 QVERIFY(parent.testAttribute(Qt::WA_WState_Created));
7097 QVERIFY(parent.internalWinId());
7099 QVERIFY(child.testAttribute(Qt::WA_WState_Created));
7100 QVERIFY(!child.internalWinId());
7102 QVERIFY(grandChild.testAttribute(Qt::WA_WState_Created));
7103 QVERIFY(!grandChild.internalWinId());
7105 QVERIFY(greatGrandChild.testAttribute(Qt::WA_WState_Created));
7106 QVERIFY(!greatGrandChild.internalWinId());
7108 // Enforce native windows all the way up in the parent hierarchy
7109 // if not WA_DontCreateNativeAncestors is set.
7110 grandChild.setAttribute(Qt::WA_DontCreateNativeAncestors);
7111 greatGrandChild.setAttribute(Qt::WA_NativeWindow);
7112 QVERIFY(greatGrandChild.internalWinId());
7113 QVERIFY(grandChild.internalWinId());
7114 QVERIFY(!child.internalWinId());
7117 // Ensure that hide() on an ancestor of a widget with
7118 // Qt::WA_DontCreateNativeAncestors still gets unmapped
7120 QWidget widget(&window);
7121 QWidget child(&widget);
7122 child.setAttribute(Qt::WA_NativeWindow);
7123 child.setAttribute(Qt::WA_DontCreateNativeAncestors);
7125 QVERIFY(child.testAttribute(Qt::WA_Mapped));
7127 QVERIFY(!child.testAttribute(Qt::WA_Mapped));
7130 // Enforce a native window when calling QWidget::winId.
7131 QVERIFY(child.winId());
7132 QVERIFY(child.internalWinId());
7134 // Check that paint on screen widgets (incl. children) are native.
7135 PaintOnScreenWidget paintOnScreen(&parent);
7136 QWidget paintOnScreenChild(&paintOnScreen);
7137 paintOnScreen.show();
7138 QVERIFY(paintOnScreen.testAttribute(Qt::WA_WState_Created));
7139 QVERIFY(!paintOnScreen.testAttribute(Qt::WA_NativeWindow));
7140 QVERIFY(!paintOnScreen.internalWinId());
7141 QVERIFY(!paintOnScreenChild.testAttribute(Qt::WA_NativeWindow));
7142 QVERIFY(!paintOnScreenChild.internalWinId());
7144 paintOnScreen.setAttribute(Qt::WA_PaintOnScreen);
7145 QVERIFY(paintOnScreen.testAttribute(Qt::WA_NativeWindow));
7146 QVERIFY(paintOnScreen.internalWinId());
7147 QVERIFY(paintOnScreenChild.testAttribute(Qt::WA_NativeWindow));
7148 QVERIFY(paintOnScreenChild.internalWinId());
7150 // Check that widgets with the Qt::MSWindowsOwnDC attribute set
7152 QWidget msWindowsOwnDC(&parent, Qt::MSWindowsOwnDC);
7153 msWindowsOwnDC.show();
7154 QVERIFY(msWindowsOwnDC.testAttribute(Qt::WA_WState_Created));
7155 QVERIFY(msWindowsOwnDC.testAttribute(Qt::WA_NativeWindow));
7156 QVERIFY(msWindowsOwnDC.internalWinId());
7158 { // Enforce a native window when calling QWidget::handle() (on X11) or QWidget::getDC() (on Windows).
7159 QWidget widget(&parent);
7161 QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
7162 QVERIFY(!widget.internalWinId());
7168 QVERIFY(widget.internalWinId());
7172 #ifndef QT_NO_XRENDER
7173 { // Enforce a native window when calling QWidget::x11PictureHandle().
7174 QWidget widget(&parent);
7176 QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
7177 QVERIFY(!widget.internalWinId());
7178 widget.x11PictureHandle();
7179 QVERIFY(widget.internalWinId());
7183 { // Make sure we don't create native windows when setting Qt::WA_X11NetWmWindowType attributes
7184 // on alien widgets (see task 194231).
7186 QVERIFY(dummy.winId());
7187 QWidget widget(&dummy);
7188 widget.setAttribute(Qt::WA_X11NetWmWindowTypeToolBar);
7189 QVERIFY(!widget.internalWinId());
7194 { // Make sure we create native ancestors when setting Qt::WA_PaintOnScreen before show().
7196 QWidget child(&topLevel);
7197 QWidget grandChild(&child);
7198 PaintOnScreenWidget greatGrandChild(&grandChild);
7200 greatGrandChild.setAttribute(Qt::WA_PaintOnScreen);
7201 QVERIFY(!child.internalWinId());
7202 QVERIFY(!grandChild.internalWinId());
7203 QVERIFY(!greatGrandChild.internalWinId());
7206 QVERIFY(child.internalWinId());
7207 QVERIFY(grandChild.internalWinId());
7208 QVERIFY(greatGrandChild.internalWinId());
7211 { // Ensure that widgets reparented into Qt::WA_PaintOnScreen widgets become native.
7213 QWidget *widget = new PaintOnScreenWidget(&topLevel);
7214 widget->setAttribute(Qt::WA_PaintOnScreen);
7215 QWidget *child = new QWidget;
7216 QWidget *dummy = new QWidget(child);
7217 QWidget *grandChild = new QWidget(child);
7218 QWidget *dummy2 = new QWidget(grandChild);
7220 child->setParent(widget);
7222 QVERIFY(!topLevel.internalWinId());
7223 QVERIFY(!child->internalWinId());
7224 QVERIFY(!dummy->internalWinId());
7225 QVERIFY(!grandChild->internalWinId());
7226 QVERIFY(!dummy2->internalWinId());
7229 QVERIFY(topLevel.internalWinId());
7230 QVERIFY(widget->testAttribute(Qt::WA_NativeWindow));
7231 QVERIFY(child->internalWinId());
7232 QVERIFY(child->testAttribute(Qt::WA_NativeWindow));
7233 QVERIFY(!child->testAttribute(Qt::WA_PaintOnScreen));
7234 QVERIFY(!dummy->internalWinId());
7235 QVERIFY(!dummy->testAttribute(Qt::WA_NativeWindow));
7236 QVERIFY(!grandChild->internalWinId());
7237 QVERIFY(!grandChild->testAttribute(Qt::WA_NativeWindow));
7238 QVERIFY(!dummy2->internalWinId());
7239 QVERIFY(!dummy2->testAttribute(Qt::WA_NativeWindow));
7242 { // Ensure that ancestors of a Qt::WA_PaintOnScreen widget stay native
7243 // if they are re-created (typically in QWidgetPrivate::setParent_sys) (task 210822).
7245 QWidget child(&window);
7248 grandChild.setWindowTitle("This causes the widget to be created");
7250 PaintOnScreenWidget paintOnScreenWidget;
7251 paintOnScreenWidget.setAttribute(Qt::WA_PaintOnScreen);
7252 paintOnScreenWidget.setParent(&grandChild);
7254 grandChild.setParent(&child);
7258 QVERIFY(window.internalWinId());
7259 QVERIFY(child.internalWinId());
7260 QVERIFY(child.testAttribute(Qt::WA_NativeWindow));
7261 QVERIFY(grandChild.internalWinId());
7262 QVERIFY(grandChild.testAttribute(Qt::WA_NativeWindow));
7263 QVERIFY(paintOnScreenWidget.internalWinId());
7264 QVERIFY(paintOnScreenWidget.testAttribute(Qt::WA_NativeWindow));
7267 { // Ensure that all siblings are native unless Qt::AA_DontCreateNativeWidgetSiblings is set.
7268 qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, false);
7270 QWidget *toolBar = new QWidget(&mainWindow);
7271 QWidget *dockWidget = new QWidget(&mainWindow);
7272 QWidget *centralWidget = new QWidget(&mainWindow);
7274 QWidget *button = new QWidget(centralWidget);
7275 QWidget *mdiArea = new QWidget(centralWidget);
7277 QWidget *horizontalScroll = new QWidget(mdiArea);
7278 QWidget *verticalScroll = new QWidget(mdiArea);
7279 QWidget *viewport = new QWidget(mdiArea);
7281 viewport->setAttribute(Qt::WA_NativeWindow);
7284 // Ensure that the viewport and its siblings are native:
7285 QVERIFY(verticalScroll->testAttribute(Qt::WA_NativeWindow));
7286 QVERIFY(verticalScroll->testAttribute(Qt::WA_NativeWindow));
7287 QVERIFY(horizontalScroll->testAttribute(Qt::WA_NativeWindow));
7289 // Ensure that the mdi area and its siblings are native:
7290 QVERIFY(mdiArea->testAttribute(Qt::WA_NativeWindow));
7291 QVERIFY(button->testAttribute(Qt::WA_NativeWindow));
7293 // Ensure that the central widget and its siblings are native:
7294 QVERIFY(centralWidget->testAttribute(Qt::WA_NativeWindow));
7295 QVERIFY(dockWidget->testAttribute(Qt::WA_NativeWindow));
7296 QVERIFY(toolBar->testAttribute(Qt::WA_NativeWindow));
7299 #endif // Q_WS_WIN / Q_WS_X11
7301 class ASWidget : public QWidget
7304 ASWidget(QSize sizeHint, QSizePolicy sizePolicy, bool layout, bool hfwLayout, QWidget *parent = 0)
7305 : QWidget(parent), mySizeHint(sizeHint)
7307 setSizePolicy(sizePolicy);
7309 QSizePolicy sp = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
7310 sp.setHeightForWidth(hfwLayout);
7312 QVBoxLayout *vbox = new QVBoxLayout;
7314 vbox->addWidget(new ASWidget(sizeHint + QSize(30, 20), sp, false, false));
7319 QSize sizeHint() const {
7321 return layout()->totalSizeHint();
7324 int heightForWidth(int width) const {
7325 if (sizePolicy().hasHeightForWidth()) {
7335 void tst_QWidget::adjustSize_data()
7337 const int MagicW = 200;
7338 const int MagicH = 100;
7340 QTest::addColumn<QSize>("sizeHint");
7341 QTest::addColumn<int>("hPolicy");
7342 QTest::addColumn<int>("vPolicy");
7343 QTest::addColumn<bool>("hfwSP");
7344 QTest::addColumn<bool>("layout");
7345 QTest::addColumn<bool>("hfwLayout");
7346 QTest::addColumn<bool>("haveParent");
7347 QTest::addColumn<QSize>("expectedSize");
7349 QTest::newRow("1") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7350 << false << false << false << false << QSize(5, qMax(6, MagicH));
7351 QTest::newRow("2") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7352 << true << false << false << false << QSize(5, qMax(10, MagicH));
7353 QTest::newRow("3") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7354 << false << true << false << false << QSize(35, 26);
7355 QTest::newRow("4") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7356 << false << true << true << false << QSize(35, 70);
7357 QTest::newRow("5") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7358 << false << false << false << false << QSize(100000, 100000);
7359 QTest::newRow("6") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7360 << true << false << false << false << QSize(100000, 100000);
7361 QTest::newRow("7") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7362 << false << true << false << false << QSize(100000, 100000);
7363 QTest::newRow("8") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7364 << false << true << true << false << QSize(100000, 100000);
7365 QTest::newRow("9") << QSize(5, 6) << int(QSizePolicy::Expanding) << int(QSizePolicy::Minimum)
7366 << true << false << false << false << QSize(qMax(5, MagicW), 10);
7368 QTest::newRow("1c") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7369 << false << false << false << true << QSize(5, 6);
7370 QTest::newRow("2c") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7371 << true << false << false << true << QSize(5, 6 /* or 10 would be OK too, since hfw contradicts sizeHint() */);
7372 QTest::newRow("3c") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7373 << false << true << false << true << QSize(35, 26);
7374 QTest::newRow("4c") << QSize(5, 6) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7375 << false << true << true << true << QSize(35, 70);
7376 QTest::newRow("5c") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7377 << false << false << false << true << QSize(40001, 30001);
7378 QTest::newRow("6c") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7379 << true << false << false << true << QSize(40001, 30001 /* or 80002 would be OK too, since hfw contradicts sizeHint() */);
7380 QTest::newRow("7c") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7381 << false << true << false << true << QSize(40001 + 30, 30001 + 20);
7382 QTest::newRow("8c") << QSize(40001, 30001) << int(QSizePolicy::Minimum) << int(QSizePolicy::Expanding)
7383 << false << true << true << true << QSize(40001 + 30, 80002 + 60);
7384 QTest::newRow("9c") << QSize(5, 6) << int(QSizePolicy::Expanding) << int(QSizePolicy::Minimum)
7385 << true << false << false << true << QSize(5, 6);
7388 void tst_QWidget::adjustSize()
7390 QFETCH(QSize, sizeHint);
7391 QFETCH(int, hPolicy);
7392 QFETCH(int, vPolicy);
7393 QFETCH(bool, hfwSP);
7394 QFETCH(bool, layout);
7395 QFETCH(bool, hfwLayout);
7396 QFETCH(bool, haveParent);
7397 QFETCH(QSize, expectedSize);
7399 QWidget *parent = new QWidget;
7401 QSizePolicy sp = QSizePolicy(QSizePolicy::Policy(hPolicy), QSizePolicy::Policy(vPolicy));
7402 sp.setHeightForWidth(hfwSP);
7404 QWidget *child = new ASWidget(sizeHint, sp, layout, hfwLayout, haveParent ? parent : 0);
7405 child->resize(123, 456);
7406 child->adjustSize();
7407 if (expectedSize == QSize(100000, 100000)) {
7408 QVERIFY(child->size().width() < sizeHint.width());
7409 QVERIFY(child->size().height() < sizeHint.height());
7411 #if defined (Q_OS_WINCE)
7413 const QRect& desktopRect = qApp->desktop()->availableGeometry();
7414 expectedSize.setWidth(qMin(expectedSize.width(), desktopRect.width()));
7415 expectedSize.setHeight(qMin(expectedSize.height(), desktopRect.height()));
7418 QCOMPARE(child->size(), expectedSize);
7424 class TestLayout : public QVBoxLayout
7428 TestLayout(QWidget *w = 0) : QVBoxLayout(w)
7430 invalidated = false;
7441 void tst_QWidget::updateGeometry_data()
7443 QTest::addColumn<QSize>("minSize");
7444 QTest::addColumn<bool>("shouldInvalidate");
7445 QTest::addColumn<QSize>("maxSize");
7446 QTest::addColumn<bool>("shouldInvalidate2");
7447 QTest::addColumn<int>("verticalSizePolicy");
7448 QTest::addColumn<bool>("shouldInvalidate3");
7449 QTest::addColumn<bool>("setVisible");
7450 QTest::addColumn<bool>("shouldInvalidate4");
7452 QTest::newRow("setMinimumSize")
7453 << QSize(100, 100) << true
7455 << int(QSizePolicy::Preferred) << false
7457 QTest::newRow("setMaximumSize")
7459 << QSize(100, 100) << true
7460 << int(QSizePolicy::Preferred) << false
7462 QTest::newRow("setMinimumSize, then maximumSize to a different size")
7463 << QSize(100, 100) << true
7464 << QSize(300, 300) << true
7465 << int(QSizePolicy::Preferred) << false
7467 QTest::newRow("setMinimumSize, then maximumSize to the same size")
7468 << QSize(100, 100) << true
7469 << QSize(100, 100) << true
7470 << int(QSizePolicy::Preferred) << false
7472 QTest::newRow("setMinimumSize, then maximumSize to the same size and then hide it")
7473 << QSize(100, 100) << true
7474 << QSize(100, 100) << true
7475 << int(QSizePolicy::Preferred) << false
7477 QTest::newRow("Change sizePolicy")
7480 << int(QSizePolicy::Minimum) << true
7485 void tst_QWidget::updateGeometry()
7487 QFETCH(QSize, minSize);
7488 QFETCH(bool, shouldInvalidate);
7489 QFETCH(QSize, maxSize);
7490 QFETCH(bool, shouldInvalidate2);
7491 QFETCH(int, verticalSizePolicy);
7492 QFETCH(bool, shouldInvalidate3);
7493 QFETCH(bool, setVisible);
7494 QFETCH(bool, shouldInvalidate4);
7496 parent.resize(200, 200);
7497 TestLayout *lout = new TestLayout();
7498 parent.setLayout(lout);
7499 QWidget *child = new QWidget(&parent);
7500 lout->addWidget(child);
7502 QApplication::processEvents();
7504 lout->invalidated = false;
7505 if (minSize.isValid())
7506 child->setMinimumSize(minSize);
7507 QCOMPARE(lout->invalidated, shouldInvalidate);
7509 lout->invalidated = false;
7510 if (maxSize.isValid())
7511 child->setMaximumSize(maxSize);
7512 QCOMPARE(lout->invalidated, shouldInvalidate2);
7514 lout->invalidated = false;
7515 child->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, (QSizePolicy::Policy)verticalSizePolicy));
7516 if (shouldInvalidate3)
7517 QCOMPARE(lout->invalidated, true);
7519 lout->invalidated = false;
7521 child->setVisible(false);
7522 QCOMPARE(lout->invalidated, shouldInvalidate4);
7525 void tst_QWidget::sendUpdateRequestImmediately()
7527 UpdateWidget updateWidget;
7528 updateWidget.show();
7530 qt_x11_wait_for_window_manager(&updateWidget);
7533 qApp->processEvents();
7535 QApplication::sendPostedEvents(); //glib workaround
7537 updateWidget.reset();
7539 QCOMPARE(updateWidget.numUpdateRequestEvents, 0);
7540 updateWidget.repaint();
7541 QCOMPARE(updateWidget.numUpdateRequestEvents, 1);
7544 // 4DWM issues on IRIX makes this test fail.
7546 void tst_QWidget::doubleRepaint()
7548 #if defined(Q_OS_MAC)
7549 if (!macHasAccessToWindowsServer())
7550 QSKIP("Not having window server access causes the wrong number of repaints to be issues");
7552 UpdateWidget widget;
7553 widget.setFocusPolicy(Qt::StrongFocus);
7554 // Filter out activation change and focus events to avoid update() calls in QWidget.
7555 widget.updateOnActivationChangeAndFocusIn = false;
7558 int expectedRepaints = 1;
7560 QTest::qWaitForWindowShown(&widget);
7562 QTRY_COMPARE(widget.numPaintEvents, expectedRepaints);
7563 widget.numPaintEvents = 0;
7565 // Minmize: Should not trigger a repaint.
7566 widget.showMinimized();
7568 QCOMPARE(widget.numPaintEvents, 0);
7569 widget.numPaintEvents = 0;
7571 // Restore: Should not trigger a repaint.
7572 widget.showNormal();
7573 QTest::qWaitForWindowShown(&widget);
7575 QCOMPARE(widget.numPaintEvents, 0);
7579 void tst_QWidget::resizeInPaintEvent()
7582 UpdateWidget widget(&window);
7584 QTest::qWaitForWindowShown(&window);
7585 QTRY_VERIFY(widget.numPaintEvents > 0);
7588 QCOMPARE(widget.numPaintEvents, 0);
7590 widget.resizeInPaintEvent = true;
7591 // This will call resize in the paintEvent, which in turn will call
7592 // invalidateBuffer() and a new update request should be posted.
7594 QCOMPARE(widget.numPaintEvents, 1);
7595 widget.numPaintEvents = 0;
7598 // Make sure the resize triggers another update.
7599 QTRY_COMPARE(widget.numPaintEvents, 1);
7602 void tst_QWidget::opaqueChildren()
7605 widget.resize(200, 200);
7607 QWidget child(&widget);
7608 child.setGeometry(-700, -700, 200, 200);
7610 QWidget grandChild(&child);
7611 grandChild.resize(200, 200);
7613 QWidget greatGrandChild(&grandChild);
7614 greatGrandChild.setGeometry(50, 50, 200, 200);
7615 greatGrandChild.setPalette(Qt::red);
7616 greatGrandChild.setAutoFillBackground(true); // Opaque child widget.
7620 qt_x11_wait_for_window_manager(&widget);
7624 // Child, grandChild and greatGrandChild are outside the ancestor clip.
7625 QRegion expectedOpaqueRegion(50, 50, 150, 150);
7626 QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion);
7628 // Now they are all inside the ancestor clip.
7629 child.setGeometry(50, 50, 150, 150);
7630 QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion);
7632 // Set mask on greatGrandChild.
7633 const QRegion mask(10, 10, 50, 50);
7634 greatGrandChild.setMask(mask);
7635 expectedOpaqueRegion &= mask.translated(50, 50);
7636 QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion);
7638 // Make greatGrandChild "transparent".
7639 greatGrandChild.setAutoFillBackground(false);
7640 QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), QRegion());
7644 class MaskSetWidget : public QWidget
7648 MaskSetWidget(QWidget* p =0)
7651 void paintEvent(QPaintEvent* event) {
7654 paintedRegion += event->region();
7655 foreach(QRect r, event->region().rects())
7656 p.fillRect(r, Qt::red);
7659 void resizeEvent(QResizeEvent*) {
7660 setMask(QRegion(QRect(0, 0, width(), 10).normalized()));
7663 QRegion paintedRegion;
7667 setGeometry(QRect(0, 50, 50, 50));
7671 setGeometry(QRect(0, 50, 150, 50));
7676 void tst_QWidget::setMaskInResizeEvent()
7681 w.setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
7684 MaskSetWidget testWidget(&w);
7685 testWidget.setGeometry(0, 0, 100, 100);
7686 testWidget.setMask(QRegion(QRect(0,0,100,10)));
7689 QTest::qWaitForWindowShown(&w);
7691 QTRY_VERIFY(w.numPaintEvents > 0);
7694 testWidget.paintedRegion = QRegion();
7695 QTimer::singleShot(0, &testWidget, SLOT(resizeDown()));
7698 QRegion expectedParentUpdate(0, 0, 100, 10); // Old testWidget area.
7699 expectedParentUpdate += testWidget.geometry(); // New testWidget area.
7700 QCOMPARE(w.paintedRegion, expectedParentUpdate);
7701 QCOMPARE(testWidget.paintedRegion, testWidget.mask());
7703 testWidget.paintedRegion = QRegion();
7704 // Now resize the widget again, but in the oposite direction
7705 QTimer::singleShot(0, &testWidget, SLOT(resizeUp()));
7708 QTRY_COMPARE(testWidget.paintedRegion, testWidget.mask());
7711 class MoveInResizeWidget : public QWidget
7715 MoveInResizeWidget(QWidget* p = 0)
7718 setWindowFlags(Qt::FramelessWindowHint);
7721 void resizeEvent(QResizeEvent*) {
7723 move(QPoint(100,100));
7725 static bool firstTime = true;
7727 QTimer::singleShot(250, this, SLOT(resizeMe()));
7738 void tst_QWidget::moveInResizeEvent()
7740 MoveInResizeWidget testWidget;
7741 testWidget.setGeometry(50, 50, 200, 200);
7743 QTest::qWaitForWindowShown(&testWidget);
7746 QRect expectedGeometry(100,100, 100, 100);
7747 QTRY_COMPARE(testWidget.geometry(), expectedGeometry);
7751 #if defined(Q_WS_WIN) || defined(Q_WS_X11)
7752 void tst_QWidget::immediateRepaintAfterShow()
7754 UpdateWidget widget;
7756 qApp->processEvents();
7757 // On X11 in particular, we are now waiting for a MapNotify event before
7758 // syncing the backing store. However, if someone request a repaint()
7759 // we must repaint immediately regardless of the current state.
7760 widget.numPaintEvents = 0;
7762 QCOMPARE(widget.numPaintEvents, 1);
7765 void tst_QWidget::immediateRepaintAfterInvalidateBuffer()
7767 QWidget *widget = new UpdateWidget;
7770 qt_x11_wait_for_window_manager(widget);
7774 static_cast<UpdateWidget *>(widget)->numPaintEvents = 0;
7776 // Marks the area covered by the widget as dirty in the backing store and
7777 // posts an UpdateRequest event.
7778 qt_widget_private(widget)->invalidateBuffer(widget->rect());
7779 QCOMPARE(static_cast<UpdateWidget *>(widget)->numPaintEvents, 0);
7781 // The entire widget is already dirty, but this time we want to update immediately
7782 // by calling repaint(), and thus we have to repaint the widget and not wait for
7783 // the UpdateRequest to be sent when we get back to the event loop.
7785 QCOMPARE(static_cast<UpdateWidget *>(widget)->numPaintEvents, 1);
7791 void tst_QWidget::effectiveWinId()
7794 QWidget child(&parent);
7797 QVERIFY(!parent.effectiveWinId());
7798 QVERIFY(!child.effectiveWinId());
7802 QVERIFY(parent.effectiveWinId());
7803 QVERIFY(child.effectiveWinId());
7806 void tst_QWidget::effectiveWinId2()
7810 class MyWidget : public QWidget {
7811 bool event(QEvent *e)
7813 if (e->type() == QEvent::WinIdChange) {
7818 return QWidget::event(e);
7823 child.setParent(&parent);
7827 child.setParent(&parent);
7830 class CustomWidget : public QWidget
7833 mutable int metricCallCount;
7835 CustomWidget(QWidget *parent = 0) : QWidget(parent), metricCallCount(0) {}
7837 virtual int metric(PaintDeviceMetric metric) const {
7839 return QWidget::metric(metric);
7843 void tst_QWidget::customDpi()
7845 QWidget *topLevel = new QWidget;
7846 CustomWidget *custom = new CustomWidget(topLevel);
7847 QWidget *child = new QWidget(custom);
7849 custom->metricCallCount = 0;
7850 topLevel->logicalDpiX();
7851 QCOMPARE(custom->metricCallCount, 0);
7852 custom->logicalDpiX();
7853 QCOMPARE(custom->metricCallCount, 1);
7854 child->logicalDpiX();
7855 QCOMPARE(custom->metricCallCount, 2);
7860 void tst_QWidget::customDpiProperty()
7862 QWidget *topLevel = new QWidget;
7863 QWidget *middle = new CustomWidget(topLevel);
7864 QWidget *child = new QWidget(middle);
7866 const int initialDpiX = topLevel->logicalDpiX();
7867 const int initialDpiY = topLevel->logicalDpiY();
7869 middle->setProperty("_q_customDpiX", 300);
7870 middle->setProperty("_q_customDpiY", 400);
7872 QCOMPARE(topLevel->logicalDpiX(), initialDpiX);
7873 QCOMPARE(topLevel->logicalDpiY(), initialDpiY);
7875 QCOMPARE(middle->logicalDpiX(), 300);
7876 QCOMPARE(middle->logicalDpiY(), 400);
7878 QCOMPARE(child->logicalDpiX(), 300);
7879 QCOMPARE(child->logicalDpiY(), 400);
7881 middle->setProperty("_q_customDpiX", QVariant());
7882 middle->setProperty("_q_customDpiY", QVariant());
7884 QCOMPARE(topLevel->logicalDpiX(), initialDpiX);
7885 QCOMPARE(topLevel->logicalDpiY(), initialDpiY);
7887 QCOMPARE(middle->logicalDpiX(), initialDpiX);
7888 QCOMPARE(middle->logicalDpiY(), initialDpiY);
7890 QCOMPARE(child->logicalDpiX(), initialDpiX);
7891 QCOMPARE(child->logicalDpiY(), initialDpiY);
7896 void tst_QWidget::quitOnCloseAttribute()
7899 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), true);
7900 w.setAttribute(Qt::WA_QuitOnClose, false);
7901 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
7903 w.setAttribute(Qt::WA_QuitOnClose);
7904 w.setWindowFlags(Qt::Tool);
7905 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
7907 w.setAttribute(Qt::WA_QuitOnClose);
7908 w.setWindowFlags(Qt::Popup);
7909 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
7911 w.setAttribute(Qt::WA_QuitOnClose);
7912 w.setWindowFlags(Qt::ToolTip);
7913 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
7915 w.setAttribute(Qt::WA_QuitOnClose);
7916 w.setWindowFlags(Qt::SplashScreen);
7917 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
7919 w.setAttribute(Qt::WA_QuitOnClose);
7920 w.setWindowFlags(Qt::SubWindow);
7921 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
7923 w.setAttribute(Qt::WA_QuitOnClose);
7924 w.setWindowFlags(Qt::Dialog);
7925 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), true);
7927 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), true);
7928 w.setWindowFlags(Qt::Tool);
7929 QCOMPARE(w.testAttribute(Qt::WA_QuitOnClose), false);
7932 void tst_QWidget::moveRect()
7935 widget.setUpdatesEnabled(false);
7936 QWidget child(&widget);
7937 child.setUpdatesEnabled(false);
7938 child.setAttribute(Qt::WA_OpaquePaintEvent);
7941 child.move(10, 10); // Don't crash.
7945 class GDIWidget : public QDialog
7948 GDIWidget() { setAttribute(Qt::WA_PaintOnScreen); }
7949 QPaintEngine *paintEngine() const { return 0; }
7952 void paintEvent(QPaintEvent *) {
7954 SelectObject(hdc, CreateSolidBrush(RGB(255, 0, 0)));
7955 Rectangle(hdc, 0, 0, 10, 10);
7959 QImage im = QPixmap::grabWindow(winId(), 0, 0, width(), height()).toImage();
7960 color = im.pixel(1, 1);
7965 QSize sizeHint() const {
7966 return QSize(400, 300);
7972 void tst_QWidget::gdiPainting()
7977 QCOMPARE(w.color, QColor(255, 0, 0));
7981 void tst_QWidget::paintOnScreenPossible()
7984 w1.setAttribute(Qt::WA_PaintOnScreen);
7985 QVERIFY(!w1.testAttribute(Qt::WA_PaintOnScreen));
7988 w2.setAttribute(Qt::WA_PaintOnScreen);
7989 QVERIFY(w2.testAttribute(Qt::WA_PaintOnScreen));
7993 void tst_QWidget::reparentStaticWidget()
7997 QWidget *child = new QWidget(&window1);
7998 child->setPalette(Qt::red);
7999 child->setAutoFillBackground(true);
8000 child->setAttribute(Qt::WA_StaticContents);
8001 child->resize(100, 100);
8003 QWidget *grandChild = new QWidget(child);
8004 grandChild->setPalette(Qt::blue);
8005 grandChild->setAutoFillBackground(true);
8006 grandChild->resize(50, 50);
8007 grandChild->setAttribute(Qt::WA_StaticContents);
8009 QTest::qWaitForWindowShown(&window1);
8013 QTest::qWaitForWindowShown(&window2);
8016 // Reparent into another top-level.
8017 child->setParent(&window2);
8020 // Please don't crash.
8021 window1.resize(window1.size() + QSize(2, 2));
8024 // Make sure we move all static children even though
8025 // the reparented widget itself is non-static.
8026 child->setAttribute(Qt::WA_StaticContents, false);
8027 child->setParent(&window1);
8030 // Please don't crash.
8031 window2.resize(window2.size() + QSize(2, 2));
8034 child->setParent(0);
8038 // Please don't crash.
8039 child->resize(child->size() + QSize(2, 2));
8040 window2.resize(window2.size() + QSize(2, 2));
8043 QWidget *siblingOfGrandChild = new QWidget(child);
8044 siblingOfGrandChild->show();
8047 // Nothing should happen when reparenting within the same top-level.
8048 grandChild->setParent(siblingOfGrandChild);
8052 QWidget paintOnScreen;
8053 paintOnScreen.setAttribute(Qt::WA_PaintOnScreen);
8054 paintOnScreen.show();
8055 QTest::qWaitForWindowShown(&paintOnScreen);
8058 child->setParent(&paintOnScreen);
8062 // Please don't crash.
8063 paintOnScreen.resize(paintOnScreen.size() + QSize(2, 2));
8068 void tst_QWidget::QTBUG6883_reparentStaticWidget2()
8071 QDockWidget *one = new QDockWidget("one", &mw);
8072 mw.addDockWidget(Qt::LeftDockWidgetArea, one , Qt::Vertical);
8074 QWidget *child = new QWidget();
8075 child->setPalette(Qt::red);
8076 child->setAutoFillBackground(true);
8077 child->setAttribute(Qt::WA_StaticContents);
8078 child->resize(100, 100);
8079 one->setWidget(child);
8081 QToolBar *mainTools = mw.addToolBar("Main Tools");
8082 mainTools->addWidget(new QLineEdit);
8085 QTest::qWaitForWindowShown(&mw);
8087 one->setFloating(true);
8093 void tst_QWidget::updateOutsideSurfaceClip()
8095 UpdateWidget widget;
8096 widget.setWindowFlags(Qt::FramelessWindowHint);
8097 widget.resize(100, 100);
8103 // Move widget partially outside buffer and change the surface clip.
8104 widget.move(-50, 0);
8107 // Update region is outside the surface clip and should not trigger a repaint.
8108 widget.update(0, 0, 20, 20);
8110 QCOMPARE(widget.numPaintEvents, 0);
8112 // Now, move the widget back so that the update region is inside the clip
8113 // and make sure we get a repaint of the dirty area.
8116 QCOMPARE(widget.numPaintEvents, 1);
8117 QCOMPARE(widget.paintedRegion, QRegion(0, 0, 20, 20));
8120 class ColorRedWidget : public QWidget
8123 ColorRedWidget(QWidget *parent = 0)
8124 : QWidget(parent, Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::ToolTip)
8128 void paintEvent(QPaintEvent *) {
8130 p.fillRect(rect(),Qt::red);
8134 void tst_QWidget::translucentWidget()
8138 ColorRedWidget label;
8139 label.setFixedSize(16,16);
8140 label.setAttribute(Qt::WA_TranslucentBackground);
8141 label.move(qApp->desktop()->availableGeometry().topLeft());
8144 qt_x11_wait_for_window_manager(&label);
8148 QPixmap widgetSnapshot;
8151 QWidget *desktopWidget = QApplication::desktop()->screen(0);
8152 if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA)
8153 widgetSnapshot = QPixmap::grabWindow(desktopWidget->winId(), 0,0, label.width(), label.height());
8156 widgetSnapshot = QPixmap::grabWindow(label.winId());
8157 QImage actual = widgetSnapshot.toImage().convertToFormat(QImage::Format_RGB32);
8158 QImage expected = pm.toImage().convertToFormat(QImage::Format_RGB32);
8159 QCOMPARE(actual.size(),expected.size());
8160 QCOMPARE(actual,expected);
8163 class MaskResizeTestWidget : public QWidget
8167 MaskResizeTestWidget(QWidget* p =0)
8169 setMask(QRegion(QRect(0, 0, 100, 100).normalized()));
8172 void paintEvent(QPaintEvent* event) {
8175 paintedRegion += event->region();
8176 foreach(QRect r, event->region().rects())
8177 p.fillRect(r, Qt::red);
8180 QRegion paintedRegion;
8183 void enlargeMask() {
8184 QRegion newMask(QRect(0, 0, 150, 150).normalized());
8189 QRegion newMask(QRect(0, 0, 50, 50).normalized());
8195 void tst_QWidget::setClearAndResizeMask()
8197 UpdateWidget topLevel;
8198 topLevel.resize(150, 150);
8200 QTest::qWaitForWindowShown(&topLevel);
8201 QTRY_VERIFY(topLevel.numPaintEvents > 0);
8204 // Mask top-level widget
8205 const QRegion topLevelMask(0, 0, 100, 100, QRegion::Ellipse);
8206 topLevel.setMask(topLevelMask);
8207 QCOMPARE(topLevel.mask(), topLevelMask);
8208 #if defined(Q_WS_WIN) || defined(Q_WS_X11) // We don't control what's happening on other platforms.
8209 // and ensure that the top-level doesn't get any update.
8210 QCOMPARE(topLevel.numPaintEvents, 0);
8215 // Clear top-level mask
8216 topLevel.clearMask();
8217 QCOMPARE(topLevel.mask(), QRegion());
8219 QRegion outsideOldMask(topLevel.rect());
8220 outsideOldMask -= topLevelMask;
8221 #if defined(Q_WS_WIN) || defined(Q_WS_X11) // We don't control what's happening on other platforms.
8222 // and ensure that the top-level gets an update for the area outside the old mask.
8223 QTRY_VERIFY(topLevel.numPaintEvents > 0);
8224 QTRY_COMPARE(topLevel.paintedRegion, outsideOldMask);
8227 UpdateWidget child(&topLevel);
8228 child.setAutoFillBackground(true); // NB! Opaque child.
8229 child.setPalette(Qt::red);
8230 child.resize(100, 100);
8237 // Mask child widget with a mask that is smaller than the rect
8238 const QRegion childMask(0, 0, 50, 50);
8239 child.setMask(childMask);
8240 QTRY_COMPARE(child.mask(), childMask);
8242 // and ensure that the child widget doesn't get any update.
8244 // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
8245 if (child.internalWinId())
8246 QCOMPARE(child.numPaintEvents, 1);
8249 QCOMPARE(child.numPaintEvents, 0);
8250 // and the parent widget gets an update for the newly exposed area.
8251 QTRY_COMPARE(topLevel.numPaintEvents, 1);
8252 QRegion expectedParentExpose(child.rect());
8253 expectedParentExpose -= childMask;
8254 QCOMPARE(topLevel.paintedRegion, expectedParentExpose);
8259 // Clear child widget mask
8261 QTRY_COMPARE(child.mask(), QRegion());
8263 // and ensure that that the child widget gets an update for the area outside the old mask.
8264 QTRY_COMPARE(child.numPaintEvents, 1);
8265 outsideOldMask = child.rect();
8267 // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
8268 if (!child.internalWinId())
8270 outsideOldMask -= childMask;
8271 QCOMPARE(child.paintedRegion, outsideOldMask);
8272 // and the parent widget doesn't get any update.
8273 QCOMPARE(topLevel.numPaintEvents, 0);
8278 // Mask child widget with a mask that is bigger than the rect
8279 child.setMask(QRegion(0, 0, 1000, 1000));
8282 // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
8283 if (child.internalWinId())
8284 QTRY_COMPARE(child.numPaintEvents, 1);
8287 // and ensure that we don't get any updates at all.
8288 QTRY_COMPARE(child.numPaintEvents, 0);
8289 QCOMPARE(topLevel.numPaintEvents, 0);
8291 // ...and the same applies when clearing the mask.
8295 // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
8296 if (child.internalWinId())
8297 QTRY_VERIFY(child.numPaintEvents > 0);
8300 QCOMPARE(child.numPaintEvents, 0);
8301 QCOMPARE(topLevel.numPaintEvents, 0);
8303 QWidget resizeParent;
8304 MaskResizeTestWidget resizeChild(&resizeParent);
8306 resizeParent.resize(300,300);
8307 resizeParent.raise();
8308 resizeParent.setWindowFlags(Qt::WindowStaysOnTopHint);
8309 resizeChild.setGeometry(50,50,200,200);
8310 QPalette pal = resizeParent.palette();
8311 pal.setColor(QPalette::Window, QColor(Qt::white));
8312 resizeParent.setPalette(pal);
8314 resizeParent.show();
8315 QTest::qWaitForWindowShown(&resizeParent);
8316 // Disable the size grip on the Mac; otherwise it'll be included when grabbing the window.
8317 resizeParent.setFixedSize(resizeParent.size());
8320 resizeChild.paintedRegion = QRegion();
8322 QTimer::singleShot(100, &resizeChild, SLOT(shrinkMask()));
8325 // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
8326 if (child.internalWinId())
8327 QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask());
8330 QTRY_COMPARE(resizeChild.paintedRegion, QRegion());
8332 resizeChild.paintedRegion = QRegion();
8333 const QRegion oldMask = resizeChild.mask();
8334 QTimer::singleShot(0, &resizeChild, SLOT(enlargeMask()));
8337 // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
8338 if (child.internalWinId())
8339 QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask());
8342 QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask() - oldMask);
8345 void tst_QWidget::maskedUpdate()
8347 UpdateWidget topLevel;
8348 topLevel.resize(200, 200);
8349 const QRegion topLevelMask(50, 50, 70, 70);
8350 topLevel.setMask(topLevelMask);
8352 UpdateWidget child(&topLevel);
8353 child.setGeometry(20, 20, 180, 180);
8354 const QRegion childMask(60, 60, 30, 30);
8355 child.setMask(childMask);
8357 UpdateWidget grandChild(&child);
8358 grandChild.setGeometry(50, 50, 100, 100);
8359 const QRegion grandChildMask(20, 20, 10, 10);
8360 grandChild.setMask(grandChildMask);
8363 QTest::qWaitForWindowShown(&topLevel);
8364 QTRY_VERIFY(topLevel.numPaintEvents > 0);
8367 #define RESET_WIDGETS \
8372 #define CLEAR_MASK(widget) \
8373 widget.clearMask(); \
8374 QTest::qWait(100); \
8377 // All widgets are transparent at this point, so any call to update() will result
8378 // in composition, i.e. the update propagates to ancestors and children.
8385 QTRY_COMPARE(topLevel.paintedRegion, topLevelMask);
8386 QTRY_COMPARE(child.paintedRegion, childMask);
8387 QTRY_COMPARE(grandChild.paintedRegion, grandChildMask);
8394 QTRY_COMPARE(topLevel.paintedRegion, childMask.translated(child.pos()));
8395 QTRY_COMPARE(child.paintedRegion, childMask);
8396 QTRY_COMPARE(grandChild.paintedRegion, grandChildMask);
8398 // GrandChild update.
8400 grandChild.update();
8403 QTRY_COMPARE(topLevel.paintedRegion, grandChildMask.translated(grandChild.mapTo(&topLevel, QPoint())));
8404 QTRY_COMPARE(child.paintedRegion, grandChildMask.translated(grandChild.pos()));
8405 QTRY_COMPARE(grandChild.paintedRegion, grandChildMask);
8407 topLevel.setAttribute(Qt::WA_OpaquePaintEvent);
8408 child.setAttribute(Qt::WA_OpaquePaintEvent);
8409 grandChild.setAttribute(Qt::WA_OpaquePaintEvent);
8411 // All widgets are now opaque, which means no composition, i.e.
8412 // the update does not propate to ancestors and children.
8419 QRegion expectedTopLevelUpdate = topLevelMask;
8420 expectedTopLevelUpdate -= childMask.translated(child.pos()); // Subtract opaque children.
8421 QTRY_COMPARE(topLevel.paintedRegion, expectedTopLevelUpdate);
8422 QTRY_COMPARE(child.paintedRegion, QRegion());
8423 QTRY_COMPARE(grandChild.paintedRegion, QRegion());
8430 QTRY_COMPARE(topLevel.paintedRegion, QRegion());
8431 QRegion expectedChildUpdate = childMask;
8432 expectedChildUpdate -= grandChildMask.translated(grandChild.pos()); // Subtract oapque children.
8433 QTRY_COMPARE(child.paintedRegion, expectedChildUpdate);
8434 QTRY_COMPARE(grandChild.paintedRegion, QRegion());
8436 // GrandChild update.
8438 grandChild.update();
8441 QTRY_COMPARE(topLevel.paintedRegion, QRegion());
8442 QTRY_COMPARE(child.paintedRegion, QRegion());
8443 QTRY_COMPARE(grandChild.paintedRegion, grandChildMask);
8445 // GrandChild update.
8446 CLEAR_MASK(grandChild);
8447 grandChild.update();
8450 QTRY_COMPARE(topLevel.paintedRegion, QRegion());
8451 QTRY_COMPARE(child.paintedRegion, QRegion());
8452 QRegion expectedGrandChildUpdate = grandChild.rect();
8453 // Clip with parent's mask.
8454 expectedGrandChildUpdate &= childMask.translated(-grandChild.pos());
8455 QCOMPARE(grandChild.paintedRegion, expectedGrandChildUpdate);
8457 // GrandChild update.
8459 grandChild.update();
8462 QTRY_COMPARE(topLevel.paintedRegion, QRegion());
8463 QTRY_COMPARE(child.paintedRegion, QRegion());
8464 expectedGrandChildUpdate = grandChild.rect();
8465 // Clip with parent's mask.
8466 expectedGrandChildUpdate &= topLevelMask.translated(-grandChild.mapTo(&topLevel, QPoint()));
8467 QTRY_COMPARE(grandChild.paintedRegion, expectedGrandChildUpdate);
8474 QTRY_COMPARE(topLevel.paintedRegion, QRegion());
8475 expectedChildUpdate = child.rect();
8476 // Clip with parent's mask.
8477 expectedChildUpdate &= topLevelMask.translated(-child.pos());
8478 expectedChildUpdate -= grandChild.geometry(); // Subtract opaque children.
8479 QTRY_COMPARE(child.paintedRegion, expectedChildUpdate);
8480 QTRY_COMPARE(grandChild.paintedRegion, QRegion());
8482 // GrandChild update.
8483 CLEAR_MASK(topLevel);
8484 grandChild.update();
8487 QTRY_COMPARE(topLevel.paintedRegion, QRegion());
8488 QTRY_COMPARE(child.paintedRegion, QRegion());
8489 QTRY_COMPARE(grandChild.paintedRegion, QRegion(grandChild.rect())); // Full update.
8492 // Windows Mobile has no proper cursor support, so skip this test on that platform.
8493 #if !defined(Q_OS_WINCE_WM)
8494 void tst_QWidget::syntheticEnterLeave()
8496 class MyWidget : public QWidget
8499 MyWidget(QWidget *parent = 0) : QWidget(parent), numEnterEvents(0), numLeaveEvents(0) {}
8500 void enterEvent(QEvent *) { ++numEnterEvents; }
8501 void leaveEvent(QEvent *) { ++numLeaveEvents; }
8506 QCursor::setPos(QPoint(0,0));
8509 window.setWindowFlags(Qt::WindowStaysOnTopHint);
8510 window.resize(200, 200);
8512 MyWidget *child1 = new MyWidget(&window);
8513 child1->setPalette(Qt::blue);
8514 child1->setAutoFillBackground(true);
8515 child1->resize(200, 200);
8516 child1->setCursor(Qt::OpenHandCursor);
8518 MyWidget *child2 = new MyWidget(&window);
8519 child2->resize(200, 200);
8521 MyWidget *grandChild = new MyWidget(child2);
8522 grandChild->setPalette(Qt::red);
8523 grandChild->setAutoFillBackground(true);
8524 grandChild->resize(200, 200);
8525 grandChild->setCursor(Qt::WaitCursor);
8530 qt_x11_wait_for_window_manager(&window);
8534 #define RESET_EVENT_COUNTS \
8535 window.numEnterEvents = 0; \
8536 window.numLeaveEvents = 0; \
8537 child1->numEnterEvents = 0; \
8538 child1->numLeaveEvents = 0; \
8539 child2->numEnterEvents = 0; \
8540 child2->numLeaveEvents = 0; \
8541 grandChild->numEnterEvents = 0; \
8542 grandChild->numLeaveEvents = 0;
8544 // Position the cursor in the middle of the window.
8545 const QPoint globalPos = window.mapToGlobal(QPoint(100, 100));
8546 QCursor::setPos(globalPos); // Enter child2 and grandChild.
8549 QCOMPARE(window.numLeaveEvents, 0);
8550 QCOMPARE(child2->numLeaveEvents, 0);
8551 QCOMPARE(grandChild->numLeaveEvents, 0);
8552 QCOMPARE(child1->numLeaveEvents, 0);
8554 // This event arrives asynchronously
8555 QTRY_COMPARE(window.numEnterEvents, 1);
8556 QCOMPARE(child2->numEnterEvents, 1);
8557 QCOMPARE(grandChild->numEnterEvents, 1);
8558 QCOMPARE(child1->numEnterEvents, 0);
8561 child2->hide(); // Leave child2 and grandChild, enter child1.
8563 QCOMPARE(window.numLeaveEvents, 0);
8564 QCOMPARE(child2->numLeaveEvents, 1);
8565 QCOMPARE(grandChild->numLeaveEvents, 1);
8566 QCOMPARE(child1->numLeaveEvents, 0);
8568 QCOMPARE(window.numEnterEvents, 0);
8569 QCOMPARE(child2->numEnterEvents, 0);
8570 QCOMPARE(grandChild->numEnterEvents, 0);
8571 QCOMPARE(child1->numEnterEvents, 1);
8574 child2->show(); // Leave child1, enter child2 and grandChild.
8576 QCOMPARE(window.numLeaveEvents, 0);
8577 QCOMPARE(child2->numLeaveEvents, 0);
8578 QCOMPARE(grandChild->numLeaveEvents, 0);
8579 QCOMPARE(child1->numLeaveEvents, 1);
8581 QCOMPARE(window.numEnterEvents, 0);
8582 QCOMPARE(child2->numEnterEvents, 1);
8583 QCOMPARE(grandChild->numEnterEvents, 1);
8584 QCOMPARE(child1->numEnterEvents, 0);
8587 delete child2; // Enter child1 (and do not send leave events to child2 and grandChild).
8589 QCOMPARE(window.numLeaveEvents, 0);
8590 QCOMPARE(child1->numLeaveEvents, 0);
8592 QCOMPARE(window.numEnterEvents, 0);
8593 QCOMPARE(child1->numEnterEvents, 1);
8597 // Windows Mobile has no proper cursor support, so skip this test on that platform.
8598 #if !defined(Q_OS_WINCE_WM)
8599 void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
8601 class SELParent : public QWidget
8604 SELParent(QWidget *parent = 0): QWidget(parent) { }
8606 void mousePressEvent(QMouseEvent *) { child->show(); }
8610 class SELChild : public QWidget
8613 SELChild(QWidget *parent = 0) : QWidget(parent), numEnterEvents(0), numMouseMoveEvents(0) {}
8614 void enterEvent(QEvent *) { ++numEnterEvents; }
8615 void mouseMoveEvent(QMouseEvent *event)
8617 QCOMPARE(event->button(), Qt::NoButton);
8618 QCOMPARE(event->buttons(), Qt::MouseButtons(Qt::NoButton));
8619 ++numMouseMoveEvents;
8621 void reset() { numEnterEvents = numMouseMoveEvents = 0; }
8622 int numEnterEvents, numMouseMoveEvents;
8625 QCursor::setPos(QPoint(0,0));
8628 parent.resize(200, 200);
8629 SELChild child(&parent);
8630 child.resize(200, 200);
8633 qt_x11_wait_for_window_manager(&parent);
8637 QCursor::setPos(child.mapToGlobal(QPoint(100, 100)));
8638 // Make sure the cursor has entered the child.
8639 QTRY_VERIFY(child.numEnterEvents > 0);
8645 // Make sure the child gets enter event and no mouse move event.
8646 QTRY_COMPARE(child.numEnterEvents, 1);
8647 QCOMPARE(child.numMouseMoveEvents, 0);
8651 child.setMouseTracking(true);
8654 // Make sure the child gets enter event and mouse move event.
8655 // Note that we verify event->button() and event->buttons()
8656 // in SELChild::mouseMoveEvent().
8657 QTRY_COMPARE(child.numEnterEvents, 1);
8658 QCOMPARE(child.numMouseMoveEvents, 1);
8660 // Sending synthetic enter/leave trough the parent's mousePressEvent handler.
8661 parent.child = &child;
8665 QTest::mouseClick(&parent, Qt::LeftButton);
8667 // Make sure the child gets enter event and one mouse move event.
8668 QTRY_COMPARE(child.numEnterEvents, 1);
8669 QCOMPARE(child.numMouseMoveEvents, 1);
8673 child.setMouseTracking(false);
8674 QTest::mouseClick(&parent, Qt::LeftButton);
8676 // Make sure the child gets enter event and no mouse move event.
8677 QTRY_COMPARE(child.numEnterEvents, 1);
8678 QCOMPARE(child.numMouseMoveEvents, 0);
8682 void tst_QWidget::windowFlags()
8685 w.setWindowFlags(w.windowFlags() | Qt::FramelessWindowHint);
8686 QVERIFY(w.windowFlags() & Qt::FramelessWindowHint);
8689 void tst_QWidget::initialPosForDontShowOnScreenWidgets()
8691 { // Check default position.
8692 const QPoint expectedPos(0, 0);
8694 widget.setAttribute(Qt::WA_DontShowOnScreen);
8695 widget.winId(); // Make sure create_sys is called.
8696 QCOMPARE(widget.pos(), expectedPos);
8697 QCOMPARE(widget.geometry().topLeft(), expectedPos);
8700 { // Explicitly move to a position.
8701 const QPoint expectedPos(100, 100);
8703 widget.setAttribute(Qt::WA_DontShowOnScreen);
8704 widget.move(expectedPos);
8705 widget.winId(); // Make sure create_sys is called.
8706 QCOMPARE(widget.pos(), expectedPos);
8707 QCOMPARE(widget.geometry().topLeft(), expectedPos);
8711 class MyEvilObject : public QObject
8715 MyEvilObject(QWidget *widgetToCrash) : QObject(), widget(widgetToCrash)
8717 connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(beEvil(QObject *)));
8723 void beEvil(QObject *) { widget->update(0, 0, 150, 150); }
8726 void tst_QWidget::updateOnDestroyedSignal()
8730 QWidget *child = new QWidget(&widget);
8731 child->resize(100, 100);
8732 child->setAutoFillBackground(true);
8733 child->setPalette(Qt::red);
8737 qt_x11_wait_for_window_manager(&widget);
8741 // Please do not crash.
8742 MyEvilObject evil(child);
8746 void tst_QWidget::toplevelLineEditFocus()
8752 QTest::qWaitForWindowShown(&w);
8755 QTRY_COMPARE(QApplication::activeWindow(), (QWidget*)&w);
8756 QTRY_COMPARE(QApplication::focusWidget(), (QWidget*)&w);
8759 void tst_QWidget::focusWidget_task254563()
8761 //having different visibility for widget is important
8764 QWidget container(&top);
8765 QWidget *widget = new QWidget(&container);
8768 widget->setFocus(); //set focus (will set the focus widget up to the toplevel to be 'widget')
8769 container.setFocus();
8770 delete widget; // will call clearFocus but that doesn't help
8771 QVERIFY(top.focusWidget() != widget); //dangling pointer
8774 // This test case relies on developer build (AUTOTEST_EXPORT).
8775 #ifdef QT_BUILD_INTERNAL
8776 void tst_QWidget::destroyBackingStore()
8782 QTest::qWaitForWindowShown(&w);
8783 QApplication::processEvents();
8784 QTRY_VERIFY(w.numPaintEvents > 0);
8787 qt_widget_private(&w)->topData()->backingStoreTracker.create(&w);
8790 QApplication::processEvents();
8792 QApplication::processEvents();
8794 QCOMPARE(w.numPaintEvents, 1);
8796 // Check one more time, because the second time around does more caching.
8798 QApplication::processEvents();
8799 QCOMPARE(w.numPaintEvents, 2);
8804 QWidgetBackingStore* backingStore(QWidget &widget)
8806 QWidgetBackingStore *backingStore = 0;
8807 #ifdef QT_BUILD_INTERNAL
8808 if (QTLWExtra *topExtra = qt_widget_private(&widget)->maybeTopData())
8809 backingStore = topExtra->backingStoreTracker.data();
8811 return backingStore;
8814 // Tables of 5000 elements do not make sense on Windows Mobile.
8815 #ifndef Q_OS_WINCE_WM
8816 void tst_QWidget::rectOutsideCoordinatesLimit_task144779()
8818 QApplication::setOverrideCursor(Qt::BlankCursor); //keep the cursor out of screen grabs
8819 QWidget main(0,Qt::FramelessWindowHint); //don't get confused by the size of the window frame
8821 palette.setColor(QPalette::Window, Qt::red);
8822 main.setPalette(palette);
8824 QDesktopWidget desktop;
8825 QRect desktopDimensions = desktop.availableGeometry(&main);
8826 QSize mainSize(400, 400);
8827 mainSize = mainSize.boundedTo(desktopDimensions.size());
8828 main.resize(mainSize);
8830 QWidget *offsetWidget = new QWidget(&main);
8831 offsetWidget->setGeometry(0, -(15000 - mainSize.height()), mainSize.width(), 15000);
8833 // big widget is too big for the coordinates, it must be limited by wrect
8834 // if wrect is not at the right position because of offsetWidget, bigwidget
8835 // is not painted correctly
8836 QWidget *bigWidget = new QWidget(offsetWidget);
8837 bigWidget->setGeometry(0, 0, mainSize.width(), 50000);
8838 palette.setColor(QPalette::Window, Qt::green);
8839 bigWidget->setPalette(palette);
8840 bigWidget->setAutoFillBackground(true);
8843 QTest::qWaitForWindowShown(&main);
8845 QPixmap correct(main.size());
8846 correct.fill(Qt::green);
8848 QTRY_COMPARE(QPixmap::grabWindow(main.winId()).toImage().convertToFormat(QImage::Format_RGB32),
8849 correct.toImage().convertToFormat(QImage::Format_RGB32));
8850 QApplication::restoreOverrideCursor();
8854 void tst_QWidget::inputFocus_task257832()
8856 QLineEdit *widget = new QLineEdit;
8858 widget->winId(); // make sure, widget has been created
8860 QTRY_VERIFY(widget->hasFocus());
8861 QCOMPARE(qApp->inputMethod()->inputItem(), static_cast<QWidget*>(widget));
8862 widget->setReadOnly(true);
8863 QVERIFY(!qApp->inputMethod()->inputItem());
8867 void tst_QWidget::setGraphicsEffect()
8869 // Check that we don't have any effect by default.
8870 QWidget *widget = new QWidget;
8871 QVERIFY(!widget->graphicsEffect());
8874 QPointer<QGraphicsEffect> blurEffect = new QGraphicsBlurEffect;
8875 widget->setGraphicsEffect(blurEffect);
8876 QCOMPARE(widget->graphicsEffect(), static_cast<QGraphicsEffect *>(blurEffect));
8878 // Ensure the existing effect is deleted when setting a new one.
8879 QPointer<QGraphicsEffect> shadowEffect = new QGraphicsDropShadowEffect;
8880 widget->setGraphicsEffect(shadowEffect);
8881 QVERIFY(!blurEffect);
8882 QCOMPARE(widget->graphicsEffect(), static_cast<QGraphicsEffect *>(shadowEffect));
8883 blurEffect = new QGraphicsBlurEffect;
8885 // Ensure the effect is uninstalled when setting it on a new target.
8886 QWidget *anotherWidget = new QWidget;
8887 anotherWidget->setGraphicsEffect(blurEffect);
8888 widget->setGraphicsEffect(blurEffect);
8889 QVERIFY(!anotherWidget->graphicsEffect());
8890 QVERIFY(!shadowEffect);
8892 // Ensure the existing effect is deleted when deleting the widget.
8894 QVERIFY(!blurEffect);
8895 delete anotherWidget;
8897 // Ensure the effect is uninstalled when deleting it
8898 widget = new QWidget;
8899 blurEffect = new QGraphicsBlurEffect;
8900 widget->setGraphicsEffect(blurEffect);
8902 QVERIFY(!widget->graphicsEffect());
8904 // Ensure the existing effect is uninstalled and deleted when setting a null effect
8905 blurEffect = new QGraphicsBlurEffect;
8906 widget->setGraphicsEffect(blurEffect);
8907 widget->setGraphicsEffect(0);
8908 QVERIFY(!widget->graphicsEffect());
8909 QVERIFY(!blurEffect);
8914 void tst_QWidget::activateWindow()
8916 // Test case for task 260685
8918 // Create first mainwindow and set it active
8919 QMainWindow* mainwindow = new QMainWindow();
8920 QLabel* label = new QLabel(mainwindow);
8921 mainwindow->setCentralWidget(label);
8922 mainwindow->setVisible(true);
8923 mainwindow->activateWindow();
8924 QTest::qWaitForWindowShown(mainwindow);
8925 qApp->processEvents();
8927 QTRY_VERIFY(mainwindow->isActiveWindow());
8929 // Create second mainwindow and set it active
8930 QMainWindow* mainwindow2 = new QMainWindow();
8931 QLabel* label2 = new QLabel(mainwindow2);
8932 mainwindow2->setCentralWidget(label2);
8933 mainwindow2->setVisible(true);
8934 mainwindow2->activateWindow();
8935 qApp->processEvents();
8937 QTRY_VERIFY(!mainwindow->isActiveWindow());
8938 QTRY_VERIFY(mainwindow2->isActiveWindow());
8940 // Revert first mainwindow back to visible active
8941 mainwindow->setVisible(true);
8942 mainwindow->activateWindow();
8943 qApp->processEvents();
8945 QTRY_VERIFY(mainwindow->isActiveWindow());
8946 QTRY_VERIFY(!mainwindow2->isActiveWindow());
8949 void tst_QWidget::openModal_taskQTBUG_5804()
8951 class Widget : public QWidget
8954 Widget(QWidget *parent) : QWidget(parent)
8960 QTimer::singleShot(10, &msgbox, SLOT(accept()));
8961 msgbox.exec(); //open a modal dialog
8965 QWidget *win = new QWidget;
8968 QTest::qWaitForWindowShown(win);
8972 void tst_QWidget::focusProxyAndInputMethods()
8974 QWidget *toplevel = new QWidget(0, Qt::X11BypassWindowManagerHint);
8975 toplevel->setAttribute(Qt::WA_InputMethodEnabled, true);
8977 QWidget *child = new QWidget(toplevel);
8978 child->setFocusProxy(toplevel);
8979 child->setAttribute(Qt::WA_InputMethodEnabled, true);
8981 toplevel->setFocusPolicy(Qt::WheelFocus);
8982 child->setFocusPolicy(Qt::WheelFocus);
8984 QVERIFY(!child->hasFocus());
8985 QVERIFY(!toplevel->hasFocus());
8988 QTest::qWaitForWindowShown(toplevel);
8989 QApplication::setActiveWindow(toplevel);
8990 QVERIFY(toplevel->hasFocus());
8991 QVERIFY(child->hasFocus());
8993 // verify that toggling input methods on the child widget
8994 // correctly propagate to the focus proxy's input method
8995 // and that the input method gets the focus proxy passed
8996 // as the focus widget instead of the child widget.
8997 // otherwise input method queries go to the wrong widget
8998 QCOMPARE(qApp->inputPanel()->inputItem(), toplevel);
9000 toplevel->setAttribute(Qt::WA_InputMethodEnabled, false);
9001 QVERIFY(!qApp->inputPanel()->inputItem());
9003 toplevel->setAttribute(Qt::WA_InputMethodEnabled, true);
9004 QCOMPARE(qApp->inputPanel()->inputItem(), toplevel);
9009 #ifdef QT_BUILD_INTERNAL
9010 class scrollWidgetWBS : public QWidget
9013 void deleteBackingStore()
9015 static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStoreTracker.destroy();
9017 void enableBackingStore()
9019 if (!static_cast<QWidgetPrivate*>(d_ptr.data())->maybeBackingStore()) {
9020 static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStoreTracker.create(this);
9021 static_cast<QWidgetPrivate*>(d_ptr.data())->invalidateBuffer(this->rect());
9028 // Test case relies on developer build (AUTOTEST_EXPORT).
9029 #ifdef QT_BUILD_INTERNAL
9030 void tst_QWidget::scrollWithoutBackingStore()
9032 scrollWidgetWBS scrollable;
9033 scrollable.resize(100,100);
9034 QLabel child(QString("@"),&scrollable);
9035 child.resize(50,50);
9037 QTest::qWaitForWindowShown(&scrollable);
9038 scrollable.scroll(50,50);
9039 QCOMPARE(child.pos(),QPoint(50,50));
9040 scrollable.deleteBackingStore();
9041 scrollable.scroll(-25,-25);
9042 QCOMPARE(child.pos(),QPoint(25,25));
9043 scrollable.enableBackingStore();
9044 QCOMPARE(child.pos(),QPoint(25,25));
9048 void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy()
9051 w.setFocusPolicy(Qt::TabFocus);
9052 QWidget *fp = new QWidget(&w);
9053 fp->setFocusPolicy(Qt::TabFocus);
9054 w.setFocusProxy(fp);
9055 QWidget::setTabOrder(&w, fp);
9057 // In debug mode, no assertion failure means it's alright.
9060 void tst_QWidget::movedAndResizedAttributes()
9062 #if defined (Q_OS_MAC) || defined(Q_WS_QWS)
9063 QEXPECT_FAIL("", "FixMe, QTBUG-8941 and QTBUG-8977", Abort);
9069 QVERIFY(!w.testAttribute(Qt::WA_Moved));
9070 QVERIFY(!w.testAttribute(Qt::WA_Resized));
9072 w.setWindowState(Qt::WindowFullScreen);
9074 QVERIFY(!w.testAttribute(Qt::WA_Moved));
9075 QVERIFY(!w.testAttribute(Qt::WA_Resized));
9077 w.setWindowState(Qt::WindowMaximized);
9079 QVERIFY(!w.testAttribute(Qt::WA_Moved));
9080 QVERIFY(!w.testAttribute(Qt::WA_Resized));
9082 w.setWindowState(Qt::WindowMinimized);
9084 QVERIFY(!w.testAttribute(Qt::WA_Moved));
9085 QVERIFY(!w.testAttribute(Qt::WA_Resized));
9089 QVERIFY(!w.testAttribute(Qt::WA_Moved));
9090 QVERIFY(!w.testAttribute(Qt::WA_Resized));
9094 QVERIFY(!w.testAttribute(Qt::WA_Moved));
9095 QVERIFY(!w.testAttribute(Qt::WA_Resized));
9099 QVERIFY(!w.testAttribute(Qt::WA_Moved));
9100 QVERIFY(!w.testAttribute(Qt::WA_Resized));
9104 QVERIFY(w.testAttribute(Qt::WA_Moved));
9105 #if defined(Q_OS_WIN)
9106 QEXPECT_FAIL("", "FixMe, QTBUG-8911", Abort);
9108 QVERIFY(!w.testAttribute(Qt::WA_Resized));
9111 QVERIFY(w.testAttribute(Qt::WA_Moved));
9112 QVERIFY(w.testAttribute(Qt::WA_Resized));
9116 void tst_QWidget::childAt()
9118 QWidget parent(0, Qt::FramelessWindowHint);
9119 parent.resize(200, 200);
9121 QWidget *child = new QWidget(&parent);
9122 child->setPalette(Qt::red);
9123 child->setAutoFillBackground(true);
9124 child->setGeometry(20, 20, 160, 160);
9126 QWidget *grandChild = new QWidget(child);
9127 grandChild->setPalette(Qt::blue);
9128 grandChild->setAutoFillBackground(true);
9129 grandChild->setGeometry(-20, -20, 220, 220);
9131 QVERIFY(!parent.childAt(19, 19));
9132 QVERIFY(!parent.childAt(180, 180));
9133 QCOMPARE(parent.childAt(20, 20), grandChild);
9134 QCOMPARE(parent.childAt(179, 179), grandChild);
9136 grandChild->setAttribute(Qt::WA_TransparentForMouseEvents);
9137 QCOMPARE(parent.childAt(20, 20), child);
9138 QCOMPARE(parent.childAt(179, 179), child);
9139 grandChild->setAttribute(Qt::WA_TransparentForMouseEvents, false);
9141 child->setMask(QRect(50, 50, 60, 60));
9143 QVERIFY(!parent.childAt(69, 69));
9144 QVERIFY(!parent.childAt(130, 130));
9145 QCOMPARE(parent.childAt(70, 70), grandChild);
9146 QCOMPARE(parent.childAt(129, 129), grandChild);
9148 child->setAttribute(Qt::WA_MouseNoMask);
9149 QCOMPARE(parent.childAt(69, 69), grandChild);
9150 QCOMPARE(parent.childAt(130, 130), grandChild);
9151 child->setAttribute(Qt::WA_MouseNoMask, false);
9153 grandChild->setAttribute(Qt::WA_TransparentForMouseEvents);
9154 QCOMPARE(parent.childAt(70, 70), child);
9155 QCOMPARE(parent.childAt(129, 129), child);
9156 grandChild->setAttribute(Qt::WA_TransparentForMouseEvents, false);
9158 grandChild->setMask(QRect(80, 80, 40, 40));
9160 QCOMPARE(parent.childAt(79, 79), child);
9161 QCOMPARE(parent.childAt(120, 120), child);
9162 QCOMPARE(parent.childAt(80, 80), grandChild);
9163 QCOMPARE(parent.childAt(119, 119), grandChild);
9165 grandChild->setAttribute(Qt::WA_MouseNoMask);
9167 QCOMPARE(parent.childAt(79, 79), grandChild);
9168 QCOMPARE(parent.childAt(120, 120), grandChild);
9172 void tst_QWidget::childAt_unifiedToolBar()
9174 QLabel *label = new QLabel(QLatin1String("foo"));
9175 QToolBar *toolBar = new QToolBar;
9176 toolBar->addWidget(new QLabel("dummy"));
9177 toolBar->addWidget(label);
9179 QMainWindow mainWindow;
9180 mainWindow.addToolBar(toolBar);
9183 // Calculate the top-left corner of the tool bar and the label (in mainWindow's coordinates).
9184 QPoint labelTopLeft = label->mapTo(&mainWindow, QPoint());
9185 QPoint toolBarTopLeft = toolBar->mapTo(&mainWindow, QPoint());
9187 QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast<QWidget *>(toolBar));
9188 QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast<QWidget *>(label));
9190 // Enable unified tool bars.
9191 mainWindow.setUnifiedTitleAndToolBarOnMac(true);
9194 // The tool bar is now in the "non-client" area of QMainWindow, i.e.
9195 // outside the mainWindow's rect(), and since mapTo et al. doesn't work
9196 // in that case (see commit 35667fd45ada49269a5987c235fdedfc43e92bb8),
9197 // we use mapToGlobal/mapFromGlobal to re-calculate the corners.
9198 QPoint oldToolBarTopLeft = toolBarTopLeft;
9199 toolBarTopLeft = mainWindow.mapFromGlobal(toolBar->mapToGlobal(QPoint()));
9200 QVERIFY(toolBarTopLeft != oldToolBarTopLeft);
9201 QVERIFY(toolBarTopLeft.y() < 0);
9202 labelTopLeft = mainWindow.mapFromGlobal(label->mapToGlobal(QPoint()));
9204 QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast<QWidget *>(toolBar));
9205 QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast<QWidget *>(label));
9208 void tst_QWidget::taskQTBUG_11373()
9210 QMainWindow * myWindow = new QMainWindow();
9211 QWidget * center = new QWidget();
9212 myWindow -> setCentralWidget(center);
9213 QWidget * drawer = new QWidget(myWindow, Qt::Drawer);
9215 QCOMPARE(drawer->isVisible(), false);
9217 myWindow -> raise();
9218 // The drawer shouldn't be visible now.
9219 QCOMPARE(drawer->isVisible(), false);
9220 myWindow -> setWindowState(Qt::WindowFullScreen);
9221 myWindow -> setWindowState(Qt::WindowNoState);
9222 // The drawer should still not be visible, since we haven't shown it.
9223 QCOMPARE(drawer->isVisible(), false);
9227 void tst_QWidget::taskQTBUG_17333_ResizeInfiniteRecursion()
9230 const char *s = "border: 1px solid;";
9231 tb.setStyleSheet(s);
9234 QTest::qWaitForWindowShown(&tb);
9235 tb.setGeometry(QRect(100, 100, 0, 100));
9236 // No crash, it works.
9239 void tst_QWidget::nativeChildFocus()
9242 QLayout *layout = new QVBoxLayout;
9243 w.setLayout(layout);
9244 QLineEdit *p1 = new QLineEdit;
9245 QLineEdit *p2 = new QLineEdit;
9246 layout->addWidget(p1);
9247 layout->addWidget(p2);
9248 p1->setObjectName("p1");
9249 p2->setObjectName("p2");
9253 p1->setAttribute(Qt::WA_NativeWindow);
9254 p2->setAttribute(Qt::WA_NativeWindow);
9255 QApplication::processEvents();
9256 QTest::qWaitForWindowShown(&w);
9259 QCOMPARE(QApplication::activeWindow(), &w);
9260 QCOMPARE(QApplication::focusWidget(), static_cast<QWidget*>(p1));
9265 static bool lenientCompare(const QPixmap &actual, const QPixmap &expected)
9267 QImage expectedImage = expected.toImage().convertToFormat(QImage::Format_RGB32);
9268 QImage actualImage = actual.toImage().convertToFormat(QImage::Format_RGB32);
9270 if (expectedImage.size() != actualImage.size()) {
9271 qWarning("Image size comparison failed: expected: %dx%d, got %dx%d",
9272 expectedImage.size().width(), expectedImage.size().height(),
9273 actualImage.size().width(), actualImage.size().height());
9277 const int size = actual.width() * actual.height();
9278 const int threshold = QPixmap::defaultDepth() == 16 ? 10 : 2;
9280 QRgb *a = (QRgb *)actualImage.bits();
9281 QRgb *e = (QRgb *)expectedImage.bits();
9282 for (int i = 0; i < size; ++i) {
9283 const QColor ca(a[i]);
9284 const QColor ce(e[i]);
9285 if (qAbs(ca.red() - ce.red()) > threshold
9286 || qAbs(ca.green() - ce.green()) > threshold
9287 || qAbs(ca.blue() - ce.blue()) > threshold) {
9288 qWarning("Color mismatch at pixel #%d: Expected: %d,%d,%d, got %d,%d,%d",
9289 i, ce.red(), ce.green(), ce.blue(), ca.red(), ca.green(), ca.blue());
9297 void tst_QWidget::grab()
9299 for (int opaque = 0; opaque < 2; ++opaque) {
9301 QImage image(128, 128, opaque ? QImage::Format_RGB32 : QImage::Format_ARGB32_Premultiplied);
9302 for (int row = 0; row < image.height(); ++row) {
9303 QRgb *line = reinterpret_cast<QRgb *>(image.scanLine(row));
9304 for (int col = 0; col < image.width(); ++col)
9305 line[col] = qRgba(rand() & 255, row, col, opaque ? 255 : 127);
9308 QPalette pal = widget.palette();
9309 pal.setBrush(QPalette::Window, QBrush(image));
9310 widget.setPalette(pal);
9311 widget.resize(128, 128);
9313 QPixmap expected(64, 64);
9315 expected.fill(Qt::transparent);
9317 QPainter p(&expected);
9318 p.translate(-64, -64);
9319 p.drawTiledPixmap(0, 0, 128, 128, pal.brush(QPalette::Window).texture(), 0, 0);
9322 QPixmap actual = widget.grab(QRect(64, 64, 64, 64));
9323 QVERIFY(lenientCompare(actual, expected));
9325 actual = widget.grab(QRect(64, 64, -1, -1));
9326 QVERIFY(lenientCompare(actual, expected));
9328 // Make sure a widget that is not yet shown is grabbed correctly.
9329 QTreeWidget widget2;
9330 actual = widget2.grab(QRect());
9332 expected = widget2.grab(QRect());
9334 QVERIFY(lenientCompare(actual, expected));
9338 QTEST_MAIN(tst_QWidget)
9339 #include "tst_qwidget.moc"