From c47b370f96a87393a622a87df8d1a3c79bd5b1b1 Mon Sep 17 00:00:00 2001 From: Andras Becsi Date: Thu, 13 Sep 2012 15:18:19 +0200 Subject: Fix Flickable movementEnded() signal emission In case the content was flicked horizontally so that the vertical position did not change handleMouseReleaseEvent performed a fixup for the vertical position to be an integer _before_ starting the horizontal flick. For some large content the rounding fixup had finished before the flicking animation started which resulted in a premature emission of the movementEnded() signal. This race condition did not affect vertical flicking because the vertical animation had always been started before the horizontal fixup was scheduled. The issue was revealed by QQuickWebView which above a certain velocity threshold locks the movement in one direction, thus produces the exact same vertical position throughout a horizontal pan gesture. This patch removes the race condition by starting the flick animation in either direction first then performing the position fixup if needed. There does not seem to be a reliable way to auto-test this. Change-Id: Idc8fb59b0a6ead71c6cfc7083a386d51048ec50c Reviewed-by: Jocelyn Turcotte Reviewed-by: Shawn Rutledge Reviewed-by: Frederik Gladhorn --- src/quick/items/qquickflickable.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 99a0c503a5..5ba5908ccc 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1172,27 +1172,31 @@ void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event) flickBoost = canBoost ? qBound(1.0, flickBoost+0.25, QML_FLICK_MULTIFLICK_MAXBOOST) : 1.0; - bool flickedV = false; + bool flickedVertically = false; vVelocity *= flickBoost; - if (q->yflick() && qAbs(vVelocity) > MinimumFlickVelocity && qAbs(event->localPos().y() - pressPos.y()) > FlickThreshold) { + bool isVerticalFlickAllowed = q->yflick() && qAbs(vVelocity) > MinimumFlickVelocity && qAbs(event->localPos().y() - pressPos.y()) > FlickThreshold; + if (isVerticalFlickAllowed) { velocityTimeline.reset(vData.smoothVelocity); vData.smoothVelocity.setValue(-vVelocity); - flickedV = flickY(vVelocity); - } else { - fixupY(); + flickedVertically = flickY(vVelocity); } - bool flickedH = false; + bool flickedHorizontally = false; hVelocity *= flickBoost; - if (q->xflick() && qAbs(hVelocity) > MinimumFlickVelocity && qAbs(event->localPos().x() - pressPos.x()) > FlickThreshold) { + bool isHorizontalFlickAllowed = q->xflick() && qAbs(hVelocity) > MinimumFlickVelocity && qAbs(event->localPos().x() - pressPos.x()) > FlickThreshold; + if (isHorizontalFlickAllowed) { velocityTimeline.reset(hData.smoothVelocity); hData.smoothVelocity.setValue(-hVelocity); - flickedH = flickX(hVelocity); - } else { - fixupX(); + flickedHorizontally = flickX(hVelocity); } - flickingStarted(flickedH, flickedV); + if (!isVerticalFlickAllowed) + fixupY(); + + if (!isHorizontalFlickAllowed) + fixupX(); + + flickingStarted(flickedHorizontally, flickedVertically); if (!isViewMoving()) q->movementEnding(); } -- cgit v1.2.3