Compress touch events in QQuickWindow.
authorGunnar Sletta <gunnar.sletta@jollamobile.com>
Thu, 3 Apr 2014 11:16:42 +0000 (11:16 +0000)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 5 May 2014 14:02:45 +0000 (16:02 +0200)
Instead of sending multiple touch updates per frame, we
store the last one and flush the pending events just before
we enter into the scene graph sync phase.

[ChangeLog][QtQuick] QQuickWindow will compresses touch events
and delivers at most one touch event per frame.

Done-with: Robin Burchell <robin.burchell@jollamobile.com>
Change-Id: Ia0169bc4a3f0da67709b91ca65c326934b55d372
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
20 files changed:
src/quick/items/qquickrendercontrol.cpp
src/quick/items/qquickwindow.cpp
src/quick/items/qquickwindow_p.h
src/quick/scenegraph/qsgrenderloop.cpp
src/quick/scenegraph/qsgthreadedrenderloop.cpp
src/quick/scenegraph/qsgthreadedrenderloop_p.h
src/quick/scenegraph/qsgwindowsrenderloop.cpp
tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
tests/auto/quick/qquickitem/qquickitem.pro
tests/auto/quick/qquickitem/tst_qquickitem.cpp
tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
tests/auto/quick/qquickpincharea/qquickpincharea.pro
tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
tests/auto/quick/qquickwindow/qquickwindow.pro
tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
tests/auto/quick/shared/viewtestutil.cpp
tests/auto/quick/shared/viewtestutil.h
tests/auto/quick/touchmouse/touchmouse.pro
tests/auto/quick/touchmouse/tst_touchmouse.cpp

index 10a9691..4a199d9 100644 (file)
@@ -140,6 +140,9 @@ void QQuickRenderControl::polishItems()
         return;
 
     QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+    cd->flushDelayedTouchEvent();
+    if (!d->window)
+        return;
     cd->polishItems();
 }
 
index 49e8f3e..d6cbae7 100644 (file)
@@ -400,6 +400,7 @@ QQuickWindowPrivate::QQuickWindowPrivate()
     , renderer(0)
     , windowManager(0)
     , renderControl(0)
+    , touchRecursionGuard(0)
     , clearColor(Qt::white)
     , clearBeforeRendering(true)
     , persistentGLContext(true)
@@ -458,6 +459,8 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
     animationController = new QQuickAnimatorController();
     animationController->m_window = q;
 
+    delayedTouch = 0;
+
     QObject::connect(context, SIGNAL(initialized()), q, SIGNAL(sceneGraphInitialized()), Qt::DirectConnection);
     QObject::connect(context, SIGNAL(invalidated()), q, SIGNAL(sceneGraphInvalidated()), Qt::DirectConnection);
     QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()), Qt::DirectConnection);
@@ -1712,11 +1715,104 @@ bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
     return true;
 }
 
+static bool qquickwindow_no_touch_compression = qEnvironmentVariableIsSet("QML_NO_TOUCH_COMPRESSION");
+
 // check what kind of touch we have (begin/update) and
 // call deliverTouchPoints to actually dispatch the points
-bool QQuickWindowPrivate::deliverTouchEvent(QTouchEvent *event)
+void QQuickWindowPrivate::deliverTouchEvent(QTouchEvent *event)
 {
     qCDebug(DBG_TOUCH) << event;
+    Q_Q(QQuickWindow);
+
+    if (qquickwindow_no_touch_compression || touchRecursionGuard) {
+        reallyDeliverTouchEvent(event);
+        return;
+    }
+
+    Qt::TouchPointStates states = event->touchPointStates();
+    if (((states & (Qt::TouchPointMoved | Qt::TouchPointStationary)) != 0)
+        && ((states & (Qt::TouchPointPressed | Qt::TouchPointReleased)) == 0)) {
+        // we can only compress something that isn't a press or release
+        if (!delayedTouch) {
+            delayedTouch = new QTouchEvent(event->type(), event->device(), event->modifiers(), event->touchPointStates(), event->touchPoints());
+            delayedTouch->setTimestamp(event->timestamp());
+            if (windowManager)
+                windowManager->maybeUpdate(q);
+            return;
+        } else {
+            // check if this looks like the last touch event
+            if (delayedTouch->type() == event->type() &&
+                delayedTouch->device() == event->device() &&
+                delayedTouch->modifiers() == event->modifiers() &&
+                delayedTouch->touchPoints().count() == event->touchPoints().count())
+            {
+                // possible match.. is it really the same?
+                bool mismatch = false;
+
+                QList<QTouchEvent::TouchPoint> tpts = event->touchPoints();
+                Qt::TouchPointStates states;
+                for (int i = 0; i < event->touchPoints().count(); ++i) {
+                    const QTouchEvent::TouchPoint &tp = tpts.at(i);
+                    const QTouchEvent::TouchPoint &tp2 = delayedTouch->touchPoints().at(i);
+                    if (tp.id() != tp2.id()) {
+                        mismatch = true;
+                        break;
+                    }
+
+                    if (tp2.state() == Qt::TouchPointMoved && tp.state() == Qt::TouchPointStationary)
+                        tpts[i].setState(Qt::TouchPointMoved);
+
+                    states |= tpts.at(i).state();
+                }
+
+                // same touch event? then merge if so
+                if (!mismatch) {
+                    delayedTouch->setTouchPoints(tpts);
+                    delayedTouch->setTimestamp(event->timestamp());
+                    return;
+                }
+            }
+
+            // otherwise; we need to deliver the delayed event first, and
+            // then delay this one..
+            reallyDeliverTouchEvent(delayedTouch);
+            delete delayedTouch;
+            delayedTouch = new QTouchEvent(event->type(), event->device(), event->modifiers(), event->touchPointStates(), event->touchPoints());
+            delayedTouch->setTimestamp(event->timestamp());
+            return;
+        }
+    } else {
+        if (delayedTouch) {
+            // deliver the delayed touch first
+            reallyDeliverTouchEvent(delayedTouch);
+            delete delayedTouch;
+            delayedTouch = 0;
+        }
+        reallyDeliverTouchEvent(event);
+    }
+}
+
+void QQuickWindowPrivate::flushDelayedTouchEvent()
+{
+    if (delayedTouch) {
+        reallyDeliverTouchEvent(delayedTouch);
+        delete delayedTouch;
+        delayedTouch = 0;
+
+        // To flush pending meta-calls triggered from the recently flushed touch events.
+        // This is safe because flushDelayedEvent is only called from eventhandlers.
+        QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+    }
+}
+
+void QQuickWindowPrivate::reallyDeliverTouchEvent(QTouchEvent *event)
+{
+    qCDebug(DBG_TOUCH) << " - delivering" << event;
+
+    // If users spin the eventloop as a result of touch delivery, we disable
+    // touch compression and send events directly. This is because we consider
+    // the usecase a bit evil, but we at least don't want to lose events.
+    ++touchRecursionGuard;
 
     // List of all items that received an event before
     // When we have TouchBegin this is and will stay empty
@@ -1766,7 +1862,7 @@ bool QQuickWindowPrivate::deliverTouchEvent(QTouchEvent *event)
         Q_ASSERT(itemForTouchPointId.isEmpty());
     }
 
-    return event->isAccepted();
+    --touchRecursionGuard;
 }
 
 // This function recurses and sends the events to the individual items
index 872a054..218425c 100644 (file)
@@ -141,8 +141,10 @@ public:
 #endif
     bool deliverTouchPoints(QQuickItem *, QTouchEvent *, const QList<QTouchEvent::TouchPoint> &, QSet<int> *,
             QHash<QQuickItem *, QList<QTouchEvent::TouchPoint> > *);
-    bool deliverTouchEvent(QTouchEvent *);
+    void deliverTouchEvent(QTouchEvent *);
+    void reallyDeliverTouchEvent(QTouchEvent *);
     bool deliverTouchCancelEvent(QTouchEvent *);
