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

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

Issue 1749343004: Implement Wheel Gesture Scrolling on OSX. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Ensure only high precision scroll begins are used Created 4 years, 9 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_unittest.cc » ('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
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 the ScrollEnd when it is done.
687 } else {
688 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event);
689 input_handler_->ScrollEnd(&scroll_state);
690 }
679 if (!gesture_scroll_on_impl_thread_) 691 if (!gesture_scroll_on_impl_thread_)
680 return DID_NOT_HANDLE; 692 return DID_NOT_HANDLE;
693
694 if (scroll_elasticity_controller_)
695 HandleScrollElasticityOverscroll(gesture_event,
696 cc::InputHandlerScrollResult());
697
681 gesture_scroll_on_impl_thread_ = false; 698 gesture_scroll_on_impl_thread_ = false;
682 return DID_HANDLE; 699 return DID_HANDLE;
683 } 700 }
684 701
685 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureFlingStart( 702 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleGestureFlingStart(
686 const WebGestureEvent& gesture_event) { 703 const WebGestureEvent& gesture_event) {
687 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event); 704 cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event);
688 cc::InputHandler::ScrollStatus scroll_status; 705 cc::InputHandler::ScrollStatus scroll_status;
689 scroll_status.main_thread_scrolling_reasons = 706 scroll_status.main_thread_scrolling_reasons =
690 cc::MainThreadScrollingReason::kNotScrollingOnMain; 707 cc::MainThreadScrollingReason::kNotScrollingOnMain;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 switch (gesture_event.type) { 900 switch (gesture_event.type) {
884 case WebInputEvent::GestureTapCancel: 901 case WebInputEvent::GestureTapCancel:
885 case WebInputEvent::GestureTapDown: 902 case WebInputEvent::GestureTapDown:
886 return false; 903 return false;
887 904
888 case WebInputEvent::GestureScrollBegin: 905 case WebInputEvent::GestureScrollBegin:
889 if (!input_handler_->IsCurrentlyScrollingLayerAt( 906 if (!input_handler_->IsCurrentlyScrollingLayerAt(
890 gfx::Point(gesture_event.x, gesture_event.y), 907 gfx::Point(gesture_event.x, gesture_event.y),
891 fling_parameters_.sourceDevice == blink::WebGestureDeviceTouchpad 908 fling_parameters_.sourceDevice == blink::WebGestureDeviceTouchpad
892 ? cc::InputHandler::NON_BUBBLING_GESTURE 909 ? cc::InputHandler::NON_BUBBLING_GESTURE
893 : cc::InputHandler::GESTURE)) { 910 : cc::InputHandler::TOUCHSCREEN)) {
894 CancelCurrentFling(); 911 CancelCurrentFling();
895 return false; 912 return false;
896 } 913 }
897 914
898 // TODO(jdduke): Use |gesture_event.data.scrollBegin.delta{X,Y}Hint| to 915 // TODO(jdduke): Use |gesture_event.data.scrollBegin.delta{X,Y}Hint| to
899 // determine if the ScrollBegin should immediately cancel the fling. 916 // determine if the ScrollBegin should immediately cancel the fling.
900 ExtendBoostedFlingTimeout(gesture_event); 917 ExtendBoostedFlingTimeout(gesture_event);
901 return true; 918 return true;
902 919
903 case WebInputEvent::GestureScrollUpdate: { 920 case WebInputEvent::GestureScrollUpdate: {
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 // It's possible the provided |increment| is sufficiently small as to not 1320 // 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. 1321 // trigger a scroll, e.g., with a trivial time delta between fling updates.
1305 // Return true in this case to prevent early fling termination. 1322 // Return true in this case to prevent early fling termination.
1306 if (std::abs(clipped_increment.width) < kScrollEpsilon && 1323 if (std::abs(clipped_increment.width) < kScrollEpsilon &&
1307 std::abs(clipped_increment.height) < kScrollEpsilon) 1324 std::abs(clipped_increment.height) < kScrollEpsilon)
1308 return true; 1325 return true;
1309 1326
1310 return did_scroll; 1327 return did_scroll;
1311 } 1328 }
1312 1329
1330 void InputHandlerProxy::HandleScrollElasticityOverscroll(
1331 const WebGestureEvent& gesture_event,
1332 const cc::InputHandlerScrollResult& scroll_result) {
1333 DCHECK(scroll_elasticity_controller_);
1334 // Send the event and its disposition to the elasticity controller to update
1335 // the over-scroll animation. Note that the call to the elasticity controller
1336 // is made asynchronously, to minimize divergence between main thread and
1337 // impl thread event handling paths.
1338 base::ThreadTaskRunnerHandle::Get()->PostTask(
1339 FROM_HERE,
1340 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult,
1341 scroll_elasticity_controller_->GetWeakPtr(), gesture_event,
1342 scroll_result));
1343 }
1344
1313 } // 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_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698