Commit a12ef847 authored by Sahel Sharify's avatar Sahel Sharify Committed by Commit Bot

Fling bubbles from OOPIF properly.

While we are bubbling a scroll sequence GFS is sent to the fling controllers
of both the oopif and the bubbling target. The fling controller of the oopif
calls progressFling and generates a GSU with inertial phase, the GSU gets acked
immediately before getting sent to the renderer since we are in bubbling mode.
Then the oopif's fling controller receives the unconsumed GSU ack and generates
a GSE to complete the scrolling sequence on the oopif. The bubbling target's
fling controller receives and processes the GFS and generates GSUs which are
sent to the target's renderer.

If the GSE generated by the oopif's fling controller gets bubbled before
the GFS, the bubbling target gets reset and the target does not receive the
GFS. This cl fixes the issue by making sure that the events generated by the
oopif's fling controller are not bubbled to the target. Also in case of
GFS bubbling, the GFC should also get sent to the bubbling target to make
sure that the fling controller in charge of flinging receives the GFC.


Bug: 884728, 249063
Test: BrowserSideFlingBrowserTest.[Touchpad|Touchscreen]FlingBubblesFromOOPIF
Change-Id: I064944f125bebcb746f329af4cfb117f3be94ff0
Reviewed-on: https://chromium-review.googlesource.com/c/1274193Reviewed-by: default avatarKevin McNee <mcnee@chromium.org>
Reviewed-by: default avatarCharlie Reis <creis@chromium.org>
Commit-Queue: Charlie Reis <creis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599001}
parent 2693fe10
......@@ -279,7 +279,8 @@ void CrossProcessFrameConnector::BubbleScrollEvent(
DCHECK(event.GetType() == blink::WebInputEvent::kGestureScrollBegin ||
event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
event.GetType() == blink::WebInputEvent::kGestureFlingStart);
event.GetType() == blink::WebInputEvent::kGestureFlingStart ||
event.GetType() == blink::WebInputEvent::kGestureFlingCancel);
auto* parent_view = GetParentRenderWidgetHostView();
if (!parent_view)
......@@ -302,7 +303,9 @@ void CrossProcessFrameConnector::BubbleScrollEvent(
if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
is_scroll_bubbling_ = true;
} else if (is_scroll_bubbling_) {
} else if (is_scroll_bubbling_ ||
event.GetType() == blink::WebInputEvent::kGestureFlingCancel) {
// For GFC events the router decides whether to bubble them or not.
event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
}
if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
......
......@@ -293,6 +293,9 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
if (view == last_fling_start_target_)
last_fling_start_target_ = nullptr;
if (view == last_fling_start_bubbled_target_)
last_fling_start_bubbled_target_ = nullptr;
event_targeter_->ViewWillBeDestroyed(view);
}
......@@ -1001,7 +1004,8 @@ void RenderWidgetHostInputEventRouter::BubbleScrollEvent(
DCHECK(event.GetType() == blink::WebInputEvent::kGestureScrollBegin ||
event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
event.GetType() == blink::WebInputEvent::kGestureFlingStart);
event.GetType() == blink::WebInputEvent::kGestureFlingStart ||
event.GetType() == blink::WebInputEvent::kGestureFlingCancel);
ui::LatencyInfo latency_info =
ui::WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(event);
......@@ -1030,7 +1034,20 @@ void RenderWidgetHostInputEventRouter::BubbleScrollEvent(
}
bubbling_gesture_scroll_target_.target = target_view;
} else if (event.GetType() == blink::WebInputEvent::kGestureFlingCancel) {
// GFC event must get bubbled to the same target view that the last GFS has
// been bubbled.
if (last_fling_start_bubbled_target_) {
last_fling_start_bubbled_target_->ProcessGestureEvent(
GestureEventInTarget(event, last_fling_start_bubbled_target_),
latency_info);
last_fling_start_bubbled_target_ = nullptr;
}
return;
} else { // !(event.GetType() == blink::WebInputEvent::kGestureScrollBegin)
// && !(event.GetType() ==
// blink::WebInputEvent::kGestureFlingCancel)
if (!bubbling_gesture_scroll_target_.target) {
// The GestureScrollBegin event is not bubbled, don't bubble the rest of
// the scroll events.
......@@ -1062,6 +1079,12 @@ void RenderWidgetHostInputEventRouter::BubbleScrollEvent(
bubbling_gesture_scroll_target_.target->ProcessGestureEvent(
GestureEventInTarget(event, bubbling_gesture_scroll_target_.target),
latency_info);
// The GFC should be sent to the view that handles the GFS.
if (event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
last_fling_start_bubbled_target_ = bubbling_gesture_scroll_target_.target;
}
if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
first_bubbling_scroll_target_.target = nullptr;
......
......@@ -308,6 +308,12 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
// Tracked for the purpose of targeting subsequent fling cancel events.
RenderWidgetHostViewBase* last_fling_start_target_ = nullptr;
// During scroll bubbling we bubble the GFS to the target view so that its
// fling controller takes care of flinging. In this case we should also send
// the GFC to the bubbling target so that the fling controller currently in
// charge of the fling progress could handle the fling cancellelation as well.
RenderWidgetHostViewBase* last_fling_start_bubbled_target_ = nullptr;
// Tracked for the purpose of providing a root_view when dispatching emulated
// touch/gesture events.
RenderWidgetHostViewBase* last_emulated_event_root_view_;
......
......@@ -527,6 +527,24 @@ void RenderWidgetHostViewChildFrame::GestureEventAck(
ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS ||
ack_result == INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE;
// The inertial events on Mac should still get bubbled since there is no GFS to
// bubble and the inertial events are received from the OS.
#if !defined(OS_MACOSX)
// When a GFS is bubbled, we still send it to the fling controller of the
// child view to finish the scroll sequence. However the GSU and GSE events
// that are generated by the child view's fling controller do not need to get
// bubbled since the GFS event itself is bubbled and the target's fling
// controller will take care of flinging.
if ((event.GetType() == blink::WebInputEvent::kGestureScrollEnd &&
event.data.scroll_end.inertial_phase ==
blink::WebGestureEvent::kMomentumPhase) ||
(event.GetType() == blink::WebInputEvent::kGestureScrollUpdate &&
event.data.scroll_update.inertial_phase ==
blink::WebGestureEvent::kMomentumPhase)) {
return;
}
#endif // defined(OS_MACOSX)
if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin) &&
should_bubble) {
DCHECK(!is_scroll_sequence_bubbling_);
......@@ -545,7 +563,8 @@ void RenderWidgetHostViewChildFrame::GestureEventAck(
should_bubble) ||
event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
event.GetType() == blink::WebInputEvent::kGestureFlingStart ||
event.GetType() == blink::WebInputEvent::kGestureFlingCancel) {
frame_connector_->BubbleScrollEvent(event);
}
}
......
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