Remove redundant touch processing in QtGui and widgets.
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>
Sat, 10 Dec 2011 14:30:18 +0000 (16:30 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 14 Dec 2011 12:17:19 +0000 (13:17 +0100)
The duplicated hash tables in QGuiApplicationPrivate and
QApplicationPrivate are now unified into one single hash table in
QGuiApplicationPrivate. This also reduced the number of lookups.

The extra processing needed to keep the touch points' first/lastPos
values in sync is now done only once, in QGuiApplication. This
eliminates the performance penalty (for widget-based apps) that was
introduced during the QPA migration.

As an added bonus the patch adds support for touch events arriving
simultaenously from multiple devices. This was broken before: As there
is no guarantee that two devices/drivers will not send touch points
with the same ID, using structures with only the ID as key is
wrong. The proper key is composed of the device ID (that is, a
QTouchDevice pointer) and the touch point ID.

The exported internal function qt_translateRawTouchEvent() has been
removed. This function cannot work properly in the QPA world: It
injected touches into the widget subsystem (QApplication) only which
is wrong, and would result in half-filled touch events due to not
routing the injected data through QGuiApplication. Autotests using
this function are migrated to
QWindowSystemInterface::handleTouchEvent().

Change-Id: I7632781d77f9e0ac4626fd7c9933511c94492156
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
dist/changes-5.0.0
src/gui/kernel/qguiapplication.cpp
src/gui/kernel/qguiapplication_p.h
src/testlib/qtesttouch.h
src/widgets/kernel/qapplication.cpp
src/widgets/kernel/qapplication_p.h
tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp
tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp

index daf68ee..8dbda70 100644 (file)
@@ -113,6 +113,10 @@ information about a particular change.
 
   * The event type parameter is removed from handleTouchEvent().
 
+- The previously exported function qt_translateRawTouchEvent() has been removed.
+  Use QWindowSystemInterface::handleTouchEvent() instead.
+
+
 ****************************************************************************
 *                           General                                        *
 ****************************************************************************
index dc8e5ed..312d8f5 100644 (file)
@@ -823,6 +823,18 @@ void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::Cl
     QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
 }
 
+Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k)
+{
+    return qHash(k.device) + k.touchPointId;
+}
+
+Q_GUI_EXPORT bool operator==(const QGuiApplicationPrivate::ActiveTouchPointsKey &a,
+                             const QGuiApplicationPrivate::ActiveTouchPointsKey &b)
+{
+    return a.device == b.device
+            && a.touchPointId == b.touchPointId;
+}
+
 void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
 {
     QWindow *window = e->window.data();
@@ -840,13 +852,15 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
         // update state
         QWeakPointer<QWindow> w;
         QTouchEvent::TouchPoint previousTouchPoint;
+        ActiveTouchPointsKey touchInfoKey(e->device, touchPoint.id());
+        ActiveTouchPointsValue &touchInfo = d->activeTouchPoints[touchInfoKey];
         switch (touchPoint.state()) {
         case Qt::TouchPointPressed:
             if (e->device->type() == QTouchDevice::TouchPad) {
                 // on touch-pads, send all touch points to the same widget
-                w = d->windowForTouchPointId.isEmpty()
+                w = d->activeTouchPoints.isEmpty()
                     ? QWeakPointer<QWindow>()
-                    : d->windowForTouchPointId.constBegin().value();
+                    : d->activeTouchPoints.constBegin().value().window;
             }
 
             if (!w) {
@@ -858,7 +872,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
                 w = window;
             }
 
-            d->windowForTouchPointId[touchPoint.id()] = w;
+            touchInfo.window = w;
             touchPoint.d->startScreenPos = touchPoint.screenPos();
             touchPoint.d->lastScreenPos = touchPoint.screenPos();
             touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
@@ -866,14 +880,15 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
             if (touchPoint.pressure() < qreal(0.))
                 touchPoint.d->pressure = qreal(1.);
 
-            d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
+            touchInfo.touchPoint = touchPoint;
             break;
 
         case Qt::TouchPointReleased:
-            w = d->windowForTouchPointId.take(touchPoint.id());
+            w = touchInfo.window;
             if (!w)
                 continue;
-            previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
+
+            previousTouchPoint = touchInfo.touchPoint;
             touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
             touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
             touchPoint.d->startPos = previousTouchPoint.startPos();
@@ -882,14 +897,15 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
             touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
             if (touchPoint.pressure() < qreal(0.))
                 touchPoint.d->pressure = qreal(0.);
+
             break;
 
         default:
-            w = d->windowForTouchPointId.value(touchPoint.id());
+            w = touchInfo.window;
             if (!w)
                 continue;
-            Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
-            previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
+
+            previousTouchPoint = touchInfo.touchPoint;
             touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
             touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
             touchPoint.d->startPos = previousTouchPoint.startPos();
@@ -902,7 +918,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
             // Stationary points might not be delivered down to the receiving item
             // and get their position transformed, keep the old values instead.
             if (touchPoint.state() != Qt::TouchPointStationary)
-                d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
+                touchInfo.touchPoint = touchPoint;
             break;
         }
 
@@ -969,6 +985,16 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
 
         QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
     }
