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 17 matching lines...) Expand all Loading... | |
28 using blink::WebGestureEvent; | 28 using blink::WebGestureEvent; |
29 using blink::WebInputEvent; | 29 using blink::WebInputEvent; |
30 using blink::WebMouseEvent; | 30 using blink::WebMouseEvent; |
31 using blink::WebMouseWheelEvent; | 31 using blink::WebMouseWheelEvent; |
32 using blink::WebPoint; | 32 using blink::WebPoint; |
33 using blink::WebTouchEvent; | 33 using blink::WebTouchEvent; |
34 using blink::WebTouchPoint; | 34 using blink::WebTouchPoint; |
35 | 35 |
36 namespace { | 36 namespace { |
37 | 37 |
38 const int32_t kEventDispositionUndefined = -1; | |
39 | |
38 // Maximum time between a fling event's timestamp and the first |Animate| call | 40 // Maximum time between a fling event's timestamp and the first |Animate| call |
39 // for the fling curve to use the fling timestamp as the initial animation time. | 41 // for the fling curve to use the fling timestamp as the initial animation time. |
40 // Two frames allows a minor delay between event creation and the first animate. | 42 // Two frames allows a minor delay between event creation and the first animate. |
41 const double kMaxSecondsFromFlingTimestampToFirstAnimate = 2. / 60.; | 43 const double kMaxSecondsFromFlingTimestampToFirstAnimate = 2. / 60.; |
42 | 44 |
43 // Threshold for determining whether a fling scroll delta should have caused the | 45 // Threshold for determining whether a fling scroll delta should have caused the |
44 // client to scroll. | 46 // client to scroll. |
45 const float kScrollEpsilon = 0.1f; | 47 const float kScrollEpsilon = 0.1f; |
46 | 48 |
47 // Minimum fling velocity required for the active fling and new fling for the | 49 // Minimum fling velocity required for the active fling and new fling for the |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
214 #ifndef NDEBUG | 216 #ifndef NDEBUG |
215 expect_scroll_update_end_(false), | 217 expect_scroll_update_end_(false), |
216 #endif | 218 #endif |
217 gesture_scroll_on_impl_thread_(false), | 219 gesture_scroll_on_impl_thread_(false), |
218 gesture_pinch_on_impl_thread_(false), | 220 gesture_pinch_on_impl_thread_(false), |
219 fling_may_be_active_on_main_thread_(false), | 221 fling_may_be_active_on_main_thread_(false), |
220 disallow_horizontal_fling_scroll_(false), | 222 disallow_horizontal_fling_scroll_(false), |
221 disallow_vertical_fling_scroll_(false), | 223 disallow_vertical_fling_scroll_(false), |
222 has_fling_animation_started_(false), | 224 has_fling_animation_started_(false), |
223 smooth_scroll_enabled_(false), | 225 smooth_scroll_enabled_(false), |
224 uma_latency_reporting_enabled_(base::TimeTicks::IsHighResolution()) { | 226 uma_latency_reporting_enabled_(base::TimeTicks::IsHighResolution()), |
227 use_gesture_events_for_mouse_wheel_(true), | |
228 touch_start_result_(kEventDispositionUndefined) { | |
225 DCHECK(client); | 229 DCHECK(client); |
226 input_handler_->BindToClient(this); | 230 input_handler_->BindToClient(this); |
227 cc::ScrollElasticityHelper* scroll_elasticity_helper = | 231 cc::ScrollElasticityHelper* scroll_elasticity_helper = |
228 input_handler_->CreateScrollElasticityHelper(); | 232 input_handler_->CreateScrollElasticityHelper(); |
229 if (scroll_elasticity_helper) { | 233 if (scroll_elasticity_helper) { |
230 scroll_elasticity_controller_.reset( | 234 scroll_elasticity_controller_.reset( |
231 new InputScrollElasticityController(scroll_elasticity_helper)); | 235 new InputScrollElasticityController(scroll_elasticity_helper)); |
232 } | 236 } |
233 } | 237 } |
234 | 238 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 case WebInputEvent::GestureFlingCancel: | 334 case WebInputEvent::GestureFlingCancel: |
331 if (CancelCurrentFling()) | 335 if (CancelCurrentFling()) |
332 return DID_HANDLE; | 336 return DID_HANDLE; |
333 else if (!fling_may_be_active_on_main_thread_) | 337 else if (!fling_may_be_active_on_main_thread_) |
334 return DROP_EVENT; | 338 return DROP_EVENT; |
335 return DID_NOT_HANDLE; | 339 return DID_NOT_HANDLE; |
336 | 340 |
337 case WebInputEvent::TouchStart: | 341 case WebInputEvent::TouchStart: |
338 return HandleTouchStart(static_cast<const WebTouchEvent&>(event)); | 342 return HandleTouchStart(static_cast<const WebTouchEvent&>(event)); |
339 | 343 |
344 case WebInputEvent::TouchMove: | |
345 return HandleTouchMove(static_cast<const WebTouchEvent&>(event)); | |
346 | |
347 case WebInputEvent::TouchEnd: | |
348 return HandleTouchEnd(static_cast<const WebTouchEvent&>(event)); | |
349 | |
340 case WebInputEvent::MouseMove: { | 350 case WebInputEvent::MouseMove: { |
341 const WebMouseEvent& mouse_event = | 351 const WebMouseEvent& mouse_event = |
342 static_cast<const WebMouseEvent&>(event); | 352 static_cast<const WebMouseEvent&>(event); |
343 // TODO(tony): Ignore when mouse buttons are down? | 353 // TODO(tony): Ignore when mouse buttons are down? |
344 // TODO(davemoore): This should never happen, but bug #326635 showed some | 354 // TODO(davemoore): This should never happen, but bug #326635 showed some |
345 // surprising crashes. | 355 // surprising crashes. |
346 CHECK(input_handler_); | 356 CHECK(input_handler_); |
347 input_handler_->MouseMoveAt(gfx::Point(mouse_event.x, mouse_event.y)); | 357 input_handler_->MouseMoveAt(gfx::Point(mouse_event.x, mouse_event.y)); |
348 return DID_NOT_HANDLE; | 358 return DID_NOT_HANDLE; |
349 } | 359 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 #if defined(OS_MACOSX) | 423 #if defined(OS_MACOSX) |
414 // Mac does not smooth scroll wheel events (crbug.com/574283). | 424 // Mac does not smooth scroll wheel events (crbug.com/574283). |
415 return false; | 425 return false; |
416 #else | 426 #else |
417 return smooth_scroll_enabled_ && !event.hasPreciseScrollingDeltas; | 427 return smooth_scroll_enabled_ && !event.hasPreciseScrollingDeltas; |
418 #endif | 428 #endif |
419 } | 429 } |
420 | 430 |
421 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( | 431 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( |
422 const WebMouseWheelEvent& wheel_event) { | 432 const WebMouseWheelEvent& wheel_event) { |
433 if (use_gesture_events_for_mouse_wheel_) { | |
434 cc::EventListenerProperties properties = | |
435 input_handler_->GetEventListenerProperties( | |
436 cc::EventListenerClass::kMouseWheel); | |
437 switch (properties) { | |
438 case cc::EventListenerProperties::kPassive: | |
439 return NON_BLOCKING; | |
440 case cc::EventListenerProperties::kBlockingAndPassive: | |
441 case cc::EventListenerProperties::kBlocking: | |
442 return DID_NOT_HANDLE; | |
443 case cc::EventListenerProperties::kNone: | |
444 return DROP_EVENT; | |
445 default: | |
446 NOTREACHED(); | |
447 return DROP_EVENT; | |
448 } | |
449 } | |
450 return ScrollByMouseWheel(wheel_event); | |
451 } | |
452 | |
453 InputHandlerProxy::EventDisposition InputHandlerProxy::ScrollByMouseWheel( | |
454 const WebMouseWheelEvent& wheel_event) { | |
423 InputHandlerProxy::EventDisposition result = DID_NOT_HANDLE; | 455 InputHandlerProxy::EventDisposition result = DID_NOT_HANDLE; |
424 cc::InputHandlerScrollResult scroll_result; | 456 cc::InputHandlerScrollResult scroll_result; |
425 | 457 |
426 // TODO(ccameron): The rail information should be pushed down into | 458 // TODO(ccameron): The rail information should be pushed down into |
427 // InputHandler. | 459 // InputHandler. |
428 gfx::Vector2dF scroll_delta( | 460 gfx::Vector2dF scroll_delta( |
429 wheel_event.railsMode != WebInputEvent::RailsModeVertical | 461 wheel_event.railsMode != WebInputEvent::RailsModeVertical |
430 ? -wheel_event.deltaX | 462 ? -wheel_event.deltaX |
431 : 0, | 463 : 0, |
432 wheel_event.railsMode != WebInputEvent::RailsModeHorizontal | 464 wheel_event.railsMode != WebInputEvent::RailsModeHorizontal |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
713 return DID_NOT_HANDLE; | 745 return DID_NOT_HANDLE; |
714 } | 746 } |
715 return DROP_EVENT; | 747 return DROP_EVENT; |
716 } | 748 } |
717 } | 749 } |
718 return DID_NOT_HANDLE; | 750 return DID_NOT_HANDLE; |
719 } | 751 } |
720 | 752 |
721 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleTouchStart( | 753 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleTouchStart( |
722 const blink::WebTouchEvent& touch_event) { | 754 const blink::WebTouchEvent& touch_event) { |
723 for (size_t i = 0; i < touch_event.touchesLength; ++i) { | 755 EventDisposition result = DROP_EVENT; |
724 if (touch_event.touches[i].state != WebTouchPoint::StatePressed) | 756 size_t touch_index = 0; |
757 for (; touch_index < touch_event.touchesLength; ++touch_index) { | |
758 if (touch_event.touches[touch_index].state != WebTouchPoint::StatePressed) | |
725 continue; | 759 continue; |
726 if (input_handler_->DoTouchEventsBlockScrollAt( | 760 if (input_handler_->DoTouchEventsBlockScrollAt( |
727 gfx::Point(touch_event.touches[i].position.x, | 761 gfx::Point(touch_event.touches[touch_index].position.x, |
728 touch_event.touches[i].position.y))) { | 762 touch_event.touches[touch_index].position.y))) { |
729 // TODO(rbyers): We should consider still sending the touch events to | 763 result = DID_NOT_HANDLE; |
730 // main asynchronously (crbug.com/455539). | 764 break; |
731 return DID_NOT_HANDLE; | |
732 } | 765 } |
733 } | 766 } |
734 return DROP_EVENT; | 767 |
768 // If |touch_index| has incremented to the length; it wasn't processed. | |
769 if (touch_index == touch_event.touchesLength) { | |
tdresser
2016/02/10 19:37:17
Would it be more straight forward to just check if
dtapuska
2016/02/10 22:05:22
Done.
| |
770 switch (input_handler_->GetEventListenerProperties( | |
771 cc::EventListenerClass::kTouch)) { | |
772 case cc::EventListenerProperties::kPassive: | |
773 result = NON_BLOCKING; | |
774 break; | |
775 case cc::EventListenerProperties::kBlocking: | |
776 // The touch area rects above already have checked whether it hits | |
777 // a blocking region. Since it does not the event can be dropped. | |
778 result = DROP_EVENT; | |
779 break; | |
780 case cc::EventListenerProperties::kBlockingAndPassive: | |
781 // There is at least one passive listener that needs to possibly | |
782 // be notified so it can't be dropped. | |
783 result = NON_BLOCKING; | |
784 break; | |
785 case cc::EventListenerProperties::kNone: | |
786 result = DROP_EVENT; | |
787 break; | |
788 default: | |
789 NOTREACHED(); | |
790 result = DROP_EVENT; | |
791 break; | |
792 } | |
793 } | |
794 | |
795 // Update |touch_start_result_| if |result| generates a higher level | |
796 // of blocking. | |
tdresser
2016/02/10 19:37:17
This is a bit hard to read - maybe add a comment w
dtapuska
2016/02/10 22:05:22
Done.
| |
797 if (touch_start_result_ == kEventDispositionUndefined || | |
798 result == DID_NOT_HANDLE || | |
799 (result == NON_BLOCKING && touch_start_result_ == DROP_EVENT)) | |
800 touch_start_result_ = result; | |
tdresser
2016/02/10 19:37:17
Is this also correct?
if (touch_start_result_ ==
dtapuska
2016/02/10 22:05:22
Done.
| |
801 | |
802 return result; | |
803 } | |
804 | |
805 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleTouchMove( | |
806 const blink::WebTouchEvent& touch_event) { | |
807 if (touch_start_result_ != kEventDispositionUndefined) | |
808 return static_cast<EventDisposition>(touch_start_result_); | |
809 return DID_NOT_HANDLE; | |
810 } | |
811 | |
812 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleTouchEnd( | |
813 const blink::WebTouchEvent& touch_event) { | |
814 if (touch_event.touchesLength == 1) | |
815 touch_start_result_ = kEventDispositionUndefined; | |
816 return DID_NOT_HANDLE; | |
tdresser
2016/02/10 19:37:17
Is this DID_NOT_HANDLE correct?
dtapuska
2016/02/10 22:05:22
Yes; HandleTouchEnd was in the default block befor
tdresser
2016/02/11 14:24:01
Acknowledged.
| |
735 } | 817 } |
736 | 818 |
737 bool InputHandlerProxy::FilterInputEventForFlingBoosting( | 819 bool InputHandlerProxy::FilterInputEventForFlingBoosting( |
738 const WebInputEvent& event) { | 820 const WebInputEvent& event) { |
739 if (!WebInputEvent::isGestureEventType(event.type)) | 821 if (!WebInputEvent::isGestureEventType(event.type)) |
740 return false; | 822 return false; |
741 | 823 |
742 if (!fling_curve_) { | 824 if (!fling_curve_) { |
743 DCHECK(!deferred_fling_cancel_time_seconds_); | 825 DCHECK(!deferred_fling_cancel_time_seconds_); |
744 return false; | 826 return false; |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1068 // flings always go through the normal InputHandler. | 1150 // flings always go through the normal InputHandler. |
1069 if (synchronous_input_handler_ && | 1151 if (synchronous_input_handler_ && |
1070 input_handler_->IsCurrentlyScrollingInnerViewport()) | 1152 input_handler_->IsCurrentlyScrollingInnerViewport()) |
1071 synchronous_input_handler_->SetNeedsSynchronousAnimateInput(); | 1153 synchronous_input_handler_->SetNeedsSynchronousAnimateInput(); |
1072 else | 1154 else |
1073 input_handler_->SetNeedsAnimateInput(); | 1155 input_handler_->SetNeedsAnimateInput(); |
1074 } | 1156 } |
1075 | 1157 |
1076 bool InputHandlerProxy::TouchpadFlingScroll( | 1158 bool InputHandlerProxy::TouchpadFlingScroll( |
1077 const WebFloatSize& increment) { | 1159 const WebFloatSize& increment) { |
1078 WebMouseWheelEvent synthetic_wheel; | 1160 InputHandlerProxy::EventDisposition disposition; |
1079 synthetic_wheel.type = WebInputEvent::MouseWheel; | 1161 cc::EventListenerProperties properties = |
1080 synthetic_wheel.timeStampSeconds = InSecondsF(base::TimeTicks::Now()); | 1162 input_handler_->GetEventListenerProperties( |
1081 synthetic_wheel.deltaX = increment.width; | 1163 cc::EventListenerClass::kMouseWheel); |
1082 synthetic_wheel.deltaY = increment.height; | 1164 switch (properties) { |
1083 synthetic_wheel.hasPreciseScrollingDeltas = true; | 1165 case cc::EventListenerProperties::kPassive: |
1084 synthetic_wheel.x = fling_parameters_.point.x; | 1166 disposition = NON_BLOCKING; |
1085 synthetic_wheel.y = fling_parameters_.point.y; | 1167 break; |
1086 synthetic_wheel.globalX = fling_parameters_.globalPoint.x; | 1168 case cc::EventListenerProperties::kBlocking: |
1087 synthetic_wheel.globalY = fling_parameters_.globalPoint.y; | 1169 disposition = DID_NOT_HANDLE; |
1088 synthetic_wheel.modifiers = fling_parameters_.modifiers; | 1170 break; |
1171 case cc::EventListenerProperties::kNone: { | |
1172 WebMouseWheelEvent synthetic_wheel; | |
1173 synthetic_wheel.type = WebInputEvent::MouseWheel; | |
1174 synthetic_wheel.timeStampSeconds = InSecondsF(base::TimeTicks::Now()); | |
1175 synthetic_wheel.deltaX = increment.width; | |
1176 synthetic_wheel.deltaY = increment.height; | |
1177 synthetic_wheel.hasPreciseScrollingDeltas = true; | |
1178 synthetic_wheel.x = fling_parameters_.point.x; | |
1179 synthetic_wheel.y = fling_parameters_.point.y; | |
1180 synthetic_wheel.globalX = fling_parameters_.globalPoint.x; | |
1181 synthetic_wheel.globalY = fling_parameters_.globalPoint.y; | |
1182 synthetic_wheel.modifiers = fling_parameters_.modifiers; | |
1089 | 1183 |
1090 InputHandlerProxy::EventDisposition disposition = | 1184 disposition = ScrollByMouseWheel(synthetic_wheel); |
1091 HandleInputEvent(synthetic_wheel); | 1185 break; |
1186 } | |
1187 default: | |
1188 NOTREACHED(); | |
1189 return false; | |
1190 } | |
1191 | |
1092 switch (disposition) { | 1192 switch (disposition) { |
1093 case DID_HANDLE: | 1193 case DID_HANDLE: |
1094 return true; | 1194 return true; |
1095 case DROP_EVENT: | 1195 case DROP_EVENT: |
1096 break; | 1196 break; |
1197 case NON_BLOCKING: | |
1198 // TODO(dtapuska): Process the fling on the compositor thread | |
1199 // but post the events to the main thread; for now just pass it to the | |
1200 // main thread. | |
1097 case DID_NOT_HANDLE: | 1201 case DID_NOT_HANDLE: |
1098 TRACE_EVENT_INSTANT0("input", | 1202 TRACE_EVENT_INSTANT0("input", |
1099 "InputHandlerProxy::scrollBy::AbortFling", | 1203 "InputHandlerProxy::scrollBy::AbortFling", |
1100 TRACE_EVENT_SCOPE_THREAD); | 1204 TRACE_EVENT_SCOPE_THREAD); |
1101 // If we got a DID_NOT_HANDLE, that means we need to deliver wheels on the | 1205 // If we got a DID_NOT_HANDLE, that means we need to deliver wheels on the |
1102 // main thread. In this case we need to schedule a commit and transfer the | 1206 // main thread. In this case we need to schedule a commit and transfer the |
1103 // fling curve over to the main thread and run the rest of the wheels from | 1207 // fling curve over to the main thread and run the rest of the wheels from |
1104 // there. This can happen when flinging a page that contains a scrollable | 1208 // there. This can happen when flinging a page that contains a scrollable |
1105 // subarea that we can't scroll on the thread if the fling starts outside | 1209 // subarea that we can't scroll on the thread if the fling starts outside |
1106 // the subarea but then is flung "under" the pointer. | 1210 // the subarea but then is flung "under" the pointer. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1171 // trigger a scroll, e.g., with a trivial time delta between fling updates. | 1275 // trigger a scroll, e.g., with a trivial time delta between fling updates. |
1172 // Return true in this case to prevent early fling termination. | 1276 // Return true in this case to prevent early fling termination. |
1173 if (std::abs(clipped_increment.width) < kScrollEpsilon && | 1277 if (std::abs(clipped_increment.width) < kScrollEpsilon && |
1174 std::abs(clipped_increment.height) < kScrollEpsilon) | 1278 std::abs(clipped_increment.height) < kScrollEpsilon) |
1175 return true; | 1279 return true; |
1176 | 1280 |
1177 return did_scroll; | 1281 return did_scroll; |
1178 } | 1282 } |
1179 | 1283 |
1180 } // namespace ui | 1284 } // namespace ui |
OLD | NEW |