Commit b9f219b4 authored by chaopeng's avatar chaopeng Committed by Commit Bot

Recompute PositionInWidget for each wheel or touchpad gesture event

This issue is because we use a fixed transform to compute PositionInWidget
for each wheel or touchpad gesture event. If the OOPIF scrolled, use of the
fixed transform would give wrong coordinates.

In this patch, we recompute all scroll event's PositionInWidget in scroll
sequence.

This patch only changes wheel and touchpad gesture event. Touch and gesture
events be fixed in a fix in following patch.

Bug: 923560
Change-Id: I557d65e756f0933f2efbc26802179b3531c03826
Reviewed-on: https://chromium-review.googlesource.com/c/1427607Reviewed-by: default avatarKevin McNee <mcnee@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Commit-Queue: Jianpeng Chao <chaopeng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#628228}
parent f47f58d5
...@@ -264,8 +264,8 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed( ...@@ -264,8 +264,8 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
} }
touch_event_ack_queue_->UpdateQueueAfterTargetDestroyed(view); touch_event_ack_queue_->UpdateQueueAfterTargetDestroyed(view);
if (view == wheel_target_.target) if (view == wheel_target_)
wheel_target_.target = nullptr; wheel_target_ = nullptr;
// If the target that's being destroyed is in the gesture target map, we // If the target that's being destroyed is in the gesture target map, we
// replace it with nullptr so that we maintain the 1:1 correspondence between // replace it with nullptr so that we maintain the 1:1 correspondence between
...@@ -281,8 +281,8 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed( ...@@ -281,8 +281,8 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
if (view == touchscreen_gesture_target_.target) if (view == touchscreen_gesture_target_.target)
touchscreen_gesture_target_.target = nullptr; touchscreen_gesture_target_.target = nullptr;
if (view == touchpad_gesture_target_.target) if (view == touchpad_gesture_target_)
touchpad_gesture_target_.target = nullptr; touchpad_gesture_target_ = nullptr;
if (view == bubbling_gesture_scroll_target_) { if (view == bubbling_gesture_scroll_target_) {
bubbling_gesture_scroll_target_ = nullptr; bubbling_gesture_scroll_target_ = nullptr;
...@@ -586,20 +586,13 @@ void RenderWidgetHostInputEventRouter::DispatchMouseWheelEvent( ...@@ -586,20 +586,13 @@ void RenderWidgetHostInputEventRouter::DispatchMouseWheelEvent(
const blink::WebMouseWheelEvent& mouse_wheel_event, const blink::WebMouseWheelEvent& mouse_wheel_event,
const ui::LatencyInfo& latency, const ui::LatencyInfo& latency,
const base::Optional<gfx::PointF>& target_location) { const base::Optional<gfx::PointF>& target_location) {
base::Optional<gfx::PointF> point_in_target = target_location;
if (!root_view->IsMouseLocked()) { if (!root_view->IsMouseLocked()) {
if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseBegan) { if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseBegan) {
wheel_target_.target = target; wheel_target_ = target;
if (target_location.has_value()) {
wheel_target_.delta =
target_location.value() - mouse_wheel_event.PositionInWidget();
}
} else { } else {
if (wheel_target_.target) { if (wheel_target_) {
DCHECK(!target && !target_location.has_value()); DCHECK(!target);
target = wheel_target_.target; target = wheel_target_;
point_in_target.emplace(mouse_wheel_event.PositionInWidget() +
wheel_target_.delta);
} else if ((mouse_wheel_event.phase == } else if ((mouse_wheel_event.phase ==
blink::WebMouseWheelEvent::kPhaseEnded || blink::WebMouseWheelEvent::kPhaseEnded ||
mouse_wheel_event.momentum_phase == mouse_wheel_event.momentum_phase ==
...@@ -618,21 +611,22 @@ void RenderWidgetHostInputEventRouter::DispatchMouseWheelEvent( ...@@ -618,21 +611,22 @@ void RenderWidgetHostInputEventRouter::DispatchMouseWheelEvent(
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
return; return;
} }
// If target_location doesn't have a value, it can be for two reasons:
// 1. |target| is null, in which case we would have early returned from the
// check above.
// 2. The event we are receiving is not a phaseBegan, in which case we should
// have got a valid |point_in_target| from wheel_target_.delta above.
DCHECK(point_in_target.has_value());
blink::WebMouseWheelEvent event = mouse_wheel_event; blink::WebMouseWheelEvent event = mouse_wheel_event;
event.SetPositionInWidget(point_in_target->x(), point_in_target->y()); gfx::PointF point_in_target;
if (target_location) {
point_in_target = target_location.value();
} else {
point_in_target = target->TransformRootPointToViewCoordSpace(
mouse_wheel_event.PositionInWidget());
}
event.SetPositionInWidget(point_in_target.x(), point_in_target.y());
target->ProcessMouseWheelEvent(event, latency); target->ProcessMouseWheelEvent(event, latency);
if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseEnded || if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseEnded ||
mouse_wheel_event.momentum_phase == mouse_wheel_event.momentum_phase ==
blink::WebMouseWheelEvent::kPhaseEnded) { blink::WebMouseWheelEvent::kPhaseEnded) {
wheel_target_.target = nullptr; wheel_target_ = nullptr;
} }
} }
...@@ -1023,7 +1017,7 @@ void RenderWidgetHostInputEventRouter::BubbleScrollEvent( ...@@ -1023,7 +1017,7 @@ void RenderWidgetHostInputEventRouter::BubbleScrollEvent(
// should inform the child view, so that it does not go on to send us // should inform the child view, so that it does not go on to send us
// the updates. See https://crbug.com/828422 // the updates. See https://crbug.com/828422
if (target_view == touchscreen_gesture_target_.target || if (target_view == touchscreen_gesture_target_.target ||
target_view == touchpad_gesture_target_.target || target_view == touchpad_gesture_target_ ||
target_view == touch_target_.target) { target_view == touch_target_.target) {
return; return;
} }
...@@ -1524,12 +1518,14 @@ void RenderWidgetHostInputEventRouter::DispatchTouchpadGestureEvent( ...@@ -1524,12 +1518,14 @@ void RenderWidgetHostInputEventRouter::DispatchTouchpadGestureEvent(
// of routing. // of routing.
if (touchpad_gesture_event.GetType() == if (touchpad_gesture_event.GetType() ==
blink::WebInputEvent::kGestureFlingStart) { blink::WebInputEvent::kGestureFlingStart) {
if (wheel_target_.target) { if (wheel_target_) {
blink::WebGestureEvent gesture_fling = touchpad_gesture_event; blink::WebGestureEvent gesture_fling = touchpad_gesture_event;
gesture_fling.SetPositionInWidget(gesture_fling.PositionInWidget() + gfx::PointF point_in_target =
wheel_target_.delta); wheel_target_->TransformRootPointToViewCoordSpace(
wheel_target_.target->ProcessGestureEvent(gesture_fling, latency); gesture_fling.PositionInWidget());
last_fling_start_target_ = wheel_target_.target; gesture_fling.SetPositionInWidget(point_in_target);
wheel_target_->ProcessGestureEvent(gesture_fling, latency);
last_fling_start_target_ = wheel_target_;
} else { } else {
root_view->GestureEventAck(touchpad_gesture_event, root_view->GestureEventAck(touchpad_gesture_event,
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
...@@ -1552,37 +1548,35 @@ void RenderWidgetHostInputEventRouter::DispatchTouchpadGestureEvent( ...@@ -1552,37 +1548,35 @@ void RenderWidgetHostInputEventRouter::DispatchTouchpadGestureEvent(
} }
if (target) { if (target) {
touchpad_gesture_target_.target = target; touchpad_gesture_target_ = target;
// TODO(mohsen): Instead of just computing a delta, we should extract the
// complete transform. We assume it doesn't change for the duration of the
// touchpad gesture sequence, though this could be wrong; a better approach
// might be to always transform each point to the
// |touchpad_gesture_target_.target| for the duration of the sequence.
DCHECK(target_location.has_value());
touchpad_gesture_target_.delta =
target_location.value() - touchpad_gesture_event.PositionInWidget();
// Abort any scroll bubbling in progress to avoid double entry. // Abort any scroll bubbling in progress to avoid double entry.
CancelScrollBubblingIfConflicting(touchpad_gesture_target_.target); CancelScrollBubblingIfConflicting(touchpad_gesture_target_);
} }
if (!touchpad_gesture_target_.target) { if (!touchpad_gesture_target_) {
root_view->GestureEventAck(touchpad_gesture_event, root_view->GestureEventAck(touchpad_gesture_event,
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
return; return;
} }
blink::WebGestureEvent gesture_event = touchpad_gesture_event; blink::WebGestureEvent gesture_event = touchpad_gesture_event;
// TODO(mohsen): Add tests to check event location. gfx::PointF point_in_target;
gesture_event.SetPositionInWidget(gesture_event.PositionInWidget() + if (target_location) {
touchpad_gesture_target_.delta); point_in_target = target_location.value();
touchpad_gesture_target_.target->ProcessGestureEvent(gesture_event, latency); } else {
point_in_target =
touchpad_gesture_target_->TransformRootPointToViewCoordSpace(
gesture_event.PositionInWidget());
}
gesture_event.SetPositionInWidget(point_in_target);
touchpad_gesture_target_->ProcessGestureEvent(gesture_event, latency);
if (touchpad_gesture_event.GetType() == if (touchpad_gesture_event.GetType() ==
blink::WebInputEvent::kGesturePinchEnd || blink::WebInputEvent::kGesturePinchEnd ||
touchpad_gesture_event.GetType() == touchpad_gesture_event.GetType() ==
blink::WebInputEvent::kGestureDoubleTap) { blink::WebInputEvent::kGestureDoubleTap) {
touchpad_gesture_target_.target = nullptr; touchpad_gesture_target_ = nullptr;
} }
} }
......
...@@ -189,7 +189,6 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter ...@@ -189,7 +189,6 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
viz::FrameSinkIdHash>; viz::FrameSinkIdHash>;
struct TargetData { struct TargetData {
RenderWidgetHostViewBase* target; RenderWidgetHostViewBase* target;
gfx::Vector2dF delta;
gfx::Transform transform; gfx::Transform transform;
TargetData() : target(nullptr) {} TargetData() : target(nullptr) {}
...@@ -331,11 +330,11 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter ...@@ -331,11 +330,11 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
// The following variable is temporary, for diagnosis of // The following variable is temporary, for diagnosis of
// https://crbug.com/824774. // https://crbug.com/824774.
bool touchscreen_gesture_target_in_map_; bool touchscreen_gesture_target_in_map_;
TargetData touchpad_gesture_target_; RenderWidgetHostViewBase* touchpad_gesture_target_ = nullptr;
RenderWidgetHostViewBase* bubbling_gesture_scroll_target_ = nullptr; RenderWidgetHostViewBase* bubbling_gesture_scroll_target_ = nullptr;
RenderWidgetHostViewChildFrame* bubbling_gesture_scroll_origin_ = nullptr; 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_; RenderWidgetHostViewBase* wheel_target_ = nullptr;
// Maintains the same target between mouse down and mouse up. // Maintains the same target between mouse down and mouse up.
TargetData mouse_capture_target_; TargetData mouse_capture_target_;
......
...@@ -313,20 +313,19 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessMacBrowserTest, ...@@ -313,20 +313,19 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessMacBrowserTest,
contents->GetRenderWidgetHostView()); contents->GetRenderWidgetHostView());
RenderWidgetHostInputEventRouter* router = contents->GetInputEventRouter(); RenderWidgetHostInputEventRouter* router = contents->GetInputEventRouter();
EXPECT_EQ(nullptr, router->touchpad_gesture_target_.target); EXPECT_EQ(nullptr, router->touchpad_gesture_target_);
gfx::Point main_frame_point(25, 575); gfx::Point main_frame_point(25, 575);
gfx::Point child_center(150, 450); gfx::Point child_center(150, 450);
// Send touchpad pinch sequence to main-frame. // Send touchpad pinch sequence to main-frame.
SendMacTouchpadPinchSequenceWithExpectedTarget( SendMacTouchpadPinchSequenceWithExpectedTarget(
rwhv_parent, main_frame_point, router->touchpad_gesture_target_.target, rwhv_parent, main_frame_point, router->touchpad_gesture_target_,
rwhv_parent); rwhv_parent);
// Send touchpad pinch sequence to child. // Send touchpad pinch sequence to child.
SendMacTouchpadPinchSequenceWithExpectedTarget( SendMacTouchpadPinchSequenceWithExpectedTarget(
rwhv_parent, child_center, router->touchpad_gesture_target_.target, rwhv_parent, child_center, router->touchpad_gesture_target_, rwhv_child);
rwhv_child);
} }
} // namespace content } // namespace content
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