+
+    // Remove released points from the hash table only after the event is
+    // delivered. When the receiver is a widget, QApplication will access
+    // activeTouchPoints during delivery and therefore nothing can be removed
+    // before sending the event.
+    for (int i = 0; i < e->points.count(); ++i) {
+        QTouchEvent::TouchPoint touchPoint = e->points.at(i);
+        if (touchPoint.state() == Qt::TouchPointReleased)
+            d->activeTouchPoints.remove(ActiveTouchPointsKey(e->device, touchPoint.id()));
+    }
 }
 
 void QGuiApplicationPrivate::reportScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e)
index 9c8a2ca..2d13127 100644 (file)
@@ -189,15 +189,29 @@ public:
     QShortcutMap shortcutMap;
 #endif
 
+    struct ActiveTouchPointsKey {
+        ActiveTouchPointsKey(QTouchDevice *dev, int id) : device(dev), touchPointId(id) { }
+        QTouchDevice *device;
+        int touchPointId;
+    };
+    struct ActiveTouchPointsValue {
+        QWeakPointer<QWindow> window;
+        QWeakPointer<QObject> target;
+        QTouchEvent::TouchPoint touchPoint;
+    };
+    QHash<ActiveTouchPointsKey, ActiveTouchPointsValue> activeTouchPoints;
+
 private:
     void init();
 
     static QGuiApplicationPrivate *self;
-
-    QMap<int, QWeakPointer<QWindow> > windowForTouchPointId;
-    QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints;
 };
 
+Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k);
+
+Q_GUI_EXPORT bool operator==(const QGuiApplicationPrivate::ActiveTouchPointsKey &a,
+                             const QGuiApplicationPrivate::ActiveTouchPointsKey &b);
+
 QT_END_NAMESPACE
 
 QT_END_HEADER
index 57085ad..3763a9a 100644 (file)
@@ -62,13 +62,6 @@ QT_BEGIN_NAMESPACE
 
 QT_MODULE(Test)
 
-#ifdef QT_WIDGETS_LIB
-extern Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
-                                                   QTouchDevice *device,
-                                                   const QList<QTouchEvent::TouchPoint> &touchPoints,
-                                                   ulong timestamp);
-#endif
-
 namespace QTest
 {
 
@@ -137,19 +130,43 @@ namespace QTest
                 if (targetWindow)
                 {
                     QWindowSystemInterface::handleTouchEvent(targetWindow, device, touchPointList(points.values()));
-                    QTest::qWait(10);
                 }
 #ifdef QT_WIDGETS_LIB
                 else if (targetWidget)
                 {
-                    qt_translateRawTouchEvent(targetWidget, device, points.values(), 0);
+                    QWindowSystemInterface::handleTouchEvent(targetWidget->windowHandle(), device, touchPointList(points.values()));
                 }
 #endif
             }
+            QCoreApplication::processEvents();
             previousPoints = points;
             points.clear();
         }
 
+        static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt)
+        {
+            QWindowSystemInterface::TouchPoint p;
+            p.id = pt.id();
+            p.flags = pt.flags();
+            p.normalPosition = pt.normalizedPos();
+            p.area = pt.screenRect();
+            p.pressure = pt.pressure();
+            p.state = pt.state();
+            p.velocity = pt.velocity();
+            p.rawPositions = pt.rawScreenPositions();
+            return p;
+        }
+        static QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QList<QTouchEvent::TouchPoint>& pointList)
+        {
+            QList<struct QWindowSystemInterface::TouchPoint> newList;
+
+            Q_FOREACH (QTouchEvent::TouchPoint p, pointList)
+            {
+                newList.append(touchPoint(p));
+            }
+            return newList;
+        }
+
     private:
 #ifdef QT_WIDGETS_LIB
         QTouchEventSequence(QWidget *widget, QTouchDevice *aDevice)
@@ -198,27 +215,6 @@ namespace QTest
                 return window->mapToGlobal(pt);
             return targetWindow ? targetWindow->mapToGlobal(pt) : pt;
         }
