Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: ui/events/blink/input_handler_proxy.cc

Issue 2362863003: Handle touchpad flings with passive event listeners on compositor thread. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/events/blink/input_handler_proxy.h ('k') | ui/events/blink/input_handler_proxy_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "ui/events/blink/input_handler_proxy.h" 5 #include "ui/events/blink/input_handler_proxy.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "base/auto_reset.h" 11 #include "base/auto_reset.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/threading/thread_task_runner_handle.h" 17 #include "base/threading/thread_task_runner_handle.h"
18 #include "base/trace_event/trace_event.h" 18 #include "base/trace_event/trace_event.h"
19 #include "cc/input/main_thread_scrolling_reason.h" 19 #include "cc/input/main_thread_scrolling_reason.h"
20 #include "third_party/WebKit/public/platform/WebInputEvent.h" 20 #include "third_party/WebKit/public/platform/WebInputEvent.h"
21 #include "ui/events/blink/did_overscroll_params.h" 21 #include "ui/events/blink/did_overscroll_params.h"
22 #include "ui/events/blink/input_handler_proxy_client.h" 22 #include "ui/events/blink/input_handler_proxy_client.h"
23 #include "ui/events/blink/input_scroll_elasticity_controller.h" 23 #include "ui/events/blink/input_scroll_elasticity_controller.h"
24 #include "ui/events/blink/web_input_event_traits.h"
24 #include "ui/events/latency_info.h" 25 #include "ui/events/latency_info.h"
25 #include "ui/gfx/geometry/point_conversions.h" 26 #include "ui/gfx/geometry/point_conversions.h"
26 27
27 using blink::WebFloatPoint; 28 using blink::WebFloatPoint;
28 using blink::WebFloatSize; 29 using blink::WebFloatSize;
29 using blink::WebGestureEvent; 30 using blink::WebGestureEvent;
30 using blink::WebInputEvent; 31 using blink::WebInputEvent;
31 using blink::WebMouseEvent; 32 using blink::WebMouseEvent;
32 using blink::WebMouseWheelEvent; 33 using blink::WebMouseWheelEvent;
33 using blink::WebPoint; 34 using blink::WebPoint;
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 return DID_NOT_HANDLE; 468 return DID_NOT_HANDLE;
468 case cc::EventListenerProperties::kNone: 469 case cc::EventListenerProperties::kNone:
469 return DROP_EVENT; 470 return DROP_EVENT;
470 default: 471 default:
471 NOTREACHED(); 472 NOTREACHED();
472 return DROP_EVENT; 473 return DROP_EVENT;
473 } 474 }
474 } 475 }
475 476
476 InputHandlerProxy::EventDisposition InputHandlerProxy::ScrollByMouseWheel( 477 InputHandlerProxy::EventDisposition InputHandlerProxy::ScrollByMouseWheel(
477 const WebMouseWheelEvent& wheel_event) { 478 const WebMouseWheelEvent& wheel_event,
478 InputHandlerProxy::EventDisposition result = DID_NOT_HANDLE; 479 cc::EventListenerProperties listener_properties) {
479 cc::InputHandlerScrollResult scroll_result; 480 DCHECK(listener_properties == cc::EventListenerProperties::kPassive ||
481 listener_properties == cc::EventListenerProperties::kNone);
480 482
481 // TODO(ccameron): The rail information should be pushed down into 483 // TODO(ccameron): The rail information should be pushed down into
482 // InputHandler. 484 // InputHandler.
483 gfx::Vector2dF scroll_delta( 485 gfx::Vector2dF scroll_delta(
484 wheel_event.railsMode != WebInputEvent::RailsModeVertical 486 wheel_event.railsMode != WebInputEvent::RailsModeVertical
485 ? -wheel_event.deltaX 487 ? -wheel_event.deltaX
486 : 0, 488 : 0,
487 wheel_event.railsMode != WebInputEvent::RailsModeHorizontal 489 wheel_event.railsMode != WebInputEvent::RailsModeHorizontal
488 ? -wheel_event.deltaY 490 ? -wheel_event.deltaY
489 : 0); 491 : 0);
490 492
491 if (wheel_event.scrollByPage) { 493 if (wheel_event.scrollByPage) {
492 // TODO(jamesr): We don't properly handle scroll by page in the compositor 494 // TODO(jamesr): We don't properly handle scroll by page in the compositor
493 // thread, so punt it to the main thread. http://crbug.com/236639 495 // thread, so punt it to the main thread. http://crbug.com/236639
494 result = DID_NOT_HANDLE;
495 RecordMainThreadScrollingReasons( 496 RecordMainThreadScrollingReasons(
496 blink::WebGestureDeviceTouchpad, 497 blink::WebGestureDeviceTouchpad,
497 cc::MainThreadScrollingReason::kPageBasedScrolling); 498 cc::MainThreadScrollingReason::kPageBasedScrolling);
498 499 return DID_NOT_HANDLE;
499 } else { 500 } else {
500 DCHECK(!ShouldAnimate(wheel_event.hasPreciseScrollingDeltas)); 501 DCHECK(!ShouldAnimate(wheel_event.hasPreciseScrollingDeltas));
501 cc::ScrollStateData scroll_state_begin_data; 502 cc::ScrollStateData scroll_state_begin_data;
502 scroll_state_begin_data.position_x = wheel_event.x; 503 scroll_state_begin_data.position_x = wheel_event.x;
503 scroll_state_begin_data.position_y = wheel_event.y; 504 scroll_state_begin_data.position_y = wheel_event.y;
504 scroll_state_begin_data.is_beginning = true; 505 scroll_state_begin_data.is_beginning = true;
505 cc::ScrollState scroll_state_begin(scroll_state_begin_data); 506 cc::ScrollState scroll_state_begin(scroll_state_begin_data);
506 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin( 507 cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin(
507 &scroll_state_begin, cc::InputHandler::WHEEL); 508 &scroll_state_begin, cc::InputHandler::WHEEL);
508 509
509 RecordMainThreadScrollingReasons( 510 RecordMainThreadScrollingReasons(
510 blink::WebGestureDeviceTouchpad, 511 blink::WebGestureDeviceTouchpad,
511 scroll_status.main_thread_scrolling_reasons); 512 scroll_status.main_thread_scrolling_reasons);
512 513
513 switch (scroll_status.thread) { 514 switch (scroll_status.thread) {
514 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: { 515 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: {
515 TRACE_EVENT_INSTANT2("input", 516 TRACE_EVENT_INSTANT2("input",
516 "InputHandlerProxy::handle_input wheel scroll", 517 "InputHandlerProxy::handle_input wheel scroll",
517 TRACE_EVENT_SCOPE_THREAD, "deltaX", 518 TRACE_EVENT_SCOPE_THREAD, "deltaX",
518 scroll_delta.x(), "deltaY", scroll_delta.y()); 519 scroll_delta.x(), "deltaY", scroll_delta.y());
519 520
520 cc::ScrollStateData scroll_state_update_data; 521 cc::ScrollStateData scroll_state_update_data;
521 scroll_state_update_data.delta_x = scroll_delta.x(); 522 scroll_state_update_data.delta_x = scroll_delta.x();
522 scroll_state_update_data.delta_y = scroll_delta.y(); 523 scroll_state_update_data.delta_y = scroll_delta.y();
523 scroll_state_update_data.position_x = wheel_event.x; 524 scroll_state_update_data.position_x = wheel_event.x;
524 scroll_state_update_data.position_y = wheel_event.y; 525 scroll_state_update_data.position_y = wheel_event.y;
525 cc::ScrollState scroll_state_update(scroll_state_update_data); 526 cc::ScrollState scroll_state_update(scroll_state_update_data);
526 527
527 scroll_result = input_handler_->ScrollBy(&scroll_state_update); 528 cc::InputHandlerScrollResult scroll_result =
529 input_handler_->ScrollBy(&scroll_state_update);
528 HandleOverscroll(gfx::Point(wheel_event.x, wheel_event.y), 530 HandleOverscroll(gfx::Point(wheel_event.x, wheel_event.y),
529 scroll_result); 531 scroll_result);
530 532
531 cc::ScrollStateData scroll_state_end_data; 533 cc::ScrollStateData scroll_state_end_data;
532 scroll_state_end_data.is_ending = true; 534 scroll_state_end_data.is_ending = true;
533 cc::ScrollState scroll_state_end(scroll_state_end_data); 535 cc::ScrollState scroll_state_end(scroll_state_end_data);
534 input_handler_->ScrollEnd(&scroll_state_end); 536 input_handler_->ScrollEnd(&scroll_state_end);
535 537
536 result = scroll_result.did_scroll ? DID_HANDLE : DROP_EVENT; 538 if (scroll_result.did_scroll) {
537 break; 539 return listener_properties == cc::EventListenerProperties::kPassive
540 ? DID_HANDLE_NON_BLOCKING
541 : DID_HANDLE;
542 }
543 return DROP_EVENT;
538 } 544 }
539 case cc::InputHandler::SCROLL_IGNORED: 545 case cc::InputHandler::SCROLL_IGNORED:
540 // TODO(jamesr): This should be DROP_EVENT, but in cases where we fail 546 // TODO(jamesr): This should be DROP_EVENT, but in cases where we fail
541 // to properly sync scrollability it's safer to send the event to the 547 // to properly sync scrollability it's safer to send the event to the
542 // main thread. Change back to DROP_EVENT once we have synchronization 548 // main thread. Change back to DROP_EVENT once we have synchronization
543 // bugs sorted out. 549 // bugs sorted out.
544 result = DID_NOT_HANDLE; 550 return DID_NOT_HANDLE;
545 break;
546 case cc::InputHandler::SCROLL_UNKNOWN: 551 case cc::InputHandler::SCROLL_UNKNOWN:
547 case cc::InputHandler::SCROLL_ON_MAIN_THREAD: 552 case cc::InputHandler::SCROLL_ON_MAIN_THREAD:
548 result = DID_NOT_HANDLE; 553 return DID_NOT_HANDLE;
549 break; 554 default:
555 NOTREACHED();
556 return DID_NOT_HANDLE;
550 } 557 }
551 } 558 }
552 return result;
553 } 559 }
554 560
555 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollBegin( 561 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollBegin(
556 const WebGestureEvent& gesture_event) { 562 const WebGestureEvent& gesture_event) {
557 if (gesture_scroll_on_impl_thread_) 563 if (gesture_scroll_on_impl_thread_)
558 CancelCurrentFling(); 564 CancelCurrentFling();
559 565
560 #ifndef NDEBUG 566 #ifndef NDEBUG
561 DCHECK(!expect_scroll_update_end_); 567 DCHECK(!expect_scroll_update_end_);
562 expect_scroll_update_end_ = true; 568 expect_scroll_update_end_ = true;
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 input_handler_->SetNeedsAnimateInput(); 1196 input_handler_->SetNeedsAnimateInput();
1191 } 1197 }
1192 1198
1193 bool InputHandlerProxy::TouchpadFlingScroll( 1199 bool InputHandlerProxy::TouchpadFlingScroll(
1194 const WebFloatSize& increment) { 1200 const WebFloatSize& increment) {
1195 InputHandlerProxy::EventDisposition disposition; 1201 InputHandlerProxy::EventDisposition disposition;
1196 cc::EventListenerProperties properties = 1202 cc::EventListenerProperties properties =
1197 input_handler_->GetEventListenerProperties( 1203 input_handler_->GetEventListenerProperties(
1198 cc::EventListenerClass::kMouseWheel); 1204 cc::EventListenerClass::kMouseWheel);
1199 switch (properties) { 1205 switch (properties) {
1200 case cc::EventListenerProperties::kPassive:
1201 disposition = DID_HANDLE_NON_BLOCKING;
1202 break;
1203 case cc::EventListenerProperties::kBlocking: 1206 case cc::EventListenerProperties::kBlocking:
1204 disposition = DID_NOT_HANDLE; 1207 disposition = DID_NOT_HANDLE;
1205 break; 1208 break;
1209 case cc::EventListenerProperties::kPassive:
1206 case cc::EventListenerProperties::kNone: { 1210 case cc::EventListenerProperties::kNone: {
1207 WebMouseWheelEvent synthetic_wheel; 1211 WebMouseWheelEvent synthetic_wheel;
1208 synthetic_wheel.type = WebInputEvent::MouseWheel; 1212 synthetic_wheel.type = WebInputEvent::MouseWheel;
1209 synthetic_wheel.timeStampSeconds = InSecondsF(base::TimeTicks::Now()); 1213 synthetic_wheel.timeStampSeconds = InSecondsF(base::TimeTicks::Now());
1210 synthetic_wheel.deltaX = increment.width; 1214 synthetic_wheel.deltaX = increment.width;
1211 synthetic_wheel.deltaY = increment.height; 1215 synthetic_wheel.deltaY = increment.height;
1212 synthetic_wheel.hasPreciseScrollingDeltas = true; 1216 synthetic_wheel.hasPreciseScrollingDeltas = true;
1213 synthetic_wheel.x = fling_parameters_.point.x; 1217 synthetic_wheel.x = fling_parameters_.point.x;
1214 synthetic_wheel.y = fling_parameters_.point.y; 1218 synthetic_wheel.y = fling_parameters_.point.y;
1215 synthetic_wheel.globalX = fling_parameters_.globalPoint.x; 1219 synthetic_wheel.globalX = fling_parameters_.globalPoint.x;
1216 synthetic_wheel.globalY = fling_parameters_.globalPoint.y; 1220 synthetic_wheel.globalY = fling_parameters_.globalPoint.y;
1217 synthetic_wheel.modifiers = fling_parameters_.modifiers; 1221 synthetic_wheel.modifiers = fling_parameters_.modifiers;
1218 1222
1219 disposition = ScrollByMouseWheel(synthetic_wheel); 1223 disposition = ScrollByMouseWheel(synthetic_wheel, properties);
1224
1225 // Send the event over to the main thread.
1226 if (disposition == DID_HANDLE_NON_BLOCKING) {
1227 client_->DispatchNonBlockingEventToMainThread(
1228 ui::WebInputEventTraits::Clone(synthetic_wheel), ui::LatencyInfo());
1229 }
1220 break; 1230 break;
1221 } 1231 }
1222 default: 1232 default:
1223 NOTREACHED(); 1233 NOTREACHED();
1224 return false; 1234 return false;
1225 } 1235 }
1226 1236
1227 switch (disposition) { 1237 switch (disposition) {
1228 case DID_HANDLE: 1238 case DID_HANDLE:
1239 case DID_HANDLE_NON_BLOCKING:
1229 return true; 1240 return true;
1230 case DROP_EVENT: 1241 case DROP_EVENT:
1231 break; 1242 break;
1232 case DID_HANDLE_NON_BLOCKING:
1233 // TODO(dtapuska): Process the fling on the compositor thread
1234 // but post the events to the main thread; for now just pass it to the
1235 // main thread.
1236 case DID_NOT_HANDLE: 1243 case DID_NOT_HANDLE:
1237 TRACE_EVENT_INSTANT0("input", 1244 TRACE_EVENT_INSTANT0("input",
1238 "InputHandlerProxy::scrollBy::AbortFling", 1245 "InputHandlerProxy::scrollBy::AbortFling",
1239 TRACE_EVENT_SCOPE_THREAD); 1246 TRACE_EVENT_SCOPE_THREAD);
1240 // If we got a DID_NOT_HANDLE, that means we need to deliver wheels on the 1247 // If we got a DID_NOT_HANDLE, that means we need to deliver wheels on the
1241 // main thread. In this case we need to schedule a commit and transfer the 1248 // main thread. In this case we need to schedule a commit and transfer the
1242 // fling curve over to the main thread and run the rest of the wheels from 1249 // fling curve over to the main thread and run the rest of the wheels from
1243 // there. This can happen when flinging a page that contains a scrollable 1250 // there. This can happen when flinging a page that contains a scrollable
1244 // subarea that we can't scroll on the thread if the fling starts outside 1251 // subarea that we can't scroll on the thread if the fling starts outside
1245 // the subarea but then is flung "under" the pointer. 1252 // the subarea but then is flung "under" the pointer.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 // is made asynchronously, to minimize divergence between main thread and 1336 // is made asynchronously, to minimize divergence between main thread and
1330 // impl thread event handling paths. 1337 // impl thread event handling paths.
1331 base::ThreadTaskRunnerHandle::Get()->PostTask( 1338 base::ThreadTaskRunnerHandle::Get()->PostTask(
1332 FROM_HERE, 1339 FROM_HERE,
1333 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult, 1340 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult,
1334 scroll_elasticity_controller_->GetWeakPtr(), gesture_event, 1341 scroll_elasticity_controller_->GetWeakPtr(), gesture_event,
1335 scroll_result)); 1342 scroll_result));
1336 } 1343 }
1337 1344
1338 } // namespace ui 1345 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/blink/input_handler_proxy.h ('k') | ui/events/blink/input_handler_proxy_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698