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 "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 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 "Event.Latency.RendererImpl.GestureFlingStart", | 201 "Event.Latency.RendererImpl.GestureFlingStart", |
202 delta.InMicroseconds(), 1, 1000000, 100); | 202 delta.InMicroseconds(), 1, 1000000, 100); |
203 break; | 203 break; |
204 default: | 204 default: |
205 NOTREACHED(); | 205 NOTREACHED(); |
206 break; | 206 break; |
207 } | 207 } |
208 } | 208 } |
209 } | 209 } |
210 | 210 |
211 cc::InputHandler::ScrollInputType GestureScrollInputType( | |
212 blink::WebGestureDevice device) { | |
213 return device == blink::WebGestureDeviceTouchpad | |
214 ? cc::InputHandler::WHEEL | |
215 : cc::InputHandler::TOUCHSCREEN; | |
216 } | |
217 | |
211 } // namespace | 218 } // namespace |
212 | 219 |
213 namespace ui { | 220 namespace ui { |
214 | 221 |
215 InputHandlerProxy::InputHandlerProxy(cc::InputHandler* input_handler, | 222 InputHandlerProxy::InputHandlerProxy(cc::InputHandler* input_handler, |
216 InputHandlerProxyClient* client) | 223 InputHandlerProxyClient* client) |
217 : client_(client), | 224 : client_(client), |
218 input_handler_(input_handler), | 225 input_handler_(input_handler), |
219 deferred_fling_cancel_time_seconds_(0), | 226 deferred_fling_cancel_time_seconds_(0), |
220 synchronous_input_handler_(nullptr), | 227 synchronous_input_handler_(nullptr), |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount); | 424 cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount); |
418 } else { | 425 } else { |
419 UMA_HISTOGRAM_ENUMERATION( | 426 UMA_HISTOGRAM_ENUMERATION( |
420 kWheelHistogramName, i + 1, | 427 kWheelHistogramName, i + 1, |
421 cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount); | 428 cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount); |
422 } | 429 } |
423 } | 430 } |
424 } | 431 } |
425 } | 432 } |
426 | 433 |
427 bool InputHandlerProxy::ShouldAnimate( | 434 bool InputHandlerProxy::ShouldAnimate(bool has_precise_scroll_deltas) const { |
428 const blink::WebMouseWheelEvent& event) const { | |
429 #if defined(OS_MACOSX) | 435 #if defined(OS_MACOSX) |
430 // Mac does not smooth scroll wheel events (crbug.com/574283). | 436 // Mac does not smooth scroll wheel events (crbug.com/574283). |
431 return false; | 437 return false; |
432 #else | 438 #else |
433 return smooth_scroll_enabled_ && !event.hasPreciseScrollingDeltas; | 439 return smooth_scroll_enabled_ && !has_precise_scroll_deltas; |
434 #endif | 440 #endif |
435 } | 441 } |
436 | 442 |
437 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( | 443 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( |
438 const WebMouseWheelEvent& wheel_event) { | 444 const WebMouseWheelEvent& wheel_event) { |
439 // Only call |CancelCurrentFling()| if a fling was active, as it will | 445 // Only call |CancelCurrentFling()| if a fling was active, as it will |
440 // otherwise disrupt an in-progress touch scroll. | 446 // otherwise disrupt an in-progress touch scroll. |
441 if (!wheel_event.hasPreciseScrollingDeltas && fling_curve_) | 447 if (!wheel_event.hasPreciseScrollingDeltas && fling_curve_) |
442 CancelCurrentFling(); | 448 CancelCurrentFling(); |
443 | 449 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 // TODO(jamesr): We don't properly handle scroll by page in the compositor | 486 // TODO(jamesr): We don't properly handle scroll by page in the compositor |
481 // thread, so punt it to the main thread. http://crbug.com/236639 | 487 // thread, so punt it to the main thread. http://crbug.com/236639 |
482 result = DID_NOT_HANDLE; | 488 result = DID_NOT_HANDLE; |
483 RecordMainThreadScrollingReasons( | 489 RecordMainThreadScrollingReasons( |
484 wheel_event.type, cc::MainThreadScrollingReason::kPageBasedScrolling); | 490 wheel_event.type, cc::MainThreadScrollingReason::kPageBasedScrolling); |
485 | 491 |
486 } else if (!wheel_event.canScroll) { | 492 } else if (!wheel_event.canScroll) { |
487 // Wheel events with |canScroll| == false will not trigger scrolling, | 493 // Wheel events with |canScroll| == false will not trigger scrolling, |
488 // only event handlers. Forward to the main thread. | 494 // only event handlers. Forward to the main thread. |
489 result = DID_NOT_HANDLE; | 495 result = DID_NOT_HANDLE; |
490 } else if (ShouldAnimate(wheel_event)) { | 496 } else if (ShouldAnimate(wheel_event.hasPreciseScrollingDeltas)) { |
491 cc::InputHandler::ScrollStatus scroll_status = | 497 cc::InputHandler::ScrollStatus scroll_status = |
492 input_handler_->ScrollAnimated(gfx::Point(wheel_event.x, wheel_event.y), | 498 input_handler_->ScrollAnimated(gfx::Point(wheel_event.x, wheel_event.y), |
493 scroll_delta); | 499 scroll_delta); |
494 | 500 |
495 RecordMainThreadScrollingReasons( | 501 RecordMainThreadScrollingReasons( |
496 wheel_event.type, scroll_status.main_thread_scrolling_reasons); | 502 wheel_event.type, scroll_status.main_thread_scrolling_reasons); |
497 | 503 |
498 switch (scroll_status.thread) { | 504 switch (scroll_status.thread) { |
499 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: | 505 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: |
500 result = DID_HANDLE; | 506 result = DID_HANDLE; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
585 expect_scroll_update_end_ = true; | 591 expect_scroll_update_end_ = true; |
586 #endif | 592 #endif |
587 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); | 593 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); |
588 cc::InputHandler::ScrollStatus scroll_status; | 594 cc::InputHandler::ScrollStatus scroll_status; |
589 if (gesture_event.data.scrollBegin.deltaHintUnits == | 595 if (gesture_event.data.scrollBegin.deltaHintUnits == |
590 blink::WebGestureEvent::ScrollUnits::Page) { | 596 blink::WebGestureEvent::ScrollUnits::Page) { |
591 scroll_status.thread = cc::InputHandler::SCROLL_ON_MAIN_THREAD; | 597 scroll_status.thread = cc::InputHandler::SCROLL_ON_MAIN_THREAD; |
592 scroll_status.main_thread_scrolling_reasons = | 598 scroll_status.main_thread_scrolling_reasons = |
593 cc::MainThreadScrollingReason::kContinuingMainThreadScroll; | 599 cc::MainThreadScrollingReason::kContinuingMainThreadScroll; |
594 } else if (gesture_event.data.scrollBegin.targetViewport) { | 600 } else if (gesture_event.data.scrollBegin.targetViewport) { |
595 scroll_status = input_handler_->RootScrollBegin(&scroll_state, | 601 scroll_status = input_handler_->RootScrollBegin( |
596 cc::InputHandler::GESTURE); | 602 &scroll_state, GestureScrollInputType(gesture_event.sourceDevice)); |
597 } else if (smooth_scroll_enabled_ && | 603 } else if (ShouldAnimate(gesture_event.data.scrollBegin.deltaHintUnits != |
598 gesture_event.data.scrollBegin.deltaHintUnits == | 604 blink::WebGestureEvent::ScrollUnits::Pixels)) { |
599 blink::WebGestureEvent::ScrollUnits::Pixels) { | 605 gfx::Point scroll_point(gesture_event.x, gesture_event.y); |
600 // Generate a scroll begin/end combination to determine if | 606 scroll_status = input_handler_->ScrollAnimatedBegin(scroll_point); |
601 // this can actually be handled by the impl thread or not. But | 607 } else { |
602 // don't generate any scroll yet; GestureScrollUpdate will generate | |
603 // the scroll animation. | |
604 scroll_status = input_handler_->ScrollBegin( | 608 scroll_status = input_handler_->ScrollBegin( |
605 &scroll_state, cc::InputHandler::ANIMATED_WHEEL); | 609 &scroll_state, GestureScrollInputType(gesture_event.sourceDevice)); |
606 if (scroll_status.thread == cc::InputHandler::SCROLL_ON_IMPL_THREAD) { | |
607 cc::ScrollStateData scroll_state_end_data; | |
608 scroll_state_end_data.is_ending = true; | |
609 cc::ScrollState scroll_state_end(scroll_state_end_data); | |
610 input_handler_->ScrollEnd(&scroll_state_end); | |
611 } | |
612 } else { | |
613 scroll_status = | |
614 input_handler_->ScrollBegin(&scroll_state, cc::InputHandler::GESTURE); | |
615 } | 610 } |
616 UMA_HISTOGRAM_ENUMERATION("Renderer4.CompositorScrollHitTestResult", | 611 UMA_HISTOGRAM_ENUMERATION("Renderer4.CompositorScrollHitTestResult", |
617 scroll_status.thread, | 612 scroll_status.thread, |
618 cc::InputHandler::LAST_SCROLL_STATUS + 1); | 613 cc::InputHandler::LAST_SCROLL_STATUS + 1); |
619 | 614 |
620 RecordMainThreadScrollingReasons(gesture_event.type, | 615 RecordMainThreadScrollingReasons(gesture_event.type, |
621 scroll_status.main_thread_scrolling_reasons); | 616 scroll_status.main_thread_scrolling_reasons); |
622 | 617 |
618 InputHandlerProxy::EventDisposition result = DID_NOT_HANDLE; | |
623 switch (scroll_status.thread) { | 619 switch (scroll_status.thread) { |
624 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: | 620 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: |
625 TRACE_EVENT_INSTANT0("input", | 621 TRACE_EVENT_INSTANT0("input", |
626 "InputHandlerProxy::handle_input gesture scroll", | 622 "InputHandlerProxy::handle_input gesture scroll", |
627 TRACE_EVENT_SCOPE_THREAD); | 623 TRACE_EVENT_SCOPE_THREAD); |
628 gesture_scroll_on_impl_thread_ = true; | 624 gesture_scroll_on_impl_thread_ = true; |
629 return DID_HANDLE; | 625 result = DID_HANDLE; |
626 break; | |
630 case cc::InputHandler::SCROLL_UNKNOWN: | 627 case cc::InputHandler::SCROLL_UNKNOWN: |
631 case cc::InputHandler::SCROLL_ON_MAIN_THREAD: | 628 case cc::InputHandler::SCROLL_ON_MAIN_THREAD: |
632 return DID_NOT_HANDLE; | 629 result = DID_NOT_HANDLE; |
630 break; | |
633 case cc::InputHandler::SCROLL_IGNORED: | 631 case cc::InputHandler::SCROLL_IGNORED: |
634 return DROP_EVENT; | 632 result = DROP_EVENT; |
633 break; | |
635 } | 634 } |
636 return DID_NOT_HANDLE; | 635 if (scroll_elasticity_controller_ && result != DID_NOT_HANDLE) |
636 HandleScrollElasticityOverscroll(gesture_event, | |
637 cc::InputHandlerScrollResult()); | |
638 | |
639 return result; | |
637 } | 640 } |
638 | 641 |
639 InputHandlerProxy::EventDisposition | 642 InputHandlerProxy::EventDisposition |
640 InputHandlerProxy::HandleGestureScrollUpdate( | 643 InputHandlerProxy::HandleGestureScrollUpdate( |
641 const WebGestureEvent& gesture_event) { | 644 const WebGestureEvent& gesture_event) { |
642 #ifndef NDEBUG | 645 #ifndef NDEBUG |
643 DCHECK(expect_scroll_update_end_); | 646 DCHECK(expect_scroll_update_end_); |
644 #endif | 647 #endif |
645 if (!gesture_scroll_on_impl_thread_ && !gesture_pinch_on_impl_thread_) | 648 if (!gesture_scroll_on_impl_thread_ && !gesture_pinch_on_impl_thread_) |
646 return DID_NOT_HANDLE; | 649 return DID_NOT_HANDLE; |
647 | 650 |
648 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); | 651 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); |
649 gfx::Point scroll_point(gesture_event.x, gesture_event.y); | 652 gfx::Point scroll_point(gesture_event.x, gesture_event.y); |
650 gfx::Vector2dF scroll_delta(-gesture_event.data.scrollUpdate.deltaX, | 653 gfx::Vector2dF scroll_delta(-gesture_event.data.scrollUpdate.deltaX, |
651 -gesture_event.data.scrollUpdate.deltaY); | 654 -gesture_event.data.scrollUpdate.deltaY); |
652 | 655 |
653 if (smooth_scroll_enabled_ && | 656 if (ShouldAnimate(gesture_event.data.scrollUpdate.deltaUnits != |
654 gesture_event.data.scrollUpdate.deltaUnits == | 657 blink::WebGestureEvent::ScrollUnits::Pixels)) { |
655 blink::WebGestureEvent::ScrollUnits::Pixels) { | |
656 switch (input_handler_->ScrollAnimated(scroll_point, scroll_delta).thread) { | 658 switch (input_handler_->ScrollAnimated(scroll_point, scroll_delta).thread) { |
657 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: | 659 case cc::InputHandler::SCROLL_ON_IMPL_THREAD: |
658 return DID_HANDLE; | 660 return DID_HANDLE; |
659 case cc::InputHandler::SCROLL_IGNORED: | 661 case cc::InputHandler::SCROLL_IGNORED: |
660 return DROP_EVENT; | 662 return DROP_EVENT; |
661 default: | 663 default: |
662 return DID_NOT_HANDLE; | 664 return DID_NOT_HANDLE; |
663 } | 665 } |
664 } | 666 } |
665 cc::InputHandlerScrollResult scroll_result = | 667 cc::InputHandlerScrollResult scroll_result = |
666 input_handler_->ScrollBy(&scroll_state); | 668 input_handler_->ScrollBy(&scroll_state); |
667 HandleOverscroll(scroll_point, scroll_result); | 669 HandleOverscroll(scroll_point, scroll_result); |
670 | |
671 if (scroll_elasticity_controller_) | |
672 HandleScrollElasticityOverscroll(gesture_event, scroll_result); | |
673 | |
668 return scroll_result.did_scroll ? DID_HANDLE : DROP_EVENT; | 674 return scroll_result.did_scroll ? DID_HANDLE : DROP_EVENT; |
669 } | 675 } |
670 | 676 |
671 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollEnd( | 677 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureScrollEnd( |
672 const WebGestureEvent& gesture_event) { | 678 const WebGestureEvent& gesture_event) { |
673 #ifndef NDEBUG | 679 #ifndef NDEBUG |
674 DCHECK(expect_scroll_update_end_); | 680 DCHECK(expect_scroll_update_end_); |
675 expect_scroll_update_end_ = false; | 681 expect_scroll_update_end_ = false; |
676 #endif | 682 #endif |
677 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); | 683 if (ShouldAnimate(gesture_event.data.scrollEnd.deltaUnits != |
678 input_handler_->ScrollEnd(&scroll_state); | 684 blink::WebGestureEvent::ScrollUnits::Pixels)) { |
685 // Do nothing if the scroll is being animated; the scroll animation will | |
686 // generate | |
687 // the ScrollEnd when it is done. | |
tdresser
2016/03/09 14:30:06
Line wrapping is weird here.
dtapuska
2016/03/09 16:12:29
Done.
| |
688 } else { | |
689 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); | |
690 input_handler_->ScrollEnd(&scroll_state); | |
691 } | |
679 if (!gesture_scroll_on_impl_thread_) | 692 if (!gesture_scroll_on_impl_thread_) |
680 return DID_NOT_HANDLE; | 693 return DID_NOT_HANDLE; |
694 | |
695 if (scroll_elasticity_controller_) | |
696 HandleScrollElasticityOverscroll(gesture_event, | |
697 cc::InputHandlerScrollResult()); | |
698 | |
681 gesture_scroll_on_impl_thread_ = false; | 699 gesture_scroll_on_impl_thread_ = false; |
682 return DID_HANDLE; | 700 return DID_HANDLE; |
683 } | 701 } |
684 | 702 |
685 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureFlingStart( | 703 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureFlingStart( |
686 const WebGestureEvent& gesture_event) { | 704 const WebGestureEvent& gesture_event) { |
687 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); | 705 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); |
688 cc::InputHandler::ScrollStatus scroll_status; | 706 cc::InputHandler::ScrollStatus scroll_status; |
689 scroll_status.main_thread_scrolling_reasons = | 707 scroll_status.main_thread_scrolling_reasons = |
690 cc::MainThreadScrollingReason::kNotScrollingOnMain; | 708 cc::MainThreadScrollingReason::kNotScrollingOnMain; |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
883 switch (gesture_event.type) { | 901 switch (gesture_event.type) { |
884 case WebInputEvent::GestureTapCancel: | 902 case WebInputEvent::GestureTapCancel: |
885 case WebInputEvent::GestureTapDown: | 903 case WebInputEvent::GestureTapDown: |
886 return false; | 904 return false; |
887 | 905 |
888 case WebInputEvent::GestureScrollBegin: | 906 case WebInputEvent::GestureScrollBegin: |
889 if (!input_handler_->IsCurrentlyScrollingLayerAt( | 907 if (!input_handler_->IsCurrentlyScrollingLayerAt( |
890 gfx::Point(gesture_event.x, gesture_event.y), | 908 gfx::Point(gesture_event.x, gesture_event.y), |
891 fling_parameters_.sourceDevice == blink::WebGestureDeviceTouchpad | 909 fling_parameters_.sourceDevice == blink::WebGestureDeviceTouchpad |
892 ? cc::InputHandler::NON_BUBBLING_GESTURE | 910 ? cc::InputHandler::NON_BUBBLING_GESTURE |
893 : cc::InputHandler::GESTURE)) { | 911 : cc::InputHandler::TOUCHSCREEN)) { |
894 CancelCurrentFling(); | 912 CancelCurrentFling(); |
895 return false; | 913 return false; |
896 } | 914 } |
897 | 915 |
898 // TODO(jdduke): Use |gesture_event.data.scrollBegin.delta{X,Y}Hint| to | 916 // TODO(jdduke): Use |gesture_event.data.scrollBegin.delta{X,Y}Hint| to |
899 // determine if the ScrollBegin should immediately cancel the fling. | 917 // determine if the ScrollBegin should immediately cancel the fling. |
900 ExtendBoostedFlingTimeout(gesture_event); | 918 ExtendBoostedFlingTimeout(gesture_event); |
901 return true; | 919 return true; |
902 | 920 |
903 case WebInputEvent::GestureScrollUpdate: { | 921 case WebInputEvent::GestureScrollUpdate: { |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1303 // It's possible the provided |increment| is sufficiently small as to not | 1321 // It's possible the provided |increment| is sufficiently small as to not |
1304 // trigger a scroll, e.g., with a trivial time delta between fling updates. | 1322 // trigger a scroll, e.g., with a trivial time delta between fling updates. |
1305 // Return true in this case to prevent early fling termination. | 1323 // Return true in this case to prevent early fling termination. |
1306 if (std::abs(clipped_increment.width) < kScrollEpsilon && | 1324 if (std::abs(clipped_increment.width) < kScrollEpsilon && |
1307 std::abs(clipped_increment.height) < kScrollEpsilon) | 1325 std::abs(clipped_increment.height) < kScrollEpsilon) |
1308 return true; | 1326 return true; |
1309 | 1327 |
1310 return did_scroll; | 1328 return did_scroll; |
1311 } | 1329 } |
1312 | 1330 |
1331 void InputHandlerProxy::HandleScrollElasticityOverscroll( | |
1332 const WebGestureEvent& gesture_event, | |
1333 const cc::InputHandlerScrollResult& scroll_result) { | |
1334 DCHECK(scroll_elasticity_controller_); | |
1335 // Send the event and its disposition to the elasticity controller to update | |
1336 // the over-scroll animation. Note that the call to the elasticity controller | |
1337 // is made asynchronously, to minimize divergence between main thread and | |
1338 // impl thread event handling paths. | |
1339 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
1340 FROM_HERE, | |
1341 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult, | |
1342 scroll_elasticity_controller_->GetWeakPtr(), gesture_event, | |
1343 scroll_result)); | |
1344 } | |
1345 | |
1313 } // namespace ui | 1346 } // namespace ui |
OLD | NEW |