-        QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt)
-        {
-            QWindowSystemInterface::TouchPoint p;
-            p.id = pt.id();
-            p.flags = pt.flags();
-            p.normalPosition = pt.screenRect().topLeft();
-            p.area = pt.screenRect();
-            p.pressure = pt.pressure();
-            p.state = pt.state();
-            return p;
-        }
-        QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QList<QTouchEvent::TouchPoint>& pointList)
-        {
-            QList<struct QWindowSystemInterface::TouchPoint> newList;
-
-            Q_FOREACH (QTouchEvent::TouchPoint p, pointList)
-            {
-                newList.append(touchPoint(p));
-            }
-            return newList;
-        }
 
         QMap<int, QTouchEvent::TouchPoint> previousPoints;
         QMap<int, QTouchEvent::TouchPoint> points;
index 4c4cb40..a4a1aa8 100644 (file)
@@ -3904,7 +3904,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
                 // the first widget to accept the TouchBegin gets an implicit grab.
                 for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
                     const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
-                    d->widgetForTouchPointId[touchPoint.id()] = widget;
+                    d->activeTouchPoints[QGuiApplicationPrivate::ActiveTouchPointsKey(touchEvent->device(), touchPoint.id())].target = widget;
                 }
                 break;
             } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
@@ -5168,41 +5168,43 @@ void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEven
 
         rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta);
         touchPoint.d->rect = rect;
-        if (touchPoint.state() == Qt::TouchPointPressed) {
-            touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
-            touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
-        }
+        touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
+        touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
     }
 }
 
 void QApplicationPrivate::initializeMultitouch()
 {
-    widgetForTouchPointId.clear();
-    appCurrentTouchPoints.clear();
-
     initializeMultitouch_sys();
 }
 
 void QApplicationPrivate::cleanupMultitouch()
 {
     cleanupMultitouch_sys();
-
-    widgetForTouchPointId.clear();
-    appCurrentTouchPoints.clear();
 }
 
-int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos)
+QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos)
 {
     int closestTouchPointId = -1;
+    QObject *closestTarget = 0;
     qreal closestDistance = qreal(0.);
-    foreach (const QTouchEvent::TouchPoint &touchPoint, appCurrentTouchPoints) {
-        qreal distance = QLineF(screenPos, touchPoint.screenPos()).length();
-        if (closestTouchPointId == -1 || distance < closestDistance) {
-            closestTouchPointId = touchPoint.id();
-            closestDistance = distance;
+    QHash<ActiveTouchPointsKey, ActiveTouchPointsValue>::const_iterator it = activeTouchPoints.constBegin(),
+            ite = activeTouchPoints.constEnd();
+    while (it != ite) {
+        if (it.key().device == device) {
+            const QTouchEvent::TouchPoint &touchPoint = it->touchPoint;
+            qreal dx = screenPos.x() - touchPoint.screenPos().x();
+            qreal dy = screenPos.y() - touchPoint.screenPos().y();
+            qreal distance = dx * dx + dy * dy;
+            if (closestTouchPointId == -1 || distance < closestDistance) {
+                closestTouchPointId = touchPoint.id();
+                closestDistance = distance;
+                closestTarget = it.value().target.data();
+            }
         }
+        ++it;
     }
-    return closestTouchPointId;
+    return static_cast<QWidget *>(closestTarget);
 }
 
 void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
@@ -5222,91 +5224,46 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
         touchPoint.d = touchPoint.d->detach();
 
         // update state
-        QWeakPointer<QWidget> widget;
-        switch (touchPoint.state()) {
-        case Qt::TouchPointPressed:
-        {
+        QWeakPointer<QObject> target;
+        ActiveTouchPointsKey touchInfoKey(device, touchPoint.id());
+        ActiveTouchPointsValue &touchInfo = d->activeTouchPoints[touchInfoKey];
+        if (touchPoint.state() == Qt::TouchPointPressed) {
             if (device->type() == QTouchDevice::TouchPad) {
                 // on touch-pads, send all touch points to the same widget
-                widget = d->widgetForTouchPointId.isEmpty()
-                         ? QWeakPointer<QWidget>()
-                         : d->widgetForTouchPointId.constBegin().value();
+                target = d->activeTouchPoints.isEmpty()
+                        ? QWeakPointer<QObject>()
+                        : d->activeTouchPoints.constBegin().value().target;
             }
 
-            if (!widget) {
+            if (!target) {
                 // determine which widget this event will go to
                 if (!window)
                     window = QApplication::topLevelAt(touchPoint.screenPos().toPoint());
                 if (!window)
                     continue;
-                widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint()));
-                if (!widget)
-                    widget = window;
+                target = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint()));
+                if (!target)
+                    target = window;
             }
 
             if (device->type() == QTouchDevice::TouchScreen) {
-                int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos());
-                QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId).data();
+                QWidget *closestWidget = d->findClosestTouchPointTarget(device, touchPoint.screenPos());
+                QWidget *widget = static_cast<QWidget *>(target.data());
                 if (closestWidget
-                    && (widget.data()->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget.data()))) {
-                    widget = closestWidget;
+                        && (widget->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget))) {
+                    target = closestWidget;
                 }
             }
 
