Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/renderer/input/input_handler_proxy.h" | 5 #include "content/renderer/input/input_handler_proxy.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "content/common/input/did_overscroll_params.h" | 12 #include "content/common/input/did_overscroll_params.h" |
| 13 #include "content/common/input/web_input_event_traits.h" | 13 #include "content/common/input/web_input_event_traits.h" |
| 14 #include "content/public/common/content_switches.h" | 14 #include "content/public/common/content_switches.h" |
| 15 #include "content/renderer/input/input_handler_proxy_client.h" | 15 #include "content/renderer/input/input_handler_proxy_client.h" |
| 16 #include "content/renderer/input/input_scroll_elasticity_controller.h" | |
| 16 #include "third_party/WebKit/public/platform/Platform.h" | 17 #include "third_party/WebKit/public/platform/Platform.h" |
| 17 #include "third_party/WebKit/public/web/WebInputEvent.h" | 18 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 18 #include "ui/events/latency_info.h" | 19 #include "ui/events/latency_info.h" |
| 19 #include "ui/gfx/frame_time.h" | 20 #include "ui/gfx/frame_time.h" |
| 20 #include "ui/gfx/geometry/point_conversions.h" | 21 #include "ui/gfx/geometry/point_conversions.h" |
| 21 | 22 |
| 22 using blink::WebFloatPoint; | 23 using blink::WebFloatPoint; |
| 23 using blink::WebFloatSize; | 24 using blink::WebFloatSize; |
| 24 using blink::WebGestureEvent; | 25 using blink::WebGestureEvent; |
| 25 using blink::WebInputEvent; | 26 using blink::WebInputEvent; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 gesture_scroll_on_impl_thread_(false), | 155 gesture_scroll_on_impl_thread_(false), |
| 155 gesture_pinch_on_impl_thread_(false), | 156 gesture_pinch_on_impl_thread_(false), |
| 156 fling_may_be_active_on_main_thread_(false), | 157 fling_may_be_active_on_main_thread_(false), |
| 157 disallow_horizontal_fling_scroll_(false), | 158 disallow_horizontal_fling_scroll_(false), |
| 158 disallow_vertical_fling_scroll_(false), | 159 disallow_vertical_fling_scroll_(false), |
| 159 has_fling_animation_started_(false) { | 160 has_fling_animation_started_(false) { |
| 160 DCHECK(client); | 161 DCHECK(client); |
| 161 input_handler_->BindToClient(this); | 162 input_handler_->BindToClient(this); |
| 162 smooth_scroll_enabled_ = CommandLine::ForCurrentProcess()->HasSwitch( | 163 smooth_scroll_enabled_ = CommandLine::ForCurrentProcess()->HasSwitch( |
| 163 switches::kEnableSmoothScrolling); | 164 switches::kEnableSmoothScrolling); |
| 165 | |
| 166 #if defined(OS_MACOSX) | |
| 167 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 168 switches::kEnableThreadedEventHandlingMac)) { | |
| 169 scroll_elasticity_controller_.reset(new InputScrollElasticityController( | |
| 170 input_handler_->CreateScrollElasticityHelper())); | |
| 171 } | |
| 172 #endif | |
| 164 } | 173 } |
| 165 | 174 |
| 166 InputHandlerProxy::~InputHandlerProxy() {} | 175 InputHandlerProxy::~InputHandlerProxy() {} |
| 167 | 176 |
| 168 void InputHandlerProxy::WillShutdown() { | 177 void InputHandlerProxy::WillShutdown() { |
| 169 input_handler_ = NULL; | 178 input_handler_ = NULL; |
| 170 client_->WillShutdown(); | 179 client_->WillShutdown(); |
| 180 if (scroll_elasticity_controller_) | |
|
jdduke (slow)
2014/11/13 03:03:09
Can we just reset the variable and get rid of the
ccameron
2014/11/13 03:08:09
Good point, yeah, that's simpler.
| |
| 181 scroll_elasticity_controller_->WillShutdown(); | |
| 171 } | 182 } |
| 172 | 183 |
| 173 InputHandlerProxy::EventDisposition | 184 InputHandlerProxy::EventDisposition |
| 174 InputHandlerProxy::HandleInputEventWithLatencyInfo( | 185 InputHandlerProxy::HandleInputEventWithLatencyInfo( |
| 175 const WebInputEvent& event, | 186 const WebInputEvent& event, |
| 176 ui::LatencyInfo* latency_info) { | 187 ui::LatencyInfo* latency_info) { |
| 177 DCHECK(input_handler_); | 188 DCHECK(input_handler_); |
| 178 | 189 |
| 179 SendScrollLatencyUma(event, *latency_info); | 190 SendScrollLatencyUma(event, *latency_info); |
| 180 | 191 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 CancelCurrentFling(); | 280 CancelCurrentFling(); |
| 270 } | 281 } |
| 271 break; | 282 break; |
| 272 } | 283 } |
| 273 | 284 |
| 274 return DID_NOT_HANDLE; | 285 return DID_NOT_HANDLE; |
| 275 } | 286 } |
| 276 | 287 |
| 277 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( | 288 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( |
| 278 const WebMouseWheelEvent& wheel_event) { | 289 const WebMouseWheelEvent& wheel_event) { |
| 290 InputHandlerProxy::EventDisposition result = DID_NOT_HANDLE; | |
| 291 cc::InputHandlerScrollResult scroll_result; | |
| 292 | |
| 279 if (wheel_event.scrollByPage) { | 293 if (wheel_event.scrollByPage) { |
| 280 // TODO(jamesr): We don't properly handle scroll by page in the compositor | 294 // TODO(jamesr): We don't properly handle scroll by page in the compositor |
| 281 // thread, so punt it to the main thread. http://crbug.com/236639 | 295 // thread, so punt it to the main thread. http://crbug.com/236639 |
| 282 return DID_NOT_HANDLE; | 296 result = DID_NOT_HANDLE; |
| 283 } | 297 } else if (wheel_event.modifiers & WebInputEvent::ControlKey) { |
| 284 if (wheel_event.modifiers & WebInputEvent::ControlKey) { | |
| 285 // Wheel events involving the control key never trigger scrolling, only | 298 // Wheel events involving the control key never trigger scrolling, only |
| 286 // event handlers. Forward to the main thread. | 299 // event handlers. Forward to the main thread. |
| 287 return DID_NOT_HANDLE; | 300 result = DID_NOT_HANDLE; |
| 288 } | 301 } else if (smooth_scroll_enabled_) { |
| 289 if (smooth_scroll_enabled_) { | |
| 290 cc::InputHandler::ScrollStatus scroll_status = | 302 cc::InputHandler::ScrollStatus scroll_status = |
| 291 input_handler_->ScrollAnimated( | 303 input_handler_->ScrollAnimated( |
| 292 gfx::Point(wheel_event.x, wheel_event.y), | 304 gfx::Point(wheel_event.x, wheel_event.y), |
| 293 gfx::Vector2dF(-wheel_event.deltaX, -wheel_event.deltaY)); | 305 gfx::Vector2dF(-wheel_event.deltaX, -wheel_event.deltaY)); |
| 294 switch (scroll_status) { | 306 switch (scroll_status) { |
| 295 case cc::InputHandler::ScrollStarted: | 307 case cc::InputHandler::ScrollStarted: |
| 296 return DID_HANDLE; | 308 result = DID_HANDLE; |
| 309 break; | |
| 297 case cc::InputHandler::ScrollIgnored: | 310 case cc::InputHandler::ScrollIgnored: |
| 298 return DROP_EVENT; | 311 result = DROP_EVENT; |
| 299 default: | 312 default: |
| 300 return DID_NOT_HANDLE; | 313 result = DID_NOT_HANDLE; |
| 314 break; | |
| 315 } | |
| 316 } else { | |
| 317 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( | |
| 318 gfx::Point(wheel_event.x, wheel_event.y), cc::InputHandler::Wheel); | |
| 319 switch (scroll_status) { | |
| 320 case cc::InputHandler::ScrollStarted: { | |
| 321 TRACE_EVENT_INSTANT2( | |
| 322 "input", "InputHandlerProxy::handle_input wheel scroll", | |
| 323 TRACE_EVENT_SCOPE_THREAD, "deltaX", -wheel_event.deltaX, "deltaY", | |
| 324 -wheel_event.deltaY); | |
| 325 gfx::Point scroll_point(wheel_event.x, wheel_event.y); | |
| 326 gfx::Vector2dF scroll_delta(-wheel_event.deltaX, -wheel_event.deltaY); | |
| 327 scroll_result = input_handler_->ScrollBy(scroll_point, scroll_delta); | |
| 328 HandleOverscroll(scroll_point, scroll_result); | |
| 329 input_handler_->ScrollEnd(); | |
| 330 result = scroll_result.did_scroll ? DID_HANDLE : DROP_EVENT; | |
| 331 break; | |
| 332 } | |
| 333 case cc::InputHandler::ScrollIgnored: | |
| 334 // TODO(jamesr): This should be DROP_EVENT, but in cases where we fail | |
| 335 // to properly sync scrollability it's safer to send the event to the | |
| 336 // main thread. Change back to DROP_EVENT once we have synchronization | |
| 337 // bugs sorted out. | |
| 338 result = DID_NOT_HANDLE; | |
| 339 break; | |
| 340 case cc::InputHandler::ScrollUnknown: | |
| 341 case cc::InputHandler::ScrollOnMainThread: | |
| 342 result = DID_NOT_HANDLE; | |
| 343 break; | |
| 344 case cc::InputHandler::ScrollStatusCount: | |
| 345 NOTREACHED(); | |
| 346 break; | |
| 301 } | 347 } |
| 302 } | 348 } |
| 303 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( | 349 |
| 304 gfx::Point(wheel_event.x, wheel_event.y), cc::InputHandler::Wheel); | 350 // Send the event and its disposition to the elasticity controller to update |
| 305 switch (scroll_status) { | 351 // the over-scroll animation. If the event is to be handled on the main |
| 306 case cc::InputHandler::ScrollStarted: { | 352 // thread, the event and its disposition will be sent to the elasticity |
| 307 TRACE_EVENT_INSTANT2( | 353 // controller after being handled on the main thread. |
| 308 "input", | 354 if (scroll_elasticity_controller_ && result != DID_NOT_HANDLE) { |
| 309 "InputHandlerProxy::handle_input wheel scroll", | 355 // Note that the call to the elasticity controller is made asynchronously, |
| 310 TRACE_EVENT_SCOPE_THREAD, | 356 // to minimize divergence between main thread and impl thread event |
| 311 "deltaX", | 357 // handling paths. |
| 312 -wheel_event.deltaX, | 358 base::MessageLoop::current()->PostTask( |
| 313 "deltaY", | 359 FROM_HERE, |
| 314 -wheel_event.deltaY); | 360 base::Bind(&InputScrollElasticityController::ObserveWheelEventAndResult, |
| 315 gfx::Point scroll_point(wheel_event.x, wheel_event.y); | 361 scroll_elasticity_controller_->GetWeakPtr(), wheel_event, |
| 316 gfx::Vector2dF scroll_delta(-wheel_event.deltaX, -wheel_event.deltaY); | 362 scroll_result)); |
| 317 cc::InputHandlerScrollResult scroll_result = input_handler_->ScrollBy( | |
| 318 scroll_point, scroll_delta); | |
| 319 HandleOverscroll(scroll_point, scroll_result); | |
| 320 input_handler_->ScrollEnd(); | |
| 321 return scroll_result.did_scroll ? DID_HANDLE : DROP_EVENT; | |
| 322 } | |
| 323 case cc::InputHandler::ScrollIgnored: | |
| 324 // TODO(jamesr): This should be DROP_EVENT, but in cases where we fail | |
| 325 // to properly sync scrollability it's safer to send the event to the | |
| 326 // main thread. Change back to DROP_EVENT once we have synchronization | |
| 327 // bugs sorted out. | |
| 328 return DID_NOT_HANDLE; | |
| 329 case cc::InputHandler::ScrollUnknown: | |
| 330 case cc::InputHandler::ScrollOnMainThread: | |
| 331 return DID_NOT_HANDLE; | |
| 332 case cc::InputHandler::ScrollStatusCount: | |
| 333 NOTREACHED(); | |
| 334 break; | |
| 335 } | 363 } |
| 336 return DID_NOT_HANDLE; | 364 return result; |
| 337 } | 365 } |
| 338 | 366 |
| 339 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollBegin( | 367 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollBegin( |
| 340 const WebGestureEvent& gesture_event) { | 368 const WebGestureEvent& gesture_event) { |
| 341 DCHECK(!gesture_scroll_on_impl_thread_); | 369 DCHECK(!gesture_scroll_on_impl_thread_); |
| 342 #ifndef NDEBUG | 370 #ifndef NDEBUG |
| 343 DCHECK(!expect_scroll_update_end_); | 371 DCHECK(!expect_scroll_update_end_); |
| 344 expect_scroll_update_end_ = true; | 372 expect_scroll_update_end_ = true; |
| 345 #endif | 373 #endif |
| 346 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( | 374 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 632 const blink::WebGestureEvent& event) { | 660 const blink::WebGestureEvent& event) { |
| 633 TRACE_EVENT_INSTANT0("input", | 661 TRACE_EVENT_INSTANT0("input", |
| 634 "InputHandlerProxy::ExtendBoostedFlingTimeout", | 662 "InputHandlerProxy::ExtendBoostedFlingTimeout", |
| 635 TRACE_EVENT_SCOPE_THREAD); | 663 TRACE_EVENT_SCOPE_THREAD); |
| 636 deferred_fling_cancel_time_seconds_ = | 664 deferred_fling_cancel_time_seconds_ = |
| 637 event.timeStampSeconds + kFlingBoostTimeoutDelaySeconds; | 665 event.timeStampSeconds + kFlingBoostTimeoutDelaySeconds; |
| 638 last_fling_boost_event_ = event; | 666 last_fling_boost_event_ = event; |
| 639 } | 667 } |
| 640 | 668 |
| 641 void InputHandlerProxy::Animate(base::TimeTicks time) { | 669 void InputHandlerProxy::Animate(base::TimeTicks time) { |
| 670 if (scroll_elasticity_controller_) | |
| 671 scroll_elasticity_controller_->Animate(time); | |
| 672 | |
| 642 if (!fling_curve_) | 673 if (!fling_curve_) |
| 643 return; | 674 return; |
| 644 | 675 |
| 645 double monotonic_time_sec = InSecondsF(time); | 676 double monotonic_time_sec = InSecondsF(time); |
| 646 | 677 |
| 647 if (deferred_fling_cancel_time_seconds_ && | 678 if (deferred_fling_cancel_time_seconds_ && |
| 648 monotonic_time_sec > deferred_fling_cancel_time_seconds_) { | 679 monotonic_time_sec > deferred_fling_cancel_time_seconds_) { |
| 649 CancelCurrentFling(); | 680 CancelCurrentFling(); |
| 650 return; | 681 return; |
| 651 } | 682 } |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 // trigger a scroll, e.g., with a trivial time delta between fling updates. | 888 // trigger a scroll, e.g., with a trivial time delta between fling updates. |
| 858 // Return true in this case to prevent early fling termination. | 889 // Return true in this case to prevent early fling termination. |
| 859 if (std::abs(clipped_increment.width) < kScrollEpsilon && | 890 if (std::abs(clipped_increment.width) < kScrollEpsilon && |
| 860 std::abs(clipped_increment.height) < kScrollEpsilon) | 891 std::abs(clipped_increment.height) < kScrollEpsilon) |
| 861 return true; | 892 return true; |
| 862 | 893 |
| 863 return did_scroll; | 894 return did_scroll; |
| 864 } | 895 } |
| 865 | 896 |
| 866 } // namespace content | 897 } // namespace content |
| OLD | NEW |