Fix routing of mouse wheel events while pointer is locked.
BUG=701965
Review-Url: https://codereview.chromium.org/2765903002
Cr-Commit-Position: refs/heads/master@{#459220}
diff --git a/content/browser/pointer_lock_browsertest.cc b/content/browser/pointer_lock_browsertest.cc
index cf1a792e..f1853c0 100644
--- a/content/browser/pointer_lock_browsertest.cc
+++ b/content/browser/pointer_lock_browsertest.cc
@@ -315,4 +315,115 @@
web_contents()->GetMouseLockWidget());
}
+IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWheelEventRouting) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+ FrameTreeNode* child = root->child_at(0);
+ RenderWidgetHostInputEventRouter* router =
+ web_contents()->GetInputEventRouter();
+ RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
+ root->current_frame_host()->GetView());
+ RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
+ child->current_frame_host()->GetView());
+
+ // Request a pointer lock on the root frame's body.
+ EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));
+
+ // Root frame should have been granted pointer lock.
+ bool locked = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(root,
+ "window.domAutomationController.send("
+ "document.pointerLockElement == "
+ "document.body);",
+ &locked));
+ EXPECT_TRUE(locked);
+
+ // Add a mouse move wheel event listener to the root frame.
+ EXPECT_TRUE(ExecuteScript(
+ root,
+ "var x; var y; var mX; var mY; document.addEventListener('mousewheel', "
+ "function(e) {x = e.x; y = e.y; dX = e.deltaX; dY = e.deltaY;});"));
+ MainThreadFrameObserver root_observer(root_view->GetRenderWidgetHost());
+ root_observer.Wait();
+
+ blink::WebMouseWheelEvent wheel_event(
+ blink::WebInputEvent::MouseWheel, blink::WebInputEvent::NoModifiers,
+ blink::WebInputEvent::TimeStampForTesting);
+ wheel_event.x = 10;
+ wheel_event.y = 11;
+ wheel_event.deltaX = -12;
+ wheel_event.deltaY = -13;
+ router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo());
+
+ // Make sure that the renderer handled the input event.
+ root_observer.Wait();
+
+ int x, y, deltaX, deltaY;
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ root, "window.domAutomationController.send(x);", &x));
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ root, "window.domAutomationController.send(y);", &y));
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ root, "window.domAutomationController.send(dX);", &deltaX));
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ root, "window.domAutomationController.send(dY);", &deltaY));
+ EXPECT_EQ(10, x);
+ EXPECT_EQ(11, y);
+ EXPECT_EQ(12, deltaX);
+ EXPECT_EQ(13, deltaY);
+
+ // Release pointer lock on root frame.
+ EXPECT_TRUE(ExecuteScript(root, "document.exitPointerLock()"));
+
+ // Request a pointer lock on the child frame's body.
+ EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));
+
+ // Child frame should have been granted pointer lock.
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
+ "window.domAutomationController.send("
+ "document.pointerLockElement == "
+ "document.body);",
+ &locked));
+ EXPECT_TRUE(locked);
+
+ // Add a mouse move event listener to the child frame.
+ EXPECT_TRUE(ExecuteScript(
+ child,
+ "var x; var y; var mX; var mY; document.addEventListener('mousewheel', "
+ "function(e) {x = e.x; y = e.y; dX = e.deltaX; dY = e.deltaY;});"));
+ MainThreadFrameObserver child_observer(child_view->GetRenderWidgetHost());
+ child_observer.Wait();
+
+ gfx::Point transformed_point;
+ root_view->TransformPointToCoordSpaceForView(gfx::Point(0, 0), child_view,
+ &transformed_point);
+
+ wheel_event.x = -transformed_point.x() + 14;
+ wheel_event.y = -transformed_point.y() + 15;
+ wheel_event.deltaX = -16;
+ wheel_event.deltaY = -17;
+ // We use root_view intentionally as the RenderWidgetHostInputEventRouter is
+ // responsible for correctly routing the event to the child frame.
+ router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo());
+
+ // Make sure that the renderer handled the input event.
+ child_observer.Wait();
+
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ child, "window.domAutomationController.send(x);", &x));
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ child, "window.domAutomationController.send(y);", &y));
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ child, "window.domAutomationController.send(dX);", &deltaX));
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ child, "window.domAutomationController.send(dY);", &deltaY));
+ EXPECT_EQ(14, x);
+ EXPECT_EQ(15, y);
+ EXPECT_EQ(16, deltaX);
+ EXPECT_EQ(17, deltaY);
+}
+
} // namespace content