+    void flushDelayedTouchEvent();
     bool deliverHoverEvent(QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, bool &accepted);
     bool deliverMatchingPointsToItem(QQuickItem *item, QTouchEvent *event, QSet<int> *acceptedNewPoints, const QSet<int> &matchingNewPoints, const QList<QTouchEvent::TouchPoint> &matchingPoints);
     QTouchEvent *touchEventForItemBounds(QQuickItem *target, const QTouchEvent &originalEvent);
@@ -210,6 +212,8 @@ public:
     QSGRenderLoop *windowManager;
     QQuickRenderControl *renderControl;
     QQuickAnimatorController *animationController;
+    QTouchEvent *delayedTouch;
+    int touchRecursionGuard;
 
     QColor clearColor;
 
index 6647ec8..00e67aa 100644 (file)
@@ -334,6 +334,12 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
     if (!current)
         return;
 
+    if (!data.grabOnly) {
+        cd->flushDelayedTouchEvent();
+        // Event delivery/processing triggered the window to be deleted or stop rendering.
+        if (!m_windows.contains(window))
+            return;
+    }
     cd->polishItems();
 
     emit window->afterAnimating();
index 7b01f64..a5b46b7 100644 (file)
@@ -51,6 +51,8 @@
 #include <QtGui/QScreen>
 #include <QtGui/QOffscreenSurface>
 
+#include <qpa/qwindowsysteminterface.h>
+
 #include <QtQuick/QQuickWindow>
 #include <private/qquickwindow_p.h>
 
@@ -1063,13 +1065,33 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
 {
     QSG_GUI_DEBUG(w->window, "polishAndSync()");
 
-    if (!w->window->isExposed() || !w->window->isVisible() || w->window->size().isEmpty()) {
+    QQuickWindow *window = w->window;
+    if (!window->isExposed() || !window->isVisible() || window->size().isEmpty()) {
         QSG_GUI_DEBUG(w->window, " - not exposed, aborting...");
         killTimer(w->timerId);
         w->timerId = 0;
         return;
     }
 
+    // Flush pending touch events.
+    // First we force flushing of the windowing system events, so that we're
+    // working with the latest possible data. This can trigger event processing
+    // which in turn can stop rendering this window, so verify that before
+    // proceeding. Then we flush the touch event and as that also does event
+    // processing, verify again that we still are active and rendering.
+    QWindowSystemInterface::flushWindowSystemEvents();
+    w = windowFor(m_windows, window);
+    if (w) {
+        QQuickWindowPrivate::get(window)->flushDelayedTouchEvent();
+        w = windowFor(m_windows, window);
+    }
+    if (!w) {
+        QSG_GUI_DEBUG(w->window, " - removed after event flushing..");
+        killTimer(w->timerId);
+        w->timerId = 0;
+        return;
+    }
+
 
 #ifndef QSG_NO_RENDER_TIMING
     QElapsedTimer timer;
@@ -1081,7 +1103,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
         timer.start();
 #endif
 
-    QQuickWindowPrivate *d = QQuickWindowPrivate::get(w->window);
+    QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
     d->polishItems();
 
 #ifndef QSG_NO_RENDER_TIMING
@@ -1091,14 +1113,14 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
 
     w->updateDuringSync = false;
 
-    emit w->window->afterAnimating();
+    emit window->afterAnimating();
 
-    QSG_GUI_DEBUG(w->window, " - lock for sync...");
+    QSG_GUI_DEBUG(window, " - lock for sync...");
     w->thread->mutex.lock();
     m_lockedForSync = true;
-    w->thread->postEvent(new WMSyncEvent(w->window, inExpose));
+    w->thread->postEvent(new WMSyncEvent(window, inExpose));
 
-    QSG_GUI_DEBUG(w->window, " - wait for sync...");
+    QSG_GUI_DEBUG(window, " - wait for sync...");
 #ifndef QSG_NO_RENDER_TIMING
     if (profileFrames)
         waitTime = timer.nsecsElapsed();
@@ -1106,7 +1128,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
     w->thread->waitCondition.wait(&w->thread->mutex);
     m_lockedForSync = false;
     w->thread->mutex.unlock();
-    QSG_GUI_DEBUG(w->window, " - unlocked after sync...");
+    QSG_GUI_DEBUG(window, " - unlocked after sync...");
 
 #ifndef QSG_NO_RENDER_TIMING
     if (profileFrames)
@@ -1117,9 +1139,9 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
     w->timerId = 0;
 
     if (m_animation_timer == 0 && m_animation_driver->isRunning()) {
-        QSG_GUI_DEBUG(w->window, " - animations advancing");
+        QSG_GUI_DEBUG(window, " - animations advancing");
         m_animation_driver->advance();
-        QSG_GUI_DEBUG(w->window, " - animations done");
+        QSG_GUI_DEBUG(window, " - animations done");
         // We need to trigger another sync to keep animations running...
         maybePostPolishRequest(w);
         emit timeToIncubate();
@@ -1131,7 +1153,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
 #ifndef QSG_NO_RENDER_TIMING
     if (qsg_render_timing)
         qDebug(" - Gui Thread: window=%p, polish=%d, lock=%d, block/sync=%d -- animations=%d",
-               w->window,
+               window,
                int(polishTime/1000000),
                int((waitTime - polishTime)/1000000),
                int((syncTime - waitTime)/1000000),
@@ -1145,6 +1167,17 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
 #endif
 }
 
+QSGThreadedRenderLoop::Window *QSGThreadedRenderLoop::windowForTimer(int timerId) const
+{
+    for (int i=0; i<m_windows.size(); ++i) {
+        if (m_windows.at(i).timerId == timerId) {
+            return const_cast<Window *>(&m_windows.at(i));
+            break;
+        }
+    }
+    return 0;
+}
+
 bool QSGThreadedRenderLoop::event(QEvent *e)
 {
     switch ((int) e->type()) {
@@ -1157,13 +1190,7 @@ bool QSGThreadedRenderLoop::event(QEvent *e)
             emit timeToIncubate();
         } else {
             QSG_GUI_DEBUG((void *) 0, "QEvent::Timer -> Polish & Sync");
-            Window *w = 0;
-            for (int i=0; i<m_windows.size(); ++i) {
-                if (m_windows.at(i).timerId == te->timerId()) {
-                    w = const_cast<Window *>(&m_windows.at(i));
-                    break;
-                }
-            }
+            Window *w = windowForTimer(te->timerId());
             if (w)
                 polishAndSync(w);
         }
index c347190..970bd63 100644 (file)
@@ -95,6 +95,7 @@ private:
 
     void releaseResources(Window *window, bool inDestructor);
     bool checkAndResetForceUpdate(QQuickWindow *window);
+    Window *windowForTimer(int timerId) const;
 
     bool anyoneShowing() const;
     void initialize();
index 913b737..32f5241 100644 (file)
@@ -442,6 +442,11 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
     if (!m_gl->makeCurrent(window))
         return;
 
+    d->flushDelayedTouchEvent();
+    // Event delivery or processing has caused the window to stop rendering.
+    if (!windowData(window))
+        return;
+
     QSG_RENDER_TIMING_SAMPLE(time_start);
 
     RLDEBUG(" - polishing");
index 8ab86bf..7cc3350 100644 (file)
@@ -100,7 +100,7 @@ private slots:
     void pressDelayWithLoader();
 
 private:
-    void flickWithTouch(QWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to);
+    void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to);
     QQmlEngine engine;
 };
 
@@ -1349,20 +1349,18 @@ void tst_qquickflickable::flickTwiceUsingTouches()
     QTRY_VERIFY(contentYAfterSecondFlick > (contentYAfterFirstFlick + 80.0f));
 }
 
-void tst_qquickflickable::flickWithTouch(QWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to)
+void tst_qquickflickable::flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to)
 {
-    QTest::touchEvent(window, touchDevice)
-        .press(0, from, window);
-    QTest::qWait(1);
+    QTest::touchEvent(window, touchDevice).press(0, from, window);
+    QQuickTouchUtils::flush(window);
+
     QPoint diff = to - from;
     for (int i = 1; i <= 8; ++i) {
-        QTest::touchEvent(window, touchDevice)
-            .move(0, from + i*diff/8, window);
-        QTest::qWait(1);
+        QTest::touchEvent(window, touchDevice).move(0, from + i*diff/8, window);
+        QQuickTouchUtils::flush(window);
     }
-    QTest::touchEvent(window, touchDevice)
-        .release(0, to, window);
-    QTest::qWait(1);
+    QTest::touchEvent(window, touchDevice).release(0, to, window);
+    QQuickTouchUtils::flush(window);
 }
 
 void tst_qquickflickable::nestedStopAtBounds_data()
