aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickitem.cpp6
-rw-r--r--tests/auto/quick/qquickmousearea/data/containsMouse.qml14
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp46
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"