From 6dc8f47bb05a8acb3cbcc697e0dc05356a01d4cf Mon Sep 17 00:00:00 2001
From: Gunnar Sletta <gunnar.sletta@jollamobile.com>
Date: Thu, 3 Apr 2014 11:16:42 +0000
Subject: [PATCH] Compress touch events in QQuickWindow.

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>
---
 src/quick/items/qquickrendercontrol.cpp       |   3 +
 src/quick/items/qquickwindow.cpp              | 100 ++++++++++++++-
 src/quick/items/qquickwindow_p.h              |   6 +-
 src/quick/scenegraph/qsgrenderloop.cpp        |   6 +
 .../scenegraph/qsgthreadedrenderloop.cpp      |  61 ++++++---
 .../scenegraph/qsgthreadedrenderloop_p.h      |   1 +
 src/quick/scenegraph/qsgwindowsrenderloop.cpp |   5 +
 .../qquickflickable/tst_qquickflickable.cpp   |  20 ++-
 tests/auto/quick/qquickitem/qquickitem.pro    |   1 +
 .../auto/quick/qquickitem/tst_qquickitem.cpp  |   4 +
 .../qquickmultipointtoucharea.pro             |   1 +
 .../tst_qquickmultipointtoucharea.cpp         |  91 +++++++++++++-
 .../quick/qquickpincharea/qquickpincharea.pro |   1 +
 .../qquickpincharea/tst_qquickpincharea.cpp   |  25 ++++
 .../auto/quick/qquickwindow/qquickwindow.pro  |   1 +
 .../quick/qquickwindow/tst_qquickwindow.cpp   |  50 +++++---
 tests/auto/quick/shared/viewtestutil.cpp      |  23 ++++
 tests/auto/quick/shared/viewtestutil.h        |   4 +
 tests/auto/quick/touchmouse/touchmouse.pro    |   1 +
 .../auto/quick/touchmouse/tst_touchmouse.cpp  | 117 ++++++++++++++++--
 20 files changed, 456 insertions(+), 65 deletions(-)

diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index 10a9691b65..4a199d9352 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -140,6 +140,9 @@ void QQuickRenderControl::polishItems()
         return;
 
     QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+    cd->flushDelayedTouchEvent();
+    if (!d->window)
+        return;
     cd->polishItems();
 }
 
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 49e8f3e373..d6cbae7d2a 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -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
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 872a054666..218425c08c 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -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;
 
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 6647ec83d0..00e67aa944 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -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();
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 7b01f64ee0..a5b46b7c75 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -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);
         }
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
index c347190e2b..970bd63040 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h
+++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
@@ -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();
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 913b737798..32f52417bb 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -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");
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 8ab86bf2d3..7cc3350b05 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -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()
diff --git a/tests/auto/quick/qquickitem/qquickitem.pro b/tests/auto/quick/qquickitem/qquickitem.pro
index d4bd0874d8..1d8ae0148b 100644
--- a/tests/auto/quick/qquickitem/qquickitem.pro
+++ b/tests/auto/quick/qquickitem/qquickitem.pro
@@ -3,6 +3,7 @@ TARGET = tst_qquickitem
 SOURCES += tst_qquickitem.cpp
 
 include (../../shared/util.pri)
+include (../shared/util.pri)
 
 macx:CONFIG -= app_bundle
 
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index f4f2374183..8db515432a 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -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);
 
diff --git a/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro b/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
index d3abc198d9..5724a7179e 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
+++ b/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
@@ -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
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index 1d4932c432..842babddd9 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -48,12 +48,14 @@
 #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;
 
diff --git a/tests/auto/quick/qquickpincharea/qquickpincharea.pro b/tests/auto/quick/qquickpincharea/qquickpincharea.pro
index 970ce48851..fa14afa261 100644
--- a/tests/auto/quick/qquickpincharea/qquickpincharea.pro
+++ b/tests/auto/quick/qquickpincharea/qquickpincharea.pro
@@ -6,6 +6,7 @@ macx:CONFIG -= app_bundle
 SOURCES += tst_qquickpincharea.cpp
 
 include (../../shared/util.pri)
+include (../shared/util.pri)
 
 TESTDATA = data/*
 
diff --git a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
index b9d314b63e..1dbce1b730 100644
--- a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
+++ b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp
@@ -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);
     }
 }
diff --git a/tests/auto/quick/qquickwindow/qquickwindow.pro b/tests/auto/quick/qquickwindow/qquickwindow.pro
index 46cf96423f..2d1d62c135 100644
--- a/tests/auto/quick/qquickwindow/qquickwindow.pro
+++ b/tests/auto/quick/qquickwindow/qquickwindow.pro
@@ -3,6 +3,7 @@ TARGET = tst_qquickwindow
 SOURCES += tst_qquickwindow.cpp
 
 include (../../shared/util.pri)
+include(../shared/util.pri)
 
 macx:CONFIG -= app_bundle
 
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 0e7b7c103a..18b0dd5132 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -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;
 }
 
diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp
index 0e3964d52d..aa6d7c4a93 100644
--- a/tests/auto/quick/shared/viewtestutil.cpp
+++ b/tests/auto/quick/shared/viewtestutil.cpp
@@ -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;
+    }
+
+}
diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h
index 5b0b10b69c..e10966ddba 100644
--- a/tests/auto/quick/shared/viewtestutil.h
+++ b/tests/auto/quick/shared/viewtestutil.h
@@ -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>)
diff --git a/tests/auto/quick/touchmouse/touchmouse.pro b/tests/auto/quick/touchmouse/touchmouse.pro
index 445bee08ae..7d23dfc0ae 100644
--- a/tests/auto/quick/touchmouse/touchmouse.pro
+++ b/tests/auto/quick/touchmouse/touchmouse.pro
@@ -8,6 +8,7 @@ macx:CONFIG -= app_bundle
 SOURCES  += tst_touchmouse.cpp
 
 include (../../shared/util.pri)
+include (../shared/util.pri)
 
 TESTDATA = data/*
 
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index 5b4ad0ffa3..1d947b4d8c 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -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);
-- 
GitLab