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;