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 15 matching lines...) Expand all Loading... | |
26 | 26 |
27 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( | 27 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( |
28 const TouchEventWithLatencyInfo& event_to_cancel) { | 28 const TouchEventWithLatencyInfo& event_to_cancel) { |
29 TouchEventWithLatencyInfo event = event_to_cancel; | 29 TouchEventWithLatencyInfo event = event_to_cancel; |
30 event.event.type = WebInputEvent::TouchCancel; | 30 event.event.type = WebInputEvent::TouchCancel; |
31 for (size_t i = 0; i < event.event.touchesLength; i++) | 31 for (size_t i = 0; i < event.event.touchesLength; i++) |
32 event.event.touches[i].state = WebTouchPoint::StateCancelled; | 32 event.event.touches[i].state = WebTouchPoint::StateCancelled; |
33 return event; | 33 return event; |
34 } | 34 } |
35 | 35 |
36 bool IsNewTouchGesture(const WebTouchEvent& event) { | 36 bool IsNewTouchSequence(const WebTouchEvent& event) { |
37 if (event.type != WebInputEvent::TouchStart) | 37 if (event.type != WebInputEvent::TouchStart) |
38 return false; | 38 return false; |
39 if (!event.touchesLength) | 39 if (!event.touchesLength) |
40 return false; | 40 return false; |
41 for (size_t i = 0; i < event.touchesLength; i++) { | 41 for (size_t i = 0; i < event.touchesLength; i++) { |
42 if (event.touches[i].state != WebTouchPoint::StatePressed) | 42 if (event.touches[i].state != WebTouchPoint::StatePressed) |
43 return false; | 43 return false; |
44 } | 44 } |
45 return true; | 45 return true; |
46 } | 46 } |
(...skipping 26 matching lines...) Expand all Loading... | |
73 bool ConfirmTouchEvent(InputEventAckState ack_result) { | 73 bool ConfirmTouchEvent(InputEventAckState ack_result) { |
74 switch (pending_ack_state_) { | 74 switch (pending_ack_state_) { |
75 case PENDING_ACK_NONE: | 75 case PENDING_ACK_NONE: |
76 timeout_monitor_.Stop(); | 76 timeout_monitor_.Stop(); |
77 return false; | 77 return false; |
78 case PENDING_ACK_ORIGINAL_EVENT: | 78 case PENDING_ACK_ORIGINAL_EVENT: |
79 if (AckedTimeoutEventRequiresCancel(ack_result)) { | 79 if (AckedTimeoutEventRequiresCancel(ack_result)) { |
80 SetPendingAckState(PENDING_ACK_CANCEL_EVENT); | 80 SetPendingAckState(PENDING_ACK_CANCEL_EVENT); |
81 TouchEventWithLatencyInfo cancel_event = | 81 TouchEventWithLatencyInfo cancel_event = |
82 ObtainCancelEventForTouchEvent(timeout_event_); | 82 ObtainCancelEventForTouchEvent(timeout_event_); |
83 touch_queue_->UpdateTouchAckStates( | |
84 cancel_event.event, kDefaultNotForwardedAck); | |
85 touch_queue_->client_->SendTouchEventImmediately(cancel_event); | 83 touch_queue_->client_->SendTouchEventImmediately(cancel_event); |
86 } else { | 84 } else { |
87 SetPendingAckState(PENDING_ACK_NONE); | 85 SetPendingAckState(PENDING_ACK_NONE); |
88 touch_queue_->UpdateTouchAckStates(timeout_event_.event, ack_result); | 86 touch_queue_->UpdateTouchAckStates(timeout_event_.event, ack_result); |
89 } | 87 } |
90 return true; | 88 return true; |
91 case PENDING_ACK_CANCEL_EVENT: | 89 case PENDING_ACK_CANCEL_EVENT: |
92 SetPendingAckState(PENDING_ACK_NONE); | 90 SetPendingAckState(PENDING_ACK_NONE); |
93 return true; | 91 return true; |
94 } | 92 } |
(...skipping 24 matching lines...) Expand all Loading... | |
119 SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT); | 117 SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT); |
120 touch_queue_->FlushQueue(); | 118 touch_queue_->FlushQueue(); |
121 } | 119 } |
122 | 120 |
123 // Skip a cancel event if the timed-out event had no consumer and was the | 121 // Skip a cancel event if the timed-out event had no consumer and was the |
124 // initial event in the gesture. | 122 // initial event in the gesture. |
125 bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const { | 123 bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const { |
126 DCHECK(HasTimeoutEvent()); | 124 DCHECK(HasTimeoutEvent()); |
127 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) | 125 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) |
128 return true; | 126 return true; |
129 return !IsNewTouchGesture(timeout_event_.event); | 127 return !IsNewTouchSequence(timeout_event_.event); |
130 } | 128 } |
131 | 129 |
132 void SetPendingAckState(PendingAckState new_pending_ack_state) { | 130 void SetPendingAckState(PendingAckState new_pending_ack_state) { |
133 DCHECK_NE(pending_ack_state_, new_pending_ack_state); | 131 DCHECK_NE(pending_ack_state_, new_pending_ack_state); |
134 switch (new_pending_ack_state) { | 132 switch (new_pending_ack_state) { |
135 case PENDING_ACK_ORIGINAL_EVENT: | 133 case PENDING_ACK_ORIGINAL_EVENT: |
136 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); | 134 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); |
137 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this); | 135 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this); |
138 break; | 136 break; |
139 case PENDING_ACK_CANCEL_EVENT: | 137 case PENDING_ACK_CANCEL_EVENT: |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
234 // when the event is acked. | 232 // when the event is acked. |
235 bool ignore_ack_; | 233 bool ignore_ack_; |
236 | 234 |
237 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); | 235 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); |
238 }; | 236 }; |
239 | 237 |
240 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client) | 238 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client) |
241 : client_(client), | 239 : client_(client), |
242 dispatching_touch_ack_(NULL), | 240 dispatching_touch_ack_(NULL), |
243 dispatching_touch_(false), | 241 dispatching_touch_(false), |
244 has_handlers_(false), | 242 touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT), |
245 scroll_in_progress_(false), | |
246 renderer_is_consuming_touch_gesture_(false), | |
247 ack_timeout_enabled_(false) { | 243 ack_timeout_enabled_(false) { |
248 DCHECK(client); | 244 DCHECK(client); |
249 } | 245 } |
250 | 246 |
251 TouchEventQueue::~TouchEventQueue() { | 247 TouchEventQueue::~TouchEventQueue() { |
252 if (!touch_queue_.empty()) | 248 if (!touch_queue_.empty()) |
253 STLDeleteElements(&touch_queue_); | 249 STLDeleteElements(&touch_queue_); |
254 } | 250 } |
255 | 251 |
256 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { | 252 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { |
257 // Optimization of the case without touch handlers. Removing this path | |
258 // yields identical results, but this avoids unnecessary allocations. | |
259 if (!has_handlers_) { | |
260 DCHECK(touch_queue_.empty()); | |
261 client_->OnTouchEventAck(event, kDefaultNotForwardedAck); | |
262 return; | |
263 } | |
264 | |
265 // If the queueing of |event| was triggered by an ack dispatch, defer | 253 // If the queueing of |event| was triggered by an ack dispatch, defer |
266 // processing the event until the dispatch has finished. | 254 // processing the event until the dispatch has finished. |
267 if (touch_queue_.empty() && !dispatching_touch_ack_) { | 255 if (touch_queue_.empty() && !dispatching_touch_ack_) { |
256 // Optimization of the case without touch handlers. Removing this path | |
257 // yields identical results, but this avoids unnecessary allocations. | |
258 if (touch_filtering_state_ == DROP_ALL_TOUCHES || | |
259 (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE && | |
260 !IsNewTouchSequence(event.event))) { | |
261 client_->OnTouchEventAck(event, kDefaultNotForwardedAck); | |
262 return; | |
263 } | |
264 | |
268 // There is no touch event in the queue. Forward it to the renderer | 265 // There is no touch event in the queue. Forward it to the renderer |
269 // immediately. | 266 // immediately. |
270 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); | 267 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); |
271 TryForwardNextEventToRenderer(); | 268 TryForwardNextEventToRenderer(); |
272 return; | 269 return; |
273 } | 270 } |
274 | 271 |
275 // If the last queued touch-event was a touch-move, and the current event is | 272 // If the last queued touch-event was a touch-move, and the current event is |
276 // also a touch-move, then the events can be coalesced into a single event. | 273 // also a touch-move, then the events can be coalesced into a single event. |
277 if (touch_queue_.size() > 1) { | 274 if (touch_queue_.size() > 1) { |
278 CoalescedWebTouchEvent* last_event = touch_queue_.back(); | 275 CoalescedWebTouchEvent* last_event = touch_queue_.back(); |
279 if (last_event->CoalesceEventIfPossible(event)) | 276 if (last_event->CoalesceEventIfPossible(event)) |
280 return; | 277 return; |
281 } | 278 } |
282 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); | 279 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); |
283 } | 280 } |
284 | 281 |
285 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, | 282 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, |
286 const ui::LatencyInfo& latency_info) { | 283 const ui::LatencyInfo& latency_info) { |
287 DCHECK(!dispatching_touch_ack_); | 284 DCHECK(!dispatching_touch_ack_); |
288 dispatching_touch_ = false; | 285 dispatching_touch_ = false; |
289 | 286 |
290 if (timeout_handler_ && timeout_handler_->ConfirmTouchEvent(ack_result)) | 287 if (timeout_handler_ && timeout_handler_->ConfirmTouchEvent(ack_result)) |
291 return; | 288 return; |
292 | 289 |
293 if (touch_queue_.empty()) | 290 if (touch_queue_.empty()) |
294 return; | 291 return; |
295 | 292 |
296 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) | 293 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED && |
297 renderer_is_consuming_touch_gesture_ = true; | 294 touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT) |
295 touch_filtering_state_ = FORWARD_ALL_TOUCHES; | |
298 | 296 |
299 const WebTouchEvent& acked_event = | 297 const WebTouchEvent& acked_event = |
300 touch_queue_.front()->coalesced_event().event; | 298 touch_queue_.front()->coalesced_event().event; |
301 UpdateTouchAckStates(acked_event, ack_result); | 299 UpdateTouchAckStates(acked_event, ack_result); |
302 PopTouchEventToClient(ack_result, latency_info); | 300 PopTouchEventToClient(ack_result, latency_info); |
303 TryForwardNextEventToRenderer(); | 301 TryForwardNextEventToRenderer(); |
304 } | 302 } |
305 | 303 |
306 void TouchEventQueue::TryForwardNextEventToRenderer() { | 304 void TouchEventQueue::TryForwardNextEventToRenderer() { |
307 DCHECK(!dispatching_touch_ack_); | 305 DCHECK(!dispatching_touch_ack_); |
308 // If there are queued touch events, then try to forward them to the renderer | 306 // If there are queued touch events, then try to forward them to the renderer |
309 // immediately, or ACK the events back to the client if appropriate. | 307 // immediately, or ACK the events back to the client if appropriate. |
310 while (!touch_queue_.empty()) { | 308 while (!touch_queue_.empty()) { |
311 const TouchEventWithLatencyInfo& touch = | 309 const TouchEventWithLatencyInfo& touch = |
312 touch_queue_.front()->coalesced_event(); | 310 touch_queue_.front()->coalesced_event(); |
313 if (IsNewTouchGesture(touch.event)) { | |
314 touch_ack_states_.clear(); | |
315 renderer_is_consuming_touch_gesture_ = false; | |
316 } | |
317 if (ShouldForwardToRenderer(touch.event)) { | 311 if (ShouldForwardToRenderer(touch.event)) { |
318 ForwardToRenderer(touch); | 312 ForwardToRenderer(touch); |
319 break; | 313 break; |
320 } | 314 } |
321 PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo()); | 315 PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo()); |
322 } | 316 } |
323 } | 317 } |
324 | 318 |
325 void TouchEventQueue::ForwardToRenderer( | 319 void TouchEventQueue::ForwardToRenderer( |
326 const TouchEventWithLatencyInfo& touch) { | 320 const TouchEventWithLatencyInfo& touch) { |
327 DCHECK(!dispatching_touch_); | 321 DCHECK(!dispatching_touch_); |
322 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES); | |
323 | |
324 if (IsNewTouchSequence(touch.event)) { | |
325 touch_filtering_state_ = | |
326 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT | |
327 : FORWARD_ALL_TOUCHES; | |
328 touch_ack_states_.clear(); | |
329 } | |
330 | |
328 // A synchronous ack will reset |dispatching_touch_|, in which case | 331 // A synchronous ack will reset |dispatching_touch_|, in which case |
329 // the touch timeout should not be started. | 332 // the touch timeout should not be started. |
330 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); | 333 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); |
331 client_->SendTouchEventImmediately(touch); | 334 client_->SendTouchEventImmediately(touch); |
332 if (ack_timeout_enabled_ && | 335 if (dispatching_touch_ && |
333 dispatching_touch_ && | 336 touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT && |
334 !renderer_is_consuming_touch_gesture_ && | |
335 ShouldTouchTypeTriggerTimeout(touch.event.type)) { | 337 ShouldTouchTypeTriggerTimeout(touch.event.type)) { |
336 DCHECK(timeout_handler_); | 338 DCHECK(timeout_handler_); |
337 timeout_handler_->Start(touch); | 339 timeout_handler_->Start(touch); |
338 } | 340 } |
339 } | 341 } |
340 | 342 |
341 void TouchEventQueue::OnGestureScrollEvent( | 343 void TouchEventQueue::OnGestureScrollEvent( |
342 const GestureEventWithLatencyInfo& gesture_event) { | 344 const GestureEventWithLatencyInfo& gesture_event) { |
343 blink::WebInputEvent::Type type = gesture_event.event.type; | 345 if (gesture_event.event.type != blink::WebInputEvent::GestureScrollBegin) |
344 if (type == blink::WebInputEvent::GestureScrollBegin) { | 346 return; |
345 // We assume the scroll event are generated synchronously from | |
346 // dispatching a touch event ack, so that we can fake a cancel | |
347 // event that has the correct touch ids as the touch event that | |
348 // is being acked. If not, we don't do the touch-cancel optimization. | |
349 if (scroll_in_progress_ || !dispatching_touch_ack_) | |
350 return; | |
351 scroll_in_progress_ = true; | |
352 | 347 |
353 // If we have a timeout event, a cancel has already been dispatched | 348 // We assume that scroll events are generated synchronously from |
354 // for the current touch stream. | 349 // dispatching a touch event ack. This allows us to generate a synthetic |
355 if (HasTimeoutEvent()) | 350 // cancel event that has the same touch ids as the touch event that |
356 return; | 351 // is being acked. Otherwise, we don't perform the touch-cancel optimization. |
352 if (!dispatching_touch_ack_) | |
353 return; | |
357 | 354 |
358 // Fake a TouchCancel to cancel the touch points of the touch event | 355 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE) |
359 // that is currently being acked. | 356 return; |
360 // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we | 357 |
361 // are in the scope of PopTouchEventToClient() and that no touch event | 358 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; |
362 // in the queue is waiting for ack from renderer. So we can just insert | 359 |
363 // the touch cancel at the beginning of the queue. | 360 // Fake a TouchCancel to cancel the touch points of the touch event |
364 touch_queue_.push_front(new CoalescedWebTouchEvent( | 361 // that is currently being acked. |
365 ObtainCancelEventForTouchEvent( | 362 // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we |
366 dispatching_touch_ack_->coalesced_event()), true)); | 363 // are in the scope of PopTouchEventToClient() and that no touch event |
367 } else if (type == blink::WebInputEvent::GestureScrollEnd || | 364 // in the queue is waiting for ack from renderer. So we can just insert |
368 type == blink::WebInputEvent::GestureFlingStart) { | 365 // the touch cancel at the beginning of the queue. |
369 scroll_in_progress_ = false; | 366 touch_queue_.push_front(new CoalescedWebTouchEvent( |
370 } | 367 ObtainCancelEventForTouchEvent( |
368 dispatching_touch_ack_->coalesced_event()), true)); | |
371 } | 369 } |
372 | 370 |
373 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { | 371 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { |
374 DCHECK(!dispatching_touch_ack_); | 372 DCHECK(!dispatching_touch_ack_); |
375 DCHECK(!dispatching_touch_); | 373 DCHECK(!dispatching_touch_); |
376 if (has_handlers_ == has_handlers) | |
377 return; | |
378 | 374 |
379 has_handlers_ = has_handlers; | 375 if (has_handlers) { |
380 | 376 if (touch_filtering_state_ == DROP_ALL_TOUCHES) { |
381 if (!has_handlers_) { | 377 // If no touch handler was previously registered, ensure that we don't |
382 // TODO(jdduke): Synthesize a TouchCancel if necessary to update Blink touch | 378 // send a partial touch sequence to the renderer. |
383 // state tracking. | 379 DCHECK(touch_queue_.empty()); |
380 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; | |
381 } | |
382 } else { | |
383 touch_filtering_state_ = DROP_ALL_TOUCHES; | |
Rick Byers
2014/01/23 18:40:14
I had to think about this for a minute to convince
jdduke (slow)
2014/01/24 05:29:22
Ahh, I actually never intended to remove that TODO
| |
384 if (timeout_handler_) | 384 if (timeout_handler_) |
385 timeout_handler_->Reset(); | 385 timeout_handler_->Reset(); |
386 if (!touch_queue_.empty()) | 386 if (!touch_queue_.empty()) |
387 ProcessTouchAck(kDefaultNotForwardedAck, ui::LatencyInfo()); | 387 ProcessTouchAck(kDefaultNotForwardedAck, ui::LatencyInfo()); |
388 // As there is no touch handler, ack'ing the event should flush the queue. | 388 // As there is no touch handler, ack'ing the event should flush the queue. |
389 DCHECK(touch_queue_.empty()); | 389 DCHECK(touch_queue_.empty()); |
390 } else { | |
391 DCHECK(touch_queue_.empty()); | |
392 // Prevent a partial sequence from being sent to the renderer. | |
393 TouchPointAckStates::iterator ack_it = touch_ack_states_.begin(); | |
394 for (; ack_it != touch_ack_states_.end(); ++ack_it) | |
395 ack_it->second = kDefaultNotForwardedAck; | |
396 } | 390 } |
397 } | 391 } |
398 | 392 |
399 bool TouchEventQueue::IsPendingAckTouchStart() const { | 393 bool TouchEventQueue::IsPendingAckTouchStart() const { |
400 DCHECK(!dispatching_touch_ack_); | 394 DCHECK(!dispatching_touch_ack_); |
401 if (touch_queue_.empty()) | 395 if (touch_queue_.empty()) |
402 return false; | 396 return false; |
403 | 397 |
404 const blink::WebTouchEvent& event = | 398 const blink::WebTouchEvent& event = |
405 touch_queue_.front()->coalesced_event().event; | 399 touch_queue_.front()->coalesced_event().event; |
(...skipping 23 matching lines...) Expand all Loading... | |
429 } | 423 } |
430 | 424 |
431 const TouchEventWithLatencyInfo& | 425 const TouchEventWithLatencyInfo& |
432 TouchEventQueue::GetLatestEventForTesting() const { | 426 TouchEventQueue::GetLatestEventForTesting() const { |
433 return touch_queue_.back()->coalesced_event(); | 427 return touch_queue_.back()->coalesced_event(); |
434 } | 428 } |
435 | 429 |
436 void TouchEventQueue::FlushQueue() { | 430 void TouchEventQueue::FlushQueue() { |
437 DCHECK(!dispatching_touch_ack_); | 431 DCHECK(!dispatching_touch_ack_); |
438 DCHECK(!dispatching_touch_); | 432 DCHECK(!dispatching_touch_); |
433 if (touch_filtering_state_ != DROP_ALL_TOUCHES) | |
434 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; | |
439 while (!touch_queue_.empty()) | 435 while (!touch_queue_.empty()) |
440 PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo()); | 436 PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo()); |
441 } | 437 } |
442 | 438 |
443 void TouchEventQueue::PopTouchEventToClient( | 439 void TouchEventQueue::PopTouchEventToClient( |
444 InputEventAckState ack_result, | 440 InputEventAckState ack_result, |
445 const ui::LatencyInfo& renderer_latency_info) { | 441 const ui::LatencyInfo& renderer_latency_info) { |
446 DCHECK(!dispatching_touch_ack_); | 442 DCHECK(!dispatching_touch_ack_); |
447 if (touch_queue_.empty()) | 443 if (touch_queue_.empty()) |
448 return; | 444 return; |
(...skipping 14 matching lines...) Expand all Loading... | |
463 iter->latency.AddNewLatencyFrom(renderer_latency_info); | 459 iter->latency.AddNewLatencyFrom(renderer_latency_info); |
464 client_->OnTouchEventAck((*iter), ack_result); | 460 client_->OnTouchEventAck((*iter), ack_result); |
465 } | 461 } |
466 } | 462 } |
467 | 463 |
468 bool TouchEventQueue::ShouldForwardToRenderer( | 464 bool TouchEventQueue::ShouldForwardToRenderer( |
469 const WebTouchEvent& event) const { | 465 const WebTouchEvent& event) const { |
470 if (HasTimeoutEvent()) | 466 if (HasTimeoutEvent()) |
471 return false; | 467 return false; |
472 | 468 |
473 if (!has_handlers_) | 469 if (touch_filtering_state_ == DROP_ALL_TOUCHES) |
474 return false; | 470 return false; |
475 | 471 |
476 if (scroll_in_progress_ && | 472 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE && |
477 event.type != blink::WebInputEvent::TouchCancel) | 473 event.type != WebInputEvent::TouchCancel) { |
474 if (IsNewTouchSequence(event)) | |
475 return true; | |
478 return false; | 476 return false; |
477 } | |
479 | 478 |
480 // Touch press events should always be forwarded to the renderer. | 479 // Touch press events should always be forwarded to the renderer. |
481 if (event.type == WebInputEvent::TouchStart) | 480 if (event.type == WebInputEvent::TouchStart) |
482 return true; | 481 return true; |
483 | 482 |
484 for (unsigned int i = 0; i < event.touchesLength; ++i) { | 483 for (unsigned int i = 0; i < event.touchesLength; ++i) { |
485 const WebTouchPoint& point = event.touches[i]; | 484 const WebTouchPoint& point = event.touches[i]; |
486 // If a point has been stationary, then don't take it into account. | 485 // If a point has been stationary, then don't take it into account. |
487 if (point.state == WebTouchPoint::StateStationary) | 486 if (point.state == WebTouchPoint::StateStationary) |
488 continue; | 487 continue; |
(...skipping 27 matching lines...) Expand all Loading... | |
516 } else if (event.type == WebInputEvent::TouchStart) { | 515 } else if (event.type == WebInputEvent::TouchStart) { |
517 for (unsigned i = 0; i < event.touchesLength; ++i) { | 516 for (unsigned i = 0; i < event.touchesLength; ++i) { |
518 const WebTouchPoint& point = event.touches[i]; | 517 const WebTouchPoint& point = event.touches[i]; |
519 if (point.state == WebTouchPoint::StatePressed) | 518 if (point.state == WebTouchPoint::StatePressed) |
520 touch_ack_states_[point.id] = ack_result; | 519 touch_ack_states_[point.id] = ack_result; |
521 } | 520 } |
522 } | 521 } |
523 } | 522 } |
524 | 523 |
525 } // namespace content | 524 } // namespace content |
OLD | NEW |