Index: content/browser/renderer_host/render_widget_host_view_mac.mm |
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm |
index efe95f0a6e7492a295e168eaa7c62e2d5582fbc3..c6e189dfa5139b2cbf010fe8b192ff3ed55292dc 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm |
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm |
@@ -1756,6 +1756,50 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged( |
UpdateScreenInfo(cocoa_view_); |
} |
+void RenderWidgetHostViewMac::ScheduleMouseWheelEndDispatching( |
+ blink::WebMouseWheelEvent wheel_event, |
+ bool should_route_event) { |
+ mouse_wheel_end_dispatch_timer_.Start( |
+ FROM_HERE, |
+ base::TimeDelta::FromMilliseconds( |
+ kDefaultMouseWheelLatchingTransactionMs), |
+ base::Bind( |
+ &RenderWidgetHostViewMac::SendSyntheticWheelEventWithPhaseEnded, |
+ base::Unretained(this), wheel_event, should_route_event)); |
+} |
+ |
+void RenderWidgetHostViewMac::DispatchPendingWheelEndEvent() { |
+ if (mouse_wheel_end_dispatch_timer_.IsRunning()) { |
+ base::Closure task = mouse_wheel_end_dispatch_timer_.user_task(); |
+ mouse_wheel_end_dispatch_timer_.Stop(); |
+ task.Run(); |
+ } |
+} |
+ |
+void RenderWidgetHostViewMac::IgnorePendingWheelEndEvent() { |
+ mouse_wheel_end_dispatch_timer_.Stop(); |
+} |
+ |
+bool RenderWidgetHostViewMac::HasPendingWheelEndEvent() { |
+ return mouse_wheel_end_dispatch_timer_.IsRunning(); |
+} |
+ |
+void RenderWidgetHostViewMac::SendSyntheticWheelEventWithPhaseEnded( |
+ blink::WebMouseWheelEvent wheel_event, |
+ bool should_route_event) { |
+ wheel_event.dispatch_type = |
+ blink::WebInputEvent::DispatchType::kEventNonBlocking; |
+ if (should_route_event) { |
+ render_widget_host_->delegate() |
+ ->GetInputEventRouter() |
+ ->RouteMouseWheelEvent(this, &wheel_event, |
+ ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
+ } else { |
+ ProcessMouseWheelEvent(wheel_event, |
+ ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
+ } |
+} |
+ |
} // namespace content |
// RenderWidgetHostViewCocoa --------------------------------------------------- |
@@ -2356,10 +2400,14 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged( |
WebMouseWheelEvent webEvent = WebMouseWheelEventBuilder::Build( |
event, self); |
webEvent.rails_mode = mouseWheelFilter_.UpdateRailsMode(webEvent); |
- ui::LatencyInfo latency_info(ui::SourceEventType::WHEEL); |
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); |
- renderWidgetHostView_->render_widget_host_-> |
- ForwardWheelEventWithLatencyInfo(webEvent, latency_info); |
+ if (renderWidgetHostView_->wheel_scroll_latching_enabled()) { |
+ renderWidgetHostView_->ScheduleMouseWheelEndDispatching(webEvent, false); |
+ } else { |
+ ui::LatencyInfo latency_info(ui::SourceEventType::WHEEL); |
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); |
+ renderWidgetHostView_->render_widget_host_ |
+ ->ForwardWheelEventWithLatencyInfo(webEvent, latency_info); |
+ } |
} |
if (endWheelMonitor_) { |
@@ -2565,6 +2613,28 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged( |
webEvent.rails_mode = mouseWheelFilter_.UpdateRailsMode(webEvent); |
ui::LatencyInfo latency_info(ui::SourceEventType::WHEEL); |
latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); |
+ if (renderWidgetHostView_->wheel_scroll_latching_enabled()) { |
+ if (webEvent.phase == blink::WebMouseWheelEvent::kPhaseEnded) { |
+ // Don't send the wheel end event immediately, start a timer instead to |
+ // see whether momentum phase of the scrolling starts or not. |
+ renderWidgetHostView_->ScheduleMouseWheelEndDispatching( |
+ webEvent, renderWidgetHostView_->ShouldRouteEvent(webEvent)); |
+ return; |
+ } |
+ if (webEvent.phase == blink::WebMouseWheelEvent::kPhaseBegan) { |
+ // A new scrolling sequence has started, send the pending wheel end |
+ // event to end the previous scrolling sequence. |
+ renderWidgetHostView_->DispatchPendingWheelEndEvent(); |
+ |
+ } else if (webEvent.momentum_phase == |
+ blink::WebMouseWheelEvent::kPhaseBegan) { |
+ // Momentum phase has started, drop the pending wheel end event to make |
+ // sure that no wheel end event will be sent during the momentum phase |
+ // of scrolling. |
+ renderWidgetHostView_->IgnorePendingWheelEndEvent(); |
+ } |
+ } |
+ |
if (renderWidgetHostView_->ShouldRouteEvent(webEvent)) { |
renderWidgetHostView_->render_widget_host_->delegate() |
->GetInputEventRouter() |