-            d->widgetForTouchPointId[touchPoint.id()] = widget;
-            touchPoint.d->startScreenPos = touchPoint.screenPos();
-            touchPoint.d->lastScreenPos = touchPoint.screenPos();
-            touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
-            touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
-            if (touchPoint.pressure() < qreal(0.))
-                touchPoint.d->pressure = qreal(1.);
-
-            d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
-            break;
-        }
-        case Qt::TouchPointReleased:
-        {
-            widget = d->widgetForTouchPointId.take(touchPoint.id());
-            if (!widget)
-                continue;
-
-            QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
-            touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
-            touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
-            touchPoint.d->startPos = previousTouchPoint.startPos();
-            touchPoint.d->lastPos = previousTouchPoint.pos();
-            touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
-            touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
-            if (touchPoint.pressure() < qreal(0.))
-                touchPoint.d->pressure = qreal(0.);
-            break;
-        }
-        default:
-            widget = d->widgetForTouchPointId.value(touchPoint.id());
-            if (!widget)
+            touchInfo.target = target;
+        } else {
+            target = touchInfo.target;
+            if (!target)
                 continue;
-
-            Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
-            QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
-            touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
-            touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
-            touchPoint.d->startPos = previousTouchPoint.startPos();
-            touchPoint.d->lastPos = previousTouchPoint.pos();
-            touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
-            touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
-            if (touchPoint.pressure() < qreal(0.))
-                touchPoint.d->pressure = qreal(1.);
-            d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
-            break;
         }
-        Q_ASSERT(widget.data() != 0);
-
-        // make the *scene* functions return the same as the *screen* functions
-        touchPoint.d->sceneRect = touchPoint.screenRect();
-        touchPoint.d->startScenePos = touchPoint.startScreenPos();
-        touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
+        Q_ASSERT(target.data() != 0);
 
-        StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget.data()];
+        StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[static_cast<QWidget *>(target.data())];
         maskAndPoints.first |= touchPoint.state();
         maskAndPoints.second.append(touchPoint);
     }
@@ -5345,7 +5302,7 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
         updateTouchPointsForWidget(widget, &touchEvent);
         touchEvent.setTimestamp(timestamp);
         touchEvent.setWindow(window->windowHandle());
-        touchEvent.setTarget(window);
+        touchEvent.setTarget(widget);
 
         switch (touchEvent.type()) {
         case QEvent::TouchBegin:
@@ -5367,14 +5324,6 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
     }
 }
 
-Q_WIDGETS_EXPORT void qt_translateRawTouchEvent(QWidget *window,
-                                                QTouchDevice *device,
-                                                const QList<QTouchEvent::TouchPoint> &touchPoints,
-                                                ulong timestamp)
-{
-    QApplicationPrivate::translateRawTouchEvent(window, device, touchPoints, timestamp);
-}
-
 #ifndef QT_NO_GESTURES
 QGestureManager* QGestureManager::instance()
 {
index 3841cef..ac4b4ad 100644 (file)
@@ -472,14 +472,12 @@ public:
     QPixmap *ignore_cursor;
 #endif
 
-    QMap<int, QWeakPointer<QWidget> > widgetForTouchPointId;
-    QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints;
     static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent);
     void initializeMultitouch();
     void initializeMultitouch_sys();
     void cleanupMultitouch();
     void cleanupMultitouch_sys();
-    int findClosestTouchPointId(const QPointF &screenPos);
+    QWidget *findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos);
     void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint);
     void removeTouchPoint(int touchPointId);
     static void translateRawTouchEvent(QWidget *widget,
@@ -554,11 +552,6 @@ private:
     static bool isAlien(QWidget *);
 };
 
-Q_WIDGETS_EXPORT void qt_translateRawTouchEvent(QWidget *window,
-                                                QTouchDevice *device,
-                                                const QList<QTouchEvent::TouchPoint> &touchPoints,
-                                                ulong timestamp);
-
 #if defined(Q_WS_WIN)
   extern void qt_win_set_cursor(QWidget *, bool);
 #elif defined(Q_WS_X11)
index 07afe4a..40e627d 100644 (file)
@@ -209,6 +209,8 @@ private slots:
     void deleteInRawEventTranslation();
     void crashInQGraphicsSceneAfterNotHandlingTouchBegin();
     void touchBeginWithGraphicsWidget();
