| 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 ae2131f38b84cd2b8d4aa9db36a4c9421ef34178..b9cc039df19a5282ef8f436436ea6276e7c92afd 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 {
|
| + 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),
|
| processing_acks_(false) {
|
| if (config.touch_ack_timeout_supported) {
|
| @@ -121,6 +179,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)
|
| @@ -303,6 +363,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;
|
|
|