diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 1ab4de97b14b84..5adbc7f33a8959 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc @@ -4430,3 +4430,21 @@ IN_PROC_BROWSER_TEST_F(WebViewTest, AutoResizeMessages) { embedder->GetRenderWidgetHostView()->GetRenderWidgetHost()->GetProcess(), guest->GetRenderWidgetHostView()->GetRenderWidgetHost())); } + +// Test that a guest sees the synthetic wheel events of a touchpad pinch. +IN_PROC_BROWSER_TEST_F(WebViewTest, TouchpadPinchSyntheticWheelEvents) { + ASSERT_TRUE(StartEmbeddedTestServer()); + LoadAppWithGuest("web_view/touchpad_pinch"); + content::WebContents* guest_contents = GetGuestWebContents(); + + ExtensionTestMessageListener synthetic_wheel_listener("Seen wheel event", + false); + + const gfx::Rect contents_rect = guest_contents->GetContainerBounds(); + const gfx::Point pinch_position(contents_rect.width() / 2, + contents_rect.height() / 2); + content::SimulateGesturePinchSequence(guest_contents, pinch_position, 1.23, + blink::kWebGestureDeviceTouchpad); + + ASSERT_TRUE(synthetic_wheel_listener.WaitUntilSatisfied()); +} diff --git a/chrome/browser/apps/platform_apps/app_browsertest.cc b/chrome/browser/apps/platform_apps/app_browsertest.cc index bc99655cbf0ef0..d2754f8532c8c2 100644 --- a/chrome/browser/apps/platform_apps/app_browsertest.cc +++ b/chrome/browser/apps/platform_apps/app_browsertest.cc @@ -1400,4 +1400,27 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, NewWindowAboutBlank) { ASSERT_TRUE(RunPlatformAppTest("platform_apps/new_window_about_blank")); } +// Test that an app window sees the synthetic wheel events of a touchpad pinch. +// While the app window itself does not scale in response to a pinch, we +// still offer the synthetic wheels for pages that want to implement custom +// pinch zoom behaviour. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, + TouchpadPinchSyntheticWheelEvents) { + LoadAndLaunchPlatformApp("touchpad_pinch", "Launched"); + + WebContents* web_contents = GetFirstAppWindowWebContents(); + ASSERT_TRUE(web_contents); + + ExtensionTestMessageListener synthetic_wheel_listener("Seen wheel event", + false); + + const gfx::Rect contents_rect = web_contents->GetContainerBounds(); + const gfx::Point pinch_position(contents_rect.width() / 2, + contents_rect.height() / 2); + content::SimulateGesturePinchSequence(web_contents, pinch_position, 1.23, + blink::kWebGestureDeviceTouchpad); + + ASSERT_TRUE(synthetic_wheel_listener.WaitUntilSatisfied()); +} + } // namespace extensions diff --git a/chrome/test/data/extensions/platform_apps/touchpad_pinch/background.js b/chrome/test/data/extensions/platform_apps/touchpad_pinch/background.js new file mode 100644 index 00000000000000..3c9f502211f3fb --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/touchpad_pinch/background.js @@ -0,0 +1,7 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('window.html'); +}); diff --git a/chrome/test/data/extensions/platform_apps/touchpad_pinch/manifest.json b/chrome/test/data/extensions/platform_apps/touchpad_pinch/manifest.json new file mode 100644 index 00000000000000..c47a5d46037384 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/touchpad_pinch/manifest.json @@ -0,0 +1,10 @@ +{ + "name": "Touchpad pinch synthetic wheel event", + "version": "1", + "manifest_version": 2, + "app": { + "background": { + "scripts": ["background.js"] + } + } +} diff --git a/chrome/test/data/extensions/platform_apps/touchpad_pinch/window.html b/chrome/test/data/extensions/platform_apps/touchpad_pinch/window.html new file mode 100644 index 00000000000000..8047bf9dd31b82 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/touchpad_pinch/window.html @@ -0,0 +1,18 @@ + + + + + + +

Hello.

