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/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "content/browser/renderer_host/input/timeout_monitor.h" | 10 #include "content/browser/renderer_host/input/timeout_monitor.h" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 case PENDING_ACK_NONE: | 100 case PENDING_ACK_NONE: |
101 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) | 101 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) |
102 enabled_for_current_sequence_ = false; | 102 enabled_for_current_sequence_ = false; |
103 timeout_monitor_.Stop(); | 103 timeout_monitor_.Stop(); |
104 return false; | 104 return false; |
105 case PENDING_ACK_ORIGINAL_EVENT: | 105 case PENDING_ACK_ORIGINAL_EVENT: |
106 if (AckedTimeoutEventRequiresCancel(ack_result)) { | 106 if (AckedTimeoutEventRequiresCancel(ack_result)) { |
107 SetPendingAckState(PENDING_ACK_CANCEL_EVENT); | 107 SetPendingAckState(PENDING_ACK_CANCEL_EVENT); |
108 TouchEventWithLatencyInfo cancel_event = | 108 TouchEventWithLatencyInfo cancel_event = |
109 ObtainCancelEventForTouchEvent(timeout_event_); | 109 ObtainCancelEventForTouchEvent(timeout_event_); |
110 touch_queue_->SendTouchEventImmediately(cancel_event); | 110 touch_queue_->SendTouchEventImmediately(&cancel_event); |
111 } else { | 111 } else { |
112 SetPendingAckState(PENDING_ACK_NONE); | 112 SetPendingAckState(PENDING_ACK_NONE); |
113 touch_queue_->UpdateTouchConsumerStates(timeout_event_.event, | 113 touch_queue_->UpdateTouchConsumerStates(timeout_event_.event, |
114 ack_result); | 114 ack_result); |
115 } | 115 } |
116 return true; | 116 return true; |
117 case PENDING_ACK_CANCEL_EVENT: | 117 case PENDING_ACK_CANCEL_EVENT: |
118 SetPendingAckState(PENDING_ACK_NONE); | 118 SetPendingAckState(PENDING_ACK_NONE); |
119 return true; | 119 return true; |
120 } | 120 } |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
508 if (pending_async_touchmove_->CanCoalesceWith(touch)) { | 508 if (pending_async_touchmove_->CanCoalesceWith(touch)) { |
509 pending_async_touchmove_->CoalesceWith(touch); | 509 pending_async_touchmove_->CoalesceWith(touch); |
510 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; | 510 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; |
511 touch = *pending_async_touchmove_; | 511 touch = *pending_async_touchmove_; |
512 pending_async_touchmove_.reset(); | 512 pending_async_touchmove_.reset(); |
513 } else { | 513 } else { |
514 scoped_ptr<TouchEventWithLatencyInfo> async_move = | 514 scoped_ptr<TouchEventWithLatencyInfo> async_move = |
515 pending_async_touchmove_.Pass(); | 515 pending_async_touchmove_.Pass(); |
516 async_move->event.cancelable = false; | 516 async_move->event.cancelable = false; |
517 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true)); | 517 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true)); |
518 SendTouchEventImmediately(*async_move); | 518 SendTouchEventImmediately(async_move.get()); |
519 return; | 519 return; |
520 } | 520 } |
521 } | 521 } |
522 | 522 |
523 // Note: Touchstart events are marked cancelable to allow transitions between | 523 // Note: Touchstart events are marked cancelable to allow transitions between |
524 // platform scrolling and JS pinching. Touchend events, however, remain | 524 // platform scrolling and JS pinching. Touchend events, however, remain |
525 // uncancelable, mitigating the risk of jank when transitioning to a fling. | 525 // uncancelable, mitigating the risk of jank when transitioning to a fling. |
526 if (send_touch_events_async_ && touch.event.type != WebInputEvent::TouchStart) | 526 if (send_touch_events_async_ && touch.event.type != WebInputEvent::TouchStart) |
527 touch.event.cancelable = false; | 527 touch.event.cancelable = false; |
528 | 528 |
529 // A synchronous ack will reset |dispatching_touch_|, in which case | 529 // A synchronous ack will reset |dispatching_touch_|, in which case |
530 // the touch timeout should not be started. | 530 // the touch timeout should not be started. |
531 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); | 531 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); |
532 SendTouchEventImmediately(touch); | 532 SendTouchEventImmediately(&touch); |
533 if (dispatching_touch_ && timeout_handler_) | 533 if (dispatching_touch_ && timeout_handler_) |
534 timeout_handler_->StartIfNecessary(touch); | 534 timeout_handler_->StartIfNecessary(touch); |
535 } | 535 } |
536 | 536 |
537 void TouchEventQueue::OnGestureScrollEvent( | 537 void TouchEventQueue::OnGestureScrollEvent( |
538 const GestureEventWithLatencyInfo& gesture_event) { | 538 const GestureEventWithLatencyInfo& gesture_event) { |
539 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { | 539 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { |
540 if (!touch_consumer_states_.is_empty() && | 540 if (!touch_consumer_states_.is_empty() && |
541 !drop_remaining_touches_in_sequence_) { | 541 !drop_remaining_touches_in_sequence_) { |
542 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) | 542 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 } | 686 } |
687 | 687 |
688 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { | 688 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { |
689 DCHECK(!touch_queue_.empty()); | 689 DCHECK(!touch_queue_.empty()); |
690 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); | 690 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); |
691 touch_queue_.pop_front(); | 691 touch_queue_.pop_front(); |
692 return event.Pass(); | 692 return event.Pass(); |
693 } | 693 } |
694 | 694 |
695 void TouchEventQueue::SendTouchEventImmediately( | 695 void TouchEventQueue::SendTouchEventImmediately( |
696 const TouchEventWithLatencyInfo& touch) { | 696 TouchEventWithLatencyInfo* touch) { |
697 if (needs_async_touchmove_for_outer_slop_region_) { | 697 if (needs_async_touchmove_for_outer_slop_region_) { |
698 // Any event other than a touchmove (e.g., touchcancel or secondary | 698 // Any event other than a touchmove (e.g., touchcancel or secondary |
699 // touchstart) after a scroll has started will interrupt the need to send a | 699 // touchstart) after a scroll has started will interrupt the need to send a |
700 // an outer slop-region exceeding touchmove. | 700 // an outer slop-region exceeding touchmove. |
701 if (touch.event.type != WebInputEvent::TouchMove || | 701 if (touch->event.type != WebInputEvent::TouchMove || |
702 OutsideApplicationSlopRegion(touch.event, | 702 OutsideApplicationSlopRegion(touch->event, |
703 touch_sequence_start_position_)) | 703 touch_sequence_start_position_)) |
704 needs_async_touchmove_for_outer_slop_region_ = false; | 704 needs_async_touchmove_for_outer_slop_region_ = false; |
705 } | 705 } |
706 | 706 |
707 client_->SendTouchEventImmediately(touch); | 707 // For touchmove events, compare touch points position from current event |
708 // to last sent event and update touch points state. | |
709 if (touch->event.type == WebInputEvent::TouchMove) { | |
710 CHECK(last_sent_touchevent_); | |
711 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) { | |
712 const WebTouchPoint& last_touch_point = | |
713 last_sent_touchevent_->touches[i]; | |
714 // Touches with same id may not have same index in Touches array. | |
715 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) { | |
716 const WebTouchPoint& current_touchmove_point = touch->event.touches[j]; | |
717 if (current_touchmove_point.id != last_touch_point.id) | |
718 continue; | |
719 | |
720 if (current_touchmove_point.position == last_touch_point.position) | |
jdduke (slow)
2015/01/26 16:18:13
So, now I'm wondering if we should also check the
| |
721 touch->event.touches[j].state = WebTouchPoint::StateStationary; | |
722 | |
723 break; | |
724 } | |
725 } | |
726 } | |
727 | |
728 if (last_sent_touchevent_) | |
729 *last_sent_touchevent_ = touch->event; | |
730 else | |
731 last_sent_touchevent_.reset(new WebTouchEvent(touch->event)); | |
732 | |
733 client_->SendTouchEventImmediately(*touch); | |
708 } | 734 } |
709 | 735 |
710 TouchEventQueue::PreFilterResult | 736 TouchEventQueue::PreFilterResult |
711 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { | 737 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { |
712 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) | 738 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) |
713 return ACK_WITH_NO_CONSUMER_EXISTS; | 739 return ACK_WITH_NO_CONSUMER_EXISTS; |
714 | 740 |
715 if (touchmove_slop_suppressor_->FilterEvent(event)) | 741 if (touchmove_slop_suppressor_->FilterEvent(event)) |
716 return ACK_WITH_NOT_CONSUMED; | 742 return ACK_WITH_NOT_CONSUMED; |
717 | 743 |
718 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { | 744 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
719 touch_consumer_states_.clear(); | 745 touch_consumer_states_.clear(); |
720 send_touch_events_async_ = false; | 746 send_touch_events_async_ = false; |
721 pending_async_touchmove_.reset(); | 747 pending_async_touchmove_.reset(); |
748 last_sent_touchevent_.reset(); | |
749 | |
722 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); | 750 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); |
723 drop_remaining_touches_in_sequence_ = false; | 751 drop_remaining_touches_in_sequence_ = false; |
724 if (!has_handlers_) { | 752 if (!has_handlers_) { |
725 drop_remaining_touches_in_sequence_ = true; | 753 drop_remaining_touches_in_sequence_ = true; |
726 return ACK_WITH_NO_CONSUMER_EXISTS; | 754 return ACK_WITH_NO_CONSUMER_EXISTS; |
727 } | 755 } |
728 } | 756 } |
729 | 757 |
730 if (drop_remaining_touches_in_sequence_ && | 758 if (drop_remaining_touches_in_sequence_ && |
731 event.type != WebInputEvent::TouchCancel) { | 759 event.type != WebInputEvent::TouchCancel) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
771 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) | 799 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) |
772 touch_consumer_states_.mark_bit(point.id); | 800 touch_consumer_states_.mark_bit(point.id); |
773 else | 801 else |
774 touch_consumer_states_.clear_bit(point.id); | 802 touch_consumer_states_.clear_bit(point.id); |
775 } | 803 } |
776 } | 804 } |
777 } | 805 } |
778 } | 806 } |
779 | 807 |
780 } // namespace content | 808 } // namespace content |
OLD | NEW |