+    void testQGuiAppDelivery();
+    void testMultiDevice();
 
 private:
     QTouchDevice *touchScreenDevice;
@@ -597,10 +599,12 @@ void tst_QTouchEvent::basicRawEventTranslation()
     rawPosList << QPointF(12, 34) << QPointF(56, 78);
     rawTouchPoint.setRawScreenPositions(rawPosList);
     const ulong timestamp = 1234;
-    qt_translateRawTouchEvent(&touchWidget,
-                              touchScreenDevice,
-                              QList<QTouchEvent::TouchPoint>() << rawTouchPoint,
-                              timestamp);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             timestamp,
+                                             touchScreenDevice,
+                                             QTest::QTouchEventSequence::touchPointList(
+                                                 QList<QTouchEvent::TouchPoint>() << rawTouchPoint));
+    QCoreApplication::processEvents();
     QVERIFY(touchWidget.seenTouchBegin);
     QVERIFY(!touchWidget.seenTouchUpdate);
     QVERIFY(!touchWidget.seenTouchEnd);
@@ -632,10 +636,11 @@ void tst_QTouchEvent::basicRawEventTranslation()
     rawTouchPoint.setState(Qt::TouchPointMoved);
     rawTouchPoint.setScreenPos(screenPos + delta);
     rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
-    qt_translateRawTouchEvent(&touchWidget,
-                              touchScreenDevice,
-                              QList<QTouchEvent::TouchPoint>() << rawTouchPoint,
-                              0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchScreenDevice,
+                                             QTest::QTouchEventSequence::touchPointList(QList<QTouchEvent::TouchPoint>() << rawTouchPoint));
+    QCoreApplication::processEvents();
     QVERIFY(touchWidget.seenTouchBegin);
     QVERIFY(touchWidget.seenTouchUpdate);
     QVERIFY(!touchWidget.seenTouchEnd);
@@ -664,10 +669,11 @@ void tst_QTouchEvent::basicRawEventTranslation()
     rawTouchPoint.setState(Qt::TouchPointReleased);
     rawTouchPoint.setScreenPos(screenPos + delta + delta);
     rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
-    qt_translateRawTouchEvent(&touchWidget,
-                              touchScreenDevice,
-                              QList<QTouchEvent::TouchPoint>() << rawTouchPoint,
-                              0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchScreenDevice,
+                                             QTest::QTouchEventSequence::touchPointList(QList<QTouchEvent::TouchPoint>() << rawTouchPoint));
+    QCoreApplication::processEvents();
     QVERIFY(touchWidget.seenTouchBegin);
     QVERIFY(touchWidget.seenTouchUpdate);
     QVERIFY(touchWidget.seenTouchEnd);
@@ -731,7 +737,11 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen()
     rawTouchPoints[1].setState(Qt::TouchPointPressed);
     rawTouchPoints[1].setScreenPos(rightScreenPos);
     rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
-    qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchScreenDevice,
+                                             QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
+    QCoreApplication::processEvents();
     QVERIFY(!touchWidget.seenTouchBegin);
     QVERIFY(!touchWidget.seenTouchUpdate);
     QVERIFY(!touchWidget.seenTouchEnd);
@@ -792,7 +802,11 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen()
     rawTouchPoints[1].setState(Qt::TouchPointMoved);
     rawTouchPoints[1].setScreenPos(centerScreenPos);
     rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
-    qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchScreenDevice,
+                                             QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
+    QCoreApplication::processEvents();
     QVERIFY(!touchWidget.seenTouchBegin);
     QVERIFY(!touchWidget.seenTouchUpdate);
     QVERIFY(!touchWidget.seenTouchEnd);
@@ -853,7 +867,11 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen()
     rawTouchPoints[1].setState(Qt::TouchPointReleased);
     rawTouchPoints[1].setScreenPos(centerScreenPos);
     rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
-    qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchScreenDevice,
+                                             QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
+    QCoreApplication::processEvents();
     QVERIFY(!touchWidget.seenTouchBegin);
     QVERIFY(!touchWidget.seenTouchUpdate);
     QVERIFY(!touchWidget.seenTouchEnd);
@@ -946,7 +964,11 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad()
     rawTouchPoints[1].setState(Qt::TouchPointPressed);
     rawTouchPoints[1].setScreenPos(rightScreenPos);
     rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