+ + + diff --git a/chrome/test/data/extensions/platform_apps/touchpad_pinch/window.js b/chrome/test/data/extensions/platform_apps/touchpad_pinch/window.js new file mode 100644 index 00000000000000..903b4b31334bbe --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/touchpad_pinch/window.js @@ -0,0 +1,17 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +window.onload = () => { + document.body.addEventListener('wheel', (e) => { + chrome.test.sendMessage('Seen wheel event'); + }); + + // We need to wait for the compositor thread to be made aware of the wheel + // listener before sending the pinch event sequence. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { + chrome.test.sendMessage('Launched'); + }); + }); +}; diff --git a/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/embedder.html b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/embedder.html new file mode 100644 index 00000000000000..72a7e7af0bf27e --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/embedder.html @@ -0,0 +1,10 @@ + + + + + + diff --git a/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/embedder.js b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/embedder.js new file mode 100644 index 00000000000000..7fc9d1a6dd6c6b --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/embedder.js @@ -0,0 +1,20 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +window.onload = () => { + chrome.test.getConfig(function(config) { + var guestURL = 'http://localhost:' + config.testServer.port + + '/extensions/platform_apps/web_view/touchpad_pinch/guest.html'; + var webview = document.createElement('webview'); + webview.src = guestURL; + webview.addEventListener('loadstop', () => { + webview.contentWindow.postMessage({}, '*'); + }); + document.body.appendChild(webview); + }); +}; + +window.addEventListener('message', (e) => { + chrome.test.sendMessage(e.data); +}); diff --git a/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/guest.html b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/guest.html new file mode 100644 index 00000000000000..d2ae67649c6ea4 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/guest.html @@ -0,0 +1,18 @@ + + + + + + +

Hello.

+ + + diff --git a/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/guest.js b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/guest.js new file mode 100644 index 00000000000000..66fce92efe978e --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/guest.js @@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var parentWindow = null; + +window.onload = () => { + document.body.addEventListener('wheel', (e) => { + parentWindow.postMessage('Seen wheel event', '*'); + }); +}; + +window.addEventListener('message', (e) => { + parentWindow = e.source; + + // We need to wait for the compositor thread to be made aware of the wheel + // listener before sending the pinch event sequence. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { + parentWindow.postMessage('WebViewTest.LAUNCHED', '*'); + }); + }); +}); diff --git a/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/manifest.json b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/manifest.json new file mode 100644 index 00000000000000..b58b16fb2b36dc --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/manifest.json @@ -0,0 +1,13 @@ +{ + "name": " Touchpad pinch synthetic wheel event", + "version": "1", + "manifest_version": 2, + "permissions": [ + "webview" + ], + "app": { + "background": { + "scripts": ["test.js"] + } + } +} diff --git a/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/test.js b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/test.js new file mode 100644 index 00000000000000..1bb2b229dabfbc --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/touchpad_pinch/test.js @@ -0,0 +1,7 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('embedder.html'); +}); diff --git a/components/guest_view/browser/guest_view_base.cc b/components/guest_view/browser/guest_view_base.cc index 18cd29c19ed2f6..7951f7d66cd9b5 100644 --- a/components/guest_view/browser/guest_view_base.cc +++ b/components/guest_view/browser/guest_view_base.cc @@ -683,7 +683,11 @@ bool GuestViewBase::ShouldFocusPageAfterCrash() { bool GuestViewBase::PreHandleGestureEvent(WebContents* source, const blink::WebGestureEvent& event) { - return blink::WebInputEvent::IsPinchGestureEventType(event.GetType()); + // Pinch events which cause a scale change should not be routed to a guest. + // We still allow synthetic wheel events for touchpad pinch to go to the page. + DCHECK(!blink::WebInputEvent::IsPinchGestureEventType(event.GetType()) || + event.NeedsWheelEvent()); + return false; } void GuestViewBase::UpdatePreferredSize(WebContents* target_web_contents, diff --git a/extensions/browser/app_window/app_web_contents_helper.cc b/extensions/browser/app_window/app_web_contents_helper.cc index 21d676e9f7f798..158d1a2783ab9d 100644 --- a/extensions/browser/app_window/app_web_contents_helper.cc +++ b/extensions/browser/app_window/app_web_contents_helper.cc @@ -32,8 +32,18 @@ AppWebContentsHelper::AppWebContentsHelper( // static bool AppWebContentsHelper::ShouldSuppressGestureEvent( const blink::WebGestureEvent& event) { + // Disable "smart zoom" (double-tap with two fingers on Mac trackpad). + if (event.GetType() == blink::WebInputEvent::kGestureDoubleTap) + return true; + // Disable pinch zooming in app windows. - return blink::WebInputEvent::IsPinchGestureEventType(event.GetType()); + if (blink::WebInputEvent::IsPinchGestureEventType(event.GetType())) { + // Only suppress pinch events that cause a scale change. We still + // allow synthetic wheel events for touchpad pinch to go to the page. + return !event.NeedsWheelEvent(); + } + + return false; } content::WebContents* AppWebContentsHelper::OpenURLFromTab(