diff options
Diffstat (limited to 'content')
21 files changed, 227 insertions, 13 deletions
diff --git a/content/browser/compositor/delegated_frame_host.cc b/content/browser/compositor/delegated_frame_host.cc index 4a32e70..53a943f 100644 --- a/content/browser/compositor/delegated_frame_host.cc +++ b/content/browser/compositor/delegated_frame_host.cc @@ -207,11 +207,12 @@ uint32_t DelegatedFrameHost::GetSurfaceIdNamespace() { } cc::SurfaceId DelegatedFrameHost::SurfaceIdAtPoint( + cc::SurfaceHittestDelegate* delegate, const gfx::Point& point, gfx::Point* transformed_point) { if (surface_id_.is_null()) return surface_id_; - cc::SurfaceHittest hittest(nullptr, GetSurfaceManager()); + cc::SurfaceHittest hittest(delegate, GetSurfaceManager()); gfx::Transform target_transform; cc::SurfaceId target_surface_id = hittest.GetTargetSurfaceAtPoint(surface_id_, point, &target_transform); diff --git a/content/browser/compositor/delegated_frame_host.h b/content/browser/compositor/delegated_frame_host.h index d1237af..51a89fb 100644 --- a/content/browser/compositor/delegated_frame_host.h +++ b/content/browser/compositor/delegated_frame_host.h @@ -159,7 +159,8 @@ class CONTENT_EXPORT DelegatedFrameHost uint32_t GetSurfaceIdNamespace(); // Returns a null SurfaceId if this DelegatedFrameHost has not yet created // a compositor Surface. - cc::SurfaceId SurfaceIdAtPoint(const gfx::Point& point, + cc::SurfaceId SurfaceIdAtPoint(cc::SurfaceHittestDelegate* delegate, + const gfx::Point& point, gfx::Point* transformed_point); // Given the SurfaceID of a Surface that is contained within this class' diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index e121325..891d4c7 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc @@ -45,6 +45,7 @@ #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_helper.h" #include "content/browser/renderer_host/render_widget_host_delegate.h" +#include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_owner_delegate.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/common/content_constants_internal.h" @@ -444,6 +445,7 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostImpl, msg) IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone) + IPC_MESSAGE_HANDLER(FrameHostMsg_HittestData, OnHittestData) IPC_MESSAGE_HANDLER(InputHostMsg_QueueSyntheticGesture, OnQueueSyntheticGesture) IPC_MESSAGE_HANDLER(InputHostMsg_ImeCancelComposition, @@ -1508,6 +1510,12 @@ void RenderWidgetHostImpl::OnRenderProcessGone(int status, int exit_code) { } } +void RenderWidgetHostImpl::OnHittestData( + const FrameHostMsg_HittestData_Params& params) { + if (delegate_) + delegate_->GetInputEventRouter()->OnHittestData(params); +} + void RenderWidgetHostImpl::OnClose() { ShutdownAndDestroyWidget(true); } diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index b944c20..2b3ceb7 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h @@ -46,6 +46,7 @@ #include "ui/events/latency_info.h" #include "ui/gfx/native_widget_types.h" +struct FrameHostMsg_HittestData_Params; struct ViewHostMsg_SelectionBounds_Params; struct ViewHostMsg_TextInputState_Params; struct ViewHostMsg_UpdateRect_Params; @@ -590,6 +591,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : public RenderWidgetHost, void OnSelectionBoundsChanged( const ViewHostMsg_SelectionBounds_Params& params); void OnForwardCompositorProto(const std::vector<uint8_t>& proto); + void OnHittestData(const FrameHostMsg_HittestData_Params& params); // Called (either immediately or asynchronously) after we're done with our // BackingStore and can send an ACK to the renderer so it can paint onto it diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc index eef72ac..67bbd4e 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc @@ -4,12 +4,29 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" +#include "cc/quads/surface_draw_quad.h" +#include "cc/surfaces/surface_id_allocator.h" #include "cc/surfaces/surface_manager.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" +#include "content/common/frame_messages.h" #include "third_party/WebKit/public/web/WebInputEvent.h" namespace content { +RenderWidgetHostInputEventRouter::HittestDelegate::HittestDelegate( + const std::unordered_map<cc::SurfaceId, HittestData, cc::SurfaceIdHash>& + hittest_data) + : hittest_data_(hittest_data) {} + +bool RenderWidgetHostInputEventRouter::HittestDelegate::RejectHitTarget( + const cc::SurfaceDrawQuad* surface_quad, + const gfx::Point& point_in_quad_space) { + auto it = hittest_data_.find(surface_quad->surface_id); + if (it != hittest_data_.end() && it->second.ignored_for_hittest) + return true; + return false; +} + RenderWidgetHostInputEventRouter::RenderWidgetHostInputEventRouter() : active_touches_(0) {} @@ -28,12 +45,16 @@ RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget( return root_view; } + // The hittest delegate is used to reject hittesting quads based on extra + // hittesting data send by the renderer. + HittestDelegate delegate(hittest_data_); + // The conversion of point to transform_point is done over the course of the // hit testing, and reflect transformations that would normally be applied in // the renderer process if the event was being routed between frames within a // single process with only one RenderWidgetHost. uint32_t surface_id_namespace = - root_view->SurfaceIdNamespaceAtPoint(point, transformed_point); + root_view->SurfaceIdNamespaceAtPoint(&delegate, point, transformed_point); const SurfaceIdNamespaceOwnerMap::iterator iter = owner_map_.find(surface_id_namespace); // If the point hit a Surface whose namspace is no longer in the map, then @@ -134,6 +155,24 @@ void RenderWidgetHostInputEventRouter::AddSurfaceIdNamespaceOwner( void RenderWidgetHostInputEventRouter::RemoveSurfaceIdNamespaceOwner( uint32_t id) { owner_map_.erase(id); + + for (auto it = hittest_data_.begin(); it != hittest_data_.end();) { + if (cc::SurfaceIdAllocator::NamespaceForId(it->first) == id) + it = hittest_data_.erase(it); + else + ++it; + } +} + +void RenderWidgetHostInputEventRouter::OnHittestData( + const FrameHostMsg_HittestData_Params& params) { + if (owner_map_.find(cc::SurfaceIdAllocator::NamespaceForId( + params.surface_id)) == owner_map_.end()) { + return; + } + HittestData data; + data.ignored_for_hittest = params.ignored_for_hittest; + hittest_data_[params.surface_id] = data; } } // namespace content diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h index 03902f5..ec45f15 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.h +++ b/content/browser/renderer_host/render_widget_host_input_event_router.h @@ -6,12 +6,17 @@ #define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_INPUT_EVENT_ROUTER_H_ #include <stdint.h> +#include <unordered_map> #include "base/containers/hash_tables.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "cc/surfaces/surface_hittest_delegate.h" +#include "cc/surfaces/surface_id.h" #include "content/common/content_export.h" +struct FrameHostMsg_HittestData_Params; + namespace blink { class WebMouseEvent; class WebMouseWheelEvent; @@ -56,7 +61,25 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter { return owner_map_.find(id) != owner_map_.end(); } + void OnHittestData(const FrameHostMsg_HittestData_Params& params); + private: + struct HittestData { + bool ignored_for_hittest; + }; + + class HittestDelegate : public cc::SurfaceHittestDelegate { + public: + HittestDelegate( + const std::unordered_map<cc::SurfaceId, HittestData, cc::SurfaceIdHash>& + hittest_data); + bool RejectHitTarget(const cc::SurfaceDrawQuad* surface_quad, + const gfx::Point& point_in_quad_space) override; + + const std::unordered_map<cc::SurfaceId, HittestData, cc::SurfaceIdHash>& + hittest_data_; + }; + using WeakTarget = base::WeakPtr<RenderWidgetHostViewBase>; using SurfaceIdNamespaceOwnerMap = base::hash_map<uint32_t, base::WeakPtr<RenderWidgetHostViewBase>>; @@ -68,6 +91,8 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter { SurfaceIdNamespaceOwnerMap owner_map_; WeakTarget current_touch_target_; int active_touches_; + std::unordered_map<cc::SurfaceId, HittestData, cc::SurfaceIdHash> + hittest_data_; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostInputEventRouter); }; diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 02e38ec..df5db76 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -2208,6 +2208,7 @@ void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) { } uint32_t RenderWidgetHostViewAura::SurfaceIdNamespaceAtPoint( + cc::SurfaceHittestDelegate* delegate, const gfx::Point& point, gfx::Point* transformed_point) { DCHECK(device_scale_factor_ != 0.0f); @@ -2216,8 +2217,8 @@ uint32_t RenderWidgetHostViewAura::SurfaceIdNamespaceAtPoint( // |point| from DIPs to pixels before hittesting. gfx::Point point_in_pixels = gfx::ConvertPointToPixel(device_scale_factor_, point); - cc::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint(point_in_pixels, - transformed_point); + cc::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint( + delegate, point_in_pixels, transformed_point); *transformed_point = gfx::ConvertPointToDIP(device_scale_factor_, *transformed_point); diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 4775a6f..b3a7d24 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -195,7 +195,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura void LockCompositingSurface() override; void UnlockCompositingSurface() override; uint32_t GetSurfaceIdNamespace() override; - uint32_t SurfaceIdNamespaceAtPoint(const gfx::Point& point, + uint32_t SurfaceIdNamespaceAtPoint(cc::SurfaceHittestDelegate* delegate, + const gfx::Point& point, gfx::Point* transformed_point) override; void ProcessMouseEvent(const blink::WebMouseEvent& event) override; void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event) override; diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 6adada7..780ced5 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc @@ -676,6 +676,7 @@ uint32_t RenderWidgetHostViewBase::GetSurfaceIdNamespace() { } uint32_t RenderWidgetHostViewBase::SurfaceIdNamespaceAtPoint( + cc::SurfaceHittestDelegate* delegate, const gfx::Point& point, gfx::Point* transformed_point) { NOTREACHED(); diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index fa223b8..8c6102e 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h @@ -51,6 +51,10 @@ class WebMouseEvent; class WebMouseWheelEvent; } +namespace cc { +class SurfaceHittestDelegate; +} + namespace ui { class LatencyInfo; } @@ -202,8 +206,10 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView, // methods are invoked on the RenderWidgetHostView that should be able to // properly handle the event (i.e. it has focus for keyboard events, or has // been identified by hit testing mouse, touch or gesture events). - virtual uint32_t SurfaceIdNamespaceAtPoint(const gfx::Point& point, - gfx::Point* transformed_point); + virtual uint32_t SurfaceIdNamespaceAtPoint( + cc::SurfaceHittestDelegate* delegate, + const gfx::Point& point, + gfx::Point* transformed_point); virtual void ProcessKeyboardEvent(const NativeWebKeyboardEvent& event) {} virtual void ProcessMouseEvent(const blink::WebMouseEvent& event) {} virtual void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event) {} diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index 459f16a..f4cd27b 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h @@ -349,7 +349,8 @@ class CONTENT_EXPORT RenderWidgetHostViewMac scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget() override; uint32_t GetSurfaceIdNamespace() override; - uint32_t SurfaceIdNamespaceAtPoint(const gfx::Point& point, + uint32_t SurfaceIdNamespaceAtPoint(cc::SurfaceHittestDelegate* delegate, + const gfx::Point& point, gfx::Point* transformed_point) override; // Returns true when we can do SurfaceHitTesting for the event type. bool ShouldRouteEvent(const blink::WebInputEvent& event) const; diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 87b86b0..9987017 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -1570,6 +1570,7 @@ uint32_t RenderWidgetHostViewMac::GetSurfaceIdNamespace() { } uint32_t RenderWidgetHostViewMac::SurfaceIdNamespaceAtPoint( + cc::SurfaceHittestDelegate* delegate, const gfx::Point& point, gfx::Point* transformed_point) { // The surface hittest happens in device pixels, so we need to convert the @@ -1578,8 +1579,8 @@ uint32_t RenderWidgetHostViewMac::SurfaceIdNamespaceAtPoint( ->GetDisplayNearestWindow(cocoa_view_) .device_scale_factor(); gfx::Point point_in_pixels = gfx::ConvertPointToPixel(scale_factor, point); - cc::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint(point_in_pixels, - transformed_point); + cc::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint( + delegate, point_in_pixels, transformed_point); *transformed_point = gfx::ConvertPointToDIP(scale_factor, *transformed_point); // It is possible that the renderer has not yet produced a surface, in which diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 67318be..f7a373b 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc @@ -772,6 +772,78 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessHighDPIBrowserTest, SurfaceHitTestTestHelper(shell(), embedded_test_server()); } +// This test tests that browser process hittesting ignores frames with +// pointer-events: none. +#if defined(OS_ANDROID) +// Browser process hit testing is not implemented on Android. +// https://crbug.com/491334 +#define MAYBE_SurfaceHitTestPointerEventsNone \ + DISABLED_SurfaceHitTestPointerEventsNone +#else +#define MAYBE_SurfaceHitTestPointerEventsNone SurfaceHitTestPointerEventsNone +#endif +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + MAYBE_SurfaceHitTestPointerEventsNone) { + GURL main_url(embedded_test_server()->GetURL( + "/frame_tree/page_with_positioned_frame_pointer-events_none.html")); + NavigateToURL(shell(), main_url); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->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 = + static_cast<WebContentsImpl*>(shell()->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()); + + // We need to wait for a compositor frame from the child frame, at which + // point its surface will be created. + while (rwhv_child->RendererFrameNumber() <= 0) { + // TODO(lazyboy): Find a better way to avoid sleeping like this. See + // http://crbug.com/405282 for details. + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), + base::TimeDelta::FromMilliseconds(10)); + run_loop.Run(); + } + + // Target input event to child frame. + blink::WebMouseEvent child_event; + child_event.type = blink::WebInputEvent::MouseDown; + child_event.button = blink::WebPointerProperties::ButtonLeft; + child_event.x = 75; + child_event.y = 75; + child_event.clickCount = 1; + main_frame_monitor.ResetEventReceived(); + child_frame_monitor.ResetEventReceived(); + router->RouteMouseEvent(root_view, &child_event); + + EXPECT_TRUE(main_frame_monitor.EventWasReceived()); + EXPECT_EQ(75, main_frame_monitor.event().x); + EXPECT_EQ(75, main_frame_monitor.event().y); + EXPECT_FALSE(child_frame_monitor.EventWasReceived()); +} + // Tests OOPIF rendering by checking that the RWH of the iframe generates // OnSwapCompositorFrame message. #if defined(OS_ANDROID) @@ -4408,7 +4480,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_CreateContextMenuTest) { // updated compositor surfaces from both renderer processes. gfx::Point point(75, 75); gfx::Point transformed_point; - while (root_view->SurfaceIdNamespaceAtPoint(point, &transformed_point) != + while (root_view->SurfaceIdNamespaceAtPoint(nullptr, point, + &transformed_point) != rwhv_child->GetSurfaceIdNamespace()) { base::RunLoop run_loop; base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 510b0fe..6e9f362 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h @@ -504,6 +504,17 @@ IPC_STRUCT_BEGIN(FrameMsg_SerializeAsMHTML_Params) IPC_STRUCT_MEMBER(bool, is_last_frame) IPC_STRUCT_END() +// This message is used to send hittesting data from the renderer in order +// to perform hittesting on the browser process. +IPC_STRUCT_BEGIN(FrameHostMsg_HittestData_Params) + // |surface_id| represents the surface used by this remote frame. + IPC_STRUCT_MEMBER(cc::SurfaceId, surface_id) + + // If |ignored_for_hittest| then this surface should be ignored during + // hittesting. + IPC_STRUCT_MEMBER(bool, ignored_for_hittest) +IPC_STRUCT_END() + #if defined(OS_MACOSX) || defined(OS_ANDROID) // This message is used for supporting popup menus on Mac OS X and Android using // native controls. See the FrameHostMsg_ShowPopup message. @@ -1410,6 +1421,9 @@ IPC_MESSAGE_ROUTED5(FrameHostMsg_Find_Reply, int /* active_match_ordinal */, bool /* final_update */) +// Sends hittesting data needed to perform hittesting on the browser process. +IPC_MESSAGE_ROUTED1(FrameHostMsg_HittestData, FrameHostMsg_HittestData_Params) + #if defined(OS_MACOSX) || defined(OS_ANDROID) // Message to show/hide a popup menu using native controls. diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index a8c9147..b08f9dd 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn @@ -33,6 +33,7 @@ source_set("renderer") { "//cc/blink", "//cc/proto", "//cc/surfaces", + "//cc/surfaces:surface_id", "//components/scheduler:scheduler", "//components/startup_metric_utils/common", "//components/url_formatter", diff --git a/content/renderer/child_frame_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index ef85384..0166a08 100644 --- a/content/renderer/child_frame_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc @@ -293,6 +293,7 @@ void ChildFrameCompositingHelper::OnSetSurface( const gfx::Size& frame_size, float scale_factor, const cc::SurfaceSequence& sequence) { + surface_id_ = surface_id; scoped_refptr<ThreadSafeSender> sender( RenderThreadImpl::current()->thread_safe_sender()); cc::SurfaceLayer::SatisfyCallback satisfy_callback = diff --git a/content/renderer/child_frame_compositing_helper.h b/content/renderer/child_frame_compositing_helper.h index d2d4e78..707955c 100644 --- a/content/renderer/child_frame_compositing_helper.h +++ b/content/renderer/child_frame_compositing_helper.h @@ -15,6 +15,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/shared_memory.h" #include "cc/layers/delegated_frame_resource_collection.h" +#include "cc/surfaces/surface_id.h" #include "content/common/content_export.h" #include "ui/gfx/geometry/size.h" @@ -23,7 +24,6 @@ class SharedMemory; } namespace cc { -struct SurfaceId; struct SurfaceSequence; class CompositorFrame; @@ -79,6 +79,8 @@ class CONTENT_EXPORT ChildFrameCompositingHelper void UpdateVisibility(bool); void ChildFrameGone(); + cc::SurfaceId surface_id() const { return surface_id_; } + // cc::DelegatedFrameProviderClient implementation. void UnusedResourcesAreAvailable() override; @@ -146,6 +148,7 @@ class CONTENT_EXPORT ChildFrameCompositingHelper scoped_refptr<cc::DelegatedFrameProvider> frame_provider_; scoped_ptr<blink::WebLayer> web_layer_; + cc::SurfaceId surface_id_; blink::WebFrame* frame_; DISALLOW_COPY_AND_ASSIGN(ChildFrameCompositingHelper); diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index d8effb5..7a52f2c 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc @@ -195,6 +195,17 @@ bool RenderFrameProxy::IsMainFrameDetachedFromTree() const { render_view_->webview()->mainFrame()->isWebLocalFrame(); } +void RenderFrameProxy::WillBeginCompositorFrame() { + if (compositing_helper_) { + FrameHostMsg_HittestData_Params params; + params.surface_id = compositing_helper_->surface_id(); + params.ignored_for_hittest = web_frame_->isIgnoredForHitTest(); + render_widget_->QueueMessage( + new FrameHostMsg_HittestData(render_widget_->routing_id(), params), + MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE); + } +} + void RenderFrameProxy::DidCommitCompositorFrame() { if (compositing_helper_.get()) compositing_helper_->DidCommitCompositorFrame(); diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 7581d38..f6dc700 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h @@ -104,6 +104,10 @@ class CONTENT_EXPORT RenderFrameProxy bool Send(IPC::Message* msg) override; // Out-of-process child frames receive a signal from RenderWidgetCompositor + // when a compositor frame will begin. + void WillBeginCompositorFrame(); + + // Out-of-process child frames receive a signal from RenderWidgetCompositor // when a compositor frame has committed. void DidCommitCompositorFrame(); diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index ddd60cb..345528f 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -1223,6 +1223,9 @@ void RenderWidget::WillBeginCompositorFrame() { // is done. UpdateTextInputState(ShowIme::HIDE_IME, ChangeSource::FROM_NON_IME); UpdateSelectionBounds(); + + FOR_EACH_OBSERVER(RenderFrameProxy, render_frame_proxies_, + WillBeginCompositorFrame()); } /////////////////////////////////////////////////////////////////////////////// diff --git a/content/test/data/frame_tree/page_with_positioned_frame_pointer-events_none.html b/content/test/data/frame_tree/page_with_positioned_frame_pointer-events_none.html new file mode 100644 index 0000000..2e42948 --- /dev/null +++ b/content/test/data/frame_tree/page_with_positioned_frame_pointer-events_none.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> +iframe { + position:absolute; + top: 50px; + left: 50px; + width: 100px; + height: 100px; + pointer-events: none; +} +</style> +<html> +<body> +<iframe src="/cross-site/baz.com/title1.html"></iframe> +This page contains a positioned cross-origin iframe. +</body> +</html> |