diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2019-12-04 16:15:16 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2019-12-06 16:57:40 +0100 |
commit | 090f404cf80da35734f712b02cc1543acecd5b62 (patch) | |
tree | 57ff34091b51c7aa1576ac97d2dc6ff6cde26389 /tests/auto/quick/pointerhandlers | |
parent | 7cdc3727a2b01c59d0a9e19a3cfc4e226ac1ab77 (diff) |
Don't let PointerHandler steal touch grab from preventStealing MouseArea
The scenario:
- mouse press: MouseArea grabs; DragHandler gets a passive grab
- drag a little: DragHandler's drag threshold is exceeded
- drag some more: DragHandler tries to take the exclusive grab
This grab takeover succeeded before, because although MA has
keepMouseGrab(), the event being delivered is a touch event,
and MA does not have keepTouchGrab().
If this happens while QQuickWindowPrivate::touchMouseId is the
same touchpoint that the DragHandler is trying to grab, it should
not succeed, because we honor the keepMouseGrab() flag. I.e.
keepMouseGrab() implies keepTouchGrab() whenever the touchpoint
under consideration is currently the touch-mouse.
On the other hand, if a DragHandler is used on some item inside
a Flickable: on press, the Flickable grabs right away (it has a
bad case of FOMO), but the DragHandler just gets a passive grab.
When the drag threshold is exceeded, DragHandler must be able to
steal the grab from Flickable, because Flickable was just being too
aggressive. So now we have the rule that if the Item it wants to steal
the grab from is a parent of the type that filters all events,
it's OK to ignore the keepMouseGrab() flag and steal anyway
(as it did before this patch).
Fixes: QTBUG-79163
Change-Id: I2b3f175bea867cb737357857657653b0a7b83995
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'tests/auto/quick/pointerhandlers')
-rw-r--r-- | tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp | 28 |
1 files changed, 23 insertions, 5 deletions
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 03cff92f46..794562fea0 100644 --- a/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp @@ -51,6 +51,7 @@ public: private slots: void dragHandlerInSiblingStealingGrabFromMouseAreaViaMouse(); + void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch_data(); void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch(); private: @@ -110,8 +111,18 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaMouse QCOMPARE(handler->active(), false); } -void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch() // QTBUG-77624 +void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch_data() { + QTest::addColumn<bool>("preventStealing"); + + QTest::newRow("allow stealing") << false; + QTest::newRow("prevent stealing") << true; +} + +void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch() // QTBUG-77624 and QTBUG-79163 +{ + QFETCH(bool, preventStealing); + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); QScopedPointer<QQuickView> windowPtr; createView(windowPtr, "dragTakeOverFromSibling.qml"); @@ -122,6 +133,7 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch QVERIFY(handler); QQuickMouseArea *ma = window->rootObject()->findChild<QQuickMouseArea*>(); QVERIFY(ma); + ma->setPreventStealing(preventStealing); QPoint p1(150, 150); QTest::QTouchEventSequence touch = QTest::touchEvent(window, touchDevice); @@ -135,7 +147,7 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch // Start dragging // DragHandler keeps monitoring, due to its passive grab, - // and eventually steals the exclusive grab from MA + // and eventually steals the exclusive grab from MA if MA allows it int dragStoleGrab = 0; for (int i = 0; i < 4; ++i) { p1 += QPoint(dragThreshold / 2, 0); @@ -146,9 +158,15 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch } if (dragStoleGrab) qCDebug(lcPointerTests, "DragHandler stole the grab after %d events", dragStoleGrab); - QVERIFY(dragStoleGrab > 1); - QCOMPARE(handler->active(), true); - QCOMPARE(ma->pressed(), false); + if (preventStealing) { + QCOMPARE(dragStoleGrab, 0); + QCOMPARE(handler->active(), false); + QCOMPARE(ma->pressed(), true); + } else { + QVERIFY(dragStoleGrab > 1); + QCOMPARE(handler->active(), true); + QCOMPARE(ma->pressed(), false); + } touch.release(1, p1).commit(); QQuickTouchUtils::flush(window); |