| 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..19e42a1c10e2e9affaace39ee54de4cdbc7aff79 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));
|
| +
|
| if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) {
|
| - if (ShouldRouteEvent(event)) {
|
| + bool should_route_event = ShouldRouteEvent(event);
|
| + if (host_view_->wheel_scroll_latching_enabled())
|
| + AddPhaseAndScheduleEndEvent(mouse_wheel_event, should_route_event);
|
| + if (should_route_event) {
|
| host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(
|
| host_view_, &mouse_wheel_event, *event->latency());
|
| } else {
|
| @@ -388,7 +392,7 @@ void RenderWidgetHostViewEventHandler::OnMouseEvent(ui::MouseEvent* event) {
|
|
|
| void RenderWidgetHostViewEventHandler::OnScrollEvent(ui::ScrollEvent* event) {
|
| TRACE_EVENT0("input", "RenderWidgetHostViewBase::OnScrollEvent");
|
| -
|
| + bool should_route_event = ShouldRouteEvent(event);
|
| if (event->type() == ui::ET_SCROLL) {
|
| #if !defined(OS_WIN)
|
| // TODO(ananta)
|
| @@ -404,7 +408,9 @@ 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)) {
|
| + if (host_view_->wheel_scroll_latching_enabled())
|
| + AddPhaseAndScheduleEndEvent(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 +425,19 @@ 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)) {
|
| + 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"));
|
| + // Stop the timer to avoid sending a synthetic wheel event with
|
| + // kPhaseEnded.
|
| + mouse_wheel_end_dispatch_timer_.Stop();
|
| + }
|
| }
|
|
|
| event->SetHandled();
|
| @@ -519,18 +529,32 @@ 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_end_dispatch_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_end_dispatch_timer_.user_task();
|
| + mouse_wheel_end_dispatch_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.
|
| + mouse_wheel_end_dispatch_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 +911,51 @@ void RenderWidgetHostViewEventHandler::ProcessTouchEvent(
|
| host_->ForwardTouchEventWithLatencyInfo(event, latency);
|
| }
|
|
|
| +void RenderWidgetHostViewEventHandler::SendSyntheticWheelEventWithPhaseEnded(
|
| + blink::WebMouseWheelEvent last_mouse_wheel_event,
|
| + bool should_route_event) {
|
| + DCHECK(host_view_->wheel_scroll_latching_enabled());
|
| + 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::AddPhaseAndScheduleEndEvent(
|
| + blink::WebMouseWheelEvent& mouse_wheel_event,
|
| + bool should_route_event) {
|
| + DCHECK_EQ(blink::WebMouseWheelEvent::kPhaseNone, mouse_wheel_event.phase);
|
| + DCHECK_EQ(blink::WebMouseWheelEvent::kPhaseNone,
|
| + mouse_wheel_event.momentum_phase);
|
| +
|
| + if (!mouse_wheel_end_dispatch_timer_.IsRunning()) {
|
| + mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
|
| + mouse_wheel_end_dispatch_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_end_dispatch_timer_.Reset();
|
| + }
|
| +}
|
| +
|
| } // namespace content
|
|
|