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 |