Chromium Code Reviews| Index: content/browser/site_per_process_browsertest.cc |
| diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc |
| index ea4bb0da5c3fc3c61f87442773244420a49bf876..8a42ff77585a780d894c592ab5fc799419ef077e 100644 |
| --- a/content/browser/site_per_process_browsertest.cc |
| +++ b/content/browser/site_per_process_browsertest.cc |
| @@ -1298,6 +1298,126 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| EXPECT_FALSE(child_frame_monitor.EventWasReceived()); |
| } |
| +// Verify that mouse capture works on a RenderWidgetHostView level, so that |
| +// dragging scroll bars and selecting text continues even when the mouse |
| +// cursor crosses over inter-process frame boundaries. |
|
nasko
2016/09/14 16:36:47
nit: s/inter-process/cross-process/
kenrb
2016/09/14 20:33:32
Done.
|
| +#if defined(OS_ANDROID) |
| +// Browser process hit testing is not implemented on Android. |
| +// https://crbug.com/491334 |
| +#define MAYBE_CrossProcessMouseCapture DISABLED_CrossProcessMouseCapture |
| +#else |
| +#define MAYBE_CrossProcessMouseCapture CrossProcessMouseCapture |
| +#endif |
| +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| + MAYBE_CrossProcessMouseCapture) { |
| + GURL main_url(embedded_test_server()->GetURL( |
| + "/frame_tree/page_with_positioned_frame.html")); |
| + NavigateToURL(shell(), main_url); |
|
nasko
2016/09/14 16:36:48
EXPECT_TRUE
kenrb
2016/09/14 20:33:32
Done.
|
| + |
| + // It is safe to obtain the root frame tree node here, as it doesn't change. |
| + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
| + ASSERT_EQ(1U, root->child_count()); |
| + |
| + FrameTreeNode* child_node = root->child_at(0); |
| + GURL site_url(embedded_test_server()->GetURL("baz.com", "/title1.html")); |
| + EXPECT_EQ(site_url, child_node->current_url()); |
| + EXPECT_NE(shell()->web_contents()->GetSiteInstance(), |
| + child_node->current_frame_host()->GetSiteInstance()); |
| + |
| + // Create listeners for mouse events. |
| + RenderWidgetHostMouseEventMonitor main_frame_monitor( |
| + root->current_frame_host()->GetRenderWidgetHost()); |
| + RenderWidgetHostMouseEventMonitor child_frame_monitor( |
| + child_node->current_frame_host()->GetRenderWidgetHost()); |
| + |
| + RenderWidgetHostInputEventRouter* router = |
| + web_contents()->GetInputEventRouter(); |
| + |
| + RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>( |
| + root->current_frame_host()->GetRenderWidgetHost()->GetView()); |
| + RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>( |
| + child_node->current_frame_host()->GetRenderWidgetHost()->GetView()); |
| + |
| + SurfaceHitTestReadyNotifier notifier( |
| + static_cast<RenderWidgetHostViewChildFrame*>(rwhv_child)); |
| + notifier.WaitForSurfaceReady(); |
| + |
| + // Target MouseDown to child frame. |
| + blink::WebMouseEvent mouse_event; |
| + mouse_event.type = blink::WebInputEvent::MouseDown; |
| + mouse_event.button = blink::WebPointerProperties::Button::Left; |
| + mouse_event.x = 75; |
| + mouse_event.y = 75; |
| + mouse_event.clickCount = 1; |
| + main_frame_monitor.ResetEventReceived(); |
| + child_frame_monitor.ResetEventReceived(); |
| + router->RouteMouseEvent(root_view, &mouse_event); |
| + |
| + EXPECT_FALSE(main_frame_monitor.EventWasReceived()); |
| + EXPECT_TRUE(child_frame_monitor.EventWasReceived()); |
| + |
| + // Target MouseMove to main frame. This should still be routed to the |
| + // child frame because it is now capturing mouse input. |
| + mouse_event.type = blink::WebInputEvent::MouseMove; |
| + mouse_event.modifiers = blink::WebInputEvent::LeftButtonDown; |
| + mouse_event.x = 1; |
| + mouse_event.y = 1; |
| + main_frame_monitor.ResetEventReceived(); |
| + child_frame_monitor.ResetEventReceived(); |
| + router->RouteMouseEvent(root_view, &mouse_event); |
| + |
| + EXPECT_FALSE(main_frame_monitor.EventWasReceived()); |
| + EXPECT_TRUE(child_frame_monitor.EventWasReceived()); |
| + |
| + // A MouseUp to the child frame should cancel the mouse capture. |
| + mouse_event.type = blink::WebInputEvent::MouseUp; |
| + mouse_event.modifiers = 0; |
| + mouse_event.x = 75; |
| + mouse_event.y = 75; |
| + main_frame_monitor.ResetEventReceived(); |
| + child_frame_monitor.ResetEventReceived(); |
| + router->RouteMouseEvent(root_view, &mouse_event); |
| + |
| + EXPECT_FALSE(main_frame_monitor.EventWasReceived()); |
| + EXPECT_TRUE(child_frame_monitor.EventWasReceived()); |
| + |
| + // Subsequent MouseMove events targeted to the main frame should be routed |
| + // to that frame. |
| + mouse_event.type = blink::WebInputEvent::MouseMove; |
| + mouse_event.x = 1; |
| + mouse_event.y = 1; |
|
nasko
2016/09/14 16:36:48
nit: Should we actually move the mouse event to a
kenrb
2016/09/14 20:33:32
Done.
|
| + main_frame_monitor.ResetEventReceived(); |
| + child_frame_monitor.ResetEventReceived(); |
| + router->RouteMouseEvent(root_view, &mouse_event); |
| + |
| + EXPECT_TRUE(main_frame_monitor.EventWasReceived()); |
| + EXPECT_FALSE(child_frame_monitor.EventWasReceived()); |
| + |
| + // Target MouseDown to the main frame to cause it to capture input. |
| + mouse_event.type = blink::WebInputEvent::MouseDown; |
| + mouse_event.x = 1; |
| + mouse_event.y = 1; |
| + main_frame_monitor.ResetEventReceived(); |
| + child_frame_monitor.ResetEventReceived(); |
| + router->RouteMouseEvent(root_view, &mouse_event); |
| + |
| + EXPECT_TRUE(main_frame_monitor.EventWasReceived()); |
| + EXPECT_FALSE(child_frame_monitor.EventWasReceived()); |
| + |
| + // Sending a MouseMove to the child frame should still result in the main |
| + // frame receiving the event. |
| + mouse_event.type = blink::WebInputEvent::MouseMove; |
| + mouse_event.modifiers = blink::WebInputEvent::LeftButtonDown; |
| + mouse_event.x = 75; |
| + mouse_event.y = 75; |
| + main_frame_monitor.ResetEventReceived(); |
| + child_frame_monitor.ResetEventReceived(); |
| + router->RouteMouseEvent(root_view, &mouse_event); |
| + |
| + EXPECT_TRUE(main_frame_monitor.EventWasReceived()); |
| + EXPECT_FALSE(child_frame_monitor.EventWasReceived()); |
| +} |
| + |
| // Tests OOPIF rendering by checking that the RWH of the iframe generates |
| // OnSwapCompositorFrame message. |
| #if defined(OS_ANDROID) |