From cce9ee69dcd402503260876b5a170ac203aee0a1 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Thu, 6 Apr 2017 16:17:54 -0400 Subject: [PATCH] Bug 1345355 - Allow pinch gestures with a zero span change but a nonzero focus change to scroll. r=botond It appears that some touchpad devices send us "touch" events (i.e. WM_TOUCH on Windows) but with all touch points having the same coordinates. This ends up getting detected as a zero-span pinch gesture in APZ, which short-circuits early and doesn't really get processed. Therefore even if the focus point changes we don't do any corresponding scroll. This patch shifts things around a little so that the short-circuit doesn't happen quite so early, and we still scroll when the focus point changes, even if the span is zero. MozReview-Commit-ID: 3CaQN1MsM8y --- gfx/layers/apz/src/AsyncPanZoomController.cpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index 4ee6b6f43b39..ba5c8991d4c8 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -1368,14 +1368,6 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) { MOZ_ASSERT(mFrameMetrics.IsRootContent()); MOZ_ASSERT(mFrameMetrics.GetZoom().AreScalesSame()); - float prevSpan = aEvent.mPreviousSpan; - if (fabsf(prevSpan) <= EPSILON || fabsf(aEvent.mCurrentSpan) <= EPSILON) { - // We're still handling it; we've just decided to throw this event away. - return nsEventStatus_eConsumeNoDefault; - } - - float spanRatio = aEvent.mCurrentSpan / aEvent.mPreviousSpan; - { ReentrantMonitorAutoEnter lock(mMonitor); @@ -1384,12 +1376,29 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) { CSSPoint cssFocusPoint = focusPoint / mFrameMetrics.GetZoom(); ParentLayerPoint focusChange = mLastZoomFocus - focusPoint; + mLastZoomFocus = focusPoint; // If displacing by the change in focus point will take us off page bounds, // then reduce the displacement such that it doesn't. focusChange.x -= mX.DisplacementWillOverscrollAmount(focusChange.x); focusChange.y -= mY.DisplacementWillOverscrollAmount(focusChange.y); ScrollBy(focusChange / userZoom); + // If the span is zero or close to it, we don't want to process this zoom + // change because we're going to get wonky numbers for the spanRatio. So + // let's bail out here. Note that we do this after the focus-change-scroll + // above, so that if we have a pinch with zero span but changing focus, + // such as generated by some Synaptics touchpads on Windows, we still + // scroll properly. + float prevSpan = aEvent.mPreviousSpan; + if (fabsf(prevSpan) <= EPSILON || fabsf(aEvent.mCurrentSpan) <= EPSILON) { + // We might have done a nonzero ScrollBy above, so update metrics and + // repaint/recomposite + ScheduleCompositeAndMaybeRepaint(); + UpdateSharedCompositorFrameMetrics(); + return nsEventStatus_eConsumeNoDefault; + } + float spanRatio = aEvent.mCurrentSpan / aEvent.mPreviousSpan; + // When we zoom in with focus, we can zoom too much towards the boundaries // that we actually go over them. These are the needed displacements along // either axis such that we don't overscroll the boundaries when zooming. @@ -1448,8 +1457,6 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) { // We did a ScrollBy call above even if we didn't do a scale, so we // should composite for that. ScheduleComposite(); - - mLastZoomFocus = focusPoint; } return nsEventStatus_eConsumeNoDefault;