diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-12-11 14:32:04 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2017-12-13 06:53:01 +0000 |
commit | ae01e0dbf50cb6da1967e10eb95d63313dc5aa7a (patch) | |
tree | eaa4fedc4114d342c21b1b6b2d5313d0b85bf00a /src/quick/items/qquickflickable.cpp | |
parent | 61118298431a2719bb9028691810268ddb3058b7 (diff) |
Flickable: don't jump after premature movementEnding due to timer
Followup to ef8c6f6a0bf5e4c9ee41306f2df59048ab96038f: we emit
movementEnding for the benefit of the user, scrollbars, decorators
etc. in case the ScrollEnd phase means that movement really ended
(it means the user lifted his fingers from the trackpad,
but momentum events can cause the movement to continue after that).
But in case movement didn't end, we don't want to have a jump when
it resumes. But scrollingPhase will be true after an event with
ScrollBegin phase, and false after an event with ScrollEnd,
also false if the mouse is an ordinary wheel mouse without phases.
So when the timer fires, if the user has not yet lifted his fingers,
scrollingPhase is true, and that means scrolling isn't really ending,
so we should not set vMoved to false.
Setting vMoved to false will cause the drag() function to
reset vData.dragStartOffset to the current dy value, which
ultimately causes the jump in contentY. It should be done only
when scrolling really ends. If the timer fires and scrollingPhase
is false, we can be sure it really ended. But if you flick, then
rest your fingers, then lift them, there is no momentum, so the
final event has scroll phase ScrollEnd, and we need to run the
timer one more time to detect that there are no more updates
and finish the transition back to the default state (set vMoved back
to false, emit signals such as movementEnded, etc.)
The ultimate solution is to add another Qt::ScrollPhase enum,
such as ScrollMomentum, but we should not do that in the 5.9 series.
Task-number: QTBUG-63026
Change-Id: I854c52a680028cb1d43b133be65653d87a05a0b1
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src/quick/items/qquickflickable.cpp')
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 3662827973..44612edc49 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1444,17 +1444,23 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) case Qt::ScrollUpdate: if (d->scrollingPhase) d->pressed = true; -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS + // TODO eliminate this timer when ScrollMomentum has been added d->movementEndingTimer.start(MovementEndingTimerInterval, this); #endif break; case Qt::ScrollEnd: + // TODO most of this should be done at transition to ScrollMomentum phase, + // then do what the movementEndingTimer triggers at transition to ScrollEnd phase d->pressed = false; d->scrollingPhase = false; d->draggingEnding(); event->accept(); returnToBounds(); d->lastPosTime = -1; +#ifdef Q_OS_MACOS + d->movementEndingTimer.start(MovementEndingTimerInterval, this); +#endif return; } @@ -2671,13 +2677,15 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding) if (hMovementEnding && d->hData.moving && (!d->pressed && !d->stealMouse)) { d->hData.moving = false; - d->hMoved = false; + if (!d->scrollingPhase) + d->hMoved = false; emit movingHorizontallyChanged(); } if (vMovementEnding && d->vData.moving && (!d->pressed && !d->stealMouse)) { d->vData.moving = false; - d->vMoved = false; + if (!d->scrollingPhase) + d->vMoved = false; emit movingVerticallyChanged(); } if (wasMoving && !isMoving()) { |