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

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/1357563Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Commit-Queue: Kevin McNee <mcnee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#615184}
parent 0f1396ae
...@@ -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
ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED || // its ack is not consumed. For the rest of the scroll events
ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS || // (GestureScrollUpdate, GestureScrollEnd) are bubbled if the
ack_result == INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE; // GestureScrollBegin was bubbled.
if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin) &&
should_bubble) {
DCHECK(!is_scroll_sequence_bubbling_); DCHECK(!is_scroll_sequence_bubbling_);
is_scroll_sequence_bubbling_ = true; is_scroll_sequence_bubbling_ =
} else if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd) { ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED ||
is_scroll_sequence_bubbling_ = false; ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS ||
ack_result == INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE;
} }
// 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 event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
// forward them for bubbling if the GestureScrollBegin event is forwarded. event.GetType() == blink::WebInputEvent::kGestureScrollEnd)) {
if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin &&
should_bubble) ||
event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
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