Use input event timestamps in QQuickFlickable if available.
authorAndras Becsi <andras.becsi@nokia.com>
Tue, 29 Nov 2011 14:24:27 +0000 (15:24 +0100)
committerQt by Nokia <qt-info@nokia.com>
Tue, 20 Dec 2011 12:36:16 +0000 (13:36 +0100)
Change-Id: If89ad205dec9ffdba4ca196cdc1a2e5fd9258260
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/quick/items/qquickflickable.cpp
src/quick/items/qquickflickable_p_p.h

index aca3542..704d1e1 100644 (file)
@@ -174,6 +174,8 @@ QQuickFlickablePrivate::QQuickFlickablePrivate()
     , hMoved(false), vMoved(false)
     , stealMouse(false), pressed(false), interactive(true), calcVelocity(false)
     , pixelAligned(false)
+    , lastPosTime(-1)
+    , lastPressTime(0)
     , deceleration(QML_FLICK_DEFAULTDECELERATION)
     , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100)
     , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(400)
@@ -194,7 +196,6 @@ void QQuickFlickablePrivate::init()
     q->setFiltersChildMouseEvents(true);
     QQuickItemPrivate *viewportPrivate = QQuickItemPrivate::get(contentItem);
     viewportPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
-    lastPosTime.invalidate();
 }
 
 /*
@@ -792,9 +793,18 @@ void QQuickFlickable::setPixelAligned(bool align)
     }
 }
 
+qint64 QQuickFlickablePrivate::computeCurrentTime(QInputEvent *event)
+{
+    if (0 != event->timestamp() && QQuickItemPrivate::consistentTime == -1)
+        return event->timestamp();
+
+    return QQuickItemPrivate::elapsed(timer);
+}
+
 void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
 {
     Q_Q(QQuickFlickable);
+    QQuickItemPrivate::start(timer);
     if (interactive && timeline.isActive()
         && (qAbs(hData.smoothVelocity.value()) > RetainGrabVelocity
             || qAbs(vData.smoothVelocity.value()) > RetainGrabVelocity)) {
@@ -813,20 +823,20 @@ void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
     vData.dragMaxBound = q->maxYExtent();
     fixupMode = Normal;
     lastPos = QPointF();
-    QQuickItemPrivate::start(lastPosTime);
+    lastPosTime = computeCurrentTime(event);
     pressPos = event->localPos();
     hData.pressPos = hData.move.value();
     vData.pressPos = vData.move.value();
     hData.flicking = false;
     vData.flicking = false;
-    QQuickItemPrivate::start(pressTime);
+    lastPressTime = computeCurrentTime(event);
     QQuickItemPrivate::start(velocityTime);
 }
 
 void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
 {
     Q_Q(QQuickFlickable);
-    if (!interactive || !lastPosTime.isValid())
+    if (!interactive || lastPosTime == -1)
         return;
     bool rejectY = false;
     bool rejectX = false;
@@ -834,9 +844,11 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
     bool stealY = stealMouse;
     bool stealX = stealMouse;
 
+    qint64 elapsed = computeCurrentTime(event) - lastPressTime;
+
     if (q->yflick()) {
         qreal dy = event->localPos().y() - pressPos.y();
-        if (qAbs(dy) > qApp->styleHints()->startDragDistance() || QQuickItemPrivate::elapsed(pressTime) > 200) {
+        if (qAbs(dy) > qApp->styleHints()->startDragDistance() || elapsed > 200) {
             if (!vMoved)
                 vData.dragStartOffset = dy;
             qreal newY = dy + vData.pressPos - vData.dragStartOffset;
@@ -868,7 +880,7 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
 
     if (q->xflick()) {
         qreal dx = event->localPos().x() - pressPos.x();
-        if (qAbs(dx) > qApp->styleHints()->startDragDistance() || QQuickItemPrivate::elapsed(pressTime) > 200) {
+        if (qAbs(dx) > qApp->styleHints()->startDragDistance() || elapsed > 200) {
             if (!hMoved)
                 hData.dragStartOffset = dx;
             qreal newX = dx + hData.pressPos - hData.dragStartOffset;
@@ -919,10 +931,11 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
     }
 
     if (!lastPos.isNull()) {
-        qreal elapsed = qreal(QQuickItemPrivate::elapsed(lastPosTime)) / 1000.;
+        qint64 currentTimestamp = computeCurrentTime(event);
+        qreal elapsed = qreal(currentTimestamp - lastPosTime) / 1000.;
         if (elapsed <= 0)
             return;
-        QQuickItemPrivate::restart(lastPosTime);
+        lastPosTime = currentTimestamp;
         qreal dy = event->localPos().y()-lastPos.y();
         if (q->yflick() && !rejectY)
             vData.addVelocitySample(dy/elapsed, maxVelocity);
@@ -942,14 +955,14 @@ void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
     pressed = false;
 
     // if we drag then pause before release we should not cause a flick.
-    qint64 elapsed = QQuickItemPrivate::elapsed(lastPosTime);
+    qint64 elapsed = computeCurrentTime(event) - lastPosTime;
 
     vData.updateVelocity();
     hData.updateVelocity();
 
     draggingEnding();
 
-    if (!lastPosTime.isValid())
+    if (lastPosTime == -1)
         return;
 
     vTime = timeline.time();
@@ -1659,6 +1672,7 @@ bool QQuickFlickable::sendMouseEvent(QMouseEvent *event)
         QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
                                event->button(), event->buttons(), event->modifiers());
 
+        mouseEvent.setTimestamp(event->timestamp());
         mouseEvent.setAccepted(false);
 
         switch (mouseEvent.type()) {
@@ -1701,12 +1715,12 @@ bool QQuickFlickable::sendMouseEvent(QMouseEvent *event)
         }
 
         return stealThisEvent || d->delayedPressEvent || disabledItem;
-    } else if (d->lastPosTime.isValid()) {
-        d->lastPosTime.invalidate();
+    } else if (d->lastPosTime != -1) {
+        d->lastPosTime = -1;
         returnToBounds();
     }
     if (event->type() == QEvent::MouseButtonRelease) {
-        d->lastPosTime.invalidate();
+        d->lastPosTime = -1;
         d->clearDelayedPress();
         d->stealMouse = false;
         d->pressed = false;
index 8ceea61..69fad68 100644 (file)
@@ -183,10 +183,11 @@ public:
     bool interactive : 1;
     bool calcVelocity : 1;
     bool pixelAligned : 1;
-    QElapsedTimer lastPosTime;
+    QElapsedTimer timer;
+    qint64 lastPosTime;
+    qint64 lastPressTime;
     QPointF lastPos;
     QPointF pressPos;
-    QElapsedTimer pressTime;
     qreal deceleration;
     qreal maxVelocity;
     QElapsedTimer velocityTime;
@@ -215,6 +216,8 @@ public:
     void handleMouseMoveEvent(QMouseEvent *);
     void handleMouseReleaseEvent(QMouseEvent *);
 
+    qint64 computeCurrentTime(QInputEvent *event);
+
     // flickableData property
     static void data_append(QDeclarativeListProperty<QObject> *, QObject *);
     static int data_count(QDeclarativeListProperty<QObject> *);