diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-07-14 16:11:24 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-07-15 16:59:45 +0000 |
commit | a0be1dc746b2dc23ef8fff2f0e3b4224d9d74c81 (patch) | |
tree | 8cb1faf21a43ece476fea2472db7c41b58012005 | |
parent | 5c1268f13a69cacae17d4dcc364f8fdfee1ca24c (diff) |
HoverHandler: don't change state if the event involves buttons
In the bug, HoverHandler was getting "hovered" during clicking, even
though it already had the opportunity to be hovered while the mouse
got into its parent's bounds (and at that time, it got un-hovered while
Button was hovered instead). It gets hovered because
QQuickDeliveryAgentPrivate::deliverMatchingPointsToItem() calls
QQuickItemPrivate::handlePointerEvent() on the ListView's contentItem,
because it has a handler. So it seems HoverHandler should not react to
that event, because a button is being pressed.
Fixes: QTBUG-72843
Change-Id: I0bbcd351130a8d16165f04809c039b24b3864bf9
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 8449180c5ebd609b6788680173a79df2f239abb8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
3 files changed, 70 insertions, 0 deletions
diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp index e3b60ad9c6..e953a5b311 100644 --- a/src/quick/handlers/qquickhoverhandler.cpp +++ b/src/quick/handlers/qquickhoverhandler.cpp @@ -109,6 +109,9 @@ void QQuickHoverHandler::componentComplete() bool QQuickHoverHandler::wantsPointerEvent(QPointerEvent *event) { + // No state change should occur if a button is being pressed or released. + if (event->isSinglePointEvent() && static_cast<QSinglePointEvent *>(event)->button()) + return false; auto &point = event->point(0); if (QQuickPointerDeviceHandler::wantsPointerEvent(event) && wantsEventPoint(event, point) && parentContains(point)) { // assume this is a mouse or tablet event, so there's only one point diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/data/hoverHandlerInGrandparentOfHoverableItem.qml b/tests/auto/quick/pointerhandlers/mousearea_interop/data/hoverHandlerInGrandparentOfHoverableItem.qml new file mode 100644 index 0000000000..a3b957a1f7 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/data/hoverHandlerInGrandparentOfHoverableItem.qml @@ -0,0 +1,33 @@ +import QtQuick 2.12 + +Item { + width: 320 + height: 240 + + Rectangle { + color: hh.hovered ? "orange" : "gray" + anchors.fill: container + } + + Item { + id: container + anchors.fill: parent + anchors.margins: 40 + + Rectangle { + width: parent.width + height: 40 + color: ma.pressed ? "blue" : ma.containsMouse ? "aquamarine" : "beige" + + MouseArea { + id: ma + anchors.fill: parent + hoverEnabled: true + } + } + + HoverHandler { + id: hh + } + } +} diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp index 4709622245..ee8f079978 100644 --- a/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp @@ -31,6 +31,7 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlproperty.h> #include <QtQuick/private/qquickdraghandler_p.h> +#include <QtQuick/private/qquickhoverhandler_p.h> #include <QtQuick/private/qquickmousearea_p.h> #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> @@ -52,6 +53,7 @@ private slots: void dragHandlerInSiblingStealingGrabFromMouseAreaViaMouse(); void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch_data(); void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch(); + void hoverHandlerDoesntHoverOnPress(); private: void createView(QScopedPointer<QQuickView> &window, const char *fileName); @@ -175,6 +177,38 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch QCOMPARE(handler->active(), false); } +void tst_MouseAreaInterop::hoverHandlerDoesntHoverOnPress() // QTBUG-72843 +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("hoverHandlerInGrandparentOfHoverableItem.qml"))); + + QPointer<QQuickHoverHandler> handler = window.rootObject()->findChild<QQuickHoverHandler*>(); + QVERIFY(handler); + QQuickMouseArea *ma = window.rootObject()->findChild<QQuickMouseArea*>(); + QVERIFY(ma); + QPoint p = ma->mapToScene(ma->boundingRect().center()).toPoint(); + + // move the mouse below the "button" but within HoverHandler's region of interest + QTest::mouseMove(&window, p + QPoint(0, 50)); + QTRY_COMPARE(handler->isHovered(), true); + // move the mouse into the "button" + QTest::mouseMove(&window, p); + // current behavior: the mouse is still within the HoverHandler's region of interest, but MouseArea is obstructing. + QTRY_COMPARE(handler->isHovered(), false); + QCOMPARE(ma->hovered(), true); + + // So HoverHandler is no longer hovered (unfortunately). Clicking should not change it. + QSignalSpy hoveredChangedSpy(handler, SIGNAL(hoveredChanged())); + QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, p); + QTRY_COMPARE(ma->pressed(), true); + QCOMPARE(handler->isHovered(), false); + QCOMPARE(hoveredChangedSpy.count(), 0); + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p); + QTRY_COMPARE(ma->pressed(), false); + QCOMPARE(handler->isHovered(), false); + QCOMPARE(hoveredChangedSpy.count(), 0); +} + QTEST_MAIN(tst_MouseAreaInterop) #include "tst_mousearea_interop.moc" |