Fix unhandled touch events not being ignored.
authorSimon Hausmann <simon.hausmann@nokia.com>
Mon, 30 Jan 2012 16:04:42 +0000 (17:04 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 2 Feb 2012 07:16:43 +0000 (08:16 +0100)
Unhandled touch events need to be ignored in order for things like
mouse event synthetization in QtGui to work.

Change-Id: I6fe9dad205c8bb8547d2424c2e2a3b3518598006
Reviewed-by: Andras Becsi <andras.becsi@nokia.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>

src/quick/items/qquickcanvas.cpp
tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp

index 5aa244c..8f4078d 100644 (file)
@@ -1063,6 +1063,8 @@ bool QQuickCanvasPrivate::deliverTouchEvent(QTouchEvent *event)
         deliverTouchPoints(rootItem, event, event->touchPoints(), &acceptedNewPoints, &updatedPoints);
         if (acceptedNewPoints.count() > 0)
             event->accept();
+        else
+            event->ignore();
         return event->isAccepted();
     }
 
@@ -1095,7 +1097,10 @@ bool QQuickCanvasPrivate::deliverTouchEvent(QTouchEvent *event)
         deliverTouchPoints(rootItem, event, newPoints, &acceptedNewPoints, &updatedPoints);
         if (acceptedNewPoints.count() > 0 || updatedPoints.count() != prevCount)
             event->accept();
-    }
+        else
+            event->ignore();
+    } else
+        event->ignore();
 
     if (event->touchPointStates() & Qt::TouchPointReleased) {
         for (int i=0; i<touchPoints.count(); i++) {
index 099f29d..5f90e89 100644 (file)
@@ -55,18 +55,26 @@ class TestItem : public QQuickItem
 {
 Q_OBJECT
 public:
-    TestItem(QQuickItem *parent = 0) : QQuickItem(parent), focused(false), pressCount(0), releaseCount(0), wheelCount(0) {}
+    TestItem(QQuickItem *parent = 0)
+        : QQuickItem(parent), focused(false), pressCount(0), releaseCount(0)
+        , wheelCount(0), acceptIncomingTouchEvents(true)
+        , touchEventReached(false) {}
 
     bool focused;
     int pressCount;
     int releaseCount;
     int wheelCount;
+    bool acceptIncomingTouchEvents;
+    bool touchEventReached;
 protected:
     virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; }
     virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; }
     virtual void mousePressEvent(QMouseEvent *event) { event->accept(); ++pressCount; }
     virtual void mouseReleaseEvent(QMouseEvent *event) { event->accept(); ++releaseCount; }
-    virtual void touchEvent(QTouchEvent *event) { event->accept(); }
+    virtual void touchEvent(QTouchEvent *event) {
+        touchEventReached = true;
+        event->setAccepted(acceptIncomingTouchEvents);
+    }
     virtual void wheelEvent(QWheelEvent *event) { event->accept(); ++wheelCount; }
 };
 
@@ -139,7 +147,8 @@ private slots:
     void enabledFocus();
 
     void mouseGrab();
-    void touchEventAccept();
+    void touchEventAcceptIgnore_data();
+    void touchEventAcceptIgnore();
     void polishOutsideAnimation();
     void polishOnCompleted();
 
@@ -1016,8 +1025,18 @@ void tst_qquickitem::mouseGrab()
     delete canvas;
 }
 
-void tst_qquickitem::touchEventAccept()
+void tst_qquickitem::touchEventAcceptIgnore_data()
+{
+    QTest::addColumn<bool>("itemSupportsTouch");
+
+    QTest::newRow("with touch") << true;
+    QTest::newRow("without touch") << false;
+}
+
+void tst_qquickitem::touchEventAcceptIgnore()
 {
+    QFETCH(bool, itemSupportsTouch);
+
     TestCanvas *canvas = new TestCanvas;
     canvas->resize(100, 100);
     canvas->show();
@@ -1025,18 +1044,77 @@ void tst_qquickitem::touchEventAccept()
     TestItem *item = new TestItem;
     item->setSize(QSizeF(100, 100));
     item->setParentItem(canvas->rootItem());
+    item->acceptIncomingTouchEvents = itemSupportsTouch;
 
-    static QTouchDevice* device = new QTouchDevice;
-    device->setType(QTouchDevice::TouchScreen);
-    QWindowSystemInterface::registerTouchDevice(device);
+    static QTouchDevice* device = 0;
+    if (!device) {
+        device =new QTouchDevice;
+        device->setType(QTouchDevice::TouchScreen);
+        QWindowSystemInterface::registerTouchDevice(device);
+    }
+
+    // Send Begin, Update & End touch sequence
+    {
+        QTouchEvent::TouchPoint point;
+        point.setId(1);
+        point.setPos(QPointF(50, 50));
+        point.setScreenPos(point.pos());
+        point.setState(Qt::TouchPointPressed);
 
-    QTouchEvent *event = new QTouchEvent(QEvent::TouchBegin, device);
+        QTouchEvent event(QEvent::TouchBegin, device,
+                          Qt::NoModifier,
+                          Qt::TouchPointPressed,
+                          QList<QTouchEvent::TouchPoint>() << point);
+        event.setAccepted(true);
 
-    bool accepted = canvas->event(event);
+        item->touchEventReached = false;
 
-    QVERIFY(accepted && event->isAccepted());
+        bool accepted = canvas->event(&event);
+
+        QVERIFY(item->touchEventReached);
+        QCOMPARE(accepted && event.isAccepted(), itemSupportsTouch);
+    }
+    {
+        QTouchEvent::TouchPoint point;
+        point.setId(1);
+        point.setPos(QPointF(60, 60));
+        point.setScreenPos(point.pos());
+        point.setState(Qt::TouchPointMoved);
+
+        QTouchEvent event(QEvent::TouchUpdate, device,
+                          Qt::NoModifier,
+                          Qt::TouchPointMoved,
+                          QList<QTouchEvent::TouchPoint>() << point);
+        event.setAccepted(true);
+
+        item->touchEventReached = false;
+
+        bool accepted = canvas->event(&event);
+
+        QCOMPARE(item->touchEventReached, itemSupportsTouch);
+        QCOMPARE(accepted && event.isAccepted(), itemSupportsTouch);
+    }
+    {
+        QTouchEvent::TouchPoint point;
+        point.setId(1);
+        point.setPos(QPointF(60, 60));
+        point.setScreenPos(point.pos());
+        point.setState(Qt::TouchPointReleased);
+
+        QTouchEvent event(QEvent::TouchEnd, device,
+                          Qt::NoModifier,
+                          Qt::TouchPointReleased,
+                          QList<QTouchEvent::TouchPoint>() << point);
+        event.setAccepted(true);
+
+        item->touchEventReached = false;
+
+        bool accepted = canvas->event(&event);
+
+        QCOMPARE(item->touchEventReached, itemSupportsTouch);
+        QCOMPARE(accepted && event.isAccepted(), itemSupportsTouch);
+    }
 
-    delete event;
     delete item;
     delete canvas;
 }