Commit e90c3a03 authored by Kevin McNee's avatar Kevin McNee Committed by Commit Bot

Reland "Refactor OOPIF scroll bubbling state and cancellation"

This is a reland of b9e5ed2a

Original change's description:
> Refactor OOPIF scroll bubbling state and cancellation
>
> Whether or not a child is bubbling scroll was being tracked in both
> CrossProcessFrameConnector and RenderWidgetHostViewChildFrame. It's
> simpler to just have it in RWHVCF.
>
> There are several cases where we generate fake scroll updates when
> cancelling scroll bubbling. This is a relic from the non-scroll latching
> code paths and has been removed. We also deduplicate the scroll bubbling
> cancellation code.
>
> We were tracking the view from which scroll events are bubbled by keeping
> a reference to that view's parent. We now just keep a reference to the
> originating view directly.
>
> We also now properly cancel scroll bubbling when a child detaches.
>
> Bug: 828422, 897216
> Change-Id: Iee983bd9ea05b324d556c66320a1bc5e544de057
> Reviewed-on: https://chromium-review.googlesource.com/c/1357563
> Reviewed-by: Ken Buchanan <kenrb@chromium.org>
> Commit-Queue: Kevin McNee <mcnee@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#615184}

Tbr: kenrb@chromium.org
Bug: 828422, 897216
Change-Id: If529545300f6bbb7a7056cdbebbd8317cb274f7a
Reviewed-on: https://chromium-review.googlesource.com/c/1371010Reviewed-by: default avatarKevin McNee <mcnee@chromium.org>
Commit-Queue: Kevin McNee <mcnee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#615557}
parent 26cbade5
...@@ -68,8 +68,7 @@ RenderFrameHostImpl* RootRenderFrameHost(RenderFrameHostImpl* frame) { ...@@ -68,8 +68,7 @@ RenderFrameHostImpl* RootRenderFrameHost(RenderFrameHostImpl* frame) {
CrossProcessFrameConnector::CrossProcessFrameConnector( CrossProcessFrameConnector::CrossProcessFrameConnector(
RenderFrameProxyHost* frame_proxy_in_parent_renderer) RenderFrameProxyHost* frame_proxy_in_parent_renderer)
: FrameConnectorDelegate(IsUseZoomForDSFEnabled()), : FrameConnectorDelegate(IsUseZoomForDSFEnabled()),
frame_proxy_in_parent_renderer_(frame_proxy_in_parent_renderer), frame_proxy_in_parent_renderer_(frame_proxy_in_parent_renderer) {
is_scroll_bubbling_(false) {
frame_proxy_in_parent_renderer->frame_tree_node() frame_proxy_in_parent_renderer->frame_tree_node()
->render_manager() ->render_manager()
->current_frame_host() ->current_frame_host()
...@@ -119,14 +118,13 @@ void CrossProcessFrameConnector::SetView(RenderWidgetHostViewChildFrame* view) { ...@@ -119,14 +118,13 @@ void CrossProcessFrameConnector::SetView(RenderWidgetHostViewChildFrame* view) {
// The RenderWidgetHostDelegate needs to be checked because SetView() can // The RenderWidgetHostDelegate needs to be checked because SetView() can
// be called during nested WebContents destruction. See // be called during nested WebContents destruction. See
// https://crbug.com/644306. // https://crbug.com/644306.
if (is_scroll_bubbling_ && GetParentRenderWidgetHostView() && if (GetParentRenderWidgetHostView() &&
GetParentRenderWidgetHostView()->host()->delegate()) { GetParentRenderWidgetHostView()->host()->delegate()) {
GetParentRenderWidgetHostView() GetParentRenderWidgetHostView()
->host() ->host()
->delegate() ->delegate()
->GetInputEventRouter() ->GetInputEventRouter()
->CancelScrollBubbling(view_); ->WillDetachChildView(view_);
is_scroll_bubbling_ = false;
} }
view_->SetFrameConnectorDelegate(nullptr); view_->SetFrameConnectorDelegate(nullptr);
} }
...@@ -298,14 +296,7 @@ void CrossProcessFrameConnector::BubbleScrollEvent( ...@@ -298,14 +296,7 @@ void CrossProcessFrameConnector::BubbleScrollEvent(
// action of the parent frame to Auto so that this gesture event is allowed. // action of the parent frame to Auto so that this gesture event is allowed.
parent_view->host()->input_router()->ForceSetTouchActionAuto(); parent_view->host()->input_router()->ForceSetTouchActionAuto();
if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) { event_router->BubbleScrollEvent(parent_view, view_, resent_gesture_event);
event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
is_scroll_bubbling_ = true;
} else if (is_scroll_bubbling_) {
event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
}
if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd)
is_scroll_bubbling_ = false;
} }
bool CrossProcessFrameConnector::HasFocus() { bool CrossProcessFrameConnector::HasFocus() {
......
...@@ -202,8 +202,6 @@ class CONTENT_EXPORT CrossProcessFrameConnector ...@@ -202,8 +202,6 @@ class CONTENT_EXPORT CrossProcessFrameConnector
// which is set through CSS. // which is set through CSS.
bool is_hidden_ = false; bool is_hidden_ = false;
bool is_scroll_bubbling_;
// Used to make sure we only log UMA once per renderer crash. // Used to make sure we only log UMA once per renderer crash.
bool is_crash_already_logged_ = false; bool is_crash_already_logged_ = false;
......
...@@ -55,6 +55,7 @@ namespace content { ...@@ -55,6 +55,7 @@ namespace content {
class RenderWidgetHostImpl; class RenderWidgetHostImpl;
class RenderWidgetHostView; class RenderWidgetHostView;
class RenderWidgetHostViewBase; class RenderWidgetHostViewBase;
class RenderWidgetHostViewChildFrame;
class RenderWidgetTargeter; class RenderWidgetTargeter;
class TouchEmulator; class TouchEmulator;
class TouchEventAckQueue; class TouchEventAckQueue;
...@@ -100,9 +101,10 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter ...@@ -100,9 +101,10 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
// |event| is in root coordinates. // |event| is in root coordinates.
void BubbleScrollEvent(RenderWidgetHostViewBase* target_view, void BubbleScrollEvent(RenderWidgetHostViewBase* target_view,
const blink::WebGestureEvent& event, RenderWidgetHostViewChildFrame* resending_view,
const RenderWidgetHostViewBase* resending_view); const blink::WebGestureEvent& event);
void CancelScrollBubbling(RenderWidgetHostViewBase* target_view); void WillDetachChildView(
const RenderWidgetHostViewChildFrame* detaching_view);
void AddFrameSinkIdOwner(const viz::FrameSinkId& id, void AddFrameSinkIdOwner(const viz::FrameSinkId& id,
RenderWidgetHostViewBase* owner); RenderWidgetHostViewBase* owner);
...@@ -224,13 +226,24 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter ...@@ -224,13 +226,24 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
RenderWidgetHostViewBase* target, RenderWidgetHostViewBase* target,
RenderWidgetHostViewBase* root_view); RenderWidgetHostViewBase* root_view);
// The following methods take a GestureScrollUpdate event and send a void CancelScrollBubbling();
// GestureScrollBegin or GestureScrollEnd for wrapping it. This is needed
// when GestureScrollUpdates are being forwarded for scroll bubbling. // Cancels scroll bubbling if it is unsafe to send a gesture event sequence
// to |target| considering the views involved in an ongoing scroll.
void CancelScrollBubblingIfConflicting(
const RenderWidgetHostViewBase* target);
// Wraps a touchscreen GesturePinchBegin in a GestureScrollBegin.
void SendGestureScrollBegin(RenderWidgetHostViewBase* view, void SendGestureScrollBegin(RenderWidgetHostViewBase* view,
const blink::WebGestureEvent& event); const blink::WebGestureEvent& event);
// Used to end a scroll sequence during scroll bubbling or as part of a
// wrapped pinch gesture.
void SendGestureScrollEnd(RenderWidgetHostViewBase* view, void SendGestureScrollEnd(RenderWidgetHostViewBase* view,
const blink::WebGestureEvent& event); const blink::WebGestureEvent& event);
// Used when scroll bubbling is canceled to indicate to |view| that it should
// consider the scroll sequence to have ended.
void SendGestureScrollEnd(RenderWidgetHostViewBase* view,
blink::WebGestureDevice source_device);
// Helper functions to implement RenderWidgetTargeter::Delegate functions. // Helper functions to implement RenderWidgetTargeter::Delegate functions.
RenderWidgetTargetResult FindMouseEventTarget( RenderWidgetTargetResult FindMouseEventTarget(
...@@ -315,8 +328,8 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter ...@@ -315,8 +328,8 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
// https://crbug.com/824774. // https://crbug.com/824774.
bool touchscreen_gesture_target_in_map_; bool touchscreen_gesture_target_in_map_;
TargetData touchpad_gesture_target_; TargetData touchpad_gesture_target_;
TargetData bubbling_gesture_scroll_target_; RenderWidgetHostViewBase* bubbling_gesture_scroll_target_ = nullptr;
TargetData first_bubbling_scroll_target_; RenderWidgetHostViewChildFrame* bubbling_gesture_scroll_origin_ = nullptr;
// Used to target wheel events for the duration of a scroll. // Used to target wheel events for the duration of a scroll.
TargetData wheel_target_; TargetData wheel_target_;
// Maintains the same target between mouse down and mouse up. // Maintains the same target between mouse down and mouse up.
......
...@@ -539,28 +539,25 @@ void RenderWidgetHostViewChildFrame::GestureEventAck( ...@@ -539,28 +539,25 @@ void RenderWidgetHostViewChildFrame::GestureEventAck(
if (event.IsTouchpadZoomEvent()) if (event.IsTouchpadZoomEvent())
ProcessTouchpadZoomEventAckInRoot(event, ack_result); ProcessTouchpadZoomEventAckInRoot(event, ack_result);
const bool should_bubble = // GestureScrollBegin is a blocking event; It is forwarded for bubbling if
// its ack is not consumed. For the rest of the scroll events
// (GestureScrollUpdate, GestureScrollEnd) are bubbled if the
// GestureScrollBegin was bubbled.
if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
DCHECK(!is_scroll_sequence_bubbling_);
is_scroll_sequence_bubbling_ =
ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED || ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED ||
ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS || ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS ||
ack_result == INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE; ack_result == INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE;
if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin) &&
should_bubble) {
DCHECK(!is_scroll_sequence_bubbling_);
is_scroll_sequence_bubbling_ = true;
} else if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd) {
is_scroll_sequence_bubbling_ = false;
} }
// GestureScrollBegin is a blocking event; It is forwarded for bubbling if if (is_scroll_sequence_bubbling_ &&
// its ack is not consumed. For the rest of the scroll events (event.GetType() == blink::WebInputEvent::kGestureScrollBegin ||
// (GestureScrollUpdate, GestureScrollEnd) the frame_connector_ decides to
// forward them for bubbling if the GestureScrollBegin event is forwarded.
if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin &&
should_bubble) ||
event.GetType() == blink::WebInputEvent::kGestureScrollUpdate || event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
event.GetType() == blink::WebInputEvent::kGestureScrollEnd) { event.GetType() == blink::WebInputEvent::kGestureScrollEnd)) {
frame_connector_->BubbleScrollEvent(event); frame_connector_->BubbleScrollEvent(event);
if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd)
is_scroll_sequence_bubbling_ = false;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment