Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_event_handler.cc |
| diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc |
| index 980a6780b411c34b8988b6bb93bf7d1c3dd833a0..dbbcd0a090c8fcaa5fcc5e144f46e7faf22b3b40 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc |
| +++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc |
| @@ -336,8 +336,12 @@ void RenderWidgetHostViewEventHandler::OnMouseEvent(ui::MouseEvent* event) { |
| blink::WebMouseWheelEvent mouse_wheel_event = |
| ui::MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event), |
| base::Bind(&GetScreenLocationFromEvent)); |
| + bool should_route_event = ShouldRouteEvent(event); |
|
bokan
2017/05/18 16:47:00
Nit: move this inside the `if` block.
sahel
2017/05/18 18:15:14
Done.
|
| + |
| if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) { |
| - if (ShouldRouteEvent(event)) { |
| + if (host_view_->wheel_scroll_latching_enabled()) |
| + AddSyntheticPhase(mouse_wheel_event, should_route_event); |
| + if (should_route_event) { |
| host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( |
| host_view_, &mouse_wheel_event, *event->latency()); |
| } else { |
| @@ -404,7 +408,11 @@ void RenderWidgetHostViewEventHandler::OnScrollEvent(ui::ScrollEvent* event) { |
| gesture_event.y = event->y(); |
| blink::WebMouseWheelEvent mouse_wheel_event = ui::MakeWebMouseWheelEvent( |
| *event, base::Bind(&GetScreenLocationFromEvent)); |
| - if (ShouldRouteEvent(event)) { |
| + |
| + bool should_route_event = ShouldRouteEvent(event); |
| + if (host_view_->wheel_scroll_latching_enabled()) |
| + AddSyntheticPhase(mouse_wheel_event, should_route_event); |
| + if (should_route_event) { |
| host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| host_view_, &gesture_event, |
| ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
| @@ -419,15 +427,23 @@ void RenderWidgetHostViewEventHandler::OnScrollEvent(ui::ScrollEvent* event) { |
| event->type() == ui::ET_SCROLL_FLING_CANCEL) { |
| blink::WebGestureEvent gesture_event = ui::MakeWebGestureEvent( |
| *event, base::Bind(&GetScreenLocationFromEvent)); |
| - if (ShouldRouteEvent(event)) { |
| + bool should_route_event = ShouldRouteEvent(event); |
|
bokan
2017/05/18 16:47:00
Define this variable outside only once and use in
sahel
2017/05/18 18:15:14
Done.
|
| + if (should_route_event) { |
| host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| host_view_, &gesture_event, |
| ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
| } else { |
| host_->ForwardGestureEvent(gesture_event); |
| } |
| - if (event->type() == ui::ET_SCROLL_FLING_START) |
| + if (event->type() == ui::ET_SCROLL_FLING_START) { |
| RecordAction(base::UserMetricsAction("TrackpadScrollFling")); |
| + |
| + if (mouse_wheel_phase_timer_.IsRunning()) { |
| + // Stop the timer to avoid sending a synthetic wheel event with |
| + // kPhaseEnded. |
| + mouse_wheel_phase_timer_.Stop(); |
|
bokan
2017/05/18 16:47:00
Is there any harm in calling Stop on a timer that
sahel
2017/05/18 18:15:15
Done.
|
| + } |
| + } |
| } |
| event->SetHandled(); |
| @@ -519,18 +535,34 @@ void RenderWidgetHostViewEventHandler::OnGestureEvent(ui::GestureEvent* event) { |
| } |
| if (gesture.GetType() != blink::WebInputEvent::kUndefined) { |
| + if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { |
| + RecordAction(base::UserMetricsAction("TouchscreenScroll")); |
| + |
| + if (mouse_wheel_phase_timer_.IsRunning()) { |
| + // If there is a current scroll going on and a new scroll that isn't |
| + // wheel based send a synthetic wheel event with kPhaseEnded to cancel |
| + // the current scroll. |
| + base::Closure task = mouse_wheel_phase_timer_.user_task(); |
| + mouse_wheel_phase_timer_.Stop(); |
| + task.Run(); |
| + } |
| + } else if (event->type() == ui::ET_GESTURE_SCROLL_END) { |
| + // Make sure that the next wheel event will have phase = |kPhaseBegan|. |
| + // This is for maintaining the correct phase info when some of the wheel |
| + // events get ignored while a touchscreen scroll is going on. |
| + if (mouse_wheel_phase_timer_.IsRunning()) { |
|
bokan
2017/05/18 16:47:00
If the wheel events are ignored while a touchscree
sahel
2017/05/18 18:15:15
They will be still generated (with phase info) and
bokan
2017/05/19 15:52:59
Acknowledged.
|
| + mouse_wheel_phase_timer_.Stop(); |
| + } |
| + } else if (event->type() == ui::ET_SCROLL_FLING_START) { |
| + RecordAction(base::UserMetricsAction("TouchscreenScrollFling")); |
| + } |
| + |
| if (ShouldRouteEvent(event)) { |
| host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| host_view_, &gesture, *event->latency()); |
| } else { |
| host_->ForwardGestureEventWithLatencyInfo(gesture, *event->latency()); |
| } |
| - |
| - if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { |
| - RecordAction(base::UserMetricsAction("TouchscreenScroll")); |
| - } else if (event->type() == ui::ET_SCROLL_FLING_START) { |
| - RecordAction(base::UserMetricsAction("TouchscreenScrollFling")); |
| - } |
| } |
| // If a gesture is not processed by the webpage, then WebKit processes it |
| @@ -887,4 +919,50 @@ void RenderWidgetHostViewEventHandler::ProcessTouchEvent( |
| host_->ForwardTouchEventWithLatencyInfo(event, latency); |
| } |
| +void RenderWidgetHostViewEventHandler::SendSyntheticWheelEventWithPhaseEnded( |
|
bokan
2017/05/18 16:47:00
Please add a DCHECK that touchpad latching is enab
sahel
2017/05/18 18:15:15
Done.
|
| + blink::WebMouseWheelEvent last_mouse_wheel_event, |
| + bool should_route_event) { |
| + blink::WebMouseWheelEvent mouse_wheel_event = last_mouse_wheel_event; |
| + mouse_wheel_event.delta_x = 0; |
| + mouse_wheel_event.delta_y = 0; |
| + mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded; |
| + mouse_wheel_event.dispatch_type = |
| + blink::WebInputEvent::DispatchType::kEventNonBlocking; |
| + if (should_route_event) { |
| + host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( |
| + host_view_, &mouse_wheel_event, |
| + ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
| + } else { |
| + ProcessMouseWheelEvent(mouse_wheel_event, |
| + ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
| + } |
| +} |
| + |
| +void RenderWidgetHostViewEventHandler::AddSyntheticPhase( |
|
tdresser
2017/05/18 13:49:05
The name of this function doesn't make it clear th
bokan
2017/05/18 16:47:00
IMO, it doesn't matter that the phase is "syntheti
sahel
2017/05/18 18:15:15
Done.
sahel
2017/05/18 18:15:15
I changed the name, it might be too long but is de
bokan
2017/05/19 15:52:59
We have (much) longer :)
|
| + blink::WebMouseWheelEvent& mouse_wheel_event, |
| + bool should_route_event) { |
| + DCHECK(mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseNone && |
|
bokan
2017/05/18 16:47:00
Where do the Mac events that do have this go?
sahel
2017/05/18 18:15:15
This event handler is aura only, mac events are ha
bokan
2017/05/19 15:52:59
Acknowledged.
|
| + mouse_wheel_event.momentum_phase == |
| + blink::WebMouseWheelEvent::kPhaseNone); |
| + |
| + if (!mouse_wheel_phase_timer_.IsRunning()) { |
| + mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; |
| + mouse_wheel_phase_timer_.Start( |
| + FROM_HERE, |
| + base::TimeDelta::FromMilliseconds( |
| + kDefaultMouseWheelLatchingTransactionMs), |
| + base::Bind(&RenderWidgetHostViewEventHandler:: |
| + SendSyntheticWheelEventWithPhaseEnded, |
| + base::Unretained(this), mouse_wheel_event, |
| + should_route_event)); |
| + } else { |
| + bool non_zero_delta = |
| + mouse_wheel_event.delta_x || mouse_wheel_event.delta_y; |
| + mouse_wheel_event.phase = non_zero_delta |
| + ? blink::WebMouseWheelEvent::kPhaseChanged |
| + : blink::WebMouseWheelEvent::kPhaseStationary; |
| + mouse_wheel_phase_timer_.Reset(); |
| + } |
| +} |
| + |
| } // namespace content |