From c0100e28cadf8260769eddcc7a0306d832fed92b Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 10 Feb 2012 13:43:00 +0200 Subject: [PATCH] Add basic TouchCancel handling to canvas. This makes sure that touchEvent() is properly called for all items in the scene that have an active touch. It does not handle the cancel event in any other special way. Change-Id: Id66527ced8cb63d0b29f25f37c139e6d6aec9ba0 Reviewed-by: Michael Brasser Reviewed-by: Martin Jones --- src/quick/items/qquickcanvas.cpp | 21 +++++++++++++ .../qtquick2/qquickcanvas/tst_qquickcanvas.cpp | 35 +++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp index 52344d6..cb60a23 100644 --- a/src/quick/items/qquickcanvas.cpp +++ b/src/quick/items/qquickcanvas.cpp @@ -824,6 +824,7 @@ bool QQuickCanvas::event(QEvent *e) case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: + case QEvent::TouchCancel: { QTouchEvent *touch = static_cast(e); d->translateTouchEvent(touch); @@ -1165,8 +1166,12 @@ bool QQuickCanvasPrivate::deliverTouchEvent(QTouchEvent *event) qWarning("touchUpdateEvent"); else if (event->type() == QEvent::TouchEnd) qWarning("touchEndEvent"); + else if (event->type() == QEvent::TouchCancel) + qWarning("touchCancelEvent"); #endif + Q_Q(QQuickCanvas); + QHash > updatedPoints; if (event->type() == QTouchEvent::TouchBegin) { // all points are new touch points @@ -1179,6 +1184,21 @@ bool QQuickCanvasPrivate::deliverTouchEvent(QTouchEvent *event) return event->isAccepted(); } + if (event->type() == QTouchEvent::TouchCancel) { + // A TouchCancel event will typically not contain any points. + // Deliver it to all items that have active touches. + QSet cancelDelivered; + foreach (QQuickItem *item, itemForTouchPointId) { + if (cancelDelivered.contains(item)) + continue; + cancelDelivered.insert(item); + q->sendEvent(item, event); + } + // The next touch event can only be a TouchBegin so clean up. + itemForTouchPointId.clear(); + return true; + } + const QList &touchPoints = event->touchPoints(); QList newPoints; QQuickItem *item = 0; @@ -1497,6 +1517,7 @@ bool QQuickCanvas::sendEvent(QQuickItem *item, QEvent *e) case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: + case QEvent::TouchCancel: // XXX todo - should sendEvent be doing this? how does it relate to forwarded events? if (!d->sendFilteredMouseEvent(item->parentItem(), item, e)) { e->accept(); diff --git a/tests/auto/qtquick2/qquickcanvas/tst_qquickcanvas.cpp b/tests/auto/qtquick2/qquickcanvas/tst_qquickcanvas.cpp index 4a23842..eac0d85 100644 --- a/tests/auto/qtquick2/qquickcanvas/tst_qquickcanvas.cpp +++ b/tests/auto/qtquick2/qquickcanvas/tst_qquickcanvas.cpp @@ -74,7 +74,8 @@ static QTouchEvent::TouchPoint makeTouchPoint(QQuickItem *item, const QPointF &p return tp; } -static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QList& touchPoints) +static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states = 0, + const QList& touchPoints = QList()) { TouchEventData d = { type, 0, w, states, touchPoints }; return d; @@ -197,6 +198,7 @@ private slots: void touchEvent_basic(); void touchEvent_propagation(); void touchEvent_propagation_data(); + void touchEvent_cancel(); void clearCanvas(); @@ -475,6 +477,37 @@ void tst_qquickcanvas::touchEvent_propagation_data() QTest::newRow("opacity of 0") << true << true << 0.0; } +void tst_qquickcanvas::touchEvent_cancel() +{ + TestTouchItem::clearMousePressCounter(); + + QQuickCanvas *canvas = new QQuickCanvas; + canvas->resize(250, 250); + canvas->move(100, 100); + canvas->show(); + + TestTouchItem *item = new TestTouchItem(canvas->rootItem()); + item->setPos(QPointF(50, 50)); + item->setSize(QSizeF(150, 150)); + + QPointF pos(10, 10); + QTest::touchEvent(canvas, touchDevice).press(0, item->mapToScene(pos).toPoint(),canvas); + QCoreApplication::processEvents(); + + QTRY_COMPARE(item->lastEvent.touchPoints.count(), 1); + TouchEventData d = makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(item,pos)); + COMPARE_TOUCH_DATA(item->lastEvent, d); + item->reset(); + + QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice); + QCoreApplication::processEvents(); + d = makeTouchData(QEvent::TouchCancel, canvas); + COMPARE_TOUCH_DATA(item->lastEvent, d); + + delete item; + delete canvas; +} + void tst_qquickcanvas::clearCanvas() { QQuickCanvas *canvas = new QQuickCanvas; -- 2.7.4