Handle mac trackpad zoom via GesturePinch events
Prior to this change, Mac handles pinch gestures directly in the UI layer (BrowserWindowController). Here we instead have the RenderWidgetHost send GesturePinchUpdate events, and when those events go unhandled WebContentsImpl implements the browser zoom behavior (similar to how it does already for ctrl+mousewheel events on other platforms).
This lays the groundwork in the short term for giving the web page a chance to override the pinch behavior. Longer term this will enable us to hook into the pinch-zoom codepath used for touchscreen so that we can get a similar effect (instead of just browser-zoom - which probably isn't really what the user wants when pinching).
The only observable behavior change in this CL is that pinching outside the content area (eg. in the tabstrip) no longer does anything. It's not clear what the pinch origin should be in such a case, and it probably doesn't really make sense to try to handle it (pinching is supposed to zoom whatever is under the cursor).
This adds some basic unit test coverage for the pre-existing (but untested) logic for mapping pinch scales to zoom in/out actions.
Depends on blink CL: https://src.chromium.org/viewvc/blink?view=rev&revision=168482
BUG=289887
Review URL: https://codereview.chromium.org/181723006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260452 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 79cfa06..005f768 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -332,6 +332,8 @@
minimum_zoom_percent_(static_cast<int>(kMinimumZoomFactor * 100)),
maximum_zoom_percent_(static_cast<int>(kMaximumZoomFactor * 100)),
temporary_zoom_settings_(false),
+ totalPinchGestureAmount_(0),
+ currentPinchZoomStepDelta_(0),
color_chooser_identifier_(0),
render_view_message_source_(NULL),
fullscreen_widget_routing_id_(MSG_ROUTING_NONE),
@@ -1215,6 +1217,44 @@
return delegate_ && delegate_->PreHandleGestureEvent(this, event);
}
+bool WebContentsImpl::HandleGestureEvent(
+ const blink::WebGestureEvent& event) {
+ // Some platforms (eg. Mac) send GesturePinch events for trackpad pinch-zoom.
+ // Use them to implement browser zoom, as for HandleWheelEvent above.
+ if (event.type == blink::WebInputEvent::GesturePinchUpdate &&
+ event.sourceDevice == blink::WebGestureEvent::Touchpad) {
+ // The scale difference necessary to trigger a zoom action. Derived from
+ // experimentation to find a value that feels reasonable.
+ const float kZoomStepValue = 0.6f;
+
+ // Find the (absolute) thresholds on either side of the current zoom factor,
+ // then convert those to actual numbers to trigger a zoom in or out.
+ // This logic deliberately makes the range around the starting zoom value
+ // for the gesture twice as large as the other ranges (i.e., the notches are
+ // at ..., -3*step, -2*step, -step, step, 2*step, 3*step, ... but not at 0)
+ // so that it's easier to get back to your starting point than it is to
+ // overshoot.
+ float nextStep = (abs(currentPinchZoomStepDelta_) + 1) * kZoomStepValue;
+ float backStep = abs(currentPinchZoomStepDelta_) * kZoomStepValue;
+ float zoomInThreshold = (currentPinchZoomStepDelta_ >= 0) ? nextStep
+ : -backStep;
+ float zoomOutThreshold = (currentPinchZoomStepDelta_ <= 0) ? -nextStep
+ : backStep;
+
+ totalPinchGestureAmount_ += event.data.pinchUpdate.scale;
+ if (totalPinchGestureAmount_ > zoomInThreshold) {
+ currentPinchZoomStepDelta_++;
+ delegate_->ContentsZoomChange(true);
+ } else if (totalPinchGestureAmount_ < zoomOutThreshold) {
+ currentPinchZoomStepDelta_--;
+ delegate_->ContentsZoomChange(false);
+ }
+ return true;
+ }
+
+ return false;
+}
+
#if defined(OS_WIN)
gfx::NativeViewAccessible WebContentsImpl::GetParentNativeViewAccessible() {
return accessible_parent_;