| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/render_widget_host_view_event_handler.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_event_handler.h" |
| 6 | 6 |
| 7 #include "base/metrics/user_metrics.h" | 7 #include "base/metrics/user_metrics.h" |
| 8 #include "base/metrics/user_metrics_action.h" | 8 #include "base/metrics/user_metrics_action.h" |
| 9 #include "content/browser/renderer_host/input/touch_selection_controller_client_
aura.h" | 9 #include "content/browser/renderer_host/input/touch_selection_controller_client_
aura.h" |
| 10 #include "content/browser/renderer_host/overscroll_controller.h" | 10 #include "content/browser/renderer_host/overscroll_controller.h" |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 disable_input_event_router_for_testing_(false), | 131 disable_input_event_router_for_testing_(false), |
| 132 mouse_locked_(false), | 132 mouse_locked_(false), |
| 133 pinch_zoom_enabled_(content::IsPinchToZoomEnabled()), | 133 pinch_zoom_enabled_(content::IsPinchToZoomEnabled()), |
| 134 set_focus_on_mouse_down_or_key_event_(false), | 134 set_focus_on_mouse_down_or_key_event_(false), |
| 135 synthetic_move_sent_(false), | 135 synthetic_move_sent_(false), |
| 136 host_(RenderWidgetHostImpl::From(host)), | 136 host_(RenderWidgetHostImpl::From(host)), |
| 137 host_view_(host_view), | 137 host_view_(host_view), |
| 138 popup_child_host_view_(nullptr), | 138 popup_child_host_view_(nullptr), |
| 139 popup_child_event_handler_(nullptr), | 139 popup_child_event_handler_(nullptr), |
| 140 delegate_(delegate), | 140 delegate_(delegate), |
| 141 window_(nullptr) {} | 141 window_(nullptr), |
| 142 mouse_wheel_phase_handler_(host, host_view) {} |
| 142 | 143 |
| 143 RenderWidgetHostViewEventHandler::~RenderWidgetHostViewEventHandler() {} | 144 RenderWidgetHostViewEventHandler::~RenderWidgetHostViewEventHandler() {} |
| 144 | 145 |
| 145 void RenderWidgetHostViewEventHandler::SetPopupChild( | 146 void RenderWidgetHostViewEventHandler::SetPopupChild( |
| 146 RenderWidgetHostViewBase* popup_child_host_view, | 147 RenderWidgetHostViewBase* popup_child_host_view, |
| 147 ui::EventHandler* popup_child_event_handler) { | 148 ui::EventHandler* popup_child_event_handler) { |
| 148 popup_child_host_view_ = popup_child_host_view; | 149 popup_child_host_view_ = popup_child_host_view; |
| 149 popup_child_event_handler_ = popup_child_event_handler; | 150 popup_child_event_handler_ = popup_child_event_handler; |
| 150 } | 151 } |
| 151 | 152 |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 reinterpret_cast<LPARAM>(toplevel_hwnd)); | 335 reinterpret_cast<LPARAM>(toplevel_hwnd)); |
| 335 } | 336 } |
| 336 #endif | 337 #endif |
| 337 blink::WebMouseWheelEvent mouse_wheel_event = | 338 blink::WebMouseWheelEvent mouse_wheel_event = |
| 338 ui::MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event), | 339 ui::MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event), |
| 339 base::Bind(&GetScreenLocationFromEvent)); | 340 base::Bind(&GetScreenLocationFromEvent)); |
| 340 | 341 |
| 341 if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) { | 342 if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) { |
| 342 bool should_route_event = ShouldRouteEvent(event); | 343 bool should_route_event = ShouldRouteEvent(event); |
| 343 if (host_view_->wheel_scroll_latching_enabled()) | 344 if (host_view_->wheel_scroll_latching_enabled()) |
| 344 AddPhaseAndScheduleEndEvent(mouse_wheel_event, should_route_event); | 345 mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent( |
| 346 mouse_wheel_event, should_route_event); |
| 345 if (should_route_event) { | 347 if (should_route_event) { |
| 346 host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( | 348 host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( |
| 347 host_view_, &mouse_wheel_event, *event->latency()); | 349 host_view_, &mouse_wheel_event, *event->latency()); |
| 348 } else { | 350 } else { |
| 349 ProcessMouseWheelEvent(mouse_wheel_event, *event->latency()); | 351 ProcessMouseWheelEvent(mouse_wheel_event, *event->latency()); |
| 350 } | 352 } |
| 351 } | 353 } |
| 352 } else { | 354 } else { |
| 353 bool is_selection_popup = NeedsInputGrab(popup_child_host_view_); | 355 bool is_selection_popup = NeedsInputGrab(popup_child_host_view_); |
| 354 if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) && | 356 if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) && |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 #endif | 405 #endif |
| 404 blink::WebGestureEvent gesture_event = ui::MakeWebGestureEventFlingCancel(); | 406 blink::WebGestureEvent gesture_event = ui::MakeWebGestureEventFlingCancel(); |
| 405 // Coordinates need to be transferred to the fling cancel gesture only | 407 // Coordinates need to be transferred to the fling cancel gesture only |
| 406 // for Surface-targeting to ensure that it is targeted to the correct | 408 // for Surface-targeting to ensure that it is targeted to the correct |
| 407 // RenderWidgetHost. | 409 // RenderWidgetHost. |
| 408 gesture_event.x = event->x(); | 410 gesture_event.x = event->x(); |
| 409 gesture_event.y = event->y(); | 411 gesture_event.y = event->y(); |
| 410 blink::WebMouseWheelEvent mouse_wheel_event = ui::MakeWebMouseWheelEvent( | 412 blink::WebMouseWheelEvent mouse_wheel_event = ui::MakeWebMouseWheelEvent( |
| 411 *event, base::Bind(&GetScreenLocationFromEvent)); | 413 *event, base::Bind(&GetScreenLocationFromEvent)); |
| 412 if (host_view_->wheel_scroll_latching_enabled()) | 414 if (host_view_->wheel_scroll_latching_enabled()) |
| 413 AddPhaseAndScheduleEndEvent(mouse_wheel_event, should_route_event); | 415 mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent( |
| 416 mouse_wheel_event, should_route_event); |
| 414 if (should_route_event) { | 417 if (should_route_event) { |
| 415 host_->delegate()->GetInputEventRouter()->RouteGestureEvent( | 418 host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| 416 host_view_, &gesture_event, | 419 host_view_, &gesture_event, |
| 417 ui::LatencyInfo(ui::SourceEventType::WHEEL)); | 420 ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
| 418 host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( | 421 host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( |
| 419 host_view_, &mouse_wheel_event, *event->latency()); | 422 host_view_, &mouse_wheel_event, *event->latency()); |
| 420 } else { | 423 } else { |
| 421 host_->ForwardGestureEvent(gesture_event); | 424 host_->ForwardGestureEvent(gesture_event); |
| 422 host_->ForwardWheelEventWithLatencyInfo(mouse_wheel_event, | 425 host_->ForwardWheelEventWithLatencyInfo(mouse_wheel_event, |
| 423 *event->latency()); | 426 *event->latency()); |
| 424 } | 427 } |
| 425 } else if (event->type() == ui::ET_SCROLL_FLING_START || | 428 } else if (event->type() == ui::ET_SCROLL_FLING_START || |
| 426 event->type() == ui::ET_SCROLL_FLING_CANCEL) { | 429 event->type() == ui::ET_SCROLL_FLING_CANCEL) { |
| 427 blink::WebGestureEvent gesture_event = ui::MakeWebGestureEvent( | 430 blink::WebGestureEvent gesture_event = ui::MakeWebGestureEvent( |
| 428 *event, base::Bind(&GetScreenLocationFromEvent)); | 431 *event, base::Bind(&GetScreenLocationFromEvent)); |
| 429 if (should_route_event) { | 432 if (should_route_event) { |
| 430 host_->delegate()->GetInputEventRouter()->RouteGestureEvent( | 433 host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| 431 host_view_, &gesture_event, | 434 host_view_, &gesture_event, |
| 432 ui::LatencyInfo(ui::SourceEventType::WHEEL)); | 435 ui::LatencyInfo(ui::SourceEventType::WHEEL)); |
| 433 } else { | 436 } else { |
| 434 host_->ForwardGestureEvent(gesture_event); | 437 host_->ForwardGestureEvent(gesture_event); |
| 435 } | 438 } |
| 436 if (event->type() == ui::ET_SCROLL_FLING_START) { | 439 if (event->type() == ui::ET_SCROLL_FLING_START) { |
| 437 RecordAction(base::UserMetricsAction("TrackpadScrollFling")); | 440 RecordAction(base::UserMetricsAction("TrackpadScrollFling")); |
| 438 // Stop the timer to avoid sending a synthetic wheel event with | 441 // Ignore the pending wheel end event to avoid sending a wheel event with |
| 439 // kPhaseEnded. | 442 // kPhaseEnded before a GFS. |
| 440 mouse_wheel_end_dispatch_timer_.Stop(); | 443 mouse_wheel_phase_handler_.IgnorePendingWheelEndEvent(); |
| 441 } | 444 } |
| 442 } | 445 } |
| 443 | 446 |
| 444 event->SetHandled(); | 447 event->SetHandled(); |
| 445 } | 448 } |
| 446 | 449 |
| 447 void RenderWidgetHostViewEventHandler::OnTouchEvent(ui::TouchEvent* event) { | 450 void RenderWidgetHostViewEventHandler::OnTouchEvent(ui::TouchEvent* event) { |
| 448 TRACE_EVENT0("input", "RenderWidgetHostViewBase::OnTouchEvent"); | 451 TRACE_EVENT0("input", "RenderWidgetHostViewBase::OnTouchEvent"); |
| 449 | 452 |
| 450 bool had_no_pointer = !pointer_state_.GetPointerCount(); | 453 bool had_no_pointer = !pointer_state_.GetPointerCount(); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 host_view_, &fling_cancel, | 528 host_view_, &fling_cancel, |
| 526 ui::LatencyInfo(ui::SourceEventType::TOUCH)); | 529 ui::LatencyInfo(ui::SourceEventType::TOUCH)); |
| 527 } else { | 530 } else { |
| 528 host_->ForwardGestureEvent(fling_cancel); | 531 host_->ForwardGestureEvent(fling_cancel); |
| 529 } | 532 } |
| 530 } | 533 } |
| 531 | 534 |
| 532 if (gesture.GetType() != blink::WebInputEvent::kUndefined) { | 535 if (gesture.GetType() != blink::WebInputEvent::kUndefined) { |
| 533 if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { | 536 if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { |
| 534 RecordAction(base::UserMetricsAction("TouchscreenScroll")); | 537 RecordAction(base::UserMetricsAction("TouchscreenScroll")); |
| 535 | 538 // If there is a current scroll going on and a new scroll that isn't |
| 536 if (mouse_wheel_end_dispatch_timer_.IsRunning()) { | 539 // wheel based send a synthetic wheel event with kPhaseEnded to cancel |
| 537 // If there is a current scroll going on and a new scroll that isn't | 540 // the current scroll. |
| 538 // wheel based send a synthetic wheel event with kPhaseEnded to cancel | 541 mouse_wheel_phase_handler_.DispatchPendingWheelEndEvent(); |
| 539 // the current scroll. | |
| 540 base::Closure task = mouse_wheel_end_dispatch_timer_.user_task(); | |
| 541 mouse_wheel_end_dispatch_timer_.Stop(); | |
| 542 task.Run(); | |
| 543 } | |
| 544 } else if (event->type() == ui::ET_GESTURE_SCROLL_END) { | 542 } else if (event->type() == ui::ET_GESTURE_SCROLL_END) { |
| 545 // Make sure that the next wheel event will have phase = |kPhaseBegan|. | 543 // Make sure that the next wheel event will have phase = |kPhaseBegan|. |
| 546 // This is for maintaining the correct phase info when some of the wheel | 544 // This is for maintaining the correct phase info when some of the wheel |
| 547 // events get ignored while a touchscreen scroll is going on. | 545 // events get ignored while a touchscreen scroll is going on. |
| 548 mouse_wheel_end_dispatch_timer_.Stop(); | 546 mouse_wheel_phase_handler_.IgnorePendingWheelEndEvent(); |
| 549 } else if (event->type() == ui::ET_SCROLL_FLING_START) { | 547 } else if (event->type() == ui::ET_SCROLL_FLING_START) { |
| 550 RecordAction(base::UserMetricsAction("TouchscreenScrollFling")); | 548 RecordAction(base::UserMetricsAction("TouchscreenScrollFling")); |
| 551 } | 549 } |
| 552 | 550 |
| 553 if (ShouldRouteEvent(event)) { | 551 if (ShouldRouteEvent(event)) { |
| 554 host_->delegate()->GetInputEventRouter()->RouteGestureEvent( | 552 host_->delegate()->GetInputEventRouter()->RouteGestureEvent( |
| 555 host_view_, &gesture, *event->latency()); | 553 host_view_, &gesture, *event->latency()); |
| 556 } else { | 554 } else { |
| 557 host_->ForwardGestureEventWithLatencyInfo(gesture, *event->latency()); | 555 host_->ForwardGestureEventWithLatencyInfo(gesture, *event->latency()); |
| 558 } | 556 } |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 const ui::LatencyInfo& latency) { | 902 const ui::LatencyInfo& latency) { |
| 905 host_->ForwardWheelEventWithLatencyInfo(event, latency); | 903 host_->ForwardWheelEventWithLatencyInfo(event, latency); |
| 906 } | 904 } |
| 907 | 905 |
| 908 void RenderWidgetHostViewEventHandler::ProcessTouchEvent( | 906 void RenderWidgetHostViewEventHandler::ProcessTouchEvent( |
| 909 const blink::WebTouchEvent& event, | 907 const blink::WebTouchEvent& event, |
| 910 const ui::LatencyInfo& latency) { | 908 const ui::LatencyInfo& latency) { |
| 911 host_->ForwardTouchEventWithLatencyInfo(event, latency); | 909 host_->ForwardTouchEventWithLatencyInfo(event, latency); |
| 912 } | 910 } |
| 913 | 911 |
| 914 void RenderWidgetHostViewEventHandler::SendSyntheticWheelEventWithPhaseEnded( | |
| 915 blink::WebMouseWheelEvent last_mouse_wheel_event, | |
| 916 bool should_route_event) { | |
| 917 DCHECK(host_view_->wheel_scroll_latching_enabled()); | |
| 918 blink::WebMouseWheelEvent mouse_wheel_event = last_mouse_wheel_event; | |
| 919 mouse_wheel_event.delta_x = 0; | |
| 920 mouse_wheel_event.delta_y = 0; | |
| 921 mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded; | |
| 922 mouse_wheel_event.dispatch_type = | |
| 923 blink::WebInputEvent::DispatchType::kEventNonBlocking; | |
| 924 if (should_route_event) { | |
| 925 host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent( | |
| 926 host_view_, &mouse_wheel_event, | |
| 927 ui::LatencyInfo(ui::SourceEventType::WHEEL)); | |
| 928 } else { | |
| 929 ProcessMouseWheelEvent(mouse_wheel_event, | |
| 930 ui::LatencyInfo(ui::SourceEventType::WHEEL)); | |
| 931 } | |
| 932 } | |
| 933 | |
| 934 void RenderWidgetHostViewEventHandler::AddPhaseAndScheduleEndEvent( | |
| 935 blink::WebMouseWheelEvent& mouse_wheel_event, | |
| 936 bool should_route_event) { | |
| 937 DCHECK_EQ(blink::WebMouseWheelEvent::kPhaseNone, mouse_wheel_event.phase); | |
| 938 DCHECK_EQ(blink::WebMouseWheelEvent::kPhaseNone, | |
| 939 mouse_wheel_event.momentum_phase); | |
| 940 | |
| 941 if (!mouse_wheel_end_dispatch_timer_.IsRunning()) { | |
| 942 mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; | |
| 943 mouse_wheel_end_dispatch_timer_.Start( | |
| 944 FROM_HERE, | |
| 945 base::TimeDelta::FromMilliseconds( | |
| 946 kDefaultMouseWheelLatchingTransactionMs), | |
| 947 base::Bind(&RenderWidgetHostViewEventHandler:: | |
| 948 SendSyntheticWheelEventWithPhaseEnded, | |
| 949 base::Unretained(this), mouse_wheel_event, | |
| 950 should_route_event)); | |
| 951 } else { | |
| 952 bool non_zero_delta = | |
| 953 mouse_wheel_event.delta_x || mouse_wheel_event.delta_y; | |
| 954 mouse_wheel_event.phase = non_zero_delta | |
| 955 ? blink::WebMouseWheelEvent::kPhaseChanged | |
| 956 : blink::WebMouseWheelEvent::kPhaseStationary; | |
| 957 mouse_wheel_end_dispatch_timer_.Reset(); | |
| 958 } | |
| 959 } | |
| 960 | |
| 961 } // namespace content | 912 } // namespace content |
| OLD | NEW |