Chromium Code Reviews| Index: content/browser/renderer_host/input/passthrough_touch_event_queue.cc |
| diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue.cc |
| index f7883a3015a7ebb5f940b98915b8fff241c54d4d..a13ccbf51dfc60c013d843d4c448ec8b0b734877 100644 |
| --- a/content/browser/renderer_host/input/passthrough_touch_event_queue.cc |
| +++ b/content/browser/renderer_host/input/passthrough_touch_event_queue.cc |
| @@ -24,6 +24,10 @@ using ui::LatencyInfo; |
| namespace content { |
| namespace { |
| +// A sanity check on touches received to ensure that touch movement outside |
| +// the platform slop region will cause scrolling. |
| +const double kMaxConceivablePlatformSlopRegionLengthDipsSquared = 60. * 60.; |
| + |
| // Compare all properties of touch points to determine the state. |
| bool HasPointChanged(const WebTouchPoint& point_1, |
| const WebTouchPoint& point_2) { |
| @@ -42,6 +46,59 @@ bool HasPointChanged(const WebTouchPoint& point_1, |
| } // namespace |
| +// Provides touchmove slop suppression for a touch sequence until a |
| +// (unprevented) touch will trigger immediate scrolling. |
| +class TouchMoveSlopSuppressor { |
|
tdresser
2017/04/13 18:13:35
Should this move to another file? Or the anonymous
Navid Zolghadr
2017/04/18 14:47:41
This wasn't quite possible. At least I couldn't ge
tdresser
2017/04/18 15:20:26
Acknowledged.
|
| + public: |
| + TouchMoveSlopSuppressor() : suppressing_touchmoves_(false) {} |
| + |
| + bool FilterEvent(const WebTouchEvent& event) { |
| + if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
| + suppressing_touchmoves_ = true; |
| + touch_start_location_ = gfx::PointF(event.touches[0].position); |
| + } |
| + |
| + if (event.GetType() == WebInputEvent::kTouchEnd || |
| + event.GetType() == WebInputEvent::kTouchCancel) |
| + suppressing_touchmoves_ = false; |
| + |
| + if (event.GetType() != WebInputEvent::kTouchMove) |
| + return false; |
| + |
| + if (suppressing_touchmoves_) { |
| + if (event.touches_length > 1) { |
| + suppressing_touchmoves_ = false; |
| + } else if (event.moved_beyond_slop_region) { |
| + suppressing_touchmoves_ = false; |
| + } else { |
| + // No sane slop region should be larger than 60 DIPs. |
| + DCHECK_LT( |
| + (gfx::PointF(event.touches[0].position) - touch_start_location_) |
| + .LengthSquared(), |
| + kMaxConceivablePlatformSlopRegionLengthDipsSquared); |
| + } |
| + } |
| + |
| + return suppressing_touchmoves_; |
| + } |
| + |
| + void ConfirmTouchEvent(InputEventAckState ack_result) { |
| + if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) |
| + suppressing_touchmoves_ = false; |
| + } |
| + |
| + bool suppressing_touchmoves() const { return suppressing_touchmoves_; } |
| + |
| + private: |
| + bool suppressing_touchmoves_; |
| + |
| + // Sanity check that the upstream touch provider is properly reporting whether |
| + // the touch sequence will cause scrolling. |
| + gfx::PointF touch_start_location_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TouchMoveSlopSuppressor); |
| +}; |
| + |
| PassthroughTouchEventQueue::TouchEventWithLatencyInfoAndAckState:: |
| TouchEventWithLatencyInfoAndAckState(const TouchEventWithLatencyInfo& event) |
| : TouchEventWithLatencyInfo(event), |
| @@ -59,6 +116,7 @@ PassthroughTouchEventQueue::PassthroughTouchEventQueue( |
| has_handlers_(true), |
| maybe_has_handler_for_current_sequence_(false), |
| drop_remaining_touches_in_sequence_(false), |
| + touchmove_slop_suppressor_(new TouchMoveSlopSuppressor), |
| send_touch_events_async_(false) { |
| if (config.touch_ack_timeout_supported) { |
| timeout_handler_.reset( |
| @@ -120,6 +178,8 @@ void PassthroughTouchEventQueue::ProcessTouchAck( |
| timeout_handler_->ConfirmTouchEvent(unique_touch_event_id, ack_result)) |
| return; |
| + touchmove_slop_suppressor_->ConfirmTouchEvent(ack_result); |
| + |
| auto touch_event_iter = outstanding_touches_.begin(); |
| while (touch_event_iter != outstanding_touches_.end()) { |
| if (unique_touch_event_id == touch_event_iter->event.unique_touch_event_id) |
| @@ -297,6 +357,9 @@ PassthroughTouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { |
| if (timeout_handler_ && timeout_handler_->FilterEvent(event)) |
| return ACK_WITH_NO_CONSUMER_EXISTS; |
| + if (touchmove_slop_suppressor_->FilterEvent(event)) |
| + return ACK_WITH_NOT_CONSUMED; |
| + |
| if (drop_remaining_touches_in_sequence_ && |
| event.GetType() != WebInputEvent::kTouchCancel) { |
| return ACK_WITH_NO_CONSUMER_EXISTS; |