From fb15206453faa8db26feb197dac3d16a8d6dfa1b Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Tue, 21 Jun 2016 13:40:15 +0200 Subject: [PATCH] ungrab touch points if the MultiPointTouchArea is hidden or disabled This caused MPTA to not emit onCanceled and caused the touch points 'pressed' property to not become 'false' after the MPTA was hidden or disabled. We now ungrab the touch points where we already ungrabbed the mouse. Change-Id: I90a5d4fa4b3fa470b8b60881c80418e79061f001 Task-number: QTBUG-42928 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickitem.cpp | 4 ++ .../qquickmultipointtoucharea/data/cancel.qml | 41 ++++++++++++++ .../tst_qquickmultipointtoucharea.cpp | 55 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 tests/auto/quick/qquickmultipointtoucharea/data/cancel.qml diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index d0f5f162fc..1c7a556540 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -5715,6 +5715,8 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible) QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window); if (windowPriv->mouseGrabberItem == q) q->ungrabMouse(); + if (!effectiveVisible) + q->ungrabTouchPoints(); } bool childVisibilityChanged = false; @@ -5763,6 +5765,8 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window); if (windowPriv->mouseGrabberItem == q) q->ungrabMouse(); + if (!effectiveEnable) + q->ungrabTouchPoints(); if (scope && !effectiveEnable && activeFocus) { windowPriv->clearFocusInScope( scope, q, Qt::OtherFocusReason, QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem); diff --git a/tests/auto/quick/qquickmultipointtoucharea/data/cancel.qml b/tests/auto/quick/qquickmultipointtoucharea/data/cancel.qml new file mode 100644 index 0000000000..e108003bca --- /dev/null +++ b/tests/auto/quick/qquickmultipointtoucharea/data/cancel.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +MultiPointTouchArea { + width: 240 + height: 320 + + minimumTouchPoints: 1 + maximumTouchPoints: 5 + touchPoints: [ + TouchPoint { objectName: "point1" }, + TouchPoint { objectName: "point2" }, + TouchPoint { objectName: "point3" }, + TouchPoint { objectName: "point4" }, + TouchPoint { objectName: "point5" } + ] + + function clearCounts() { + touchPointPressCount = 0; + touchPointUpdateCount = 0; + touchPointReleaseCount = 0; + touchPointCancelCount = 0; + touchCount = 0; + touchUpdatedHandled = false; + } + + property int touchPointPressCount: 0 + property int touchPointUpdateCount: 0 + property int touchPointReleaseCount: 0 + property int touchPointCancelCount: 0 + property int touchCount: 0 + property bool touchUpdatedHandled: false + + onPressed: { touchPointPressCount = touchPoints.length } + onUpdated: { touchPointUpdateCount = touchPoints.length } + onReleased: { touchPointReleaseCount = touchPoints.length } + onCanceled: { touchPointCancelCount = touchPoints.length } + onTouchUpdated: { + touchCount = touchPoints.length + touchUpdatedHandled = true + } +} diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp index 4da4767d7b..2f432e57bc 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -74,6 +74,7 @@ private slots: void transformedTouchArea(); void mouseInteraction(); void mouseInteraction_data(); + void cancel(); private: QQuickView *createAndShowView(const QString &file); @@ -1200,6 +1201,60 @@ void tst_QQuickMultiPointTouchArea::mouseInteraction() QCOMPARE(area->property("touchCount").toInt(), 0); } +void tst_QQuickMultiPointTouchArea::cancel() +{ + QScopedPointer window(createAndShowView("cancel.qml")); + QVERIFY(window->rootObject() != 0); + + QQuickMultiPointTouchArea *area = qobject_cast(window->rootObject()); + QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device); + QQuickTouchPoint *point1 = area->findChild("point1"); + + QPoint p1(20,100); + sequence.press(0, p1).commit(); + QQuickTouchUtils::flush(window.data()); + QCOMPARE(point1->pressed(), true); + QCOMPARE(area->property("touchPointPressCount").toInt(), 1); + QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); + QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); + QCOMPARE(area->property("touchPointCancelCount").toInt(), 0); + QCOMPARE(area->property("touchCount").toInt(), 1); + QMetaObject::invokeMethod(area, "clearCounts"); + + area->setVisible(false); + // we should get a onCancel signal + QCOMPARE(point1->pressed(), false); + QCOMPARE(area->property("touchPointPressCount").toInt(), 0); + QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); + QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); + QCOMPARE(area->property("touchPointCancelCount").toInt(), 1); + QCOMPARE(area->property("touchCount").toInt(), 0); + QMetaObject::invokeMethod(area, "clearCounts"); + area->setVisible(true); + + + sequence.press(0, p1).commit(); + QQuickTouchUtils::flush(window.data()); + QCOMPARE(point1->pressed(), true); + QCOMPARE(area->property("touchPointPressCount").toInt(), 1); + QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); + QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); + QCOMPARE(area->property("touchPointCancelCount").toInt(), 0); + QCOMPARE(area->property("touchCount").toInt(), 1); + QMetaObject::invokeMethod(area, "clearCounts"); + + area->setEnabled(false); + // we should get a onCancel signal + QCOMPARE(point1->pressed(), false); + QCOMPARE(area->property("touchPointPressCount").toInt(), 0); + QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); + QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); + QCOMPARE(area->property("touchPointCancelCount").toInt(), 1); + QCOMPARE(area->property("touchCount").toInt(), 0); + QMetaObject::invokeMethod(area, "clearCounts"); + +} + QTEST_MAIN(tst_QQuickMultiPointTouchArea)