diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 7eac4fe471..cda8e62587 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1546,6 +1546,15 @@ void QQuickFlickable::mouseReleaseEvent(QMouseEvent *event) void QQuickFlickable::touchEvent(QTouchEvent *event) { Q_D(QQuickFlickable); + + if (event->type() == QEvent::TouchCancel) { + if (d->interactive && d->wantsPointerEvent(event)) + d->cancelInteraction(); + else + QQuickItem::touchEvent(event); + return; + } + bool unhandled = false; const auto &firstPoint = event->points().first(); switch (firstPoint.state()) { diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 7c0bdcadea..37810c967d 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -224,6 +224,7 @@ private slots: void setContentPositionWhileDragging(); void coalescedMove(); void onlyOneMove(); + void touchCancel(); private: void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to); @@ -3236,6 +3237,34 @@ void tst_qquickflickable::onlyOneMove() QCOMPARE(flickEndedSpy.size(), 1); } +void tst_qquickflickable::touchCancel() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("flickable03.qml"))); + QQuickViewTestUtils::centerOnScreen(&window); + QVERIFY(window.isVisible()); + + QQuickFlickable *flickable = qobject_cast(window.rootObject()); + QVERIFY(flickable != nullptr); + + QSignalSpy movementStartedSpy(flickable, SIGNAL(movementStarted())); + QSignalSpy movementEndedSpy(flickable, SIGNAL(movementEnded())); + + int touchPosY = 10; + QTest::touchEvent(&window, touchDevice).press(0, {10, touchPosY}).commit(); + QQuickTouchUtils::flush(&window); + + for (int i = 0; i < 3; ++i) { + touchPosY += qApp->styleHints()->startDragDistance(); + QTest::touchEvent(&window, touchDevice).move(0, {10, touchPosY}).commit(); + QQuickTouchUtils::flush(&window); + } + + QTRY_COMPARE(movementStartedSpy.size(), 1); + QWindowSystemInterface::handleTouchCancelEvent(nullptr, touchDevice); + QTRY_COMPARE(movementEndedSpy.size(), 1); +} + QTEST_MAIN(tst_qquickflickable) #include "tst_qquickflickable.moc"