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

Side by Side Diff: content/browser/renderer_host/input/touch_event_queue.cc

Issue 171283002: Always reset touch action at the beginning of a new gesture sequence (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
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 "content/browser/renderer_host/input/touch_event_queue.h" 5 #include "content/browser/renderer_host/input/touch_event_queue.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 14 matching lines...) Expand all
25 25
26 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( 26 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent(
27 const TouchEventWithLatencyInfo& event_to_cancel) { 27 const TouchEventWithLatencyInfo& event_to_cancel) {
28 TouchEventWithLatencyInfo event = event_to_cancel; 28 TouchEventWithLatencyInfo event = event_to_cancel;
29 event.event.type = WebInputEvent::TouchCancel; 29 event.event.type = WebInputEvent::TouchCancel;
30 for (size_t i = 0; i < event.event.touchesLength; i++) 30 for (size_t i = 0; i < event.event.touchesLength; i++)
31 event.event.touches[i].state = WebTouchPoint::StateCancelled; 31 event.event.touches[i].state = WebTouchPoint::StateCancelled;
32 return event; 32 return event;
33 } 33 }
34 34
35 bool IsNewTouchSequence(const WebTouchEvent& event) {
36 if (event.type != WebInputEvent::TouchStart)
37 return false;
38 if (!event.touchesLength)
39 return false;
40 for (size_t i = 0; i < event.touchesLength; i++) {
41 if (event.touches[i].state != WebTouchPoint::StatePressed)
42 return false;
43 }
44 return true;
45 }
46
47 bool ShouldTouchTypeTriggerTimeout(WebInputEvent::Type type) { 35 bool ShouldTouchTypeTriggerTimeout(WebInputEvent::Type type) {
48 return type == WebInputEvent::TouchStart || 36 return type == WebInputEvent::TouchStart ||
49 type == WebInputEvent::TouchMove; 37 type == WebInputEvent::TouchMove;
50 } 38 }
51 39
52 } // namespace 40 } // namespace
53 41
54 42
55 // Cancels a touch sequence if a touchstart or touchmove ack response is 43 // Cancels a touch sequence if a touchstart or touchmove ack response is
56 // sufficiently delayed. 44 // sufficiently delayed.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT); 107 SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT);
120 touch_queue_->FlushQueue(); 108 touch_queue_->FlushQueue();
121 } 109 }
122 110
123 // Skip a cancel event if the timed-out event had no consumer and was the 111 // Skip a cancel event if the timed-out event had no consumer and was the
124 // initial event in the gesture. 112 // initial event in the gesture.
125 bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const { 113 bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const {
126 DCHECK(HasTimeoutEvent()); 114 DCHECK(HasTimeoutEvent());
127 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) 115 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS)
128 return true; 116 return true;
129 return !IsNewTouchSequence(timeout_event_.event); 117 return !WebInputEventTraits::IsNewTouchSequence(timeout_event_.event);
130 } 118 }
131 119
132 void SetPendingAckState(PendingAckState new_pending_ack_state) { 120 void SetPendingAckState(PendingAckState new_pending_ack_state) {
133 DCHECK_NE(pending_ack_state_, new_pending_ack_state); 121 DCHECK_NE(pending_ack_state_, new_pending_ack_state);
134 switch (new_pending_ack_state) { 122 switch (new_pending_ack_state) {
135 case PENDING_ACK_ORIGINAL_EVENT: 123 case PENDING_ACK_ORIGINAL_EVENT:
136 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); 124 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE);
137 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this); 125 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this);
138 break; 126 break;
139 case PENDING_ACK_CANCEL_EVENT: 127 case PENDING_ACK_CANCEL_EVENT:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 // Provides touchmove slop suppression for a single touch that remains within 163 // Provides touchmove slop suppression for a single touch that remains within
176 // a given slop region, unless the touchstart is preventDefault'ed. 164 // a given slop region, unless the touchstart is preventDefault'ed.
177 class TouchEventQueue::TouchMoveSlopSuppressor { 165 class TouchEventQueue::TouchMoveSlopSuppressor {
178 public: 166 public:
179 TouchMoveSlopSuppressor(double slop_suppression_length_dips) 167 TouchMoveSlopSuppressor(double slop_suppression_length_dips)
180 : slop_suppression_length_dips_squared_(slop_suppression_length_dips * 168 : slop_suppression_length_dips_squared_(slop_suppression_length_dips *
181 slop_suppression_length_dips), 169 slop_suppression_length_dips),
182 suppressing_touch_moves_(false) {} 170 suppressing_touch_moves_(false) {}
183 171
184 bool FilterEvent(const WebTouchEvent& event) { 172 bool FilterEvent(const WebTouchEvent& event) {
185 if (IsNewTouchSequence(event)) { 173 if (WebInputEventTraits::IsNewTouchSequence(event)) {
186 touch_sequence_start_position_ = 174 touch_sequence_start_position_ =
187 gfx::Point(event.touches[0].position); 175 gfx::Point(event.touches[0].position);
188 suppressing_touch_moves_ = slop_suppression_length_dips_squared_ != 0; 176 suppressing_touch_moves_ = slop_suppression_length_dips_squared_ != 0;
189 } 177 }
190 178
191 if (event.type != WebInputEvent::TouchMove) 179 if (event.type != WebInputEvent::TouchMove)
192 return false; 180 return false;
193 181
194 if (suppressing_touch_moves_) { 182 if (suppressing_touch_moves_) {
195 // Movement with a secondary pointer should terminate suppression. 183 // Movement with a secondary pointer should terminate suppression.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { 298 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
311 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent"); 299 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent");
312 300
313 // If the queueing of |event| was triggered by an ack dispatch, defer 301 // If the queueing of |event| was triggered by an ack dispatch, defer
314 // processing the event until the dispatch has finished. 302 // processing the event until the dispatch has finished.
315 if (touch_queue_.empty() && !dispatching_touch_ack_) { 303 if (touch_queue_.empty() && !dispatching_touch_ack_) {
316 // Optimization of the case without touch handlers. Removing this path 304 // Optimization of the case without touch handlers. Removing this path
317 // yields identical results, but this avoids unnecessary allocations. 305 // yields identical results, but this avoids unnecessary allocations.
318 if (touch_filtering_state_ == DROP_ALL_TOUCHES || 306 if (touch_filtering_state_ == DROP_ALL_TOUCHES ||
319 (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE && 307 (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE &&
320 !IsNewTouchSequence(event.event))) { 308 !WebInputEventTraits::IsNewTouchSequence(event.event))) {
321 client_->OnTouchEventAck(event, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); 309 client_->OnTouchEventAck(event, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
322 return; 310 return;
323 } 311 }
324 312
325 // There is no touch event in the queue. Forward it to the renderer 313 // There is no touch event in the queue. Forward it to the renderer
326 // immediately. 314 // immediately.
327 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); 315 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false));
328 TryForwardNextEventToRenderer(); 316 TryForwardNextEventToRenderer();
329 return; 317 return;
330 } 318 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 } 377 }
390 } 378 }
391 379
392 void TouchEventQueue::ForwardToRenderer( 380 void TouchEventQueue::ForwardToRenderer(
393 const TouchEventWithLatencyInfo& touch) { 381 const TouchEventWithLatencyInfo& touch) {
394 TRACE_EVENT0("input", "TouchEventQueue::ForwardToRenderer"); 382 TRACE_EVENT0("input", "TouchEventQueue::ForwardToRenderer");
395 383
396 DCHECK(!dispatching_touch_); 384 DCHECK(!dispatching_touch_);
397 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES); 385 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES);
398 386
399 if (IsNewTouchSequence(touch.event)) { 387 if (WebInputEventTraits::IsNewTouchSequence(touch.event)) {
400 touch_filtering_state_ = 388 touch_filtering_state_ =
401 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT 389 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT
402 : FORWARD_ALL_TOUCHES; 390 : FORWARD_ALL_TOUCHES;
403 touch_ack_states_.clear(); 391 touch_ack_states_.clear();
404 absorbing_touch_moves_ = false; 392 absorbing_touch_moves_ = false;
405 } 393 }
406 394
407 // A synchronous ack will reset |dispatching_touch_|, in which case 395 // A synchronous ack will reset |dispatching_touch_|, in which case
408 // the touch timeout should not be started. 396 // the touch timeout should not be started.
409 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); 397 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 return ACK_WITH_NO_CONSUMER_EXISTS; 551 return ACK_WITH_NO_CONSUMER_EXISTS;
564 552
565 if (touchmove_slop_suppressor_->FilterEvent(event)) 553 if (touchmove_slop_suppressor_->FilterEvent(event))
566 return ACK_WITH_NOT_CONSUMED; 554 return ACK_WITH_NOT_CONSUMED;
567 555
568 if (touch_filtering_state_ == DROP_ALL_TOUCHES) 556 if (touch_filtering_state_ == DROP_ALL_TOUCHES)
569 return ACK_WITH_NO_CONSUMER_EXISTS; 557 return ACK_WITH_NO_CONSUMER_EXISTS;
570 558
571 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE && 559 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE &&
572 event.type != WebInputEvent::TouchCancel) { 560 event.type != WebInputEvent::TouchCancel) {
573 if (IsNewTouchSequence(event)) 561 if (WebInputEventTraits::IsNewTouchSequence(event))
574 return FORWARD_TO_RENDERER; 562 return FORWARD_TO_RENDERER;
575 return ACK_WITH_NOT_CONSUMED; 563 return ACK_WITH_NOT_CONSUMED;
576 } 564 }
577 565
578 if (absorbing_touch_moves_ && event.type == WebInputEvent::TouchMove) 566 if (absorbing_touch_moves_ && event.type == WebInputEvent::TouchMove)
579 return ACK_WITH_NOT_CONSUMED; 567 return ACK_WITH_NOT_CONSUMED;
580 568
581 // Touch press events should always be forwarded to the renderer. 569 // Touch press events should always be forwarded to the renderer.
582 if (event.type == WebInputEvent::TouchStart) 570 if (event.type == WebInputEvent::TouchStart)
583 return FORWARD_TO_RENDERER; 571 return FORWARD_TO_RENDERER;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 } else if (event.type == WebInputEvent::TouchStart) { 605 } else if (event.type == WebInputEvent::TouchStart) {
618 for (unsigned i = 0; i < event.touchesLength; ++i) { 606 for (unsigned i = 0; i < event.touchesLength; ++i) {
619 const WebTouchPoint& point = event.touches[i]; 607 const WebTouchPoint& point = event.touches[i];
620 if (point.state == WebTouchPoint::StatePressed) 608 if (point.state == WebTouchPoint::StatePressed)
621 touch_ack_states_[point.id] = ack_result; 609 touch_ack_states_[point.id] = ack_result;
622 } 610 }
623 } 611 }
624 } 612 }
625 613
626 } // namespace content 614 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698