index d4bd087..1d8ae01 100644 (file)
@@ -3,6 +3,7 @@ TARGET = tst_qquickitem
 SOURCES += tst_qquickitem.cpp
 
 include (../../shared/util.pri)
+include (../shared/util.pri)
 
 macx:CONFIG -= app_bundle
 
index f4f2374..8db5154 100644 (file)
@@ -51,6 +51,7 @@
 #include <QTimer>
 #include <QQmlEngine>
 #include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
 
 class TestItem : public QQuickItem
 {
@@ -1311,6 +1312,7 @@ void tst_qquickitem::touchEventAcceptIgnore()
         item->touchEventReached = false;
 
         bool accepted = window.event(&event);
+        QQuickTouchUtils::flush(&window);
 
         QVERIFY(item->touchEventReached);
 
@@ -1334,6 +1336,7 @@ void tst_qquickitem::touchEventAcceptIgnore()
         item->touchEventReached = false;
 
         bool accepted = window.event(&event);
+        QQuickTouchUtils::flush(&window);
 
         QCOMPARE(item->touchEventReached, itemSupportsTouch);
 
@@ -1357,6 +1360,7 @@ void tst_qquickitem::touchEventAcceptIgnore()
         item->touchEventReached = false;
 
         bool accepted = window.event(&event);
+        QQuickTouchUtils::flush(&window);
 
         QCOMPARE(item->touchEventReached, itemSupportsTouch);
 
index d3abc19..5724a71 100644 (file)
@@ -8,6 +8,7 @@ SOURCES += tst_qquickmultipointtoucharea.cpp
 TESTDATA = data/*
 
 include(../../shared/util.pri)
+include(../shared/util.pri)
 
 QT += core-private gui-private qml-private quick-private testlib
 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
index 1d4932c..842babd 100644 (file)
 #include <QtQuick/qquickview.h>
 #include <QtGui/QScreen>
 #include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
 
 class tst_QQuickMultiPointTouchArea : public QQmlDataTest
 {
     Q_OBJECT
 public:
     tst_QQuickMultiPointTouchArea() : device(0) { }
+
 private slots:
     void initTestCase() {
         QQmlDataTest::initTestCase();
@@ -118,6 +120,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
     QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
 
     sequence.press(0, p1).press(1, p2).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(area->property("touchPointPressCount").toInt(), 2);
     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
@@ -126,6 +129,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
     QMetaObject::invokeMethod(area, "clearCounts");
 
     sequence.stationary(0).stationary(1).press(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(area->property("touchPointPressCount").toInt(), 1);
     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
@@ -136,6 +140,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
     p1 -= QPoint(10,10);
     p2 += QPoint(10,10);
     sequence.move(0, p1).move(1, p2).stationary(2).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 2);
@@ -146,6 +151,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
     p3 += QPoint(10,10);
     sequence.release(0, p1).release(1, p2)
             .move(2, p3).press(3, p4).press(4, p5).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(area->property("touchPointPressCount").toInt(), 2);
     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 1);
@@ -154,6 +160,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
     QMetaObject::invokeMethod(area, "clearCounts");
 
     sequence.release(2, p3).release(3, p4).release(4, p5).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
@@ -177,12 +184,14 @@ void tst_QQuickMultiPointTouchArea::release()
     QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
 
     sequence.press(0, p1).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point1->pressed(), true);
 
     p1 += QPoint(0,10);
 
     sequence.move(0, p1).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point1->pressed(), true);
     QCOMPARE(point1->x(), qreal(20)); QCOMPARE(point1->y(), qreal(110));
@@ -190,6 +199,7 @@ void tst_QQuickMultiPointTouchArea::release()
     p1 += QPoint(4,10);
 
     sequence.release(0, p1).commit();
+    QQuickTouchUtils::flush(window.data());
 
     //test that a release without a prior move to the release position successfully updates the point's position
     QCOMPARE(point1->pressed(), false);
@@ -216,12 +226,14 @@ void tst_QQuickMultiPointTouchArea::reuse()
     QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
 
     sequence.press(0, p1).press(1, p2).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point1->pressed(), true);
     QCOMPARE(point2->pressed(), true);
     QCOMPARE(point3->pressed(), false);
 
     sequence.release(0, p1).stationary(1).press(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     //we shouldn't reuse point 1 yet
     QCOMPARE(point1->pressed(), false);
@@ -230,24 +242,28 @@ void tst_QQuickMultiPointTouchArea::reuse()
 
     //back to base state (no touches)
     sequence.release(1, p2).release(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point1->pressed(), false);
     QCOMPARE(point2->pressed(), false);
     QCOMPARE(point3->pressed(), false);
 
     sequence.press(0, p1).press(1, p2).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point1->pressed(), true);
     QCOMPARE(point2->pressed(), true);
     QCOMPARE(point3->pressed(), false);
 
     sequence.release(0, p1).stationary(1).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point1->pressed(), false);
     QCOMPARE(point2->pressed(), true);
     QCOMPARE(point3->pressed(), false);
 
     sequence.press(4, p4).stationary(1).commit();
+    QQuickTouchUtils::flush(window.data());
 
     //the new touch point should reuse point 1
     QCOMPARE(point1->pressed(), true);
@@ -283,6 +299,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
     QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
 
     sequence.press(0, p1).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), false);
     QCOMPARE(point12->pressed(), false);
@@ -291,6 +308,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
     QCOMPARE(point23->pressed(), false);
 
     sequence.stationary(0).press(1, p2).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -304,6 +322,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
     p1 += QPoint(0,10);
     p2 += QPoint(5,0);
     sequence.move(0, p1).move(1, p2).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -315,6 +334,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
     QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
 
     sequence.stationary(0).stationary(1).press(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -323,6 +343,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
     QCOMPARE(point23->pressed(), false);
 
     sequence.stationary(0).stationary(1).stationary(2).press(3, p4).press(4, p5).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -342,6 +363,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
     p4 += QPoint(1,-1);
     p5 += QPoint(-7,10);
     sequence.move(0, p1).move(1, p2).move(2, p3).move(3, p4).move(4, p5).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -356,6 +378,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
     QCOMPARE(point23->x(), qreal(93)); QCOMPARE(point23->y(), qreal(30));
 
     sequence.release(0, p1).release(1, p2).release(2, p3).release(3, p4).release(4, p5).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), false);
     QCOMPARE(point12->pressed(), false);
@@ -388,6 +411,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
 
     sequence.press(0, p1).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), false);
     QCOMPARE(point12->pressed(), false);
@@ -396,6 +420,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     QCOMPARE(point23->pressed(), false);
 
     sequence.stationary(0).press(1, p2).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -409,6 +434,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     p1 += QPoint(0,10);
     p2 += QPoint(5,0);
     sequence.move(0, p1).move(1, p2).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -420,6 +446,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
 
     sequence.stationary(0).stationary(1).press(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -435,6 +462,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
 
     sequence.stationary(0).stationary(1).stationary(2).press(3, QPoint(80,180)).press(4, QPoint(100,180)).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -455,6 +483,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     p2 += QPoint(17,17);
     p3 += QPoint(3,0);
     sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -472,6 +501,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     p2 += QPoint(17,17);
     p3 += QPoint(3,0);
     sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), false);
     QCOMPARE(point12->pressed(), false);
@@ -489,6 +519,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     sequence.release(0, p1).release(1, p2).release(2, p3).commit();
 
     sequence.press(0, p1).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), false);
     QCOMPARE(point12->pressed(), false);
@@ -497,11 +528,13 @@ void tst_QQuickMultiPointTouchArea::nested()
     QCOMPARE(point23->pressed(), false);
 
     sequence.release(0, p1).commit();
+    QQuickTouchUtils::flush(window.data());
 
     //test with grabbing turned off
     window->rootObject()->setProperty("grabInnerArea", false);
 
     sequence.press(0, p1).press(1, p2).press(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -513,6 +546,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     p2 -= QPoint(17,17);
     p3 -= QPoint(3,0);
     sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -530,6 +564,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     p2 -= QPoint(17,17);
     p3 -= QPoint(3,0);
     sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -545,6 +580,7 @@ void tst_QQuickMultiPointTouchArea::nested()
     QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
 
     sequence.release(0, p1).release(1, p2).release(2, p3).commit();
+    QQuickTouchUtils::flush(window.data());
 }
 
 void tst_QQuickMultiPointTouchArea::inFlickable()
@@ -569,25 +605,30 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
 
     //moving one point vertically
     QTest::touchEvent(window.data(), device).press(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     QVERIFY(flickable->contentY() < 0);
     QCOMPARE(point11->pressed(), false);
     QCOMPARE(point12->pressed(), false);
 
     QTest::touchEvent(window.data(), device).release(0, p1);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window.data());
 
     QTRY_VERIFY(!flickable->isMoving());
 
@@ -595,6 +636,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
     p1 = QPoint(20,100);
     QTest::touchEvent(window.data(), device).press(0, p1).press(1, p2);
     QTest::mousePress(window.data(), Qt::LeftButton, 0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
     QCOMPARE(point12->pressed(), true);
@@ -604,18 +646,22 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
     p1 += QPoint(0,15); p2 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15); p2 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15); p2 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15); p2 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     QVERIFY(flickable->contentY() < 0);
     QCOMPARE(point11->pressed(), false);
@@ -625,7 +671,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
 
     QTest::touchEvent(window.data(), device).release(0, p1).release(1, p2);
     QTest::mouseRelease(window.data(), Qt::LeftButton, 0, p1);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window.data());
 
     QTRY_VERIFY(!flickable->isMoving());
 
@@ -633,6 +679,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
     p1 = QPoint(20,100);
     p2 = QPoint(40,100);
     QTest::touchEvent(window.data(), device).press(0, p1).press(1, p2);
+    QQuickTouchUtils::flush(window.data());
     // ensure that mouse events do not fall through to the Flickable
     mpta->setMaximumTouchPoints(3);
     QTest::mousePress(window.data(), Qt::LeftButton, 0, p1);
@@ -643,34 +690,42 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
     p1 += QPoint(15,0); p2 += QPoint(15,0);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(15,0); p2 += QPoint(15,0);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(15,0); p2 += QPoint(15,0);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(15,0); p2 += QPoint(15,0);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15); p2 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15); p2 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15); p2 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15); p2 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
     QTest::mouseMove(window.data(), p1);
+    QQuickTouchUtils::flush(window.data());
 
     QVERIFY(flickable->contentY() == 0);
     QCOMPARE(point11->pressed(), true);
@@ -678,7 +733,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
 
     QTest::touchEvent(window.data(), device).release(0, p1).release(1, p2);
     QTest::mouseRelease(window.data(), Qt::LeftButton, 0, p1);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window.data());
 }
 
 // test that dragging out of a Flickable containing a MPTA doesn't harm Flickable's state.
@@ -699,28 +754,34 @@ void tst_QQuickMultiPointTouchArea::inFlickable2()
 
     // move point horizontally, out of Flickable area
     QTest::touchEvent(window.data(), device).press(0, p1);
+    QQuickTouchUtils::flush(window.data());
     QTest::mousePress(window.data(), Qt::LeftButton, 0, p1);
 
     p1 += QPoint(15,0);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
     QTest::mouseMove(window.data(), p1);
 
     p1 += QPoint(15,0);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
     QTest::mouseMove(window.data(), p1);
 
     p1 += QPoint(15,0);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
     QTest::mouseMove(window.data(), p1);
 
     p1 += QPoint(15,0);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
     QTest::mouseMove(window.data(), p1);
 
     QVERIFY(!flickable->isMoving());
     QVERIFY(point11->pressed());
 
     QTest::touchEvent(window.data(), device).release(0, p1);
+    QQuickTouchUtils::flush(window.data());
     QTest::mouseRelease(window.data(), Qt::LeftButton, 0, p1);
     QTest::qWait(50);
 
@@ -729,26 +790,32 @@ void tst_QQuickMultiPointTouchArea::inFlickable2()
     // Check that we can still move the Flickable
     p1 = QPoint(50,100);
     QTest::touchEvent(window.data(), device).press(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     QCOMPARE(point11->pressed(), true);
 
     p1 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     p1 += QPoint(0,15);
     QTest::touchEvent(window.data(), device).move(0, p1);
+    QQuickTouchUtils::flush(window.data());
 
     QVERIFY(flickable->contentY() < 0);
     QVERIFY(flickable->isMoving());
     QCOMPARE(point11->pressed(), true);
 
     QTest::touchEvent(window.data(), device).release(0, p1);
+    QQuickTouchUtils::flush(window.data());
     QTest::qWait(50);
 
     QTRY_VERIFY(!flickable->isMoving());
@@ -859,7 +926,9 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
 
         // Touch both, release one, manipulate other touchpoint with mouse
         QTest::touchEvent(window.data(), device).press(1, touch1);
+        QQuickTouchUtils::flush(window.data());
         QTest::touchEvent(window.data(), device).press(2, touch2);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -867,12 +936,14 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
         QTest::touchEvent(window.data(), device).release(1, touch1);
         touch1.setY(20);
         QTest::mousePress(window.data(), Qt::LeftButton, 0, touch1);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
         QCOMPARE(touch2rect->property("y").toInt(), touch2.y());
         QTest::touchEvent(window.data(), device).release(2, touch2);
         QTest::mouseRelease(window.data(), Qt::LeftButton, 0, touch1);
+        QQuickTouchUtils::flush(window.data());
 
         // Start with mouse, move it, touch second point, move it
         QTest::mousePress(window.data(), Qt::LeftButton, 0, touch1);
@@ -882,12 +953,14 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         touch2.setX(60);
         QTest::touchEvent(window.data(), device).press(3, touch2);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
         QCOMPARE(touch2rect->property("y").toInt(), touch2.y());
         touch2.setY(150);
         QTest::touchEvent(window.data(), device).move(3, touch2);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -895,6 +968,7 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
 
         // Touch third point - nothing happens
         QTest::touchEvent(window.data(), device).press(4, touch3);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -903,7 +977,9 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
         // Release all
         QTest::mouseRelease(window.data(), Qt::LeftButton, 0, touch1);
         QTest::touchEvent(window.data(), device).release(3, touch2);
+        QQuickTouchUtils::flush(window.data());
         QTest::touchEvent(window.data(), device).release(4, touch3);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -922,12 +998,14 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
         QCOMPARE(touch1rect->property("x").toInt(), mouse1.x());
         QCOMPARE(touch1rect->property("y").toInt(), mouse1.y());
         QTest::touchEvent(window.data(), device).press(1, touch1);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), mouse1.x());
         QCOMPARE(touch1rect->property("y").toInt(), mouse1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch2rect->property("y").toInt(), touch1.y());
 
         QTest::touchEvent(window.data(), device).press(2, touch2).press(3, touch3).press(4, touch4);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), mouse1.x());
         QCOMPARE(touch1rect->property("y").toInt(), mouse1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch1.x());
@@ -942,6 +1020,7 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
         // Release all
         QTest::mouseRelease(window.data(), Qt::LeftButton, 0, mouse1);
         QTest::touchEvent(window.data(), device).release(1, touch1).release(2, touch2).release(3, touch3).release(4, touch4);
+        QQuickTouchUtils::flush(window.data());
     }
 
     dualmpta->setProperty("mouseEnabled", false);
@@ -964,13 +1043,16 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
         QCOMPARE(touch1rect->property("y").toInt(), 10);
 
         QTest::touchEvent(window.data(), device).press(1, touch1);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         touch1.setY(150);
         QTest::touchEvent(window.data(), device).move(1, touch1);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         QTest::touchEvent(window.data(), device).press(2, touch2);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -979,7 +1061,9 @@ void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint()
         // Release all
         QTest::mouseRelease(window.data(), Qt::LeftButton, 0, mouse1);
         QTest::touchEvent(window.data(), device).release(1, touch1);
+        QQuickTouchUtils::flush(window.data());
         QTest::touchEvent(window.data(), device).release(2, touch2);
+        QQuickTouchUtils::flush(window.data());
         QCOMPARE(touch1rect->property("x").toInt(), touch1.x());
         QCOMPARE(touch1rect->property("y").toInt(), touch1.y());
         QCOMPARE(touch2rect->property("x").toInt(), touch2.x());
@@ -1028,7 +1112,6 @@ void tst_QQuickMultiPointTouchArea::transformedTouchArea_data()
 
     QTest::newRow("3rd point inside")
         << QPoint(140, 260) << QPoint(260, 140) << QPoint(200, 140) << 0 << 0 << 1;
-
     QTest::newRow("all points inside")
         << QPoint(200, 140) << QPoint(200, 260) << QPoint(140, 200) << 1 << 2 << 3;
 
index 970ce48..fa14afa 100644 (file)
@@ -6,6 +6,7 @@ macx:CONFIG -= app_bundle
 SOURCES += tst_qquickpincharea.cpp
 
 include (../../shared/util.pri)
+include (../shared/util.pri)
 
 TESTDATA = data/*
 
index b9d314b..1dbce1b 100644 (file)
@@ -48,6 +48,7 @@
 #include <QtQuick/qquickview.h>
 #include <QtQml/qqmlcontext.h>
 #include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
 
 class tst_QQuickPinchArea: public QQmlDataTest
 {
@@ -232,15 +233,18 @@ void tst_QQuickPinchArea::scale()
     {
         QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
         pinchSequence.press(0, p1, window).commit();
+        QQuickTouchUtils::flush(window);
         // In order for the stationary point to remember its previous position,
         // we have to reuse the same pinchSequence object.  Otherwise if we let it
         // be destroyed and then start a new sequence, point 0 will default to being
         // stationary at 0, 0, and PinchArea will filter out that touchpoint because
         // it is outside its bounds.
         pinchSequence.stationary(0).press(1, p2, window).commit();
+        QQuickTouchUtils::flush(window);
         p1 -= QPoint(10,10);
         p2 += QPoint(10,10);
         pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+        QQuickTouchUtils::flush(window);
 
         QCOMPARE(root->property("scale").toReal(), 1.0);
         QVERIFY(root->property("pinchActive").toBool());
@@ -248,6 +252,7 @@ void tst_QQuickPinchArea::scale()
         p1 -= QPoint(10,10);
         p2 += QPoint(10,10);
         pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+        QQuickTouchUtils::flush(window);
 
         QCOMPARE(root->property("scale").toReal(), 1.5);
         QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
@@ -260,8 +265,10 @@ void tst_QQuickPinchArea::scale()
     {
         QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
         pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+        QQuickTouchUtils::flush(window);
         QCOMPARE(blackRect->scale(), 2.0);
         pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+        QQuickTouchUtils::flush(window);
     }
     QVERIFY(!root->property("pinchActive").toBool());
 }
@@ -293,12 +300,15 @@ void tst_QQuickPinchArea::pan()
     {
         QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
         pinchSequence.press(0, p1, window).commit();
+        QQuickTouchUtils::flush(window);
         // In order for the stationary point to remember its previous position,
         // we have to reuse the same pinchSequence object.
         pinchSequence.stationary(0).press(1, p2, window).commit();
+        QQuickTouchUtils::flush(window);
         p1 += QPoint(10,10);
         p2 += QPoint(10,10);
         pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+        QQuickTouchUtils::flush(window);
 
         QCOMPARE(root->property("scale").toReal(), 1.0);
         QVERIFY(root->property("pinchActive").toBool());
@@ -306,6 +316,7 @@ void tst_QQuickPinchArea::pan()
         p1 += QPoint(10,10);
         p2 += QPoint(10,10);
         pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+        QQuickTouchUtils::flush(window);
     }
 
     QCOMPARE(root->property("center").toPointF(), QPointF(60, 60)); // blackrect is at 50,50
@@ -316,11 +327,13 @@ void tst_QQuickPinchArea::pan()
     p1 += QPoint(100,100);
     p2 += QPoint(100,100);
     QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+    QQuickTouchUtils::flush(window);
 
     QCOMPARE(blackRect->x(), 140.0);
     QCOMPARE(blackRect->y(), 160.0);
 
     QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
+    QQuickTouchUtils::flush(window);
     QVERIFY(!root->property("pinchActive").toBool());
 }
 
@@ -355,12 +368,15 @@ void tst_QQuickPinchArea::retouch()
     {
         QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
         pinchSequence.press(0, p1, window).commit();
+        QQuickTouchUtils::flush(window);
         // In order for the stationary point to remember its previous position,
         // we have to reuse the same pinchSequence object.
         pinchSequence.stationary(0).press(1, p2, window).commit();
+        QQuickTouchUtils::flush(window);
         p1 -= QPoint(10,10);
         p2 += QPoint(10,10);
         pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+        QQuickTouchUtils::flush(window);
 
         QCOMPARE(root->property("scale").toReal(), 1.0);
         QVERIFY(root->property("pinchActive").toBool());
@@ -368,6 +384,7 @@ void tst_QQuickPinchArea::retouch()
         p1 -= QPoint(10,10);
         p2 += QPoint(10,10);
         pinchSequence.move(0, p1,window).move(1, p2,window).commit();
+        QQuickTouchUtils::flush(window);
 
         QCOMPARE(startedSpy.count(), 1);
 
@@ -382,6 +399,7 @@ void tst_QQuickPinchArea::retouch()
 
         // Hold down the first finger but release the second one
         pinchSequence.stationary(0).release(1, p2, window).commit();
+        QQuickTouchUtils::flush(window);
 
         QCOMPARE(startedSpy.count(), 1);
         QCOMPARE(finishedSpy.count(), 0);
@@ -390,9 +408,11 @@ void tst_QQuickPinchArea::retouch()
 
         // Keep holding down the first finger and re-touch the second one, then move them both
         pinchSequence.stationary(0).press(1, p2, window).commit();
+        QQuickTouchUtils::flush(window);
         p1 -= QPoint(10,10);
         p2 += QPoint(10,10);
         pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+        QQuickTouchUtils::flush(window);
 
         // Lifting and retouching results in onPinchStarted being called again
         QCOMPARE(startedSpy.count(), 2);
@@ -401,6 +421,7 @@ void tst_QQuickPinchArea::retouch()
         QCOMPARE(window->rootObject()->property("pointCount").toInt(), 2);
 
         pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+        QQuickTouchUtils::flush(window);
 
         QVERIFY(!root->property("pinchActive").toBool());
         QCOMPARE(startedSpy.count(), 2);
@@ -456,14 +477,18 @@ void tst_QQuickPinchArea::transformedPinchArea()
         QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(view, device);
         // start pinch
         pinchSequence.press(0, p1, view).commit();
+        QQuickTouchUtils::flush(view);
         // In order for the stationary point to remember its previous position,
         // we have to reuse the same pinchSequence object.
         pinchSequence.stationary(0).press(1, p2, view).commit();
+        QQuickTouchUtils::flush(view);
         pinchSequence.stationary(0).move(1, p2 + QPoint(threshold * 2, 0), view).commit();
+        QQuickTouchUtils::flush(view);
         QCOMPARE(pinchArea->property("pinching").toBool(), shouldPinch);
 
         // release pinch
         pinchSequence.release(0, p1, view).release(1, p2, view).commit();
+        QQuickTouchUtils::flush(view);
         QCOMPARE(pinchArea->property("pinching").toBool(), false);
     }
 }
index 46cf964..2d1d62c 100644 (file)
@@ -3,6 +3,7 @@ TARGET = tst_qquickwindow
 SOURCES += tst_qquickwindow.cpp
 
 include (../../shared/util.pri)
+include(../shared/util.pri)
 
 macx:CONFIG -= app_bundle
 
index 0e7b7c1..18b0dd5 100644 (file)
@@ -49,6 +49,7 @@
 #include <QtQuick/private/qquickrectangle_p.h>
 #include "../../shared/util.h"
 #include "../shared/visualtestutil.h"
+#include "../shared/viewtestutil.h"
 #include <QSignalSpy>
 #include <qpa/qwindowsysteminterface.h>
 #include <private/qquickwindow_p.h>
@@ -520,7 +521,7 @@ void tst_qquickwindow::touchEvent_basic()
     // press multiple points
     QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window)
             .press(1, bottomItem->mapToScene(pos).toPoint(), window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
     QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
     QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
@@ -531,9 +532,9 @@ void tst_qquickwindow::touchEvent_basic()
 
     // touch point on top item moves to bottom item, but top item should still receive the event
     QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, touchDevice).move(0, bottomItem->mapToScene(pos).toPoint(), window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
     COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, Qt::TouchPointMoved,
             makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
@@ -541,9 +542,9 @@ void tst_qquickwindow::touchEvent_basic()
 
     // touch point on bottom item moves to top item, but bottom item should still receive the event
     QTest::touchEvent(window, touchDevice).press(0, bottomItem->mapToScene(pos).toPoint(), window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, touchDevice).move(0, topItem->mapToScene(pos).toPoint(), window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
     COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, window, Qt::TouchPointMoved,
             makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos)));
@@ -551,10 +552,10 @@ void tst_qquickwindow::touchEvent_basic()
 
     // a single stationary press on an item shouldn't cause an event
     QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(), window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, touchDevice).stationary(0)
             .press(1, bottomItem->mapToScene(pos).toPoint(), window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);    // received press only, not stationary
     QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
     QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
@@ -566,12 +567,13 @@ void tst_qquickwindow::touchEvent_basic()
     // Otherwise you will get an assertion failure:
     // ASSERT: "itemForTouchPointId.isEmpty()" in file items/qquickwindow.cpp
     QTest::touchEvent(window, touchDevice).release(0, pos.toPoint(), window).release(1, pos.toPoint(), window);
+    QQuickTouchUtils::flush(window);
 
     // move touch point from top item to bottom, and release
     QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(),window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
     COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, window, Qt::TouchPointReleased,
             makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
@@ -580,12 +582,12 @@ void tst_qquickwindow::touchEvent_basic()
     // release while another point is pressed
     QTest::touchEvent(window, touchDevice).press(0, topItem->mapToScene(pos).toPoint(),window)
             .press(1, bottomItem->mapToScene(pos).toPoint(), window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, touchDevice).move(0, bottomItem->mapToScene(pos).toPoint(), window);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, touchDevice).release(0, bottomItem->mapToScene(pos).toPoint(), window)
                              .stationary(1);
-    QTest::qWait(50);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
     QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
     QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
@@ -833,12 +835,15 @@ void tst_qquickwindow::touchEvent_velocity()
     tp.area = QRectF(pos, QSizeF(4, 4));
     points << tp;
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     points[0].state = Qt::TouchPointMoved;
     points[0].area.adjust(5, 5, 5, 5);
     QVector2D velocity(1.5, 2.5);
     points[0].velocity = velocity;
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
-    QCoreApplication::processEvents();
+    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     QCOMPARE(item->touchEventCount, 2);
     QCOMPARE(item->lastEvent.touchPoints.count(), 1);
     QCOMPARE(item->lastVelocity, velocity);
@@ -850,7 +855,8 @@ void tst_qquickwindow::touchEvent_velocity()
     QVector2D transformedVelocity = transformMatrix.mapVector(velocity).toVector2D();
     points[0].area.adjust(5, 5, 5, 5);
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
-    QCoreApplication::processEvents();
+    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     QCOMPARE(item->lastVelocity, transformedVelocity);
     QPoint itemLocalPos = item->mapFromScene(window->mapFromGlobal(points[0].area.center().toPoint())).toPoint();
     QPoint itemLocalPosFromEvent = item->lastEvent.touchPoints[0].pos().toPoint();
@@ -858,7 +864,8 @@ void tst_qquickwindow::touchEvent_velocity()
 
     points[0].state = Qt::TouchPointReleased;
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
-    QCoreApplication::processEvents();
+    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     delete item;
 }
 
@@ -890,14 +897,19 @@ void tst_qquickwindow::mouseFromTouch_basic()
     tp.area = QRectF(pos, QSizeF(4, 4));
     points << tp;
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     points[0].state = Qt::TouchPointMoved;
     points[0].area.adjust(5, 5, 5, 5);
     QVector2D velocity(1.5, 2.5);
     points[0].velocity = velocity;
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     points[0].state = Qt::TouchPointReleased;
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
-    QCoreApplication::processEvents();
+    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
 
     // The item should have received a mouse press, move, and release.
     QCOMPARE(item->mousePressNum, 1);
@@ -916,16 +928,20 @@ void tst_qquickwindow::mouseFromTouch_basic()
     points[0].velocity = velocity;
     points[0].area = QRectF(pos, QSizeF(4, 4));
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
+    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     points[0].state = Qt::TouchPointMoved;
     points[0].area.adjust(5, 5, 5, 5);
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
-    QCoreApplication::processEvents();
+    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     QCOMPARE(item->lastMousePos.toPoint(), item->mapFromScene(window->mapFromGlobal(points[0].area.center().toPoint())).toPoint());
     QCOMPARE(item->lastVelocityFromMouseMove, transformedVelocity);
 
     points[0].state = Qt::TouchPointReleased;
     QWindowSystemInterface::handleTouchEvent(window, touchDeviceWithVelocity, points);
     QCoreApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     delete item;
 }
 
index 0e3964d..aa6d7c4 100644 (file)
@@ -47,6 +47,9 @@
 
 #include <QtTest/QTest>
 
+#include <private/qquickwindow_p.h>
+
+
 QQuickView *QQuickViewTestUtil::createView()
 {
     QQuickView *window = new QQuickView(0);
@@ -341,3 +344,23 @@ QList<QPair<QString,QString> > QQuickViewTestUtil::ListRange::getModelDataValues
     return data;
 }
 
+namespace QQuickTouchUtils {
+
+    /* QQuickWindow does event compression and only delivers events just
+     * before it is about to render the next frame. Since some tests
+     * rely on events being delivered immediately AND that no other
+     * event processing has occurred in the meanwhile, we flush the
+     * event manually and immediately.
+     */
+    void flush(QQuickWindow *window) {
+        if (!window)
+            return;
+        QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
+        if (!wd || !wd->delayedTouch)
+            return;
+        wd->reallyDeliverTouchEvent(wd->delayedTouch);
+        delete wd->delayedTouch;
+        wd->delayedTouch = 0;
+    }
+
+}
index 5b0b10b..e10966d 100644 (file)
@@ -166,6 +166,10 @@ namespace QQuickViewTestUtil
     }
 }
 
