diff options
-rw-r--r-- | src/quick/items/qquickitem.cpp | 6 | ||||
-rw-r--r-- | tests/auto/quick/qquickmousearea/data/containsMouse.qml | 14 | ||||
-rw-r--r-- | tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp | 46 |
3 files changed, 66 insertions, 0 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 38e83e08ff..83964c4a3a 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7415,6 +7415,12 @@ bool QQuickItem::isUnderMouse() const if (!d->window) return false; + // QQuickWindow handles QEvent::Leave to reset the lastMousePosition + // FIXME: Using QPointF() as the reset value means an item will not be + // under the mouse if the mouse is at 0,0 of the window. + if (QQuickWindowPrivate::get(d->window)->lastMousePosition == QPointF()) + return false; + QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition; return contains(mapFromScene(d->window->mapFromGlobal(cursorPos.toPoint()))); } diff --git a/tests/auto/quick/qquickmousearea/data/containsMouse.qml b/tests/auto/quick/qquickmousearea/data/containsMouse.qml new file mode 100644 index 0000000000..6620d7c062 --- /dev/null +++ b/tests/auto/quick/qquickmousearea/data/containsMouse.qml @@ -0,0 +1,14 @@ +import QtQuick + +Rectangle { + width: 200 + height: 200 + visible: true + MouseArea { + id: mouseArea + objectName: "mouseArea" + anchors.fill: parent + hoverEnabled: true + visible: false + } +} diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index c167eedb06..1e9f76c8ce 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -154,6 +154,7 @@ private slots: void nestedEventDelivery(); void settingHiddenInPressUngrabs(); void negativeZStackingOrder(); + void containsMouseAndVisibility(); private: int startDragDistance() const { @@ -2298,6 +2299,51 @@ void tst_QQuickMouseArea::negativeZStackingOrder() // QTBUG-83114 QVERIFY(order.at(0) == "parentMouseArea"); } +// QTBUG-87197 +void tst_QQuickMouseArea::containsMouseAndVisibility() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("containsMouse.qml"))); + + QQuickMouseArea *mouseArea = window.rootObject()->findChild<QQuickMouseArea*>("mouseArea"); + QVERIFY(mouseArea != nullptr); + QVERIFY(!mouseArea->isVisible()); + + QTest::mouseMove(&window, QPoint(10, 10)); + QTRY_VERIFY(!mouseArea->hovered()); + + mouseArea->setVisible(true); + QVERIFY(mouseArea->isVisible()); + QTRY_VERIFY(mouseArea->hovered()); + + /* we (ab-)use QPointF() as the 'reset' value in QQuickWindow's leave-event handling, + but can't verify that this leaves an invalid interpretation of states for position + QPoint(0, 0) as QTest::mouseMove interprets a null-position as "center of the window". + + So instead, verify the current (unexpectedly expected) behavior as far as testing is + concern. + */ + QTest::mouseMove(&window, QPoint(0, 0)); + QTRY_VERIFY(mouseArea->hovered()); + QTRY_VERIFY(mouseArea->isUnderMouse()); + + // move to the edge (can't move outside) + QTest::mouseMove(&window, QPoint(window.width() - 1, window.height() / 2)); + // then pretend we left + QEvent event(QEvent::Leave); + QGuiApplication::sendEvent(&window, &event); + QVERIFY(!mouseArea->hovered()); + + // toggle mouse area visibility - the hover state should not change + mouseArea->setVisible(false); + QVERIFY(!mouseArea->isVisible()); + QVERIFY(!mouseArea->hovered()); + + mouseArea->setVisible(true); + QVERIFY(mouseArea->isVisible()); + QVERIFY(!mouseArea->hovered()); +} + QTEST_MAIN(tst_QQuickMouseArea) #include "tst_qquickmousearea.moc" |