QQuickFlickable: release drag if receiving QEvent::TouchCancel

If a TouchCancel event is sent to a Flickable, it should abort
any current dragging operation done by the user. This patch will
ensure that we do so.

Fixes: QTBUG-117160
Change-Id: Iff332e597a0502396c2fd0e4988f01ab2119314d
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Reviewed-by: Seokha Ko <seokha.ko@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 5093e4c243)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 3544aae728)
This commit is contained in:
Richard Moe Gustavsen 2023-10-17 14:51:21 +02:00 committed by Shawn Rutledge
parent d0ab1d4a92
commit c6f88a807c
2 changed files with 38 additions and 0 deletions

View File

@ -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()) {

View File

@ -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<QQuickFlickable*>(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"