From 25169a444dd7c60697d123af01d6e648966da968 Mon Sep 17 00:00:00 2001 From: Seokha Ko Date: Fri, 14 Apr 2023 17:15:50 +0900 Subject: [PATCH] Flickable: Send movement signal when flick starts If there are multiple moves between touch down and release, but they are merged, or if there is only one move, flick occurs but no movement signal is generated. So, send movementStarted if the view is moving in handleReleaseEvent Fixes: QTBUG-112924 Change-Id: I774799bac2a00296a72005dcfa9ade6683836d08 Reviewed-by: Richard Moe Gustavsen (cherry picked from commit e6a363efe86dd6acbceade28d5eddbdca9c7b805) Reviewed-by: Qt Cherry-pick Bot --- src/quick/items/qquickflickable.cpp | 9 ++- .../qquickflickable/tst_qquickflickable.cpp | 76 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index c5f2c87dd6..3a75657ea8 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1480,8 +1480,15 @@ void QQuickFlickablePrivate::handleReleaseEvent(QPointerEvent *event) fixupX(); flickingStarted(flickedHorizontally, flickedVertically); - if (!isViewMoving()) + if (!isViewMoving()) { q->movementEnding(); + } else { + if (flickedVertically) + vMoved = true; + if (flickedHorizontally) + hMoved = true; + q->movementStarting(); + } } void QQuickFlickable::mousePressEvent(QMouseEvent *event) diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 68e6652809..4a8bc5faa0 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -221,6 +221,8 @@ private slots: void scrollingWithFractionalExtentSize(); void setContentPositionWhileDragging_data(); void setContentPositionWhileDragging(); + void coalescedMove(); + void onlyOneMove(); private: void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to); @@ -3123,6 +3125,80 @@ void tst_qquickflickable::setContentPositionWhileDragging() // QTBUG-104966 QVERIFY(!flickable->isDragging()); } +void tst_qquickflickable::coalescedMove() +{ + QQuickView *window = new QQuickView; + QScopedPointer windowPtr(window); + windowPtr->setSource(testFileUrl("flickable03.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickVisualTestUtils::centerOnScreen(window); + QQuickVisualTestUtils::moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(window->rootObject() != nullptr); + + QQuickFlickable *flickable = qobject_cast(window->rootObject()); + QVERIFY(flickable != nullptr); + + QSignalSpy movementStartedSpy(flickable, SIGNAL(movementStarted())); + QSignalSpy movementEndedSpy(flickable, SIGNAL(movementEnded())); + QSignalSpy flickStartedSpy(flickable, SIGNAL(flickStarted())); + QSignalSpy flickEndedSpy(flickable, SIGNAL(flickEnded())); + + QTest::touchEvent(window, touchDevice).press(0, {10, 10}).commit(); + + QTest::touchEvent(window, touchDevice).move(0, {10, 40}).commit(); + + QTest::touchEvent(window, touchDevice).move(0, {10, 100}).commit(); + + QTest::touchEvent(window, touchDevice).release(0, {10, 150}).commit(); + QQuickTouchUtils::flush(window); + + QTRY_VERIFY(!flickable->isMoving()); + + QCOMPARE(movementStartedSpy.size(), 1); + QCOMPARE(flickStartedSpy.size(), 1); + QCOMPARE(movementEndedSpy.size(), 1); + QCOMPARE(flickEndedSpy.size(), 1); +} + +void tst_qquickflickable::onlyOneMove() +{ + QQuickView *window = new QQuickView; + QScopedPointer windowPtr(window); + windowPtr->setSource(testFileUrl("flickable03.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickVisualTestUtils::centerOnScreen(window); + QQuickVisualTestUtils::moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(window->rootObject() != nullptr); + + QQuickFlickable *flickable = qobject_cast(window->rootObject()); + QVERIFY(flickable != nullptr); + + QSignalSpy movementStartedSpy(flickable, SIGNAL(movementStarted())); + QSignalSpy movementEndedSpy(flickable, SIGNAL(movementEnded())); + QSignalSpy flickStartedSpy(flickable, SIGNAL(flickStarted())); + QSignalSpy flickEndedSpy(flickable, SIGNAL(flickEnded())); + + QTest::touchEvent(window, touchDevice).press(0, {10, 10}).commit(); + QQuickTouchUtils::flush(window); + + QTest::touchEvent(window, touchDevice).move(0, {10, 100}).commit(); + QQuickTouchUtils::flush(window); + + QTest::touchEvent(window, touchDevice).release(0, {10, 200}).commit(); + QQuickTouchUtils::flush(window); + + QTRY_VERIFY(!flickable->isMoving()); + + QCOMPARE(movementStartedSpy.size(), 1); + QCOMPARE(flickStartedSpy.size(), 1); + QCOMPARE(movementEndedSpy.size(), 1); + QCOMPARE(flickEndedSpy.size(), 1); +} + QTEST_MAIN(tst_qquickflickable) #include "tst_qquickflickable.moc"