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) {
CrossProcessFrameConnector::CrossProcessFrameConnector(
RenderFrameProxyHost* frame_proxy_in_parent_renderer)
: FrameConnectorDelegate(IsUseZoomForDSFEnabled()),
frame_proxy_in_parent_renderer_(frame_proxy_in_parent_renderer),
is_scroll_bubbling_(false) {
frame_proxy_in_parent_renderer_(frame_proxy_in_parent_renderer) {
frame_proxy_in_parent_renderer->frame_tree_node()
->render_manager()
->current_frame_host()
......@@ -119,14 +118,13 @@ void CrossProcessFrameConnector::SetView(RenderWidgetHostViewChildFrame* view) {
// The RenderWidgetHostDelegate needs to be checked because SetView() can
// be called during nested WebContents destruction. See
// https://crbug.com/644306.
if (is_scroll_bubbling_ && GetParentRenderWidgetHostView() &&
if (GetParentRenderWidgetHostView() &&
GetParentRenderWidgetHostView()->host()->delegate()) {
GetParentRenderWidgetHostView()
->host()
->delegate()
->GetInputEventRouter()
->CancelScrollBubbling(view_);
is_scroll_bubbling_ = false;
->WillDetachChildView(view_);
}
view_->SetFrameConnectorDelegate(nullptr);
}
......@@ -298,14 +296,7 @@ void CrossProcessFrameConnector::BubbleScrollEvent(
// action of the parent frame to Auto so that this gesture event is allowed.
parent_view->host()->input_router()->ForceSetTouchActionAuto();
if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
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;
event_router->BubbleScrollEvent(parent_view, view_, resent_gesture_event);
}
bool CrossProcessFrameConnector::HasFocus() {
......
......@@ -202,8 +202,6 @@ class CONTENT_EXPORT CrossProcessFrameConnector
// which is set through CSS.
bool is_hidden_ = false;
bool is_scroll_bubbling_;
// Used to make sure we only log UMA once per renderer crash.
bool is_crash_already_logged_ = false;
......
......@@ -55,6 +55,7 @@ namespace content {
class RenderWidgetHostImpl;
class RenderWidgetHostView;
class RenderWidgetHostViewBase;
class RenderWidgetHostViewChildFrame;
class RenderWidgetTargeter;
class TouchEmulator;
class TouchEventAckQueue;
......@@ -100,9 +101,10 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
// |event| is in root coordinates.
void BubbleScrollEvent(RenderWidgetHostViewBase* target_view,
const blink::WebGestureEvent& event,
const RenderWidgetHostViewBase* resending_view);
void CancelScrollBubbling(RenderWidgetHostViewBase* target_view);
RenderWidgetHostViewChildFrame* resending_view,
const blink::WebGestureEvent& event);
void WillDetachChildView(
const RenderWidgetHostViewChildFrame* detaching_view);
void AddFrameSinkIdOwner(const viz::FrameSinkId& id,
RenderWidgetHostViewBase* owner);
......@@ -224,13 +226,24 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
RenderWidgetHostViewBase* target,
RenderWidgetHostViewBase* root_view);
// The following methods take a GestureScrollUpdate event and send a
// GestureScrollBegin or GestureScrollEnd for wrapping it. This is needed
// when GestureScrollUpdates are being forwarded for scroll bubbling.
void CancelScrollBubbling();
// 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,
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,
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.
RenderWidgetTargetResult FindMouseEventTarget(
......@@ -315,8 +328,8 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
// https://crbug.com/824774.
bool touchscreen_gesture_target_in_map_;
TargetData touchpad_gesture_target_;
TargetData bubbling_gesture_scroll_target_;
TargetData first_bubbling_scroll_target_;
RenderWidgetHostViewBase* bubbling_gesture_scroll_target_ = nullptr;
RenderWidgetHostViewChildFrame* bubbling_gesture_scroll_origin_ = nullptr;
// Used to target wheel events for the duration of a scroll.
TargetData wheel_target_;
// Maintains the same target between mouse down and mouse up.
......
......@@ -539,28 +539,25 @@ void RenderWidgetHostViewChildFrame::GestureEventAck(
if (event.IsTouchpadZoomEvent())
ProcessTouchpadZoomEventAckInRoot(event, ack_result);
const bool should_bubble =
ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED ||
ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS ||
ack_result == INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE;
if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin) &&
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_ = true;
} else if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd) {
is_scroll_sequence_bubbling_ = false;
is_scroll_sequence_bubbling_ =
ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED ||
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
// its ack is not consumed. For the rest of the scroll events
// (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::kGestureScrollEnd) {
if (is_scroll_sequence_bubbling_ &&
(event.GetType() == blink::WebInputEvent::kGestureScrollBegin ||
event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
event.GetType() == blink::WebInputEvent::kGestureScrollEnd)) {
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