@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013-2014 Canonical, Ltd.
2+ * Copyright (C) 2013-2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -20,51 +20,38 @@
2020#include <QtQml/QQmlEngine>
2121#include <QPointer>
2222#include <private/qquickmousearea_p.h>
23−#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
24− #include <private/qquickwindow_p.h>
25−#endif
23+#include <private/qquickwindow_p.h>
2624
2725
2826#include <DirectionalDragArea.h>
27+#include <DirectionalDragArea_p.h>
2928#include <TouchRegistry.h>
3029
3130#include "GestureTest.h"
3231
3332using namespace UbuntuGestures;
3433
35−
36−class ComplexFakeTimer : public FakeTimer
37−{
34+// Because QSignalSpy(directionalDragArea, SIGNAL(DirectionalDragArea::Status)) simply
35+// doesn't work
36+class StatusSpy : public QObject {
3837 Q_OBJECT
3938public:
40− ComplexFakeTimer(const SharedTimeSource &timeSource, QObject *parent = 0)
41− : FakeTimer(parent),
42− m_timeSource(timeSource)
43− {}
44−
45− void start() override {
46− AbstractTimer::start();
47− m_nextTimeoutTime = m_timeSource->msecsSinceReference() + (qint64)interval();
39+ StatusSpy(DirectionalDragArea *edgeDragArea) {
40+ m_recognized = false;
41+ connect(edgeDragArea->d, &DirectionalDragAreaPrivate::statusChanged,
42+ this, &StatusSpy::onStatusChanged);
4843 }
49−
50− void emitTimeout() {
51− m_nextTimeoutTime += interval();
52− Q_EMIT timeout();
44+ bool recognized() {
45+ return m_recognized;
5346 }
5447
55− qint64 nextTimeoutTime() const { return m_nextTimeoutTime; }
48+private Q_SLOTS:
49+ void onStatusChanged(DirectionalDragAreaPrivate::Status status) {
50+ m_recognized |= status == DirectionalDragAreaPrivate::Recognized;
51+ }
5652
5753private:
58− SharedTimeSource m_timeSource;
59− qint64 m_nextTimeoutTime;
60−};
61−
62−class FakeTimeSource : public UbuntuGestures::TimeSource
63−{
64−public:
65− FakeTimeSource() { m_msecsSinceReference = 0; }
66− virtual qint64 msecsSinceReference() {return m_msecsSinceReference;}
67− qint64 m_msecsSinceReference;
54+ bool m_recognized;
6855};
6956
7057/*
@@ -98,15 +85,9 @@ public:
9885 tst_DirectionalDragArea();
9986private Q_SLOTS:
10087 void init(); // called right before each and every test function is executed
101− void cleanup(); // called right after each and every test function is executed
10288
103− void edgeDrag();
104− void edgeDrag_data();
10589 void dragWithShortDirectionChange();
106− void minSpeed();
107− void minSpeed_data();
10890 void recognitionTimerUsage();
109− void maxSilenceTime();
11091 void sceneXAndX();
11192 void sceneYAndY();
11293 void twoFingerTap();
@@ -122,14 +103,24 @@ private Q_SLOTS:
122103 void immediateRecognitionWhenConstraintsDisabled();
123104 void withdrawTouchOwnershipCandidacyIfDisabledDuringRecognition();
124105 void withdrawTouchOwnershipCandidacyIfDisabledDuringRecognition_data();
125− void tappedSignal();
126− void tappedSignal_data();
127106 void gettingTouchOwnershipMakesMouseAreaBehindGetCanceled();
107+ void interleavedTouches();
108+ void makoRightEdgeDrag();
109+ void makoRightEdgeDrag_verticalDownwards();
110+ void makoLeftEdgeDrag_slowStart();
111+ void makoLeftEdgeDrag_movesSlightlyBackwardsOnStart();
128112
129113private:
114+ // QTest::touchEvent takes QPoint instead of QPointF and I don't want to
115+ // lose precision due to rounding.
116+ // Besides, those helper functions lead to more compact code.
117+ void sendTouchPress(qint64 timestamp, int id, QPointF pos);
118+ void sendTouchUpdate(qint64 timestamp, int id, QPointF pos);
119+ void sendTouchRelease(qint64 timestamp, int id, QPointF pos);
120+ void sendTouch(qint64 timestamp, int id, QPointF pos,
121+ Qt::TouchPointState pointState, QEvent::Type eventType);
122+
130123 void passTime(qint64 timeSpanMs);
131− ComplexFakeTimer *fakeTimer;
132− QSharedPointer<FakeTimeSource> fakeTimeSource;
133124};
134125
135126tst_DirectionalDragArea::tst_DirectionalDragArea()
@@ -148,185 +139,57 @@ void tst_DirectionalDragArea::init()
148139 m_view->resize(m_view->rootObject()->width(), m_view->rootObject()->height());
149140 QTRY_COMPARE(m_view->width(), (int)m_view->rootObject()->width());
150141 QTRY_COMPARE(m_view->height(), (int)m_view->rootObject()->height());
151−
152− fakeTimeSource.reset(new FakeTimeSource);
153− fakeTimer = new ComplexFakeTimer(fakeTimeSource);
154−}
155−
156−void tst_DirectionalDragArea::cleanup()
157−{
158− delete fakeTimer;
159− fakeTimer = 0;
160−
161− fakeTimeSource.reset();
162−
163− GestureTest::cleanup();
164−}
165−
166−void tst_DirectionalDragArea::passTime(qint64 timeSpanMs)
167−{
168− qint64 finalTime = fakeTimeSource->m_msecsSinceReference + timeSpanMs;
169−
170− if (fakeTimer->isRunning() && finalTime >= fakeTimer->nextTimeoutTime()) {
171− fakeTimeSource->m_msecsSinceReference = fakeTimer->nextTimeoutTime();
172− fakeTimer->emitTimeout();
173−
174− qint64 timeSpanRemainder = finalTime - fakeTimeSource->m_msecsSinceReference;
175− if (timeSpanRemainder > 0) {
176− passTime(timeSpanRemainder);
177− }
178− } else {
179− fakeTimeSource->m_msecsSinceReference = finalTime;
180− }
181142}
182143
183−namespace {
184−QPointF calculateInitialTouchPos(DirectionalDragArea *edgeDragArea)
144+void tst_DirectionalDragArea::sendTouchPress(qint64 timestamp, int id, QPointF pos)
185145{
186− QPointF localCenter(edgeDragArea->width() / 2., edgeDragArea->height() / 2.);
187− return edgeDragArea->mapToScene(localCenter);
146+ sendTouch(timestamp, id, pos, Qt::TouchPointPressed, QEvent::TouchBegin);
188147}
189148
190−QPointF calculateDirectionVector(DirectionalDragArea *edgeDragArea,
191− qreal wideningAngleMultiplier)
149+void tst_DirectionalDragArea::sendTouchUpdate(qint64 timestamp, int id, QPointF pos)
192150{
193− qreal angleRadians = edgeDragArea->wideningAngle() * wideningAngleMultiplier
194− * M_PI / 180.0;
195−
196− qreal angleCos = qCos(angleRadians);
197− qreal angleSin = qSin(angleRadians);
198−
199− switch (edgeDragArea->direction()) {
200− case Direction::Upwards:
201− return QPointF(angleSin, -angleCos);
202− case Direction::Downwards:
203− return QPointF(angleSin, angleCos);
204− case Direction::Leftwards:
205− return QPointF(-angleCos, angleSin);
206− default: // Direction::Rightwards:
207− return QPointF(angleCos, angleSin);
208− }
151+ sendTouch(timestamp, id, pos, Qt::TouchPointMoved, QEvent::TouchUpdate);
209152}
210153
211−QPointF createTouchDeviation(DirectionalDragArea *edgeDragArea)
154+void tst_DirectionalDragArea::sendTouchRelease(qint64 timestamp, int id, QPointF pos)
212155{
213− qreal deviation = edgeDragArea->maxDeviation() * 0.8;
214−
215− if (Direction::isHorizontal(edgeDragArea->direction())) {
216− return QPointF(0, deviation);
217− } else {
218− return QPointF(deviation, 0);
219− }
220−}
156+ sendTouch(timestamp, id, pos, Qt::TouchPointReleased, QEvent::TouchEnd);
221157}
222158
223−void tst_DirectionalDragArea::edgeDrag()
159+void tst_DirectionalDragArea::sendTouch(qint64 timestamp, int id, QPointF pos,
160+ Qt::TouchPointState pointState, QEvent::Type eventType)
224161{
225− QFETCH(QString, dragAreaObjectName);
226− QFETCH(qreal, wideningAngleMultiplier);
227− QFETCH(qreal, dragDistanceFactor);
228− QFETCH(bool, expectGestureRecognition);
229−
230− DirectionalDragArea *edgeDragArea =
231− m_view->rootObject()->findChild<DirectionalDragArea*>(dragAreaObjectName);
232− QVERIFY(edgeDragArea != 0);
233− edgeDragArea->setRecognitionTimer(fakeTimer);
234− edgeDragArea->setTimeSource(fakeTimeSource);
235−
236− QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool)));
237−
238− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
239− QPointF touchPoint = initialTouchPos;
240−
241− qreal desiredDragDistance = edgeDragArea->distanceThreshold()*dragDistanceFactor;
242− QPointF dragDirectionVector = calculateDirectionVector(edgeDragArea,
243− wideningAngleMultiplier);
244− qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
245− QPointF touchMovement = dragDirectionVector * movementStepDistance;
246− int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
247− int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
248−
249− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
250−
251− QCOMPARE(draggingSpy.count(), 1);
252− QCOMPARE(edgeDragArea->dragging(), true);
253−
254− if (wideningAngleMultiplier > 0) {
255− // go close to the border of the valid area for this touch point
256− // in order to make it easier to leave it by dragging at an angle
257− // slightly bigger than the widening angle
258− touchPoint += createTouchDeviation(edgeDragArea);
259− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
260− }
162+ m_fakeTimerFactory->updateTime(timestamp);
261163
262− for (int i = 0; i < totalMovementSteps; ++i) {
263− touchPoint += touchMovement;
264− passTime(movementTimeStepMs);
265− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
266− }
164+ QTouchEvent::TouchPoint point;
267165
268− if (expectGestureRecognition)
269− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
166+ point.setState(pointState);
167+ point.setId(id);
168+ point.setScenePos(pos);
169+ point.setPos(pos);
270170
271− if (edgeDragArea->status() == DirectionalDragArea::WaitingForTouch) {
272− QCOMPARE(edgeDragArea->dragging(), false);
273− QCOMPARE(draggingSpy.count(), 2);
274− }
171+ QList<QTouchEvent::TouchPoint> points;
172+ points << point;
275173
276− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
174+ QTouchEvent touchEvent(eventType, m_device, Qt::NoModifier, Qt::TouchPointPressed, points);
175+ QCoreApplication::sendEvent(m_view, &touchEvent);
277176
278− QCOMPARE(draggingSpy.count(), 2);
279− QCOMPARE(edgeDragArea->dragging(), false);
177+ QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
178+ windowPrivate->flushDelayedTouchEvent();
280179}
281180
282−void tst_DirectionalDragArea::edgeDrag_data()
181+void tst_DirectionalDragArea::passTime(qint64 timeSpanMs)
283182{
284− QTest::addColumn<QString>("dragAreaObjectName");
285− QTest::addColumn<qreal>("wideningAngleMultiplier");
286− QTest::addColumn<qreal>("dragDistanceFactor");
287− QTest::addColumn<bool>("expectGestureRecognition");
288−
289− QTest::newRow("rightwards, tiny drag")
290− << "hpDragArea" << 0.0 << 0.2 << false;
291−
292− QTest::newRow("rightwards, straight drag")
293− << "hpDragArea" << 0.0 << 3.0 << true;
294−
295− QTest::newRow("rightwards, diagonal drag")
296− << "hpDragArea" << 0.9 << 3.0 << true;
297−
298− QTest::newRow("rightwards, overly diagonal drag")
299− << "hpDragArea" << 2.0 << 3.0 << false;
300−
301− QTest::newRow("leftwards, tiny drag")
302− << "hnDragArea" << 0.0 << 0.2 << false;
303−
304− QTest::newRow("leftwards, straight drag")
305− << "hnDragArea" << 0.0 << 3.0 << true;
306−
307− QTest::newRow("leftwards, diagonal drag")
308− << "hnDragArea" << 0.9 << 3.0 << true;
309−
310− QTest::newRow("downwards, tiny drag")
311− << "vpDragArea" << 0.0 << 0.2 << false;
312−
313− QTest::newRow("downwards, straight drag")
314− << "vpDragArea" << 0.0 << 3.0 << true;
315−
316− QTest::newRow("downwards, diagonal drag")
317− << "vpDragArea" << 0.9 << 3.0 << true;
318−
319− QTest::newRow("upwards, tiny drag")
320− << "vnDragArea" << 0.0 << 0.2 << false;
321−
322− QTest::newRow("upwards, straight drag")
323− << "vnDragArea" << 0.0 << 3.0 << true;
324−
325− QTest::newRow("upwards, diagonal drag")
326− << "vnDragArea" << 0.9 << 3.0 << true;
183+ qint64 finalTime = m_fakeTimerFactory->timeSource()->msecsSinceReference() + timeSpanMs;
184+ m_fakeTimerFactory->updateTime(finalTime);
185+}
327186
328− QTest::newRow("upwards, overly diagonal drag")
329− << "vnDragArea" << 2.0 << 3.0 << false;
187+namespace {
188+QPointF calculateInitialTouchPos(DirectionalDragArea *edgeDragArea)
189+{
190+ QPointF localCenter(edgeDragArea->width() / 2., edgeDragArea->height() / 2.);
191+ return edgeDragArea->mapToScene(localCenter);
192+}
330193}
331194
332195/*
@@ -339,17 +202,17 @@ void tst_DirectionalDragArea::dragWithShortDirectionChange()
339202 DirectionalDragArea *edgeDragArea =
340203 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
341204 QVERIFY(edgeDragArea != 0);
342− edgeDragArea->setRecognitionTimer(fakeTimer);
343− edgeDragArea->setTimeSource(fakeTimeSource);
205+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
206+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
344207
345208 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
346209 QPointF touchPoint = initialTouchPos;
347210
348− qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0;
211+ qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0;
349212 QPointF dragDirectionVector(1.0, 0.0);
350− qreal touchStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
351− // make sure we are above minimum speed
352− int touchStepTimeMs = (touchStepDistance / (edgeDragArea->minSpeed() * 5.0f)) * 1000.0f;
213+ qreal touchStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
214+ // make sure we are above maximum time
215+ int touchStepTimeMs = edgeDragArea->d->maxTime / 20. ;
353216 QPointF touchMovement = dragDirectionVector * touchStepDistance;
354217
355218 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
@@ -373,65 +236,13 @@ void tst_DirectionalDragArea::dragWithShortDirectionChange()
373236 passTime(touchStepTimeMs);
374237 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
375238 } while ((touchPoint - initialTouchPos).manhattanLength() < desiredDragDistance
376− || fakeTimeSource->m_msecsSinceReference < (edgeDragArea->compositionTime() * 1.5f));
239+ || m_fakeTimerFactory->timeSource()->msecsSinceReference() < (edgeDragArea->d->compositionTime * 1.5f));
377240
378− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
241+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
379242
380243 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
381244}
382245
383−/*
384− Checks that a gesture will be rejected if it's slower than minSpeed while
385− status is Undecided.
386− */
387−void tst_DirectionalDragArea::minSpeed()
388−{
389− QFETCH(qreal, minSpeed);
390− QFETCH(qreal, speed);
391− QFETCH(int, expectedStatusAfterSpeedCheck);
392−
393− DirectionalDragArea *edgeDragArea =
394− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
395− QVERIFY(edgeDragArea != 0);
396− edgeDragArea->setRecognitionTimer(fakeTimer);
397− edgeDragArea->setTimeSource(fakeTimeSource);
398−
399− // A really long, unattainable, number. We don't want it getting recognized before
400− // the speed checks we want have been performed
401− edgeDragArea->setDistanceThreshold(500000);
402−
403− edgeDragArea->setMinSpeed(minSpeed);
404−
405− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
406− QPointF touchPoint = initialTouchPos;
407−
408− QPointF dragDirectionVector(1.0, 0.0);
409− qint64 timeStepMsecs = 10;
410− qreal distanceStep = (speed / 1000.0f) * timeStepMsecs;
411− QPointF touchMovement = dragDirectionVector * distanceStep;
412−
413− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
414−
415− // Move for a while to ensure our speed check is performed a couple of times
416− for (int i=0; i < 20; ++i) {
417− touchPoint += touchMovement;
418− passTime(timeStepMsecs);
419− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
420− }
421−
422− QCOMPARE((int)edgeDragArea->status(), expectedStatusAfterSpeedCheck);
423−}
424−
425−void tst_DirectionalDragArea::minSpeed_data()
426−{
427− QTest::addColumn<qreal>("minSpeed");
428− QTest::addColumn<qreal>("speed");
429− QTest::addColumn<int>("expectedStatusAfterSpeedCheck");
430−
431− QTest::newRow("slower than minSpeed") << 100.0 << 50.0 << (int)DirectionalDragArea::WaitingForTouch;
432− QTest::newRow("faster than minSpeed") << 100.0 << 150.0 << (int)DirectionalDragArea::Undecided;
433−}
434−
435246/*
436247 Checks that the recognition timer is started and stopped appropriately.
437248 I.e., check that it's running only while gesture recognition is taking place
@@ -442,11 +253,9 @@ void tst_DirectionalDragArea::recognitionTimerUsage()
442253 DirectionalDragArea *edgeDragArea =
443254 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
444255 QVERIFY(edgeDragArea != 0);
445− edgeDragArea->setRecognitionTimer(fakeTimer);
446− edgeDragArea->setTimeSource(fakeTimeSource);
447−
448− // don't let it interfere with our test
449− edgeDragArea->setMinSpeed(0.0);
256+ AbstractTimer *fakeTimer = m_fakeTimerFactory->createTimer();
257+ edgeDragArea->d->setRecognitionTimer(fakeTimer);
258+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
450259
451260 int timeStepMs = 5; // some arbitrary small value.
452261
@@ -454,62 +263,31 @@ void tst_DirectionalDragArea::recognitionTimerUsage()
454263 QPointF touchPoint = initialTouchPos;
455264
456265 QPointF dragDirectionVector(1.0, 0.0);
457− QPointF touchMovement = dragDirectionVector * (edgeDragArea->distanceThreshold() * 0.2f);
266+ QPointF touchMovement = dragDirectionVector * (edgeDragArea->d->distanceThreshold * 0.2f);
458267
459− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
268+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
460269 QVERIFY(!fakeTimer->isRunning());
461270
462271 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
463272
464− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
273+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
465274 QVERIFY(fakeTimer->isRunning());
466275
467276 // Move beyond distance threshold and composition time to ensure recognition
468− while (fakeTimeSource->m_msecsSinceReference <= edgeDragArea->compositionTime() ||
469− (touchPoint - initialTouchPos).manhattanLength() <= edgeDragArea->distanceThreshold()) {
277+ while (m_fakeTimerFactory->timeSource()->msecsSinceReference() <= edgeDragArea->d->compositionTime ||
278+ (touchPoint - initialTouchPos).manhattanLength() <= edgeDragArea->d->distanceThreshold) {
470279
471− QCOMPARE(edgeDragArea->status() == DirectionalDragArea::Undecided, fakeTimer->isRunning());
280+ QCOMPARE(edgeDragArea->d->status == DirectionalDragAreaPrivate::Undecided, fakeTimer->isRunning());
472281
473282 touchPoint += touchMovement;
474283 passTime(timeStepMs);
475284 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
476285 }
477286
478− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
287+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
479288 QVERIFY(!fakeTimer->isRunning());
480289}
481290
482−/*
483− A gesture should be rejected if too much time has passed without any new input
484− events from it.
485− */
486−void tst_DirectionalDragArea::maxSilenceTime()
487−{
488− DirectionalDragArea *edgeDragArea =
489− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
490− QVERIFY(edgeDragArea != 0);
491− edgeDragArea->setRecognitionTimer(fakeTimer);
492− edgeDragArea->setTimeSource(fakeTimeSource);
493−
494− // Make sure this property is not disabled
495− edgeDragArea->setMaxSilenceTime(100);
496−
497− QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
498− QPointF touchPoint = initialTouchPos;
499−
500− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
501−
502− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
503− QVERIFY(fakeTimer->isRunning());
504−
505− // Force timer to timeout until after maxSilenceTime has been reached
506− while (fakeTimeSource->m_msecsSinceReference < edgeDragArea->maxSilenceTime()) {
507− passTime(fakeTimer->interval());
508− }
509−
510− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
511−}
512−
513291/*
514292 Checks that it informs the X coordinate of the touch point in local and scene coordinates
515293 correctly.
@@ -519,18 +297,19 @@ void tst_DirectionalDragArea::sceneXAndX()
519297 DirectionalDragArea *edgeDragArea =
520298 m_view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea");
521299 QVERIFY(edgeDragArea != 0);
522− edgeDragArea->setRecognitionTimer(fakeTimer);
523− edgeDragArea->setTimeSource(fakeTimeSource);
300+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
301+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
302+ edgeDragArea->setImmediateRecognition(true);
524303
525304 QPointF touchScenePos(m_view->width() - (edgeDragArea->width()/2.0f), m_view->height()/2.0f);
526305
527− QTest::touchEvent(m_view, m_device).press(0, touchScenePos.toPoint());
306+ sendTouchPress(0 /* timestamp */, 0 /* id */, touchScenePos);
528307
529308 QSignalSpy touchXSpy(edgeDragArea, SIGNAL(touchXChanged(qreal)));
530309 QSignalSpy touchSceneXSpy(edgeDragArea, SIGNAL(touchSceneXChanged(qreal)));
531310
532311 touchScenePos.rx() = m_view->width() / 2;
533− QTest::touchEvent(m_view, m_device).move(0, touchScenePos.toPoint());
312+ sendTouchUpdate(50 /* timestamp */, 0 /* id */, touchScenePos);
534313
535314 QCOMPARE(touchXSpy.count(), 1);
536315 QCOMPARE(touchSceneXSpy.count(), 1);
@@ -547,18 +326,19 @@ void tst_DirectionalDragArea::sceneYAndY()
547326 DirectionalDragArea *edgeDragArea =
548327 m_view->rootObject()->findChild<DirectionalDragArea*>("vnDragArea");
549328 QVERIFY(edgeDragArea != 0);
550− edgeDragArea->setRecognitionTimer(fakeTimer);
551− edgeDragArea->setTimeSource(fakeTimeSource);
329+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
330+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
331+ edgeDragArea->setImmediateRecognition(true);
552332
553333 QPointF touchScenePos(m_view->width()/2.0f, m_view->height() - (edgeDragArea->height()/2.0f));
554334
555− QTest::touchEvent(m_view, m_device).press(0, touchScenePos.toPoint());
335+ sendTouchPress(0 /* timestamp */, 0 /* id */, touchScenePos);
556336
557337 QSignalSpy touchYSpy(edgeDragArea, SIGNAL(touchYChanged(qreal)));
558338 QSignalSpy touchSceneYSpy(edgeDragArea, SIGNAL(touchSceneYChanged(qreal)));
559339
560340 touchScenePos.ry() = m_view->height() / 2;
561− QTest::touchEvent(m_view, m_device).move(0, touchScenePos.toPoint());
341+ sendTouchUpdate(50 /* timestamp */, 0 /* id */, touchScenePos);
562342
563343 QCOMPARE(touchYSpy.count(), 1);
564344 QCOMPARE(touchSceneYSpy.count(), 1);
@@ -577,8 +357,8 @@ void tst_DirectionalDragArea::twoFingerTap()
577357 DirectionalDragArea *edgeDragArea =
578358 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
579359 QVERIFY(edgeDragArea != 0);
580− edgeDragArea->setRecognitionTimer(fakeTimer);
581− edgeDragArea->setTimeSource(fakeTimeSource);
360+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
361+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
582362
583363 // Make touches evenly spaced along the edgeDragArea
584364 QPoint touchAPos(edgeDragArea->width()/2.0f, m_view->height()*0.33f);
@@ -592,7 +372,7 @@ void tst_DirectionalDragArea::twoFingerTap()
592372 QTest::touchEvent(m_view, m_device)
593373 .press(0, touchAPos);
594374
595− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
375+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
596376
597377 passTime(timeStepMsecs);
598378 QTest::touchEvent(m_view, m_device)
@@ -601,20 +381,20 @@ void tst_DirectionalDragArea::twoFingerTap()
601381
602382 // A second touch point appeared during recognition, reject immediately as this
603383 // can't be a single-touch gesture anymore.
604− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
384+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
605385
606386 passTime(timeStepMsecs);
607387 QTest::touchEvent(m_view, m_device)
608388 .release(0, touchAPos)
609389 .move(1, touchBPos);
610390
611− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
391+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
612392
613393 passTime(timeStepMsecs);
614394 QTest::touchEvent(m_view, m_device)
615395 .release(1, touchBPos);
616396
617− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
397+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
618398
619399 // Perform the second two-finger tap
620400
@@ -622,27 +402,27 @@ void tst_DirectionalDragArea::twoFingerTap()
622402 QTest::touchEvent(m_view, m_device)
623403 .press(0, touchAPos);
624404
625− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
405+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
626406
627407 passTime(timeStepMsecs);
628408 QTest::touchEvent(m_view, m_device)
629409 .move(0, touchAPos)
630410 .press(1, touchBPos);
631411
632− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
412+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
633413
634414 passTime(timeStepMsecs);
635415 QTest::touchEvent(m_view, m_device)
636416 .release(0, touchAPos)
637417 .move(1, touchBPos);
638418
639− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
419+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
640420
641421 passTime(timeStepMsecs);
642422 QTest::touchEvent(m_view, m_device)
643423 .release(1, touchBPos);
644424
645− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
425+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
646426}
647427
648428/*
@@ -659,25 +439,25 @@ void tst_DirectionalDragArea::movingDDA()
659439 DirectionalDragArea *edgeDragArea =
660440 rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
661441 Q_ASSERT(edgeDragArea != 0);
662− edgeDragArea->setRecognitionTimer(fakeTimer);
663− edgeDragArea->setTimeSource(fakeTimeSource);
442+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
443+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
664444
665445 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
666446 QPointF touchPoint = initialTouchPos;
667447
668− qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
448+ qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
669449 QPointF dragDirectionVector(1.0f, 0.0f);
670450
671− qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
451+ qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
672452 QPointF touchMovement = dragDirectionVector * movementStepDistance;
673453 int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
674− int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
454+ int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
675455
676456 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
677457
678458 // Move it far ahead along the direction of the gesture
679459 // rightwardsLauncher is a parent of our DirectionalDragArea. So moving it will move our DDA
680− rightwardsLauncher->setX(rightwardsLauncher->x() + edgeDragArea->distanceThreshold() * 5.0f);
460+ rightwardsLauncher->setX(rightwardsLauncher->x() + edgeDragArea->d->distanceThreshold * 5.0f);
681461
682462 for (int i = 0; i < totalMovementSteps; ++i) {
683463 touchPoint += touchMovement;
@@ -685,7 +465,7 @@ void tst_DirectionalDragArea::movingDDA()
685465 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
686466 }
687467
688− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
468+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
689469
690470 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
691471}
@@ -699,8 +479,8 @@ void tst_DirectionalDragArea::ignoreOldFinger()
699479 DirectionalDragArea *edgeDragArea =
700480 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
701481 Q_ASSERT(edgeDragArea != 0);
702− edgeDragArea->setRecognitionTimer(fakeTimer);
703− edgeDragArea->setTimeSource(fakeTimeSource);
482+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
483+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
704484
705485 // Make touches evenly spaced along the edgeDragArea
706486 QPoint touch0Pos(edgeDragArea->width()/2.0f, m_view->height()*0.33f);
@@ -708,26 +488,26 @@ void tst_DirectionalDragArea::ignoreOldFinger()
708488
709489 QTest::touchEvent(m_view, m_device).press(0, touch0Pos);
710490
711− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
491+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
712492
713493 // leave it lying around for some time
714− passTime(qMax(edgeDragArea->maxSilenceTime(), edgeDragArea->compositionTime()) * 10);
494+ passTime(edgeDragArea->d->maxTime * 10);
715495
716− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
496+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
717497
718− qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
498+ qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
719499 QPointF dragDirectionVector(1.0f, 0.0f);
720500
721− qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
501+ qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
722502 QPointF touchMovement = dragDirectionVector * movementStepDistance;
723503 int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
724− int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
504+ int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
725505
726506 QTest::touchEvent(m_view, m_device)
727507 .move(0, touch0Pos)
728508 .press(1, touch1Pos);
729509
730− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
510+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
731511
732512 for (int i = 0; i < totalMovementSteps; ++i) {
733513 touch1Pos += touchMovement.toPoint();
@@ -737,13 +517,13 @@ void tst_DirectionalDragArea::ignoreOldFinger()
737517 .move(1, touch1Pos);
738518 }
739519
740− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
520+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
741521
742522 QTest::touchEvent(m_view, m_device)
743523 .move(0, touch0Pos)
744524 .release(1, touch1Pos);
745525
746− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
526+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
747527}
748528
749529/*
@@ -762,19 +542,19 @@ void tst_DirectionalDragArea::rotated()
762542 DirectionalDragArea *edgeDragArea =
763543 rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
764544 Q_ASSERT(edgeDragArea != 0);
765− edgeDragArea->setRecognitionTimer(fakeTimer);
766− edgeDragArea->setTimeSource(fakeTimeSource);
545+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
546+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
767547
768548 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
769549 QPointF touchPoint = initialTouchPos;
770550
771− qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
551+ qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
772552 QPointF dragDirectionVector(0.0f, 1.0f);
773553
774− qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
554+ qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
775555 QPointF touchMovement = dragDirectionVector * movementStepDistance;
776556 int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
777− int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
557+ int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
778558
779559 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
780560
@@ -784,7 +564,7 @@ void tst_DirectionalDragArea::rotated()
784564 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
785565 }
786566
787− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
567+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
788568
789569 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
790570}
@@ -802,31 +582,30 @@ void tst_DirectionalDragArea::sceneDistance()
802582 DirectionalDragArea *edgeDragArea =
803583 rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
804584 Q_ASSERT(edgeDragArea != 0);
805− edgeDragArea->setRecognitionTimer(fakeTimer);
806− edgeDragArea->setTimeSource(fakeTimeSource);
585+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
586+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
587+
588+ // to disable the position smoothing so that we can more easily check sceneDistance values
589+ edgeDragArea->setImmediateRecognition(true);
807590
808591 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
809592 QPointF touchPoint = initialTouchPos;
810593
811− qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
594+ qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
812595
813− qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
596+ qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
814597 QPointF touchMovement = dragDirectionVector * movementStepDistance;
815598 int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
816− int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
599+ int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
817600
818− QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
601+ qint64 timestamp = 0;
602+
603+ sendTouchPress(timestamp, 0, touchPoint);
819604
820−#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
821− QQuickWindowPrivate *wp = QQuickWindowPrivate::get(m_view);
822−#endif
823605 for (int i = 0; i < totalMovementSteps; ++i) {
824606 touchPoint += touchMovement;
825− passTime(movementTimeStepMs);
826− QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
827−#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
828− wp->flushDelayedTouchEvent();
829−#endif
607+ timestamp += movementTimeStepMs;
608+ sendTouchUpdate(timestamp, 0, touchPoint);
830609 }
831610
832611 qreal actualDragDistance = ((qreal)totalMovementSteps) * movementStepDistance;
@@ -836,7 +615,8 @@ void tst_DirectionalDragArea::sceneDistance()
836615 // NB: qFuzzyCompare(), used internally by QCOMPARE(), is broken.
837616 QVERIFY(qAbs(edgeDragArea->sceneDistance() - actualDragDistance) < 0.001);
838617
839− QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
618+ timestamp += movementTimeStepMs;
619+ sendTouchRelease(timestamp, 0, touchPoint);
840620}
841621
842622void tst_DirectionalDragArea::sceneDistance_data()
@@ -860,18 +640,18 @@ void tst_DirectionalDragArea::disabledWhileDragging()
860640 DirectionalDragArea *edgeDragArea =
861641 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
862642 Q_ASSERT(edgeDragArea != 0);
863− edgeDragArea->setRecognitionTimer(fakeTimer);
864− edgeDragArea->setTimeSource(fakeTimeSource);
643+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
644+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
865645
866646 QPointF touchPoint = calculateInitialTouchPos(edgeDragArea);
867647
868− qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
648+ qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2.0f;
869649 QPointF dragDirectionVector(1., 0.); // horizontal positive
870650
871− qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
651+ qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
872652 QPointF touchMovement = dragDirectionVector * movementStepDistance;
873653 int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
874− int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
654+ int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
875655
876656 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
877657
@@ -881,13 +661,13 @@ void tst_DirectionalDragArea::disabledWhileDragging()
881661 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
882662 }
883663
884− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
664+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
885665 QCOMPARE(edgeDragArea->dragging(), true);
886666
887667 // disable the dragArea while it's being dragged.
888668 edgeDragArea->setEnabled(false);
889669
890− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
670+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
891671 QCOMPARE(edgeDragArea->dragging(), false);
892672
893673 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
@@ -898,15 +678,14 @@ void tst_DirectionalDragArea::oneFingerDownFollowedByLateSecondFingerDown()
898678 DirectionalDragArea *edgeDragArea =
899679 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
900680 Q_ASSERT(edgeDragArea != 0);
901− edgeDragArea->setRecognitionTimer(fakeTimer);
902− edgeDragArea->setTimeSource(fakeTimeSource);
681+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
682+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
903683
904684 // Disable some constraints we're not interested in
905− edgeDragArea->setMaxSilenceTime(60 * 1000);
906− edgeDragArea->setMinSpeed(0);
685+ edgeDragArea->d->setMaxTime(60 * 1000);
907686
908687 // And ensure others have the values we want
909− edgeDragArea->setCompositionTime(60);
688+ edgeDragArea->d->compositionTime = 60;
910689
911690 // Put an item right behind edgeDragArea to receive the touches ignored by it
912691 DummyItem *dummyItem = new DummyItem;
@@ -923,10 +702,10 @@ void tst_DirectionalDragArea::oneFingerDownFollowedByLateSecondFingerDown()
923702
924703 QTest::touchEvent(m_view, m_device).press(0, touch0Pos);
925704
926− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
705+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
927706
928707 // We are now going to be way beyond compositionTime
929− passTime(edgeDragArea->compositionTime()*3);
708+ passTime(edgeDragArea->d->compositionTime*3);
930709
931710 QTest::touchEvent(m_view, m_device)
932711 .move(0, touch0Pos)
@@ -948,7 +727,7 @@ void tst_DirectionalDragArea::oneFingerDownFollowedByLateSecondFingerDown()
948727 .move(0, touch0Pos)
949728 .move(1, touch1Pos);
950729
951− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
730+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
952731
953732 passTime(5);
954733
@@ -956,7 +735,7 @@ void tst_DirectionalDragArea::oneFingerDownFollowedByLateSecondFingerDown()
956735 .release(0, touch0Pos)
957736 .move(1, touch1Pos);
958737
959− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
738+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
960739
961740 passTime(5);
962741
@@ -964,7 +743,7 @@ void tst_DirectionalDragArea::oneFingerDownFollowedByLateSecondFingerDown()
964743 .release(1, touch1Pos);
965744
966745 // Shouldn't be keepping info about touches that no longer exist or interest us
967− QVERIFY(edgeDragArea->m_activeTouches.isEmpty());
746+ QVERIFY(edgeDragArea->d->activeTouches.isEmpty());
968747
969748 delete dummyItem;
970749}
@@ -974,12 +753,11 @@ void tst_DirectionalDragArea::givesUpWhenLosesTouch()
974753 DirectionalDragArea *edgeDragArea =
975754 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
976755 Q_ASSERT(edgeDragArea != 0);
977− edgeDragArea->setRecognitionTimer(fakeTimer);
978− edgeDragArea->setTimeSource(fakeTimeSource);
756+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
757+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
979758
980759 // Disable some constraints we're not interested in
981− edgeDragArea->setMaxSilenceTime(60 * 1000);
982− edgeDragArea->setMinSpeed(0);
760+ edgeDragArea->d->setMaxTime(60 * 1000);
983761
984762 // Put an item right in front of edgeDragArea
985763 DummyItem *dummyItem = new DummyItem(edgeDragArea->parentItem());
@@ -998,11 +776,11 @@ void tst_DirectionalDragArea::givesUpWhenLosesTouch()
998776
999777 QTest::touchEvent(m_view, m_device).press(0, touchPos);
1000778
1001− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
779+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
1002780
1003781 m_touchRegistry->requestTouchOwnership(0, dummyItem);
1004782
1005− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
783+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1006784
1007785 dummyItem->grabTouchPoints({0});
1008786 dummyItem->touchEventHandler = [&](QTouchEvent *event) { event->accept(); };
@@ -1010,9 +788,9 @@ void tst_DirectionalDragArea::givesUpWhenLosesTouch()
1010788 passTime(5);
1011789 QTest::touchEvent(m_view, m_device).release(0, touchPos);
1012790
1013− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
791+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1014792
1015− QVERIFY(edgeDragArea->m_activeTouches.isEmpty());
793+ QVERIFY(edgeDragArea->d->activeTouches.isEmpty());
1016794}
1017795
1018796void tst_DirectionalDragArea::threeFingerDrag()
@@ -1020,15 +798,14 @@ void tst_DirectionalDragArea::threeFingerDrag()
1020798 DirectionalDragArea *edgeDragArea =
1021799 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1022800 Q_ASSERT(edgeDragArea != 0);
1023− edgeDragArea->setRecognitionTimer(fakeTimer);
1024− edgeDragArea->setTimeSource(fakeTimeSource);
801+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
802+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1025803
1026804 // Disable some constraints we're not interested in
1027− edgeDragArea->setMaxSilenceTime(60 * 1000);
1028− edgeDragArea->setMinSpeed(0);
805+ edgeDragArea->d->setMaxTime(60 * 1000);
1029806
1030807 // And ensure others have the values we want
1031− edgeDragArea->setCompositionTime(60);
808+ edgeDragArea->d->compositionTime = 60;
1032809
1033810 // Make touches evenly spaced along the edgeDragArea
1034811 QPoint touch0Pos(edgeDragArea->width()/2.0f, m_view->height()*0.25f);
@@ -1038,14 +815,14 @@ void tst_DirectionalDragArea::threeFingerDrag()
1038815 QTest::touchEvent(m_view, m_device)
1039816 .press(0, touch0Pos);
1040817
1041− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
818+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
1042819
1043820 passTime(5);
1044821 QTest::touchEvent(m_view, m_device)
1045822 .move(0, touch0Pos)
1046823 .press(1, touch1Pos);
1047824
1048− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
825+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1049826
1050827 passTime(5);
1051828 QTest::touchEvent(m_view, m_device)
@@ -1053,7 +830,7 @@ void tst_DirectionalDragArea::threeFingerDrag()
1053830 .move(1, touch1Pos)
1054831 .press(2, touch2Pos);
1055832
1056− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
833+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1057834
1058835 passTime(10);
1059836 QTest::touchEvent(m_view, m_device)
@@ -1077,7 +854,7 @@ void tst_DirectionalDragArea::threeFingerDrag()
1077854 .release(0, touch0Pos);
1078855
1079856 // Shouldn't be keepping info about touches that no longer exist or interest us
1080− QVERIFY(edgeDragArea->m_activeTouches.isEmpty());
857+ QVERIFY(edgeDragArea->d->activeTouches.isEmpty());
1081858}
1082859
1083860/*
@@ -1090,12 +867,12 @@ void tst_DirectionalDragArea::immediateRecognitionWhenConstraintsDisabled()
1090867 DirectionalDragArea *edgeDragArea =
1091868 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1092869 Q_ASSERT(edgeDragArea != 0);
1093− edgeDragArea->setRecognitionTimer(fakeTimer);
1094− edgeDragArea->setTimeSource(fakeTimeSource);
870+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
871+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1095872
1096873 // Disable the minimum amount of constraints to ensure immediate recognition
1097− edgeDragArea->setDistanceThreshold(0);
1098− edgeDragArea->setCompositionTime(0);
874+ edgeDragArea->d->setDistanceThreshold(0);
875+ edgeDragArea->d->compositionTime = 0;
1099876
1100877 // Put an item right behind edgeDragArea to receive the touches ignored by it
1101878 DummyItem *dummyItem = new DummyItem;
@@ -1111,7 +888,7 @@ void tst_DirectionalDragArea::immediateRecognitionWhenConstraintsDisabled()
1111888 QTest::touchEvent(m_view, m_device).press(0, touch0Pos);
1112889
1113890 // check for immediate recognition
1114− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
891+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
1115892
1116893 // and therefore it should have immediately grabbed the touch point,
1117894 // not letting it leak to items behind him.
@@ -1123,19 +900,19 @@ void tst_DirectionalDragArea::withdrawTouchOwnershipCandidacyIfDisabledDuringRec
1123900 DirectionalDragArea *edgeDragArea =
1124901 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1125902 Q_ASSERT(edgeDragArea != 0);
1126− edgeDragArea->setRecognitionTimer(fakeTimer);
1127− edgeDragArea->setTimeSource(fakeTimeSource);
903+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
904+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1128905
1129906 QPointF touchPoint = calculateInitialTouchPos(edgeDragArea);
1130907
1131908 // Move less than the minimum needed for the drag gesture recognition
1132− qreal desiredDragDistance = edgeDragArea->distanceThreshold()*0.5f;
909+ qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 0.5f;
1133910 QPointF dragDirectionVector(1., 0.); // horizontal positive
1134911
1135− qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
912+ qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
1136913 QPointF touchMovement = dragDirectionVector * movementStepDistance;
1137914 int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
1138− int movementTimeStepMs = (edgeDragArea->compositionTime() * 0.8f) / totalMovementSteps;
915+ int movementTimeStepMs = (edgeDragArea->d->compositionTime * 0.8f) / totalMovementSteps;
1139916
1140917 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
1141918
@@ -1145,14 +922,14 @@ void tst_DirectionalDragArea::withdrawTouchOwnershipCandidacyIfDisabledDuringRec
1145922 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
1146923 }
1147924
1148− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
925+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
1149926
1150927 // edgeDragArea should be an undecided candidate
1151928 {
1152929 auto touchInfo = m_touchRegistry->findTouchInfo(0);
1153930 QCOMPARE(touchInfo->candidates.size(), 1);
1154931 QCOMPARE(touchInfo->candidates.at(0).item.data(), edgeDragArea);
1155− QCOMPARE(touchInfo->candidates.at(0).undecided, true);
932+ QCOMPARE(touchInfo->candidates.at(0).state, TouchRegistry::CandidateInfo::Undecided);
1156933 }
1157934
1158935 // disable the dragArea while it's still recognizing a possible drag gesture.
@@ -1169,7 +946,7 @@ void tst_DirectionalDragArea::withdrawTouchOwnershipCandidacyIfDisabledDuringRec
1169946 QCOMPARE(touchInfo->candidates.size(), 0);
1170947 }
1171948
1172− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
949+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1173950
1174951 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
1175952}
@@ -1182,47 +959,13 @@ void tst_DirectionalDragArea::withdrawTouchOwnershipCandidacyIfDisabledDuringRec
1182959 QTest::newRow("invisible") << false;
1183960}
1184961
1185−void tst_DirectionalDragArea::tappedSignal()
1186−{
1187− DirectionalDragArea *edgeDragArea =
1188− m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1189− QVERIFY(edgeDragArea != 0);
1190− edgeDragArea->setRecognitionTimer(fakeTimer);
1191− edgeDragArea->setTimeSource(fakeTimeSource);
1192−
1193− QFETCH(bool, immediateGestureRecognition);
1194− if (immediateGestureRecognition) {
1195− // Disable the minimum amount of constraints to ensure immediate recognition
1196− edgeDragArea->setDistanceThreshold(0);
1197− edgeDragArea->setCompositionTime(0);
1198− }
1199−
1200− QPoint touch0Pos(edgeDragArea->width()/2.0f, m_view->height()/2.0f);
1201−
1202− QSignalSpy tappedSpy(edgeDragArea, SIGNAL(tapped()));
1203−
1204− QTest::touchEvent(m_view, m_device).press(0, touch0Pos);
1205− passTime(edgeDragArea->maxTapDuration() / 2);
1206− QTest::touchEvent(m_view, m_device).release(0, touch0Pos);
1207−
1208− QCOMPARE(tappedSpy.count(), 1);
1209−}
1210−
1211−void tst_DirectionalDragArea::tappedSignal_data()
1212−{
1213− QTest::addColumn<bool>("immediateGestureRecognition");
1214−
1215− QTest::newRow("immediate gesture recognition") << true;
1216− QTest::newRow("default gesture recognition") << false;
1217−}
1218−
1219962void tst_DirectionalDragArea::gettingTouchOwnershipMakesMouseAreaBehindGetCanceled()
1220963{
1221964 DirectionalDragArea *edgeDragArea =
1222965 m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1223966 QVERIFY(edgeDragArea != nullptr);
1224− edgeDragArea->setRecognitionTimer(fakeTimer);
1225− edgeDragArea->setTimeSource(fakeTimeSource);
967+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
968+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1226969
1227970 QQuickMouseArea *mouseArea =
1228971 m_view->rootObject()->findChild<QQuickMouseArea*>("mouseArea");
@@ -1233,12 +976,12 @@ void tst_DirectionalDragArea::gettingTouchOwnershipMakesMouseAreaBehindGetCancel
1233976 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea);
1234977 QPointF touchPoint = initialTouchPos;
1235978
1236− qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2;
979+ qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2;
1237980 QPointF dragDirectionVector(1.0f, 0.0f); // rightwards
1238− qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
981+ qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
1239982 QPointF touchMovement = dragDirectionVector * movementStepDistance;
1240983 int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
1241− int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
984+ int movementTimeStepMs = (edgeDragArea->d->compositionTime * 1.5f) / totalMovementSteps;
1242985
1243986 QCOMPARE(mouseArea->pressed(), false);
1244987
@@ -1259,13 +1002,305 @@ void tst_DirectionalDragArea::gettingTouchOwnershipMakesMouseAreaBehindGetCancel
12591002 // As the DirectionalDragArea recognizes the gesture, it grabs the touch from the MouseArea,
12601003 // which should make the MouseArea get a cancelation event, which will then cause it to
12611004 // reset its state (going back to "unpressed"/"released").
1262− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
1005+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
12631006 QCOMPARE(mouseArea->pressed(), false);
12641007 QCOMPARE(mouseAreaSpy.canceledCount, 1);
12651008
12661009 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
12671010}
12681011
1012+void tst_DirectionalDragArea::interleavedTouches()
1013+{
1014+ DirectionalDragArea *edgeDragArea =
1015+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1016+ QVERIFY(edgeDragArea != 0);
1017+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
1018+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1019+
1020+ QPointF touch0 = edgeDragArea->mapToScene(
1021+ QPointF(edgeDragArea->width()*0.5, edgeDragArea->height()*0.3));
1022+
1023+ qreal desiredDragDistance = edgeDragArea->d->distanceThreshold * 2;
1024+ QPointF dragDirectionVector(1.0f, 0.0f); // rightwards
1025+ qreal movementStepDistance = edgeDragArea->d->distanceThreshold * 0.1f;
1026+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
1027+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
1028+ int movementTimeStepMs = (edgeDragArea->d->maxTime * 0.4f) / totalMovementSteps;
1029+
1030+ QTest::touchEvent(m_view, m_device).press(0, touch0.toPoint());
1031+ for (int i = 0; i < totalMovementSteps; ++i) {
1032+ touch0 += touchMovement;
1033+ passTime(movementTimeStepMs);
1034+ QTest::touchEvent(m_view, m_device).move(0, touch0.toPoint());
1035+ }
1036+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
1037+
1038+ QPointF touch1 = edgeDragArea->mapToScene(
1039+ QPointF(edgeDragArea->width()*0.5, edgeDragArea->height()*0.6));
1040+
1041+ QTest::touchEvent(m_view, m_device)
1042+ .move(0, touch0.toPoint())
1043+ .press(1, touch1.toPoint());
1044+
1045+ touch1 += touchMovement;
1046+ passTime(movementTimeStepMs);
1047+ QTest::touchEvent(m_view, m_device)
1048+ .move(0, touch0.toPoint())
1049+ .move(1, touch1.toPoint());
1050+
1051+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Recognized);
1052+
1053+ QTest::touchEvent(m_view, m_device)
1054+ .release(0, touch0.toPoint())
1055+ .move(1, touch1.toPoint());
1056+
1057+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1058+
1059+ touch1 += touchMovement;
1060+ passTime(movementTimeStepMs);
1061+ QTest::touchEvent(m_view, m_device)
1062+ .move(1, touch1.toPoint());
1063+
1064+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1065+
1066+ QPointF touch2 = edgeDragArea->mapToScene(
1067+ QPointF(edgeDragArea->width()*0.5, edgeDragArea->height()*0.9));
1068+
1069+ passTime(edgeDragArea->d->compositionTime + movementTimeStepMs);
1070+ QTest::touchEvent(m_view, m_device)
1071+ .move(1, touch1.toPoint())
1072+ .press(2, touch2.toPoint());
1073+
1074+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::Undecided);
1075+ QCOMPARE(edgeDragArea->d->touchId, 2);
1076+
1077+ touch2 += touchMovement;
1078+ passTime(movementTimeStepMs);
1079+ QTest::touchEvent(m_view, m_device)
1080+ .move(1, touch1.toPoint())
1081+ .move(2, touch2.toPoint());
1082+
1083+ touch1 += touchMovement;
1084+ passTime(movementTimeStepMs);
1085+ QTest::touchEvent(m_view, m_device)
1086+ .move(1, touch1.toPoint())
1087+ .move(2, touch2.toPoint());
1088+
1089+ passTime(movementTimeStepMs);
1090+ QTest::touchEvent(m_view, m_device)
1091+ .release(1, touch1.toPoint())
1092+ .move(2, touch2.toPoint());
1093+
1094+ passTime(movementTimeStepMs);
1095+ QTest::touchEvent(m_view, m_device)
1096+ .release(2, touch2.toPoint());
1097+
1098+ QCOMPARE((int)edgeDragArea->d->status, (int)DirectionalDragAreaPrivate::WaitingForTouch);
1099+}
1100+
1101+/*
1102+ A valid right-edge drag performed on mako
1103+ */
1104+void tst_DirectionalDragArea::makoRightEdgeDrag()
1105+{
1106+ m_view->resize(768, 1280);
1107+ QTest::qWait(300);
1108+
1109+ DirectionalDragArea *edgeDragArea =
1110+ m_view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea");
1111+ QVERIFY(edgeDragArea != nullptr);
1112+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
1113+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1114+
1115+ StatusSpy *statusSpy = new StatusSpy(edgeDragArea);
1116+
1117+ edgeDragArea->d->setPixelsPerMm(320.0 /*mako ppi*/ * 0.03937 /* inches per mm*/);
1118+
1119+ sendTouchPress(319744, 0, QPointF(767.001, 719.719));
1120+ sendTouchUpdate(319765, 0, QPointF(765.744,729.973));
1121+ sendTouchUpdate(319784, 0, QPointF(740.879,752.182));
1122+ sendTouchUpdate(319803, 0, QPointF(689.698,795.795));
1123+ sendTouchUpdate(319826, 0, QPointF(616.978,856.212));
1124+ sendTouchUpdate(319845, 0, QPointF(558.769,906.157));
1125+ sendTouchUpdate(319859, 0, QPointF(513.219,945.266));
1126+ sendTouchUpdate(319878, 0, QPointF(481.31,975.496));
1127+ sendTouchUpdate(319902, 0, QPointF(460.016,997.439));
1128+ sendTouchUpdate(319920, 0, QPointF(449.761,1008.6));
1129+ sendTouchUpdate(319929, 0, QPointF(445.891,1012.42));
1130+ sendTouchUpdate(319947, 0, QPointF(444.884,1013.93));
1131+ sendTouchUpdate(319965, 0, QPointF(444.461,1014.35));
1132+ sendTouchUpdate(320057, 0, QPointF(444.71,1013.56));
1133+ sendTouchUpdate(320138, 0, QPointF(445.434,1013.6));
1134+ sendTouchUpdate(320154, 0, QPointF(446.338,1012.98));
1135+ sendTouchUpdate(320171, 0, QPointF(447.232,1012.08));
1136+ sendTouchRelease(320171, 0, QPointF(447.232,1012.08));
1137+
1138+ QCOMPARE(statusSpy->recognized(), true);
1139+
1140+ delete statusSpy;
1141+}
1142+
1143+/*
1144+ A vertical, downwards swipe performed on mako near its right edge.
1145+
1146+ The DirectionalDragArea on the right edge must not recognize this
1147+ gesture.
1148+ */
1149+void tst_DirectionalDragArea::makoRightEdgeDrag_verticalDownwards()
1150+{
1151+ m_view->resize(768, 1280);
1152+ QTest::qWait(300);
1153+
1154+ DirectionalDragArea *edgeDragArea =
1155+ m_view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea");
1156+ QVERIFY(edgeDragArea != nullptr);
1157+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
1158+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1159+
1160+ edgeDragArea->d->setPixelsPerMm(320.0 /*mako ppi*/ * 0.03937 /* inches per mm*/);
1161+
1162+ StatusSpy *statusSpy = new StatusSpy(edgeDragArea);
1163+
1164+ sendTouchPress(12012445, 26, QPointF(767.001,461.82));
1165+ sendTouchUpdate(12012472, 26, QPointF(767.001,462.569));
1166+ sendTouchUpdate(12012528, 26, QPointF(767.001,463.334));
1167+ sendTouchUpdate(12012546, 26, QPointF(767.001,466.856));
1168+ sendTouchUpdate(12012571, 26, QPointF(767.001,473.291));
1169+ sendTouchUpdate(12012587, 26, QPointF(767.001,487.31));
1170+ sendTouchUpdate(12012604, 26, QPointF(765.364,507.521));
1171+ sendTouchUpdate(12012618, 26, QPointF(765.364,507.521));
1172+ sendTouchUpdate(12012627, 26, QPointF(762.642,534.317));
1173+ sendTouchUpdate(12012655, 26, QPointF(760.846,573.406));
1174+ sendTouchUpdate(12012667, 26, QPointF(759.838,625.295));
1175+ sendTouchUpdate(12012675, 26, QPointF(758.875,703.207));
1176+ sendTouchUpdate(12012696, 26, QPointF(761.52,777.015));
1177+ sendTouchUpdate(12012713, 26, QPointF(765.659,835.591));
1178+ sendTouchUpdate(12012731, 26, QPointF(766.778,883.206));
1179+ sendTouchUpdate(12012748, 26, QPointF(767.001,922.937));
1180+ sendTouchUpdate(12012779, 26, QPointF(767.001,967.558));
1181+ sendTouchUpdate(12012798, 26, QPointF(767.001,1006.12));
1182+ sendTouchUpdate(12012809, 26, QPointF(767.001,1033.1));
1183+ sendTouchRelease(12012810, 26, QPointF(767.001,1033.1));
1184+
1185+ QCOMPARE(statusSpy->recognized(), false);
1186+
1187+ delete statusSpy;
1188+}
1189+
1190+/*
1191+ A valid left-edge drag performed on mako. This one starts a bit slow than speeds up
1192+ */
1193+void tst_DirectionalDragArea::makoLeftEdgeDrag_slowStart()
1194+{
1195+ m_view->resize(768, 1280);
1196+ QTest::qWait(300);
1197+
1198+ DirectionalDragArea *edgeDragArea =
1199+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1200+ QVERIFY(edgeDragArea != nullptr);
1201+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
1202+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1203+
1204+ edgeDragArea->d->setPixelsPerMm(320.0 /*mako ppi*/ * 0.03937 /* inches per mm*/);
1205+
1206+ StatusSpy *statusSpy = new StatusSpy(edgeDragArea);
1207+
1208+ sendTouchPress(4002267, 77, QPointF(0,885.154));
1209+ sendTouchUpdate(4002275, 77, QPointF(0,886.214));
1210+ sendTouchUpdate(4002311, 77, QPointF(1.09568,887.75));
1211+ sendTouchUpdate(4002329, 77, QPointF(3.53647,890.191));
1212+ sendTouchUpdate(4002347, 77, QPointF(7.87434,892.879));
1213+ sendTouchUpdate(4002366, 77, QPointF(12.3036,895.075));
1214+ sendTouchUpdate(4002384, 77, QPointF(15.8885,896.849));
1215+ sendTouchUpdate(4002406, 77, QPointF(18.4504,897.88));
1216+ sendTouchUpdate(4002420, 77, QPointF(20.2429,898.149));
1217+ sendTouchUpdate(4002439, 77, QPointF(20.9945,898.149));
1218+ sendTouchUpdate(4002457, 77, QPointF(21.8819,898.149));
1219+ sendTouchUpdate(4002480, 77, QPointF(22.7454,897.389));
1220+ sendTouchUpdate(4002493, 77, QPointF(23.5456,896.589));
1221+ sendTouchUpdate(4002511, 77, QPointF(24.5435,895.031));
1222+ sendTouchUpdate(4002529, 77, QPointF(25.4271,892.32));
1223+ sendTouchUpdate(4002548, 77, QPointF(26.3145,889.658));
1224+ sendTouchUpdate(4002566, 77, QPointF(27.2004,886.999));
1225+ sendTouchUpdate(4002584, 77, QPointF(28.035,885.048));
1226+ sendTouchUpdate(4002603, 77, QPointF(29.9684,883.167));
1227+ sendTouchUpdate(4002620, 77, QPointF(33.3591,881.403));
1228+ sendTouchUpdate(4002639, 77, QPointF(44.1017,879.642));
1229+ sendTouchUpdate(4002657, 77, QPointF(64.828,878.502));
1230+ sendTouchUpdate(4002675, 77, QPointF(87.9486,878.157));
1231+ sendTouchUpdate(4002693, 77, QPointF(112.96,877.742));
1232+ sendTouchUpdate(4002711, 77, QPointF(138.903,877.157));
1233+ sendTouchUpdate(4002729, 77, QPointF(163.204,877.157));
1234+ sendTouchUpdate(4002747, 77, QPointF(182.127,877.157));
1235+ sendTouchUpdate(4002765, 77, QPointF(194.478,877.657));
1236+ sendTouchUpdate(4002785, 77, QPointF(201.474,878.508));
1237+ sendTouchUpdate(4002803, 77, QPointF(204.855,879.401));
1238+ sendTouchUpdate(4002822, 77, QPointF(206.616,880.281));
1239+ sendTouchUpdate(4002839, 77, QPointF(207.115,880.906));
1240+ sendTouchUpdate(4002894, 77, QPointF(206.865,881.184));
1241+ sendTouchUpdate(4002912, 77, QPointF(206.865,882.143));
1242+ sendTouchUpdate(4002930, 77, QPointF(206.865,883.106));
1243+ sendTouchUpdate(4002949, 77, QPointF(206.526,883.994));
1244+ sendTouchUpdate(4002967, 77, QPointF(205.866,884.88));
1245+ sendTouchUpdate(4002985, 77, QPointF(205.866,885.766));
1246+ sendTouchUpdate(4003005, 77, QPointF(205.866,886.654));
1247+ sendTouchUpdate(4003021, 77, QPointF(205.366,887.537));
1248+ sendTouchUpdate(4003039, 77, QPointF(204.592,888.428));
1249+ sendTouchUpdate(4003050, 77, QPointF(204.367,888.653));
1250+ sendTouchRelease(4003050, 77, QPointF(204.367,888.653));
1251+
1252+ QCOMPARE(statusSpy->recognized(), true);
1253+
1254+ delete statusSpy;
1255+}
1256+
1257+void tst_DirectionalDragArea::makoLeftEdgeDrag_movesSlightlyBackwardsOnStart()
1258+{
1259+ m_view->resize(768, 1280);
1260+ QTest::qWait(300);
1261+
1262+ DirectionalDragArea *edgeDragArea =
1263+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
1264+ QVERIFY(edgeDragArea != nullptr);
1265+ edgeDragArea->d->setRecognitionTimer(m_fakeTimerFactory->createTimer());
1266+ edgeDragArea->d->setTimeSource(m_fakeTimerFactory->timeSource());
1267+
1268+ edgeDragArea->d->setPixelsPerMm(320.0 /*mako ppi*/ * 0.03937 /* inches per mm*/);
1269+
1270+ StatusSpy *statusSpy = new StatusSpy(edgeDragArea);
1271+
1272+ sendTouchPress(41097, 24, QPointF(13.9909,827.177));
1273+ sendTouchUpdate(41120, 24, QPointF(19.2375,825.677));
1274+ sendTouchUpdate(41138, 24, QPointF(18.4057,826.177));
1275+ sendTouchUpdate(41161, 24, QPointF(20.1067,825.867));
1276+ sendTouchUpdate(41177, 24, QPointF(21.8869,824.977));
1277+ sendTouchUpdate(41193, 24, QPointF(24.7603,823.494));
1278+ sendTouchUpdate(41211, 24, QPointF(28.3889,821.725));
1279+ sendTouchUpdate(41229, 24, QPointF(32.2909,819.955));
1280+ sendTouchUpdate(41247, 24, QPointF(38.2251,817.431));
1281+ sendTouchUpdate(41266, 24, QPointF(52.4182,814.223));
1282+ sendTouchUpdate(41284, 24, QPointF(85.8465,809.483));
1283+ sendTouchUpdate(41302, 24, QPointF(126.091,802.741));
1284+ sendTouchUpdate(41320, 24, QPointF(153.171,797.977));
1285+ sendTouchUpdate(41338, 24, QPointF(170.565,795.077));
1286+ sendTouchUpdate(41356, 24, QPointF(178.685,794.101));
1287+ sendTouchUpdate(41375, 24, QPointF(183.706,793.225));
1288+ sendTouchUpdate(41393, 24, QPointF(186.112,793.19));
1289+ sendTouchUpdate(41411, 24, QPointF(187.634,793.19));
1290+ sendTouchUpdate(41429, 24, QPointF(188.505,793.19));
1291+ sendTouchUpdate(41532, 24, QPointF(187.816,793.19));
1292+ sendTouchUpdate(41538, 24, QPointF(186.902,793.19));
1293+ sendTouchUpdate(41557, 24, QPointF(186.01,793.19));
1294+ sendTouchUpdate(41575, 24, QPointF(185.125,793.444));
1295+ sendTouchUpdate(41593, 24, QPointF(184.229,793.69));
1296+ sendTouchUpdate(41605, 24, QPointF(183.88,793.69));
1297+ sendTouchRelease(41607, 24, QPointF(183.88,793.69));
1298+
1299+ QCOMPARE(statusSpy->recognized(), true);
1300+
1301+ delete statusSpy;
1302+}
1303+
12691304QTEST_MAIN(tst_DirectionalDragArea)
12701305
12711306#include "tst_DirectionalDragArea.moc"