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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 if (pending_async_touchmove_->CanCoalesceWith(touch)) { | 518 if (pending_async_touchmove_->CanCoalesceWith(touch)) { |
519 pending_async_touchmove_->CoalesceWith(touch); | 519 pending_async_touchmove_->CoalesceWith(touch); |
520 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; | 520 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; |
521 touch = *pending_async_touchmove_; | 521 touch = *pending_async_touchmove_; |
522 pending_async_touchmove_.reset(); | 522 pending_async_touchmove_.reset(); |
523 } else { | 523 } else { |
524 scoped_ptr<TouchEventWithLatencyInfo> async_move = | 524 scoped_ptr<TouchEventWithLatencyInfo> async_move = |
525 pending_async_touchmove_.Pass(); | 525 pending_async_touchmove_.Pass(); |
526 async_move->event.cancelable = false; | 526 async_move->event.cancelable = false; |
527 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true)); | 527 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true)); |
528 SendTouchEventImmediately(*async_move); | 528 SendTouchEventImmediately(async_move.get()); |
529 return; | 529 return; |
530 } | 530 } |
531 } | 531 } |
532 | 532 |
533 // Note: Marking touchstart events as not-cancelable prevents them from | 533 // Note: Marking touchstart events as not-cancelable prevents them from |
534 // blocking subsequent gestures, but it may not be the best long term solution | 534 // blocking subsequent gestures, but it may not be the best long term solution |
535 // for tracking touch point dispatch. | 535 // for tracking touch point dispatch. |
536 if (send_touch_events_async_) | 536 if (send_touch_events_async_) |
537 touch.event.cancelable = false; | 537 touch.event.cancelable = false; |
538 | 538 |
539 // A synchronous ack will reset |dispatching_touch_|, in which case | 539 // A synchronous ack will reset |dispatching_touch_|, in which case |
540 // the touch timeout should not be started. | 540 // the touch timeout should not be started. |
541 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); | 541 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); |
542 SendTouchEventImmediately(touch); | 542 SendTouchEventImmediately(&touch); |
543 if (dispatching_touch_ && timeout_handler_) | 543 if (dispatching_touch_ && timeout_handler_) |
544 timeout_handler_->StartIfNecessary(touch); | 544 timeout_handler_->StartIfNecessary(touch); |
545 } | 545 } |
546 | 546 |
547 void TouchEventQueue::OnGestureScrollEvent( | 547 void TouchEventQueue::OnGestureScrollEvent( |
548 const GestureEventWithLatencyInfo& gesture_event) { | 548 const GestureEventWithLatencyInfo& gesture_event) { |
549 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { | 549 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { |
550 if (!touch_consumer_states_.is_empty() && | 550 if (!touch_consumer_states_.is_empty() && |
551 !drop_remaining_touches_in_sequence_) { | 551 !drop_remaining_touches_in_sequence_) { |
552 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) | 552 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
696 } | 696 } |
697 | 697 |
698 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { | 698 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { |
699 DCHECK(!touch_queue_.empty()); | 699 DCHECK(!touch_queue_.empty()); |
700 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); | 700 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); |
701 touch_queue_.pop_front(); | 701 touch_queue_.pop_front(); |
702 return event.Pass(); | 702 return event.Pass(); |
703 } | 703 } |
704 | 704 |
705 void TouchEventQueue::SendTouchEventImmediately( | 705 void TouchEventQueue::SendTouchEventImmediately( |
706 const TouchEventWithLatencyInfo& touch) { | 706 TouchEventWithLatencyInfo* touch) { |
707 if (needs_async_touchmove_for_outer_slop_region_) { | 707 if (needs_async_touchmove_for_outer_slop_region_) { |
708 // Any event other than a touchmove (e.g., touchcancel or secondary | 708 // Any event other than a touchmove (e.g., touchcancel or secondary |
709 // touchstart) after a scroll has started will interrupt the need to send a | 709 // touchstart) after a scroll has started will interrupt the need to send a |
710 // an outer slop-region exceeding touchmove. | 710 // an outer slop-region exceeding touchmove. |
711 if (touch.event.type != WebInputEvent::TouchMove || | 711 if (touch->event.type != WebInputEvent::TouchMove || |
712 OutsideApplicationSlopRegion(touch.event, | 712 OutsideApplicationSlopRegion(touch->event, |
713 touch_sequence_start_position_)) | 713 touch_sequence_start_position_)) |
714 needs_async_touchmove_for_outer_slop_region_ = false; | 714 needs_async_touchmove_for_outer_slop_region_ = false; |
715 } | 715 } |
716 | 716 |
717 client_->SendTouchEventImmediately(touch); | 717 // For touchmove events, compare touch points position from current event |
718 // to last sent event and update touch points state. | |
719 if (touch->event.type == WebInputEvent::TouchMove) { | |
720 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) { | |
jdduke (slow)
2015/01/06 17:57:29
|CHECK(last_sent_touchevent_);| to make the crash
USE s.singapati at gmail.com
2015/01/09 12:28:53
CHECK(last_sent_touchevent_) is fine. Or making if
| |
721 const WebTouchPoint& last_touch_point = | |
722 last_sent_touchevent_->touches[i]; | |
723 | |
724 // touches with same id may not have same index in touches array | |
jdduke (slow)
2015/01/06 17:57:29
Nit: Capitalize 'Touches' and end comment with per
USE s.singapati at gmail.com
2015/01/09 12:28:53
Done.
| |
725 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) { | |
726 const WebTouchPoint& current_touchmove_point = touch->event.touches[j]; | |
727 if (last_touch_point.id == current_touchmove_point.id) { | |
728 if (current_touchmove_point.position.x == last_touch_point.position.x | |
729 && current_touchmove_point.position.y == | |
730 last_touch_point.position.y) | |
jdduke (slow)
2015/01/06 17:57:29
Nit: Braces around this if body because the condit
USE s.singapati at gmail.com
2015/01/09 12:28:53
Done.
| |
731 touch->event.touches[j].state = WebTouchPoint::StateStationary; | |
732 | |
733 break; | |
734 } | |
735 } | |
736 } | |
737 } | |
738 | |
739 if (last_sent_touchevent_) | |
740 *last_sent_touchevent_ = touch->event; | |
741 else | |
742 last_sent_touchevent_.reset(new WebTouchEvent(touch->event)); | |
743 | |
744 client_->SendTouchEventImmediately(*touch); | |
718 } | 745 } |
719 | 746 |
720 TouchEventQueue::PreFilterResult | 747 TouchEventQueue::PreFilterResult |
721 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { | 748 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { |
722 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) | 749 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) |
723 return ACK_WITH_NO_CONSUMER_EXISTS; | 750 return ACK_WITH_NO_CONSUMER_EXISTS; |
724 | 751 |
725 if (touchmove_slop_suppressor_->FilterEvent(event)) | 752 if (touchmove_slop_suppressor_->FilterEvent(event)) |
726 return ACK_WITH_NOT_CONSUMED; | 753 return ACK_WITH_NOT_CONSUMED; |
727 | 754 |
728 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { | 755 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
729 touch_consumer_states_.clear(); | 756 touch_consumer_states_.clear(); |
730 send_touch_events_async_ = false; | 757 send_touch_events_async_ = false; |
731 pending_async_touchmove_.reset(); | 758 pending_async_touchmove_.reset(); |
759 last_sent_touchevent_.reset(); | |
760 | |
732 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); | 761 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); |
733 drop_remaining_touches_in_sequence_ = false; | 762 drop_remaining_touches_in_sequence_ = false; |
734 if (!has_handlers_) { | 763 if (!has_handlers_) { |
735 drop_remaining_touches_in_sequence_ = true; | 764 drop_remaining_touches_in_sequence_ = true; |
736 return ACK_WITH_NO_CONSUMER_EXISTS; | 765 return ACK_WITH_NO_CONSUMER_EXISTS; |
737 } | 766 } |
738 } | 767 } |
739 | 768 |
740 if (drop_remaining_touches_in_sequence_ && | 769 if (drop_remaining_touches_in_sequence_ && |
741 event.type != WebInputEvent::TouchCancel) { | 770 event.type != WebInputEvent::TouchCancel) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
777 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) | 806 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) |
778 touch_consumer_states_.mark_bit(point.id); | 807 touch_consumer_states_.mark_bit(point.id); |
779 else | 808 else |
780 touch_consumer_states_.clear_bit(point.id); | 809 touch_consumer_states_.clear_bit(point.id); |
781 } | 810 } |
782 } | 811 } |
783 } | 812 } |
784 } | 813 } |
785 | 814 |
786 } // namespace content | 815 } // namespace content |
OLD | NEW |