aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2020-11-27 08:59:20 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2020-11-30 18:46:02 +0000
commitf03615260cf6bba41393a700ca1cc58ce8742dba (patch)
treefee6edca9e36ef3796b1aae616720661162cd042 /tests
parente70ce81ac6df3c966416ecae8ef200b37c0eac7b (diff)
Allow parent to filter out-of-bounds synth-mouse for grabbing handler
Consider Flickable { Text { TapHandler { gesturePolicy: TapHandler.ReleaseWithinBounds } } } On press, TapHandler gets the exclusive grab. Now drag vertically. The Text is short in stature, so your finger soon strays out of bounds of the Text, likely before you have dragged past the drag threshold. In this case, we want Flickable to continue to filter the move events because of the fact that TapHandler is the grabber. If it was a MouseArea instead of a TapHandler, it already worked that way; so this makes behavior of handlers more consistent with that. More specifically: QQuickPointerTouchEvent::touchEventForItem() now generates a touch event even if the touchpoint is not within the bounds of the given item, but is grabbed by one of that item's handlers. Until now, we had that exception only if it was grabbed by the item itself. tst_FlickableInterop::touchAndDragHandlerOnFlickable now always drags the delegate at index 2 (the third one) from its upper-right corner, upwards and to the left. The first drag goes outside the delegate's bounds, but the Flickable/ListView/TableView filters and takes over anyway (on the next drag), to prove that it is correctly depending on the grab that the TapHandler (or DragHandler) took on press. Fixes: QTBUG-75223 Change-Id: Ie4e22c87be0af9aa3ff0146067b7705949b15c40 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 1e1674849a89db54cdbcc4e995300e3ec1624c3a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml11
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml2
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp77
5 files changed, 54 insertions, 40 deletions
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml
index b7f4662476..54b9b244c0 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnList.qml
@@ -55,7 +55,7 @@ ListView {
id: buttonDrag
objectName: "buttonDrag"
}
- Component.onCompleted: if (!root.buttonUnderTest) {
+ Component.onCompleted: if (!root.buttonUnderTest && index == 2) {
root.buttonUnderTest = this
root.delegateUnderTest = parent
}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml
index 43cc44f62e..c478f4fa41 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/dragOnTable.qml
@@ -59,7 +59,7 @@ TableView {
id: buttonDrag
objectName: "buttonDrag"
}
- Component.onCompleted: if (!root.buttonUnderTest) {
+ Component.onCompleted: if (!root.buttonUnderTest && index == 2) {
root.buttonUnderTest = this
root.delegateUnderTest = parent
}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml
index ef27955043..58b1e8caeb 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnList.qml
@@ -39,11 +39,12 @@ ListView {
spacing: 2
delegate: Rectangle {
- objectName: "itemview delegate"
+ objectName: "itemview delegate " + index
color: delegateTap.pressed ? "wheat" : "beige"
width: parent.width; height: 140
+ Text { text: index }
Rectangle {
- objectName: "button"
+ objectName: "button " + index
anchors.centerIn: parent
border.color: "tomato"
border.width: 10
@@ -52,16 +53,16 @@ ListView {
height: 100
TapHandler {
id: innerTap
- objectName: "buttonTap"
+ objectName: "buttonTap " + index
}
- Component.onCompleted: if (!root.buttonUnderTest) {
+ Component.onCompleted: if (!root.buttonUnderTest && index == 2) {
root.buttonUnderTest = this
root.delegateUnderTest = parent
}
}
TapHandler {
id: delegateTap
- objectName: "delegateTap"
+ objectName: "delegateTap " + index
}
}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml
index 6bf1054d7a..bdd05e2f5a 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/tapOnTable.qml
@@ -59,7 +59,7 @@ TableView {
id: innerTap
objectName: "buttonTap"
}
- Component.onCompleted: if (!root.buttonUnderTest) {
+ Component.onCompleted: if (!root.buttonUnderTest && index == 2) {
root.buttonUnderTest = this
root.delegateUnderTest = parent
}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
index 2cdbaf3bf6..869ba80658 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
@@ -664,30 +664,36 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable_data()
QTest::addColumn<QByteArray>("qmlFile");
QTest::addColumn<bool>("pressDelay");
QTest::addColumn<bool>("targetNull");
- QTest::newRow("tapOnFlickable") << QByteArray("tapOnFlickable.qml") << false << false;
- QTest::newRow("tapOnList") << QByteArray("tapOnList.qml") << false << false;
- QTest::newRow("tapOnTable") << QByteArray("tapOnTable.qml") << false << false;
- QTest::newRow("dragOnFlickable") << QByteArray("dragOnFlickable.qml") << false << false;
- QTest::newRow("dragOnList") << QByteArray("dragOnList.qml") << false << false;
- QTest::newRow("dragOnTable") << QByteArray("dragOnTable.qml") << false << false;
- QTest::newRow("tapDelayOnFlickable") << QByteArray("tapOnFlickable.qml") << true << false;
- QTest::newRow("tapDelayOnList") << QByteArray("tapOnList.qml") << true << false;
- QTest::newRow("tapDelayOnTable") << QByteArray("tapOnTable.qml") << true << false;
- QTest::newRow("dragDelayOnFlickable") << QByteArray("dragOnFlickable.qml") << true << false;
- QTest::newRow("dragDelayOnList") << QByteArray("dragOnList.qml") << true << false;
- QTest::newRow("dragDelayOnTable") << QByteArray("dragOnTable.qml") << true << false;
- QTest::newRow("tapOnFlickableWithNullTargets") << QByteArray("tapOnFlickable.qml") << false << true;
- QTest::newRow("tapOnListWithNullTargets") << QByteArray("tapOnList.qml") << false << true;
- QTest::newRow("tapOnTableWithNullTargets") << QByteArray("tapOnTable.qml") << false << true;
- QTest::newRow("dragOnFlickableWithNullTargets") << QByteArray("dragOnFlickable.qml") << false << true;
- QTest::newRow("dragOnListWithNullTargets") << QByteArray("dragOnList.qml") << false << true;
- QTest::newRow("dragOnTableWithNullTargets") << QByteArray("dragOnTable.qml") << false << true;
- QTest::newRow("tapDelayOnFlickableWithNullTargets") << QByteArray("tapOnFlickable.qml") << true << true;
- QTest::newRow("tapDelayOnListWithNullTargets") << QByteArray("tapOnList.qml") << true << true;
- QTest::newRow("tapDelayOnTableWithNullTargets") << QByteArray("tapOnTable.qml") << true << true;
- QTest::newRow("dragDelayOnFlickableWithNullTargets") << QByteArray("dragOnFlickable.qml") << true << true;
- QTest::newRow("dragDelayOnListWithNullTargets") << QByteArray("dragOnList.qml") << true << true;
- QTest::newRow("dragDelayOnTableWithNullTargets") << QByteArray("dragOnTable.qml") << true << true;
+ QTest::addColumn<QQuickTapHandler::GesturePolicy>("tapGesturePolicy");
+ QTest::newRow("tapOnFlickable") << QByteArray("tapOnFlickable.qml") << false << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapOnFlickable-excl") << QByteArray("tapOnFlickable.qml") << false << false << QQuickTapHandler::ReleaseWithinBounds;
+ QTest::newRow("tapOnList") << QByteArray("tapOnList.qml") << false << false << QQuickTapHandler::DragThreshold;
+ // QTBUG-75223
+ QTest::newRow("tapOnList-excl") << QByteArray("tapOnList.qml") << false << false << QQuickTapHandler::ReleaseWithinBounds;
+ QTest::newRow("tapOnTable") << QByteArray("tapOnTable.qml") << false << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragOnFlickable") << QByteArray("dragOnFlickable.qml") << false << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragOnList") << QByteArray("dragOnList.qml") << false << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragOnTable") << QByteArray("dragOnTable.qml") << false << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapDelayOnFlickable") << QByteArray("tapOnFlickable.qml") << true << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapDelayOnFlickable-excl") << QByteArray("tapOnFlickable.qml") << true << false << QQuickTapHandler::ReleaseWithinBounds;
+ QTest::newRow("tapDelayOnList") << QByteArray("tapOnList.qml") << true << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapDelayOnList-excl") << QByteArray("tapOnList.qml") << true << false << QQuickTapHandler::ReleaseWithinBounds;
+ QTest::newRow("tapDelayOnTable") << QByteArray("tapOnTable.qml") << true << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragDelayOnFlickable") << QByteArray("dragOnFlickable.qml") << true << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragDelayOnList") << QByteArray("dragOnList.qml") << true << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragDelayOnTable") << QByteArray("dragOnTable.qml") << true << false << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapOnFlickableWithNullTargets") << QByteArray("tapOnFlickable.qml") << false << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapOnListWithNullTargets") << QByteArray("tapOnList.qml") << false << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapOnTableWithNullTargets") << QByteArray("tapOnTable.qml") << false << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragOnFlickableWithNullTargets") << QByteArray("dragOnFlickable.qml") << false << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragOnListWithNullTargets") << QByteArray("dragOnList.qml") << false << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragOnTableWithNullTargets") << QByteArray("dragOnTable.qml") << false << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapDelayOnFlickableWithNullTargets") << QByteArray("tapOnFlickable.qml") << true << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapDelayOnListWithNullTargets") << QByteArray("tapOnList.qml") << true << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("tapDelayOnTableWithNullTargets") << QByteArray("tapOnTable.qml") << true << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragDelayOnFlickableWithNullTargets") << QByteArray("dragOnFlickable.qml") << true << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragDelayOnListWithNullTargets") << QByteArray("dragOnList.qml") << true << true << QQuickTapHandler::DragThreshold;
+ QTest::newRow("dragDelayOnTableWithNullTargets") << QByteArray("dragOnTable.qml") << true << true << QQuickTapHandler::DragThreshold;
}
void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
@@ -695,6 +701,7 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
QFETCH(QByteArray, qmlFile);
QFETCH(bool, pressDelay);
QFETCH(bool, targetNull);
+ QFETCH(QQuickTapHandler::GesturePolicy, tapGesturePolicy);
const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
QScopedPointer<QQuickView> windowPtr;
@@ -703,11 +710,7 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
QQuickFlickable *flickable = qmlobject_cast<QQuickFlickable*>(window->rootObject());
QVERIFY(flickable);
flickable->setPressDelay(pressDelay ? 5000 : 0);
- QQuickItem *delegate = nullptr;
- if (QQuickItemView *itemView = qmlobject_cast<QQuickItemView *>(flickable))
- delegate = itemView->currentItem();
- if (!delegate)
- delegate = flickable->property("delegateUnderTest").value<QQuickItem*>();
+ QQuickItem *delegate = flickable->property("delegateUnderTest").value<QQuickItem*>();
QQuickItem *button = delegate ? delegate->findChild<QQuickItem*>("button")
: flickable->findChild<QQuickItem*>("button");
if (!button)
@@ -716,8 +719,13 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
QQuickPointerHandler *buttonHandler = button->findChild<QQuickPointerHandler*>();
QVERIFY(buttonHandler);
QQuickTapHandler *buttonTapHandler = qmlobject_cast<QQuickTapHandler *>(buttonHandler);
+ if (buttonTapHandler)
+ buttonTapHandler->setGesturePolicy(tapGesturePolicy);
QQuickDragHandler *buttonDragHandler = qmlobject_cast<QQuickDragHandler *>(buttonHandler);
QQuickPointerHandler *delegateHandler = delegate ? delegate->findChild<QQuickPointerHandler*>() : nullptr;
+ QQuickTapHandler *delegateTapHandler = qmlobject_cast<QQuickTapHandler *>(delegateHandler);
+ if (delegateTapHandler)
+ delegateTapHandler->setGesturePolicy(tapGesturePolicy);
QQuickPointerHandler *contentItemHandler = flickable->findChild<QQuickPointerHandler*>();
QVERIFY(contentItemHandler);
// a handler declared directly in a Flickable (or item view) must actually be a child of the contentItem,
@@ -730,9 +738,12 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
contentItemHandler->setTarget(nullptr);
}
- // Drag one finger on the Flickable and make sure it flicks
+ // Drag one finger on the Flickable (between delegates) and make sure it flicks
QTest::QTouchEventSequence touchSeq = QTest::touchEvent(window, touchDevice, false);
QPoint p1(780, 460);
+ if (delegate)
+ p1 = delegate->mapToScene(delegate->clipRect().bottomRight()).toPoint() + QPoint(-1, 1);
+ qCDebug(lcPointerTests) << "drag between delegates starting @" << p1;
touchSeq.press(1, p1, window).commit();
QQuickTouchUtils::flush(window);
for (int i = 0; i < 4; ++i) {
@@ -752,8 +763,8 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
flickable->setContentY(0);
QTRY_COMPARE(flickable->isMoving(), false);
QVERIFY(delegateHandler);
- QQuickTapHandler *delegateTapHandler = qmlobject_cast<QQuickTapHandler *>(delegateHandler);
- p1 = button->mapToScene(button->clipRect().bottomRight()).toPoint() + QPoint(10, 0);
+ p1 = delegate->mapToScene(delegate->clipRect().topRight()).toPoint() + QPoint(-2, 2);
+ qCDebug(lcPointerTests) << "drag on delegate 2 starting @" << p1;
touchSeq.press(1, p1, window).commit();
QQuickTouchUtils::flush(window);
if (delegateTapHandler && !pressDelay)
@@ -762,6 +773,8 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable()
p1 -= QPoint(dragThreshold, dragThreshold);
touchSeq.move(1, p1, window).commit();
QQuickTouchUtils::flush(window);
+ qCDebug(lcPointerTests) << i << p1 << delegateHandler->objectName()
+ << "active" << delegateHandler->active() << "flickable moving" << flickable->isMoving();
if (i > 1)
QTRY_VERIFY(delegateHandler->active() || flickable->isMoving());
}