-    qt_translateRawTouchEvent(&touchWidget, touchPadDevice, rawTouchPoints, 0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchPadDevice,
+                                             QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
+    QCoreApplication::processEvents();
     QVERIFY(!touchWidget.seenTouchBegin);
     QVERIFY(!touchWidget.seenTouchUpdate);
     QVERIFY(!touchWidget.seenTouchEnd);
@@ -1007,7 +1029,11 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad()
     rawTouchPoints[1].setState(Qt::TouchPointMoved);
     rawTouchPoints[1].setScreenPos(centerScreenPos);
     rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
-    qt_translateRawTouchEvent(&touchWidget, touchPadDevice, rawTouchPoints, 0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchPadDevice,
+                                             QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
+    QCoreApplication::processEvents();
     QVERIFY(!touchWidget.seenTouchBegin);
     QVERIFY(!touchWidget.seenTouchUpdate);
     QVERIFY(!touchWidget.seenTouchEnd);
@@ -1068,7 +1094,11 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad()
     rawTouchPoints[1].setState(Qt::TouchPointReleased);
     rawTouchPoints[1].setScreenPos(centerScreenPos);
     rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
-    qt_translateRawTouchEvent(&touchWidget, touchPadDevice, rawTouchPoints, 0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchPadDevice,
+                                             QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
+    QCoreApplication::processEvents();
     QVERIFY(!touchWidget.seenTouchBegin);
     QVERIFY(!touchWidget.seenTouchUpdate);
     QVERIFY(!touchWidget.seenTouchEnd);
@@ -1326,20 +1356,32 @@ void tst_QTouchEvent::deleteInRawEventTranslation()
     rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry));
 
     // generate begin events on all widgets, the left widget should die
-    qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchScreenDevice,
+                                             QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
+    QCoreApplication::processEvents();
     QVERIFY(pl.isNull() && !pc.isNull() && !pr.isNull());
 
     // generate update events on all widget, the center widget should die
     rawTouchPoints[0].setState(Qt::TouchPointMoved);
     rawTouchPoints[1].setState(Qt::TouchPointMoved);
     rawTouchPoints[2].setState(Qt::TouchPointMoved);
-    qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchScreenDevice,
+                                             QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
+    QCoreApplication::processEvents();
 
     // generate end events on all widget, the right widget should die
     rawTouchPoints[0].setState(Qt::TouchPointReleased);
     rawTouchPoints[1].setState(Qt::TouchPointReleased);
     rawTouchPoints[2].setState(Qt::TouchPointReleased);
-    qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0);
+    QWindowSystemInterface::handleTouchEvent(touchWidget.windowHandle(),
+                                             0,
+                                             touchScreenDevice,
+                                             QTest::QTouchEventSequence::touchPointList(rawTouchPoints));
+    QCoreApplication::processEvents();
 }
 
 void tst_QTouchEvent::crashInQGraphicsSceneAfterNotHandlingTouchBegin()
@@ -1390,12 +1432,12 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget()
     QTest::qWaitForWindowShown(&view);
     view.fitInView(scene.sceneRect());
 
-    QTest::touchEvent(static_cast<QWindow *>(0), touchScreenDevice)
+    QTest::touchEvent(&view, touchScreenDevice)
             .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport());
-    QTest::touchEvent(static_cast<QWindow *>(0), touchScreenDevice)
+    QTest::touchEvent(&view, touchScreenDevice)
             .stationary(0)
             .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
-    QTest::touchEvent(static_cast<QWindow *>(0), touchScreenDevice)
+    QTest::touchEvent(&view, touchScreenDevice)
             .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport())
             .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
 
@@ -1407,12 +1449,12 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget()
     root->reset();
     glassWidget->setWindowFlags(Qt::Window); // make the glassWidget a panel
 
-    QTest::touchEvent(static_cast<QWindow *>(0), touchScreenDevice)
+    QTest::touchEvent(&view, touchScreenDevice)
             .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport());
-    QTest::touchEvent(static_cast<QWindow *>(0), touchScreenDevice)
+    QTest::touchEvent(&view, touchScreenDevice)
             .stationary(0)
             .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
-    QTest::touchEvent(static_cast<QWindow *>(0), touchScreenDevice)
+    QTest::touchEvent(&view, touchScreenDevice)
             .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport())
             .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport());
 
@@ -1425,6 +1467,143 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget()
     delete glassWidget;
 }
 
