aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-02-12 17:11:47 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-02-12 22:19:24 +0000
commitf853db24bd29343efa8694008a931c95c37c2a80 (patch)
tree79e23a8557c0603086aca7ee4893e8b0d74133bd /tests
parentb7412dc86608207cba84538cb962e4300dfe42c1 (diff)
MouseArea: fix containsMouse behavior during visibility changes
QQuickItem returns whether it contains QGuiApplicationPrivate's lastCursorPosition. Since that position stores the coordinate last seen by Qt (the window border), it will always be within the window, and within an item that covers that part of the window's border. However, QQuickWindow stores the lastMousePosition as well, and resets that value when it receives a QEvent::Leave. We can use that to test whether the window that contains the item has seen a Leave event, in which case the item is definitely not under the mouse. Notes on the test: That we use QPointF() as the "reset" value leave the small possibility that the cursor might be at position 0,0 of the window (ie inside the window), and the QQuickItem there will not be under the mouse. We can't confirm this (through an expected failure test), as QTest::mouseMove interprets a QPoint(0, 0) as "center of the window". And since we can't simulate mouse moves outside a window's boundary using QTest::mouseMove, the test needs to explicitly synthesize a QEvent::Leave for the window. Fixes: QTBUG-87197 Change-Id: I04870d6e914092275d9d790312fc702fb99f2935 Done-with: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> (cherry picked from commit ba1246c543118515ea244787f3d7f9c1133ccf0f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/qquickmousearea/data/containsMouse.qml14
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp46
2 files changed, 60 insertions, 0 deletions
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"