Flickable containing MultiPointTouchArea is unresponsive following touch.
authorMartin Jones <martin.jones@nokia.com>
Fri, 25 May 2012 03:28:22 +0000 (13:28 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 28 May 2012 03:30:34 +0000 (05:30 +0200)
MPTA was releasing the mouse grab when all touches were
released, causing the mouse release event to not be propagated
to its parents, who were then unable to correct their state.
Remove this code and allow the normal event handlers to do their
thing.

This is the same fix as was implemented for PinchArea in
9634dc440269fc03f825a6d18b371d8e612ba9ec

Change-Id: I2715677157f5838e3f81137f64765024cf2f0459
Reviewed-by: Andrew den Exter <andrew.den-exter@nokia.com>

src/quick/items/qquickmultipointtoucharea.cpp
tests/auto/quick/qquickmultipointtoucharea/data/inFlickable2.qml [new file with mode: 0644]
tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp

index 369a069..6f10ea7 100644 (file)
@@ -398,9 +398,6 @@ void QQuickMultiPointTouchArea::touchEvent(QTouchEvent *event)
             //TODO: move to canvas
             _stealMouse = false;
             setKeepMouseGrab(false);
-            QQuickCanvas *c = canvas();
-            if (c && c->mouseGrabberItem() == this)
-                ungrabMouse();
             setKeepTouchGrab(false);
             ungrabTouchPoints();
         }
@@ -698,9 +695,6 @@ bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *i, QEvent *eve
             //TODO: verify this behavior
             _stealMouse = false;
             setKeepMouseGrab(false);
-            QQuickCanvas *c = canvas();
-            if (c && c->mouseGrabberItem() == this)
-                ungrabMouse();
             setKeepTouchGrab(false);
             ungrabTouchPoints();
         }
diff --git a/tests/auto/quick/qquickmultipointtoucharea/data/inFlickable2.qml b/tests/auto/quick/qquickmultipointtoucharea/data/inFlickable2.qml
new file mode 100644 (file)
index 0000000..48773a1
--- /dev/null
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+
+Item {
+  width: 320
+  height: 400
+
+  Flickable {
+    objectName: "flickable"
+    width: 100
+    height: 400
+
+    flickableDirection: Flickable.VerticalFlick
+    contentHeight: 800
+
+    Rectangle {
+        property bool highlight: false
+        width: 300
+        height: 350
+        color: "green"
+
+        MultiPointTouchArea {
+            anchors.fill: parent
+            minimumTouchPoints: 1
+            maximumTouchPoints: 1
+            touchPoints: [ TouchPoint { id: point1; objectName: "point1" } ]
+        }
+    }
+
+  }
+}
index 063edbc..c5ede26 100644 (file)
@@ -70,6 +70,7 @@ private slots:
     void nonOverlapping();
     void nested();
     void inFlickable();
+    void inFlickable2();
     void invisible();
 
 private:
@@ -687,6 +688,88 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
     delete canvas;
 }
 
+// test that dragging out of a Flickable containing a MPTA doesn't harm Flickable's state.
+void tst_QQuickMultiPointTouchArea::inFlickable2()
+{
+    QQuickView *canvas = createAndShowView("inFlickable2.qml");
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickFlickable *flickable = canvas->rootObject()->findChild<QQuickFlickable*>("flickable");
+    QVERIFY(flickable != 0);
+
+    QQuickTouchPoint *point11 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point1");
+    QVERIFY(point11);
+
+    QCOMPARE(point11->pressed(), false);
+
+    QPoint p1(50,100);
+
+    // move point horizontally, out of Flickable area
+    QTest::touchEvent(canvas, device).press(0, p1);
+    QTest::mousePress(canvas, Qt::LeftButton, 0, p1);
+
+    p1 += QPoint(15,0);
+    QTest::touchEvent(canvas, device).move(0, p1);
+    QTest::mouseMove(canvas, p1);
+
+    p1 += QPoint(15,0);
+    QTest::touchEvent(canvas, device).move(0, p1);
+    QTest::mouseMove(canvas, p1);
+
+    p1 += QPoint(15,0);
+    QTest::touchEvent(canvas, device).move(0, p1);
+    QTest::mouseMove(canvas, p1);
+
+    p1 += QPoint(15,0);
+    QTest::touchEvent(canvas, device).move(0, p1);
+    QTest::mouseMove(canvas, p1);
+
+    QVERIFY(!flickable->isMoving());
+    QVERIFY(point11->pressed());
+
+    QTest::touchEvent(canvas, device).release(0, p1);
+    QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1);
+    QTest::qWait(50);
+
+    QTRY_VERIFY(!flickable->isMoving());
+
+    // Check that we can still move the Flickable
+    p1 = QPoint(50,100);
+    QTest::touchEvent(canvas, device).press(0, p1);
+    QTest::mousePress(canvas, Qt::LeftButton, 0, p1);
+
+    QCOMPARE(point11->pressed(), true);
+
+    p1 += QPoint(0,15);
+    QTest::touchEvent(canvas, device).move(0, p1);
+    QTest::mouseMove(canvas, p1);
+
+    p1 += QPoint(0,15);
+    QTest::touchEvent(canvas, device).move(0, p1);
+    QTest::mouseMove(canvas, p1);
+
+    p1 += QPoint(0,15);
+    QTest::touchEvent(canvas, device).move(0, p1);
+    QTest::mouseMove(canvas, p1);
+
+    p1 += QPoint(0,15);
+    QTest::touchEvent(canvas, device).move(0, p1);
+    QTest::mouseMove(canvas, p1);
+
+    QVERIFY(flickable->contentY() < 0);
+    QVERIFY(flickable->isMoving());
+    QCOMPARE(point11->pressed(), false);
+
+    QTest::touchEvent(canvas, device).release(0, p1);
+    QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1);
+    QTest::qWait(50);
+
+    QTRY_VERIFY(!flickable->isMoving());
+
+
+    delete canvas;
+}
+
 // QTBUG-23327
 void tst_QQuickMultiPointTouchArea::invisible()
 {