+class WindowTouchEventFilter : public QObject
+{
+    Q_OBJECT
+public:
+    bool eventFilter(QObject *obj, QEvent *event);
+    struct TouchInfo {
+        QList<QTouchEvent::TouchPoint> points;
+        QEvent::Type lastSeenType;
+    };
+    QMap<QTouchDevice *, TouchInfo> d;
+};
+
+bool WindowTouchEventFilter::eventFilter(QObject *, QEvent *event)
+{
+    if (event->type() == QEvent::TouchBegin
+            || event->type() == QEvent::TouchUpdate
+            || event->type() == QEvent::TouchEnd) {
+        QTouchEvent *te = static_cast<QTouchEvent *>(event);
+        TouchInfo &td = d[te->device()];
+        if (event->type() == QEvent::TouchBegin)
+            td.points.clear();
+        td.points.append(te->touchPoints());
+        td.lastSeenType = event->type();
+    }
+    return false;
+}
+
+void tst_QTouchEvent::testQGuiAppDelivery()
+{
+    QTouchDevice *device = new QTouchDevice;
+    device->setType(QTouchDevice::TouchScreen);
+    QWindowSystemInterface::registerTouchDevice(device);
+
+    QWindow *w = new QWindow;
+    w->setGeometry(100, 100, 100, 100);
+    w->show();
+    QTest::qWaitForWindowShown(w);
+
+    WindowTouchEventFilter filter;
+    w->installEventFilter(&filter);
+
+    QList<QWindowSystemInterface::TouchPoint> points;
+
+    // Pass empty list, should be ignored.
+    QWindowSystemInterface::handleTouchEvent(w, 0, points);
+    QCoreApplication::processEvents();
+    QCOMPARE(filter.d.isEmpty(), true);
+
+    QWindowSystemInterface::TouchPoint tp;
+    tp.id = 0;
+    tp.state = Qt::TouchPointPressed;
+    tp.area = QRectF(120, 120, 20, 20);
+    points.append(tp);
+
+    // Pass 0 as device, should be ignored.
+    QWindowSystemInterface::handleTouchEvent(w, 0, points);
+    QCoreApplication::processEvents();
+    QCOMPARE(filter.d.isEmpty(), true);
+
+    // Now the real thing.
+    QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchBegin
+    QCoreApplication::processEvents();
+    QCOMPARE(filter.d.count(), 1);
+    QCOMPARE(filter.d.contains(device), true);
+    QCOMPARE(filter.d.value(device).points.count(), 1);
+    QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchBegin);
+
+    points[0].state = Qt::TouchPointMoved;
+    QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchUpdate
+    QCoreApplication::processEvents();
+    QCOMPARE(filter.d.count(), 1);
+    QCOMPARE(filter.d.contains(device), true);
+    QCOMPARE(filter.d.value(device).points.count(), 2);
+    QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchUpdate);
+
+    points[0].state = Qt::TouchPointReleased;
+    QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchEnd
+    QCoreApplication::processEvents();
+    QCOMPARE(filter.d.count(), 1);
+    QCOMPARE(filter.d.contains(device), true);
+    QCOMPARE(filter.d.value(device).points.count(), 3);
+    QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchEnd);
+}
+
+void tst_QTouchEvent::testMultiDevice()
+{
+    QTouchDevice *deviceOne = new QTouchDevice;
+    deviceOne->setType(QTouchDevice::TouchScreen);
+    QWindowSystemInterface::registerTouchDevice(deviceOne);
+    QTouchDevice *deviceTwo = new QTouchDevice;
+    deviceTwo->setType(QTouchDevice::TouchScreen);
+    QWindowSystemInterface::registerTouchDevice(deviceTwo);
+
+    QWindow *w = new QWindow;
+    w->setGeometry(100, 100, 100, 100);
+    w->show();
+    QTest::qWaitForWindowShown(w);
+
+    WindowTouchEventFilter filter;
+    w->installEventFilter(&filter);
+
+    QList<QWindowSystemInterface::TouchPoint> pointsOne, pointsTwo;
+
+    // deviceOne reports a single point, deviceTwo reports the beginning of a multi-point sequence.
+    // Even though there is a point with id 0 for both devices, they should be delivered cleanly, independently.
+    QWindowSystemInterface::TouchPoint tp;
+    tp.id = 0;
+    tp.state = Qt::TouchPointPressed;
+    tp.area = QRectF(120, 120, 20, 20);
+    pointsOne.append(tp);
+
+    pointsTwo.append(tp);
+    tp.id = 1;
+    tp.area = QRectF(140, 140, 20, 20);
+    pointsTwo.append(tp);
+
+    QWindowSystemInterface::handleTouchEvent(w, deviceOne, pointsOne);
+    QWindowSystemInterface::handleTouchEvent(w, deviceTwo, pointsTwo);
+    QCoreApplication::processEvents();
+
+    QCOMPARE(filter.d.contains(deviceOne), true);
+    QCOMPARE(filter.d.contains(deviceTwo), true);
+
+    QCOMPARE(filter.d.value(deviceOne).lastSeenType, QEvent::TouchBegin);
+    QCOMPARE(filter.d.value(deviceTwo).lastSeenType, QEvent::TouchBegin);
+    QCOMPARE(filter.d.value(deviceOne).points.count(), 1);
+    QCOMPARE(filter.d.value(deviceTwo).points.count(), 2);
+
+    QCOMPARE(filter.d.value(deviceOne).points.at(0).screenRect(), pointsOne[0].area);
+    QCOMPARE(filter.d.value(deviceOne).points.at(0).state(), pointsOne[0].state);
+
+    QCOMPARE(filter.d.value(deviceTwo).points.at(0).screenRect(), pointsTwo[0].area);
+    QCOMPARE(filter.d.value(deviceTwo).points.at(0).state(), pointsTwo[0].state);
+    QCOMPARE(filter.d.value(deviceTwo).points.at(1).screenRect(), pointsTwo[1].area);
+    QCOMPARE(filter.d.value(deviceTwo).points.at(1).state(), pointsTwo[1].state);
+}
+
 QTEST_MAIN(tst_QTouchEvent)
 
 #include "tst_qtouchevent.moc"      
