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 "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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |