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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 }; | 339 }; |
340 | 340 |
341 // This class represents a single coalesced touch event. However, it also keeps | 341 // This class represents a single coalesced touch event. However, it also keeps |
342 // track of all the original touch-events that were coalesced into a single | 342 // track of all the original touch-events that were coalesced into a single |
343 // event. The coalesced event is forwarded to the renderer, while the original | 343 // event. The coalesced event is forwarded to the renderer, while the original |
344 // touch-events are sent to the Client (on ACK for the coalesced event) so that | 344 // touch-events are sent to the Client (on ACK for the coalesced event) so that |
345 // the Client receives the event with their original timestamp. | 345 // the Client receives the event with their original timestamp. |
346 class CoalescedWebTouchEvent { | 346 class CoalescedWebTouchEvent { |
347 public: | 347 public: |
348 CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event, | 348 CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event, |
349 bool suppress_client_ack) | 349 bool suppress_client_ack, |
| 350 bool fling_in_progress) |
350 : coalesced_event_(event), suppress_client_ack_(suppress_client_ack) { | 351 : coalesced_event_(event), suppress_client_ack_(suppress_client_ack) { |
351 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventQueue::QueueEvent", this); | 352 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventQueue::QueueEvent", this); |
| 353 coalesced_event_.event.isFlingInProgress = fling_in_progress; |
352 } | 354 } |
353 | 355 |
| 356 CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event, |
| 357 bool suppress_client_ack) |
| 358 : CoalescedWebTouchEvent(event, suppress_client_ack, false) {} |
| 359 |
354 ~CoalescedWebTouchEvent() { | 360 ~CoalescedWebTouchEvent() { |
355 TRACE_EVENT_ASYNC_END0("input", "TouchEventQueue::QueueEvent", this); | 361 TRACE_EVENT_ASYNC_END0("input", "TouchEventQueue::QueueEvent", this); |
356 } | 362 } |
357 | 363 |
358 // Coalesces the event with the existing event if possible. Returns whether | 364 // Coalesces the event with the existing event if possible. Returns whether |
359 // the event was coalesced. | 365 // the event was coalesced. |
360 bool CoalesceEventIfPossible( | 366 bool CoalesceEventIfPossible( |
361 const TouchEventWithLatencyInfo& event_with_latency) { | 367 const TouchEventWithLatencyInfo& event_with_latency) { |
362 if (suppress_client_ack_) | 368 if (suppress_client_ack_) |
363 return false; | 369 return false; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client, | 439 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client, |
434 const Config& config) | 440 const Config& config) |
435 : client_(client), | 441 : client_(client), |
436 dispatching_touch_ack_(false), | 442 dispatching_touch_ack_(false), |
437 dispatching_touch_(false), | 443 dispatching_touch_(false), |
438 has_handlers_(true), | 444 has_handlers_(true), |
439 has_handler_for_current_sequence_(false), | 445 has_handler_for_current_sequence_(false), |
440 drop_remaining_touches_in_sequence_(false), | 446 drop_remaining_touches_in_sequence_(false), |
441 touchmove_slop_suppressor_(new TouchMoveSlopSuppressor), | 447 touchmove_slop_suppressor_(new TouchMoveSlopSuppressor), |
442 send_touch_events_async_(false), | 448 send_touch_events_async_(false), |
443 last_sent_touch_timestamp_sec_(0) { | 449 last_sent_touch_timestamp_sec_(0), |
| 450 fling_in_progress_(false) { |
444 DCHECK(client); | 451 DCHECK(client); |
445 if (config.touch_ack_timeout_supported) { | 452 if (config.touch_ack_timeout_supported) { |
446 timeout_handler_.reset( | 453 timeout_handler_.reset( |
447 new TouchTimeoutHandler(this, | 454 new TouchTimeoutHandler(this, |
448 config.desktop_touch_ack_timeout_delay, | 455 config.desktop_touch_ack_timeout_delay, |
449 config.mobile_touch_ack_timeout_delay)); | 456 config.mobile_touch_ack_timeout_delay)); |
450 } | 457 } |
451 } | 458 } |
452 | 459 |
453 TouchEventQueue::~TouchEventQueue() { | 460 TouchEventQueue::~TouchEventQueue() { |
(...skipping 14 matching lines...) Expand all Loading... |
468 client_->OnFilteringTouchEvent(event.event); | 475 client_->OnFilteringTouchEvent(event.event); |
469 client_->OnTouchEventAck(event, | 476 client_->OnTouchEventAck(event, |
470 filter_result == ACK_WITH_NO_CONSUMER_EXISTS | 477 filter_result == ACK_WITH_NO_CONSUMER_EXISTS |
471 ? INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS | 478 ? INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS |
472 : INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 479 : INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
473 return; | 480 return; |
474 } | 481 } |
475 | 482 |
476 // There is no touch event in the queue. Forward it to the renderer | 483 // There is no touch event in the queue. Forward it to the renderer |
477 // immediately. | 484 // immediately. |
478 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); | 485 touch_queue_.push_back( |
| 486 new CoalescedWebTouchEvent(event, false, fling_in_progress_)); |
479 ForwardNextEventToRenderer(); | 487 ForwardNextEventToRenderer(); |
480 return; | 488 return; |
481 } | 489 } |
482 | 490 |
483 // If the last queued touch-event was a touch-move, and the current event is | 491 // If the last queued touch-event was a touch-move, and the current event is |
484 // also a touch-move, then the events can be coalesced into a single event. | 492 // also a touch-move, then the events can be coalesced into a single event. |
485 if (touch_queue_.size() > 1) { | 493 if (touch_queue_.size() > 1) { |
486 CoalescedWebTouchEvent* last_event = touch_queue_.back(); | 494 CoalescedWebTouchEvent* last_event = touch_queue_.back(); |
487 if (last_event->CoalesceEventIfPossible(event)) | 495 if (last_event->CoalesceEventIfPossible(event)) |
488 return; | 496 return; |
489 } | 497 } |
490 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); | 498 touch_queue_.push_back( |
| 499 new CoalescedWebTouchEvent(event, false, fling_in_progress_)); |
491 } | 500 } |
492 | 501 |
493 void TouchEventQueue::PrependTouchScrollNotification() { | 502 void TouchEventQueue::PrependTouchScrollNotification() { |
494 TRACE_EVENT0("input", "TouchEventQueue::PrependTouchScrollNotification"); | 503 TRACE_EVENT0("input", "TouchEventQueue::PrependTouchScrollNotification"); |
495 | 504 |
496 // The queue should have an in-flight event when this method is called because | 505 // The queue should have an in-flight event when this method is called because |
497 // this method is triggered by InputRouterImpl::SendGestureEvent, which is | 506 // this method is triggered by InputRouterImpl::SendGestureEvent, which is |
498 // triggered by TouchEventQueue::AckTouchEventToClient, which has just | 507 // triggered by TouchEventQueue::AckTouchEventToClient, which has just |
499 // received an ack for the in-flight event. We leave the head of the queue | 508 // received an ack for the in-flight event. We leave the head of the queue |
500 // untouched since it is the in-flight event. | 509 // untouched since it is the in-flight event. |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 DCHECK(!dispatching_touch_); | 668 DCHECK(!dispatching_touch_); |
660 std::unique_ptr<TouchEventWithLatencyInfo> touch = | 669 std::unique_ptr<TouchEventWithLatencyInfo> touch = |
661 std::move(pending_async_touchmove_); | 670 std::move(pending_async_touchmove_); |
662 touch->event.dispatchType = WebInputEvent::EventNonBlocking; | 671 touch->event.dispatchType = WebInputEvent::EventNonBlocking; |
663 touch_queue_.push_front(new CoalescedWebTouchEvent(*touch, true)); | 672 touch_queue_.push_front(new CoalescedWebTouchEvent(*touch, true)); |
664 SendTouchEventImmediately(touch.get()); | 673 SendTouchEventImmediately(touch.get()); |
665 } | 674 } |
666 | 675 |
667 void TouchEventQueue::OnGestureScrollEvent( | 676 void TouchEventQueue::OnGestureScrollEvent( |
668 const GestureEventWithLatencyInfo& gesture_event) { | 677 const GestureEventWithLatencyInfo& gesture_event) { |
| 678 if (gesture_event.event.type == WebInputEvent::GestureFlingStart) |
| 679 fling_in_progress_ = true; |
| 680 else if (gesture_event.event.type == WebInputEvent::GestureFlingCancel) |
| 681 fling_in_progress_ = false; |
| 682 |
669 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { | 683 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { |
670 if (has_handler_for_current_sequence_ && | 684 if (has_handler_for_current_sequence_ && |
671 !drop_remaining_touches_in_sequence_) { | 685 !drop_remaining_touches_in_sequence_) { |
672 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) | 686 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) |
673 << "A touch handler should be offered a touchmove before scrolling."; | 687 << "A touch handler should be offered a touchmove before scrolling."; |
674 } | 688 } |
675 | 689 |
676 pending_async_touchmove_.reset(); | 690 pending_async_touchmove_.reset(); |
677 | 691 |
678 return; | 692 return; |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) | 940 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) |
927 send_touch_events_async_ = false; | 941 send_touch_events_async_ = false; |
928 has_handler_for_current_sequence_ |= | 942 has_handler_for_current_sequence_ |= |
929 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; | 943 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; |
930 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { | 944 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { |
931 has_handler_for_current_sequence_ = false; | 945 has_handler_for_current_sequence_ = false; |
932 } | 946 } |
933 } | 947 } |
934 | 948 |
935 } // namespace content | 949 } // namespace content |
OLD | NEW |