index 81cdffe..4de05e1 100644 (file)
@@ -1941,23 +1941,52 @@ void tst_QApplication::touchEventPropagation()
         // touch event behavior on a window
         TouchEventPropagationTestWidget window;
         window.setObjectName("1. window");
-
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        window.show(); // Must have an explicitly specified QWindow for handleTouchEvent,
+                       // passing 0 would result in using topLevelAt() which is not ok in this case
+                       // as the screen position in the point is bogus.
+        QTest::qWaitForWindowShown(&window);
+        // QPA always takes screen positions and since we map the TouchPoint back to QPA's structure first,
+        // we must ensure there is a screen position in the TouchPoint that maps to a local 0, 0.
+        pressedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0)));
+        releasedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0)));
+
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(!window.seenTouchEvent);
         QVERIFY(!window.seenMouseEvent);
 
         window.reset();
         window.setAttribute(Qt::WA_AcceptTouchEvents);
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(window.seenTouchEvent);
         QVERIFY(!window.seenMouseEvent);
 
         window.reset();
         window.acceptTouchEvent = true;
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(window.seenTouchEvent);
         QVERIFY(!window.seenMouseEvent);
     }
@@ -1968,9 +1997,20 @@ void tst_QApplication::touchEventPropagation()
         window.setObjectName("2. window");
         TouchEventPropagationTestWidget widget(&window);
         widget.setObjectName("2. widget");
-
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        window.show();
+        QTest::qWaitForWindowShown(&window);
+        pressedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0)));
+        releasedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0)));
+
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(!widget.seenTouchEvent);
         QVERIFY(!widget.seenMouseEvent);
         QVERIFY(!window.seenTouchEvent);
@@ -1979,8 +2019,15 @@ void tst_QApplication::touchEventPropagation()
         window.reset();
         widget.reset();
         widget.setAttribute(Qt::WA_AcceptTouchEvents);
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(widget.seenTouchEvent);
         QVERIFY(!widget.seenMouseEvent);
         QVERIFY(!window.seenTouchEvent);
@@ -1989,8 +2036,15 @@ void tst_QApplication::touchEventPropagation()
         window.reset();
         widget.reset();
         widget.acceptMouseEvent = true;
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(widget.seenTouchEvent);
         QVERIFY(!widget.seenMouseEvent);
         QVERIFY(!window.seenTouchEvent);
@@ -1999,8 +2053,15 @@ void tst_QApplication::touchEventPropagation()
         window.reset();
         widget.reset();
         widget.acceptTouchEvent = true;
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(widget.seenTouchEvent);
         QVERIFY(!widget.seenMouseEvent);
         QVERIFY(!window.seenTouchEvent);
@@ -2010,8 +2071,15 @@ void tst_QApplication::touchEventPropagation()
         widget.reset();
         widget.setAttribute(Qt::WA_AcceptTouchEvents, false);
         window.setAttribute(Qt::WA_AcceptTouchEvents);
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(!widget.seenTouchEvent);
         QVERIFY(!widget.seenMouseEvent);
         QVERIFY(window.seenTouchEvent);
@@ -2020,8 +2088,15 @@ void tst_QApplication::touchEventPropagation()
         window.reset();
         widget.reset();
         window.acceptTouchEvent = true;
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(!widget.seenTouchEvent);
         QVERIFY(!widget.seenMouseEvent);
         QVERIFY(window.seenTouchEvent);
@@ -2031,8 +2106,15 @@ void tst_QApplication::touchEventPropagation()
         widget.reset();
         widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first
         window.acceptTouchEvent = true;
-        qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0);
-        qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0);
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(pressedTouchPoints));
+        QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
+                                                 0,
+                                                 device,
+                                                 QTest::QTouchEventSequence::touchPointList(releasedTouchPoints));
+        QCoreApplication::processEvents();
         QVERIFY(!widget.seenTouchEvent);
         QVERIFY(!widget.seenMouseEvent);
         QVERIFY(window.seenTouchEvent);