aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2022-06-28 21:49:59 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-07-04 11:05:28 +0000
commite73c94dcb112707b619ca3b1880cc98ed064a6ef (patch)
treeaadb13e63949e809330a2776d5ef5cbf829cec26 /tests
parentc425e94ad8f6b30f826b7d9964b6ff142164c864 (diff)
Flickable: don't grab on press if already moving
9f9ea6e1837620a0ff4b98e262cba2df44215967 was too drastic: we cannot simply avoid calling filterPointerEvent() on press, because it calls handlePressEvent() which calls maybeBeginDrag() which sets pressPos, among other things. Failing to set pressPos caused a regression: flicking a second time while the flickable is already moving caused it to "start over" as if it was flicking from the top again. So now we revert that fix, and instead avoid setting stealMouse to true in handlePressEvent(). This makes the second flick more like the first: it waits for move events before taking the exclusive grab; so it's ok for a delegate (such as a Button or MouseArea) to detect the press and take a grab in the meantime. Flickable does not need to grab on press during filtering: it's not a lost opportunity, because it keeps filtering its children's events later on anyway. The flickDuringFlicking() test is added for this scenario. For the same reason as tapDelegateDuringFlicking(), this is also likely to fail on Android for now. This could have some impact on d7b5a485583004ad6a1374a50b7c3f6cab00aca3 but it seems the test that was added there still passes. Fixes: QTBUG-103832 Task-number: QTBUG-38765 Task-number: QTBUG-74842 Task-number: QTBUG-104471 Change-Id: Icb45fcd94847051121ee78a970fbd5f5dc8a42a4 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Antti Määttä <antti.maatta@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io> (cherry picked from commit bb337a0e1c22896984438cbd51ab7473807f017c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/qquicklistview2/BLACKLIST4
-rw-r--r--tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp64
2 files changed, 67 insertions, 1 deletions
diff --git a/tests/auto/quick/qquicklistview2/BLACKLIST b/tests/auto/quick/qquicklistview2/BLACKLIST
index b61ef889c0..8ecf16f118 100644
--- a/tests/auto/quick/qquicklistview2/BLACKLIST
+++ b/tests/auto/quick/qquicklistview2/BLACKLIST
@@ -1,3 +1,5 @@
[tapDelegateDuringFlicking]
-android
+android # QTBUG-104471
+[flickDuringFlicking]
+android # QTBUG-104471
diff --git a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
index 7749e83b47..0cb88c501d 100644
--- a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
+++ b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
@@ -64,6 +64,8 @@ private slots:
void noCrashOnIndexChange();
void tapDelegateDuringFlicking_data();
void tapDelegateDuringFlicking();
+ void flickDuringFlicking_data();
+ void flickDuringFlicking();
private:
void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to);
@@ -380,6 +382,68 @@ void tst_QQuickListView2::tapDelegateDuringFlicking() // QTBUG-103832
QCOMPARE(canceledDelegates.count(), 1); // only the first press was canceled, not the second
}
+void tst_QQuickListView2::flickDuringFlicking_data()
+{
+ QTest::addColumn<QByteArray>("qmlFile");
+ QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior");
+
+ QTest::newRow("Button StopAtBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds);
+ QTest::newRow("MouseArea StopAtBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds);
+ QTest::newRow("Button DragOverBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds);
+ QTest::newRow("MouseArea DragOverBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds);
+ QTest::newRow("Button OvershootBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds);
+ QTest::newRow("MouseArea OvershootBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds);
+ QTest::newRow("Button DragAndOvershootBounds") << QByteArray("buttonDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+ QTest::newRow("MouseArea DragAndOvershootBounds") << QByteArray("mouseAreaDelegate.qml")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+}
+
+void tst_QQuickListView2::flickDuringFlicking() // QTBUG-103832
+{
+ QFETCH(QByteArray, qmlFile);
+ QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior);
+
+ QQuickView window;
+ QVERIFY(QQuickTest::showView(window, testFileUrl(qmlFile.constData())));
+ QQuickListView *listView = qobject_cast<QQuickListView*>(window.rootObject());
+ QVERIFY(listView);
+ listView->setBoundsBehavior(boundsBehavior);
+
+ flickWithTouch(&window, {100, 400}, {100, 100});
+ QTRY_VERIFY(listView->contentY() > 1000); // let it flick some distance
+ QVERIFY(listView->isFlicking()); // we want to test the case when it's moving and then we flick again
+ const qreal posBeforeSecondFlick = listView->contentY();
+
+ // flick again during flicking, and make sure that it doesn't jump back to the first delegate,
+ // but flicks incrementally further from the position at that time
+ QTest::touchEvent(&window, touchDevice.data()).press(0, {100, 400});
+ QQuickTouchUtils::flush(&window);
+ qCDebug(lcTests) << "second press: contentY" << posBeforeSecondFlick << "->" << listView->contentY();
+ qCDebug(lcTests) << "pressed delegates" << listView->property("pressedDelegates").toList();
+ QVERIFY(listView->contentY() >= posBeforeSecondFlick);
+
+ QTest::qWait(20);
+ QTest::touchEvent(&window, touchDevice.data()).move(0, {100, 300});
+ QQuickTouchUtils::flush(&window);
+ qCDebug(lcTests) << "first move after second press: contentY" << posBeforeSecondFlick << "->" << listView->contentY();
+ QVERIFY(listView->contentY() >= posBeforeSecondFlick);
+
+ QTest::qWait(20);
+ QTest::touchEvent(&window, touchDevice.data()).move(0, {100, 200});
+ QQuickTouchUtils::flush(&window);
+ qCDebug(lcTests) << "second move after second press: contentY" << posBeforeSecondFlick << "->" << listView->contentY();
+ QVERIFY(listView->contentY() >= posBeforeSecondFlick + 100);
+
+ QTest::touchEvent(&window, touchDevice.data()).release(0, {100, 100});
+}
+
void tst_QQuickListView2::flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to)
{
QTest::touchEvent(window, touchDevice.data()).press(0, from, window);