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 cc::ScrollElasticityControllerClient* scroll_elasticity_client = | |
| 170 input_handler_->GetScrollElasticityControllerClient(); | |
| 171 scroll_elasticity_controller_.reset( | |
| 172 new InputScrollElasticityController(scroll_elasticity_client)); | |
| 173 scroll_elasticity_client->BindToController( | |
| 174 scroll_elasticity_controller_.get()); | |
| 175 } | |
| 176 #endif | |
| 164 } | 177 } |
| 165 | 178 |
| 166 InputHandlerProxy::~InputHandlerProxy() {} | 179 InputHandlerProxy::~InputHandlerProxy() {} |
| 167 | 180 |
| 168 void InputHandlerProxy::WillShutdown() { | 181 void InputHandlerProxy::WillShutdown() { |
| 169 input_handler_ = NULL; | 182 input_handler_ = NULL; |
| 170 client_->WillShutdown(); | 183 client_->WillShutdown(); |
| 171 } | 184 } |
| 172 | 185 |
| 173 InputHandlerProxy::EventDisposition | 186 InputHandlerProxy::EventDisposition |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 CancelCurrentFling(); | 282 CancelCurrentFling(); |
| 270 } | 283 } |
| 271 break; | 284 break; |
| 272 } | 285 } |
| 273 | 286 |
| 274 return DID_NOT_HANDLE; | 287 return DID_NOT_HANDLE; |
| 275 } | 288 } |
| 276 | 289 |
| 277 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( | 290 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( |
| 278 const WebMouseWheelEvent& wheel_event) { | 291 const WebMouseWheelEvent& wheel_event) { |
| 292 InputHandlerProxy::EventDisposition result = DID_NOT_HANDLE; | |
| 293 cc::InputHandlerScrollResult scroll_result; | |
| 294 | |
| 279 if (wheel_event.scrollByPage) { | 295 if (wheel_event.scrollByPage) { |
| 280 // TODO(jamesr): We don't properly handle scroll by page in the compositor | 296 // 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 | 297 // thread, so punt it to the main thread. http://crbug.com/236639 |
| 282 return DID_NOT_HANDLE; | 298 result = DID_NOT_HANDLE; |
| 283 } | 299 } 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 | 300 // Wheel events involving the control key never trigger scrolling, only |
| 286 // event handlers. Forward to the main thread. | 301 // event handlers. Forward to the main thread. |
| 287 return DID_NOT_HANDLE; | 302 result = DID_NOT_HANDLE; |
| 288 } | 303 } else if (smooth_scroll_enabled_) { |
| 289 if (smooth_scroll_enabled_) { | |
| 290 cc::InputHandler::ScrollStatus scroll_status = | 304 cc::InputHandler::ScrollStatus scroll_status = |
| 291 input_handler_->ScrollAnimated( | 305 input_handler_->ScrollAnimated( |
| 292 gfx::Point(wheel_event.x, wheel_event.y), | 306 gfx::Point(wheel_event.x, wheel_event.y), |
| 293 gfx::Vector2dF(-wheel_event.deltaX, -wheel_event.deltaY)); | 307 gfx::Vector2dF(-wheel_event.deltaX, -wheel_event.deltaY)); |
| 294 switch (scroll_status) { | 308 switch (scroll_status) { |
| 295 case cc::InputHandler::ScrollStarted: | 309 case cc::InputHandler::ScrollStarted: |
| 296 return DID_HANDLE; | 310 result = DID_HANDLE; |
| 311 break; | |
| 297 case cc::InputHandler::ScrollIgnored: | 312 case cc::InputHandler::ScrollIgnored: |
| 298 return DROP_EVENT; | 313 result = DROP_EVENT; |
| 299 default: | 314 default: |
| 300 return DID_NOT_HANDLE; | 315 result = DID_NOT_HANDLE; |
| 316 break; | |
| 317 } | |
| 318 } else { | |
| 319 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( | |
| 320 gfx::Point(wheel_event.x, wheel_event.y), cc::InputHandler::Wheel); | |
| 321 switch (scroll_status) { | |
| 322 case cc::InputHandler::ScrollStarted: { | |
| 323 TRACE_EVENT_INSTANT2( | |
| 324 "input", "InputHandlerProxy::handle_input wheel scroll", | |
| 325 TRACE_EVENT_SCOPE_THREAD, "deltaX", -wheel_event.deltaX, "deltaY", | |
| 326 -wheel_event.deltaY); | |
| 327 gfx::Point scroll_point(wheel_event.x, wheel_event.y); | |
| 328 gfx::Vector2dF scroll_delta(-wheel_event.deltaX, -wheel_event.deltaY); | |
| 329 scroll_result = input_handler_->ScrollBy(scroll_point, scroll_delta); | |
| 330 HandleOverscroll(scroll_point, scroll_result); | |
| 331 input_handler_->ScrollEnd(); | |
| 332 result = scroll_result.did_scroll ? DID_HANDLE : DROP_EVENT; | |
| 333 break; | |
| 334 } | |
| 335 case cc::InputHandler::ScrollIgnored: | |
| 336 // TODO(jamesr): This should be DROP_EVENT, but in cases where we fail | |
| 337 // to properly sync scrollability it's safer to send the event to the | |
| 338 // main thread. Change back to DROP_EVENT once we have synchronization | |
| 339 // bugs sorted out. | |
| 340 result = DID_NOT_HANDLE; | |
| 341 break; | |
| 342 case cc::InputHandler::ScrollUnknown: | |
| 343 case cc::InputHandler::ScrollOnMainThread: | |
| 344 result = DID_NOT_HANDLE; | |
| 345 break; | |
| 346 case cc::InputHandler::ScrollStatusCount: | |
| 347 NOTREACHED(); | |
| 348 break; | |
| 301 } | 349 } |
| 302 } | 350 } |
| 303 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( | 351 |
| 304 gfx::Point(wheel_event.x, wheel_event.y), cc::InputHandler::Wheel); | 352 // Send the event and its disposition to the elasticity controller to update |
| 305 switch (scroll_status) { | 353 // the over-scroll animation. If the event is to be handled on the main |
| 306 case cc::InputHandler::ScrollStarted: { | 354 // thread, the event and its disposition will be sent after being handled |
|
jdduke (slow)
2014/11/12 02:32:24
Maybe tweak this to say something like "... and it
ccameron
2014/11/12 08:15:29
Good point -- changed to " event and its dispositi
| |
| 307 TRACE_EVENT_INSTANT2( | 355 // there. |
| 308 "input", | 356 if (scroll_elasticity_controller_ && result != DID_NOT_HANDLE) { |
| 309 "InputHandlerProxy::handle_input wheel scroll", | 357 // Note that the call to the elasticity controller is made asynchronously, |
| 310 TRACE_EVENT_SCOPE_THREAD, | 358 // to minimize divergence between main thread and impl thread event |
| 311 "deltaX", | 359 // handling paths. |
| 312 -wheel_event.deltaX, | 360 base::MessageLoop::current()->PostTask( |
|
jdduke (slow)
2014/11/12 00:55:34
Is this a speculative solution? Or have you observ
ccameron
2014/11/12 02:08:24
This was aelias' suggestion (aelais: please verify
aelias_OOO_until_Jul13
2014/11/12 02:27:41
Yes, I suggested it based on my past experience th
jdduke (slow)
2014/11/12 02:32:24
OK, thanks for the explanation, seems reasonable e
ccameron
2014/11/12 08:15:29
To be clear, that may be the right thing to do, I
| |
| 313 "deltaY", | 361 FROM_HERE, |
| 314 -wheel_event.deltaY); | 362 base::Bind(&InputScrollElasticityController::ObserveWheelEventAndResult, |
| 315 gfx::Point scroll_point(wheel_event.x, wheel_event.y); | 363 scroll_elasticity_controller_->GetWeakPtr(), wheel_event, |
| 316 gfx::Vector2dF scroll_delta(-wheel_event.deltaX, -wheel_event.deltaY); | 364 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 } | 365 } |
| 336 return DID_NOT_HANDLE; | 366 return result; |
| 337 } | 367 } |
| 338 | 368 |
| 339 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollBegin( | 369 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollBegin( |
| 340 const WebGestureEvent& gesture_event) { | 370 const WebGestureEvent& gesture_event) { |
| 341 DCHECK(!gesture_scroll_on_impl_thread_); | 371 DCHECK(!gesture_scroll_on_impl_thread_); |
| 342 #ifndef NDEBUG | 372 #ifndef NDEBUG |
| 343 DCHECK(!expect_scroll_update_end_); | 373 DCHECK(!expect_scroll_update_end_); |
| 344 expect_scroll_update_end_ = true; | 374 expect_scroll_update_end_ = true; |
| 345 #endif | 375 #endif |
| 346 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( | 376 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( |
| (...skipping 510 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. | 887 // trigger a scroll, e.g., with a trivial time delta between fling updates. |
| 858 // Return true in this case to prevent early fling termination. | 888 // Return true in this case to prevent early fling termination. |
| 859 if (std::abs(clipped_increment.width) < kScrollEpsilon && | 889 if (std::abs(clipped_increment.width) < kScrollEpsilon && |
| 860 std::abs(clipped_increment.height) < kScrollEpsilon) | 890 std::abs(clipped_increment.height) < kScrollEpsilon) |
| 861 return true; | 891 return true; |
| 862 | 892 |
| 863 return did_scroll; | 893 return did_scroll; |
| 864 } | 894 } |
| 865 | 895 |
| 866 } // namespace content | 896 } // namespace content |
| OLD | NEW |