+namespace QQuickTouchUtils {
+    void flush(QQuickWindow *window);
+}
+
 Q_DECLARE_METATYPE(QQuickViewTestUtil::QaimModel*)
 Q_DECLARE_METATYPE(QQuickViewTestUtil::ListChange)
 Q_DECLARE_METATYPE(QList<QQuickViewTestUtil::ListChange>)
index 445bee0..7d23dfc 100644 (file)
@@ -8,6 +8,7 @@ macx:CONFIG -= app_bundle
 SOURCES  += tst_touchmouse.cpp
 
 include (../../shared/util.pri)
+include (../shared/util.pri)
 
 TESTDATA = data/*
 
index 5b4ad0f..1d947b4 100644 (file)
@@ -58,6 +58,7 @@
 #include <QtQml/qqmlproperty.h>
 
 #include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
 
 struct Event
 {
@@ -221,12 +222,15 @@ void tst_TouchMouse::simpleTouchEvent()
     QPoint p1;
     p1 = QPoint(20, 20);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 1);
     QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
     p1 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 1);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 1);
     eventItem1->eventList.clear();
 
@@ -234,11 +238,14 @@ void tst_TouchMouse::simpleTouchEvent()
     eventItem1->acceptTouch = true;
     p1 = QPoint(20, 20);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 1);
     p1 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 2);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 3);
     eventItem1->eventList.clear();
 
@@ -251,6 +258,7 @@ void tst_TouchMouse::simpleTouchEvent()
     eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
     p1 = QPoint(20, 20);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 2);
     QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
     QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
@@ -268,10 +276,12 @@ void tst_TouchMouse::simpleTouchEvent()
 
     p1 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 4);
     QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchUpdate);
     QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseMove);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 6);
     QCOMPARE(eventItem1->eventList.at(4).type, QEvent::TouchEnd);
     QCOMPARE(eventItem1->eventList.at(5).type, QEvent::MouseButtonRelease);
@@ -286,13 +296,16 @@ void tst_TouchMouse::simpleTouchEvent()
     eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
     p1 = QPoint(20, 20);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 2);
     QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
     QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
     p1 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 2);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 2);
     eventItem1->eventList.clear();
 
@@ -304,13 +317,16 @@ void tst_TouchMouse::simpleTouchEvent()
     eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
     p1 = QPoint(20, 20);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 1);
     QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
     p1 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 2);
     QCOMPARE(eventItem1->eventList.at(1).type, QEvent::TouchUpdate);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 3);
     QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchEnd);
     eventItem1->eventList.clear();
@@ -376,6 +392,7 @@ void tst_TouchMouse::mouse()
     // item 2 doesn't accept anything, thus it sees a touch pass by
     QPoint p1 = QPoint(30, 30);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
 
     QCOMPARE(eventItem1->eventList.size(), 2);
     QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
@@ -412,14 +429,17 @@ void tst_TouchMouse::touchOverMouse()
     QCOMPARE(eventItem1->eventList.size(), 0);
     QPoint p1 = QPoint(20, 20);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 0);
     QCOMPARE(eventItem2->eventList.size(), 1);
     QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
     p1 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem2->eventList.size(), 2);
     QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchUpdate);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem2->eventList.size(), 3);
     QCOMPARE(eventItem2->eventList.at(2).type, QEvent::TouchEnd);
     eventItem2->eventList.clear();
@@ -456,6 +476,7 @@ void tst_TouchMouse::mouseOverTouch()
     QPoint p1 = QPoint(20, 20);
     QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 0);
     QCOMPARE(eventItem2->eventList.size(), 2);
     QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
@@ -510,10 +531,12 @@ void tst_TouchMouse::buttonOnFlickable()
     QCOMPARE(eventItem1->eventList.size(), 0);
     QPoint p1 = QPoint(20, 130);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QTRY_COMPARE(eventItem1->eventList.size(), 2);
     QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
     QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 4);
     QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchEnd);
     QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseButtonRelease);
@@ -522,9 +545,11 @@ void tst_TouchMouse::buttonOnFlickable()
     // touch button
     p1 = QPoint(10, 310);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem2->eventList.size(), 1);
     QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem2->eventList.size(), 2);
     QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchEnd);
     QCOMPARE(eventItem1->eventList.size(), 0);
@@ -536,8 +561,10 @@ void tst_TouchMouse::buttonOnFlickable()
     // click above button, no events please
     p1 = QPoint(10, 90);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 0);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 0);
     eventItem1->eventList.clear();
 
@@ -548,6 +575,7 @@ void tst_TouchMouse::buttonOnFlickable()
     QCOMPARE(eventItem1->eventList.size(), 0);
     p1 = QPoint(10, 110);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 2);
     QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
     QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
@@ -560,12 +588,13 @@ void tst_TouchMouse::buttonOnFlickable()
     p1 += QPoint(0, -10);
     QPoint p2 = p1 + QPoint(0, -10);
     QPoint p3 = p2 + QPoint(0, -10);
-    QTest::qWait(10);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).move(0, p1, window);
-    QTest::qWait(10);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).move(0, p2, window);
-    QTest::qWait(10);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).move(0, p3, window);
+    QQuickTouchUtils::flush(window);
 
     // we cannot really know when the events get grabbed away
     QVERIFY(eventItem1->eventList.size() >= 4);
@@ -578,6 +607,7 @@ void tst_TouchMouse::buttonOnFlickable()
     QVERIFY(flickable->isMovingVertically());
 
     QTest::touchEvent(window, device).release(0, p3, window);
+    QQuickTouchUtils::flush(window);
     delete window;
 }
 
@@ -625,6 +655,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
     QCOMPARE(eventItem1->eventList.size(), 0);
     QPoint p1 = QPoint(10, 110);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     // Flickable initially steals events
     QCOMPARE(eventItem1->eventList.size(), 0);
     // but we'll get the delayed mouse press after a delay
@@ -641,12 +672,13 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
     p1 += QPoint(0, -10);
     QPoint p2 = p1 + QPoint(0, -10);
     QPoint p3 = p2 + QPoint(0, -10);
-    QTest::qWait(10);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).move(0, p1, window);
-    QTest::qWait(10);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).move(0, p2, window);
-    QTest::qWait(10);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).move(0, p3, window);
+    QQuickTouchUtils::flush(window);
     QVERIFY(flickable->isMovingVertically());
 
     // flickable should have the mouse grab, and have moved the itemForTouchPointId
@@ -656,6 +688,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
     QCOMPARE(windowPriv->itemForTouchPointId[0], flickable);
 
     QTest::touchEvent(window, device).release(0, p3, window);
+    QQuickTouchUtils::flush(window);
 
     // We should not have received any synthesised mouse events from Qt gui.
     QCOMPARE(filteredEventList.count(), 0);
@@ -709,7 +742,9 @@ void tst_TouchMouse::buttonOnTouch()
     // Normal touch click
     QPoint p1 = QPoint(10, 110);
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(eventItem1->eventList.size(), 4);
     QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
     QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
@@ -730,7 +765,9 @@ void tst_TouchMouse::buttonOnTouch()
 
     // Start the events after each other
     QTest::touchEvent(window, device).press(0, p1, window);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).stationary(0).press(1, p2, window);
+    QQuickTouchUtils::flush(window);
 
     QCOMPARE(button1->scale(), 1.0);
 
@@ -738,20 +775,24 @@ void tst_TouchMouse::buttonOnTouch()
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+    QQuickTouchUtils::flush(window);
 
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+    QQuickTouchUtils::flush(window);
 //    QCOMPARE(button1->scale(), 1.5);
     qDebug() << "Button scale: " << button1->scale();
 
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+    QQuickTouchUtils::flush(window);
 //    QCOMPARE(button1->scale(), 2.0);
     qDebug() << "Button scale: " << button1->scale();
 
     QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
+    QQuickTouchUtils::flush(window);
 //    QVERIFY(eventItem1->eventList.isEmpty());
 //    QCOMPARE(button1->scale(), 2.0);
     qDebug() << "Button scale: " << button1->scale();
@@ -765,6 +806,7 @@ void tst_TouchMouse::buttonOnTouch()
     p1 = QPoint(40, 110);
     p2 = QPoint(60, 110);
     QTest::touchEvent(window, device).press(0, p1, window).press(1, p2, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(button1->scale(), 1.0);
     QCOMPARE(eventItem1->eventList.count(), 2);
     QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
@@ -774,20 +816,24 @@ void tst_TouchMouse::buttonOnTouch()
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+    QQuickTouchUtils::flush(window);
 
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+    QQuickTouchUtils::flush(window);
     //QCOMPARE(button1->scale(), 1.5);
     qDebug() << button1->scale();
 
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
+    QQuickTouchUtils::flush(window);
     qDebug() << button1->scale();
     //QCOMPARE(button1->scale(), 2.0);
 
     QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
+    QQuickTouchUtils::flush(window);
 //    QCOMPARE(eventItem1->eventList.size(), 99);
     qDebug() << button1->scale();
     //QCOMPARE(button1->scale(), 2.0);
@@ -816,18 +862,22 @@ void tst_TouchMouse::pinchOnFlickable()
     QVERIFY(flickable->contentX() == 0.0);
     QPoint p = QPoint(100, 100);
     QTest::touchEvent(window, device).press(0, p, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(rect->position(), QPointF(200.0, 200.0));
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
+    QQuickTouchUtils::flush(window);
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
-    QTest::qWait(10);
+    QQuickTouchUtils::flush(window);
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
-    QTest::qWait(10);
+    QQuickTouchUtils::flush(window);
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).release(0, p, window);
+    QQuickTouchUtils::flush(window);
 
     QGuiApplication::processEvents();
     QTest::qWait(10);
@@ -840,27 +890,35 @@ void tst_TouchMouse::pinchOnFlickable()
     QPoint p2 = QPoint(60, 20);
 
     QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
+    QQuickTouchUtils::flush(window);
     pinchSequence.press(0, p1, window).commit();
+    QQuickTouchUtils::flush(window);
     // In order for the stationary point to remember its previous position,
     // we have to reuse the same pinchSequence object.  Otherwise if we let it
     // be destroyed and then start a new sequence, point 0 will default to being
     // stationary at 0, 0, and PinchArea will filter out that touchpoint because
     // it is outside its bounds.
     pinchSequence.stationary(0).press(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(10,10);
     p2 += QPoint(10,10);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     QCOMPARE(rect->scale(), 1.0);
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     QVERIFY(rect->scale() > 1.0);
 }
 
@@ -885,17 +943,22 @@ void tst_TouchMouse::flickableOnPinch()
     QVERIFY(flickable->contentX() == 0.0);
     QPoint p = QPoint(100, 100);
     QTest::touchEvent(window, device).press(0, p, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(rect->position(), QPointF(200.0, 200.0));
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
+    QQuickTouchUtils::flush(window);
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
+    QQuickTouchUtils::flush(window);
 
     QTest::qWait(1000);
 
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).release(0, p, window);
+    QQuickTouchUtils::flush(window);
 
     QTest::qWait(1000);
 
@@ -909,26 +972,33 @@ void tst_TouchMouse::flickableOnPinch()
     QPoint p2 = QPoint(60, 20);
     QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
     pinchSequence.press(0, p1, window).commit();
+    QQuickTouchUtils::flush(window);
     // In order for the stationary point to remember its previous position,
     // we have to reuse the same pinchSequence object.  Otherwise if we let it
     // be destroyed and then start a new sequence, point 0 will default to being
     // stationary at 0, 0, and PinchArea will filter out that touchpoint because
     // it is outside its bounds.
     pinchSequence.stationary(0).press(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(10,10);
     p2 += QPoint(10,10);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     QCOMPARE(rect->scale(), 1.0);
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     QVERIFY(rect->scale() > 1.0);
 }
 
@@ -953,16 +1023,19 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
     QVERIFY(flickable->contentX() == 0.0);
     QPoint p = QPoint(100, 100);
     QTest::touchEvent(window, device).press(0, p, window);
+    QQuickTouchUtils::flush(window);
     QCOMPARE(rect->position(), QPointF(200.0, 200.0));
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
+    QQuickTouchUtils::flush(window);
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
-    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
     p -= QPoint(10, 0);
     QTest::touchEvent(window, device).move(0, p, window);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).release(0, p, window);
-    QGuiApplication::processEvents();
+    QQuickTouchUtils::flush(window);
 
     //QVERIFY(flickable->isMovingHorizontally());
 
@@ -975,26 +1048,33 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
     QPoint p2 = QPoint(60, 20);
     QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
     pinchSequence.press(0, p1, window).commit();
+    QQuickTouchUtils::flush(window);
     // In order for the stationary point to remember its previous position,
     // we have to reuse the same pinchSequence object.  Otherwise if we let it
     // be destroyed and then start a new sequence, point 0 will default to being
     // stationary at 0, 0, and PinchArea will filter out that touchpoint because
     // it is outside its bounds.
     pinchSequence.stationary(0).press(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(10,10);
     p2 += QPoint(10,10);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     QCOMPARE(rect->scale(), 1.0);
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(10, 0);
     p2 += QPoint(10, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     QVERIFY(rect->scale() > 1.0);
 
     // PinchArea should steal the event after flicking started
@@ -1002,14 +1082,18 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
     flickable->setContentX(0.0);
     p = QPoint(100, 100);
     pinchSequence.press(0, p, window).commit();
+    QQuickTouchUtils::flush(window);
     QCOMPARE(rect->position(), QPointF(200.0, 200.0));
     p -= QPoint(10, 0);
     pinchSequence.move(0, p, window).commit();
+    QQuickTouchUtils::flush(window);
     p -= QPoint(10, 0);
     pinchSequence.move(0, p, window).commit();
+    QQuickTouchUtils::flush(window);
     QGuiApplication::processEvents();
     p -= QPoint(10, 0);
     pinchSequence.move(0, p, window).commit();
+    QQuickTouchUtils::flush(window);
 
     QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
     qDebug() << "Mouse Grabber: " << windowPriv->mouseGrabberItem << " itemForTouchPointId: " << windowPriv->itemForTouchPointId;
@@ -1019,20 +1103,26 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
     p1 = QPoint(40, 100);
     p2 = QPoint(60, 100);
     pinchSequence.stationary(0).press(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     QCOMPARE(rect->scale(), 1.0);
 
     p1 -= QPoint(5, 0);
     p2 += QPoint(5, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(5, 0);
     p2 += QPoint(5, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     p1 -= QPoint(5, 0);
     p2 += QPoint(5, 0);
     pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     pinchSequence.release(0, p1, window).release(1, p2, window).commit();
+    QQuickTouchUtils::flush(window);
     QVERIFY(rect->scale() > 1.0);
     pinchSequence.release(0, p, window).commit();
+    QQuickTouchUtils::flush(window);
 }
 
 /*
@@ -1066,16 +1156,17 @@ void tst_TouchMouse::tapOnDismissiveTopMouseAreaClicksBottomOne()
     // tap the front mouse area (see qml file)
     QPoint p1(20, 20);
     QTest::touchEvent(window, device).press(0, p1, window);
-    QTest::qWait(1);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
 
     QCOMPARE(bottomClickedSpy.count(), 1);
     QCOMPARE(bottomDoubleClickedSpy.count(), 0);
-    QTest::qWait(15);
 
     QTest::touchEvent(window, device).press(0, p1, window);
-    QTest::qWait(1);
+    QQuickTouchUtils::flush(window);
     QTest::touchEvent(window, device).release(0, p1, window);
+    QQuickTouchUtils::flush(window);
 
     QCOMPARE(bottomClickedSpy.count(), 1);
     QCOMPARE(bottomDoubleClickedSpy.count(), 1);