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 |