diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2010-06-04 10:12:01 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2010-06-10 12:06:42 (GMT) |
commit | 7101ae5a0e90d97acf86a444c4d51ca45e7863fe (patch) | |
tree | e40aa11c165873378818fd2376dff4654f4c86aa /tests/auto/qwidget | |
parent | 39e11b3f49fdc01155575f6d909efd92e435d5a6 (diff) | |
download | Qt-7101ae5a0e90d97acf86a444c4d51ca45e7863fe.zip Qt-7101ae5a0e90d97acf86a444c4d51ca45e7863fe.tar.gz Qt-7101ae5a0e90d97acf86a444c4d51ca45e7863fe.tar.bz2 |
QWidget::childAt for masked child widgets doesn't work properly
Problem was that we didn't take the children's effective mask
into account when checking whether a point was inside or not.
This commit is also an optimization since we no longer check the point
against the widget's rect twice. Furthermore, unnecessary
QRegion operations are completely avoided in the common case.
Auto tests included.
Task-number: QTBUG-7150
Reviewed-by: paul
Diffstat (limited to 'tests/auto/qwidget')
-rw-r--r-- | tests/auto/qwidget/tst_qwidget.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index a1fc607..d76bbfa 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -404,6 +404,10 @@ private slots: void taskQTBUG_7532_tabOrderWithFocusProxy(); void movedAndResizedAttributes(); + void childAt(); +#ifdef Q_WS_MAC + void childAt_unifiedToolBar(); +#endif private: bool ensureScreenSize(int width, int height); @@ -10347,5 +10351,98 @@ void tst_QWidget::movedAndResizedAttributes() #endif } +void tst_QWidget::childAt() +{ + QWidget parent(0, Qt::FramelessWindowHint); + parent.resize(200, 200); + + QWidget *child = new QWidget(&parent); + child->setPalette(Qt::red); + child->setAutoFillBackground(true); + child->setGeometry(20, 20, 160, 160); + + QWidget *grandChild = new QWidget(child); + grandChild->setPalette(Qt::blue); + grandChild->setAutoFillBackground(true); + grandChild->setGeometry(-20, -20, 220, 220); + + QVERIFY(!parent.childAt(19, 19)); + QVERIFY(!parent.childAt(180, 180)); + QCOMPARE(parent.childAt(20, 20), grandChild); + QCOMPARE(parent.childAt(179, 179), grandChild); + + grandChild->setAttribute(Qt::WA_TransparentForMouseEvents); + QCOMPARE(parent.childAt(20, 20), child); + QCOMPARE(parent.childAt(179, 179), child); + grandChild->setAttribute(Qt::WA_TransparentForMouseEvents, false); + + child->setMask(QRect(50, 50, 60, 60)); + + QVERIFY(!parent.childAt(69, 69)); + QVERIFY(!parent.childAt(130, 130)); + QCOMPARE(parent.childAt(70, 70), grandChild); + QCOMPARE(parent.childAt(129, 129), grandChild); + + child->setAttribute(Qt::WA_MouseNoMask); + QCOMPARE(parent.childAt(69, 69), grandChild); + QCOMPARE(parent.childAt(130, 130), grandChild); + child->setAttribute(Qt::WA_MouseNoMask, false); + + grandChild->setAttribute(Qt::WA_TransparentForMouseEvents); + QCOMPARE(parent.childAt(70, 70), child); + QCOMPARE(parent.childAt(129, 129), child); + grandChild->setAttribute(Qt::WA_TransparentForMouseEvents, false); + + grandChild->setMask(QRect(80, 80, 40, 40)); + + QCOMPARE(parent.childAt(79, 79), child); + QCOMPARE(parent.childAt(120, 120), child); + QCOMPARE(parent.childAt(80, 80), grandChild); + QCOMPARE(parent.childAt(119, 119), grandChild); + + grandChild->setAttribute(Qt::WA_MouseNoMask); + + QCOMPARE(parent.childAt(79, 79), grandChild); + QCOMPARE(parent.childAt(120, 120), grandChild); +} + +#ifdef Q_WS_MAC +void tst_QWidget::childAt_unifiedToolBar() +{ + QLabel *label = new QLabel(QLatin1String("foo")); + QToolBar *toolBar = new QToolBar; + toolBar->addWidget(new QLabel("dummy")); + toolBar->addWidget(label); + + QMainWindow mainWindow; + mainWindow.addToolBar(toolBar); + mainWindow.show(); + + // Calculate the top-left corner of the tool bar and the label (in mainWindow's coordinates). + QPoint labelTopLeft = label->mapTo(&mainWindow, QPoint()); + QPoint toolBarTopLeft = toolBar->mapTo(&mainWindow, QPoint()); + + QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast<QWidget *>(toolBar)); + QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast<QWidget *>(label)); + + // Enable unified tool bars. + mainWindow.setUnifiedTitleAndToolBarOnMac(true); + QTest::qWait(50); + + // The tool bar is now in the "non-client" area of QMainWindow, i.e. + // outside the mainWindow's rect(), and since mapTo et al. doesn't work + // in that case (see commit 35667fd45ada49269a5987c235fdedfc43e92bb8), + // we use mapToGlobal/mapFromGlobal to re-calculate the corners. + QPoint oldToolBarTopLeft = toolBarTopLeft; + toolBarTopLeft = mainWindow.mapFromGlobal(toolBar->mapToGlobal(QPoint())); + QVERIFY(toolBarTopLeft != oldToolBarTopLeft); + QVERIFY(toolBarTopLeft.y() < 0); + labelTopLeft = mainWindow.mapFromGlobal(label->mapToGlobal(QPoint())); + + QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast<QWidget *>(toolBar)); + QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast<QWidget *>(label)); +} +#endif + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" |