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

Unified Diff: content/browser/renderer_host/input/passthrough_touch_event_queue.cc

Issue 2816613003: Add suppresion of slop region touches in browser (Closed)
Patch Set: Fix the tests Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698