Chromium Code Reviews| 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_->UpdateTouchesStateIfNeededAndSendTouchEvent( |
| 111 cancel_event); | |
| 111 } else { | 112 } else { |
| 112 SetPendingAckState(PENDING_ACK_NONE); | 113 SetPendingAckState(PENDING_ACK_NONE); |
| 113 touch_queue_->UpdateTouchConsumerStates(timeout_event_.event, | 114 touch_queue_->UpdateTouchConsumerStates(timeout_event_.event, |
| 114 ack_result); | 115 ack_result); |
| 115 } | 116 } |
| 116 return true; | 117 return true; |
| 117 case PENDING_ACK_CANCEL_EVENT: | 118 case PENDING_ACK_CANCEL_EVENT: |
| 118 SetPendingAckState(PENDING_ACK_NONE); | 119 SetPendingAckState(PENDING_ACK_NONE); |
| 119 return true; | 120 return true; |
| 120 } | 121 } |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 if (pending_async_touchmove_->CanCoalesceWith(touch)) { | 519 if (pending_async_touchmove_->CanCoalesceWith(touch)) { |
| 519 pending_async_touchmove_->CoalesceWith(touch); | 520 pending_async_touchmove_->CoalesceWith(touch); |
| 520 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; | 521 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; |
| 521 touch = *pending_async_touchmove_; | 522 touch = *pending_async_touchmove_; |
| 522 pending_async_touchmove_.reset(); | 523 pending_async_touchmove_.reset(); |
| 523 } else { | 524 } else { |
| 524 scoped_ptr<TouchEventWithLatencyInfo> async_move = | 525 scoped_ptr<TouchEventWithLatencyInfo> async_move = |
| 525 pending_async_touchmove_.Pass(); | 526 pending_async_touchmove_.Pass(); |
| 526 async_move->event.cancelable = false; | 527 async_move->event.cancelable = false; |
| 527 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true)); | 528 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true)); |
| 528 SendTouchEventImmediately(*async_move); | 529 UpdateTouchesStateIfNeededAndSendTouchEvent(*async_move); |
| 529 return; | 530 return; |
| 530 } | 531 } |
| 531 } | 532 } |
| 532 | 533 |
| 533 // Note: Marking touchstart events as not-cancelable prevents them from | 534 // Note: Marking touchstart events as not-cancelable prevents them from |
| 534 // blocking subsequent gestures, but it may not be the best long term solution | 535 // blocking subsequent gestures, but it may not be the best long term solution |
| 535 // for tracking touch point dispatch. | 536 // for tracking touch point dispatch. |
| 536 if (send_touch_events_async_) | 537 if (send_touch_events_async_) |
| 537 touch.event.cancelable = false; | 538 touch.event.cancelable = false; |
| 538 | 539 |
| 539 // A synchronous ack will reset |dispatching_touch_|, in which case | 540 // A synchronous ack will reset |dispatching_touch_|, in which case |
| 540 // the touch timeout should not be started. | 541 // the touch timeout should not be started. |
| 541 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); | 542 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); |
| 542 SendTouchEventImmediately(touch); | 543 UpdateTouchesStateIfNeededAndSendTouchEvent(touch); |
| 543 if (dispatching_touch_ && timeout_handler_) | 544 if (dispatching_touch_ && timeout_handler_) |
| 544 timeout_handler_->StartIfNecessary(touch); | 545 timeout_handler_->StartIfNecessary(touch); |
| 545 } | 546 } |
| 546 | 547 |
| 547 void TouchEventQueue::OnGestureScrollEvent( | 548 void TouchEventQueue::OnGestureScrollEvent( |
| 548 const GestureEventWithLatencyInfo& gesture_event) { | 549 const GestureEventWithLatencyInfo& gesture_event) { |
| 549 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { | 550 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { |
| 550 if (!touch_consumer_states_.is_empty() && | 551 if (!touch_consumer_states_.is_empty() && |
| 551 !drop_remaining_touches_in_sequence_) { | 552 !drop_remaining_touches_in_sequence_) { |
| 552 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) | 553 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 695 acked_event->DispatchAckToClient(ack_result, optional_latency_info, client_); | 696 acked_event->DispatchAckToClient(ack_result, optional_latency_info, client_); |
| 696 } | 697 } |
| 697 | 698 |
| 698 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { | 699 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { |
| 699 DCHECK(!touch_queue_.empty()); | 700 DCHECK(!touch_queue_.empty()); |
| 700 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); | 701 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); |
| 701 touch_queue_.pop_front(); | 702 touch_queue_.pop_front(); |
| 702 return event.Pass(); | 703 return event.Pass(); |
| 703 } | 704 } |
| 704 | 705 |
| 706 void TouchEventQueue::UpdateTouchesStateIfNeededAndSendTouchEvent( | |
| 707 TouchEventWithLatencyInfo& touch) { | |
|
jdduke (slow)
2014/12/09 20:30:25
This logic can probably be folded into SendTouchEv
USE s.singapati at gmail.com
2014/12/13 07:46:05
Done.
| |
| 708 if (touch.event.type == WebInputEvent::TouchMove) { | |
| 709 if (last_sent_touchmove_) { | |
| 710 WebTouchEvent last_touchmove_event = last_sent_touchmove_->event; | |
| 711 // compare touch points position from current event to last sent event | |
| 712 // and update touch points state. touchesLength & order of touches | |
| 713 // (point ids) should be same in consecutive TouchMoves | |
| 714 for (unsigned int i = 0; i < last_touchmove_event.touchesLength; ++i) { | |
| 715 const WebTouchPoint& last_touchmove_point = | |
| 716 last_touchmove_event.touches[i]; | |
| 717 WebTouchPoint& current_touchmove_point = touch.event.touches[i]; | |
| 718 | |
| 719 // current touches state would have been set to "StateMoved" | |
| 720 // in web_input_event_util. This check may not be needed!? | |
| 721 if (current_touchmove_point.state == WebTouchPoint::StateMoved | |
|
jdduke (slow)
2014/12/09 20:30:25
I don't think there are any guarantees that pointe
USE s.singapati at gmail.com
2014/12/13 07:46:05
Done. Form testing it is found that most of the ti
| |
| 722 && last_touchmove_point.id == current_touchmove_point.id) { | |
| 723 | |
| 724 if (fabs(current_touchmove_point.position.x - | |
| 725 last_touchmove_point.position.x) < 0.000001 | |
| 726 && fabs(current_touchmove_point.position.y - | |
| 727 last_touchmove_point.position.y) < 0.000001) | |
| 728 current_touchmove_point.state = WebTouchPoint::StateStationary; | |
| 729 } | |
| 730 } | |
| 731 } | |
| 732 last_sent_touchmove_.reset(new TouchEventWithLatencyInfo(touch)); | |
|
jdduke (slow)
2014/12/09 20:30:25
Do we need to store the LatencyInfo? I think we ca
USE s.singapati at gmail.com
2014/12/13 07:46:05
Done.
| |
| 733 } else { | |
| 734 if (last_sent_touchmove_) | |
| 735 last_sent_touchmove_.reset(); | |
| 736 } | |
| 737 | |
| 738 SendTouchEventImmediately(touch); | |
| 739 } | |
| 740 | |
| 705 void TouchEventQueue::SendTouchEventImmediately( | 741 void TouchEventQueue::SendTouchEventImmediately( |
| 706 const TouchEventWithLatencyInfo& touch) { | 742 const TouchEventWithLatencyInfo& touch) { |
| 707 if (needs_async_touchmove_for_outer_slop_region_) { | 743 if (needs_async_touchmove_for_outer_slop_region_) { |
| 708 // Any event other than a touchmove (e.g., touchcancel or secondary | 744 // 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 | 745 // touchstart) after a scroll has started will interrupt the need to send a |
| 710 // an outer slop-region exceeding touchmove. | 746 // an outer slop-region exceeding touchmove. |
| 711 if (touch.event.type != WebInputEvent::TouchMove || | 747 if (touch.event.type != WebInputEvent::TouchMove || |
| 712 OutsideApplicationSlopRegion(touch.event, | 748 OutsideApplicationSlopRegion(touch.event, |
| 713 touch_sequence_start_position_)) | 749 touch_sequence_start_position_)) |
| 714 needs_async_touchmove_for_outer_slop_region_ = false; | 750 needs_async_touchmove_for_outer_slop_region_ = false; |
| 715 } | 751 } |
| 716 | 752 |
| 717 client_->SendTouchEventImmediately(touch); | 753 client_->SendTouchEventImmediately(touch); |
| 718 } | 754 } |
| 719 | 755 |
| 720 TouchEventQueue::PreFilterResult | 756 TouchEventQueue::PreFilterResult |
| 721 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { | 757 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { |
| 722 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) | 758 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) |
| 723 return ACK_WITH_NO_CONSUMER_EXISTS; | 759 return ACK_WITH_NO_CONSUMER_EXISTS; |
| 724 | 760 |
| 725 if (touchmove_slop_suppressor_->FilterEvent(event)) | 761 if (touchmove_slop_suppressor_->FilterEvent(event)) |
| 726 return ACK_WITH_NOT_CONSUMED; | 762 return ACK_WITH_NOT_CONSUMED; |
| 727 | 763 |
| 728 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { | 764 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
| 729 touch_consumer_states_.clear(); | 765 touch_consumer_states_.clear(); |
| 730 send_touch_events_async_ = false; | 766 send_touch_events_async_ = false; |
| 731 pending_async_touchmove_.reset(); | 767 pending_async_touchmove_.reset(); |
| 768 last_sent_touchmove_.reset(); | |
| 769 | |
| 732 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); | 770 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); |
| 733 drop_remaining_touches_in_sequence_ = false; | 771 drop_remaining_touches_in_sequence_ = false; |
| 734 if (!has_handlers_) { | 772 if (!has_handlers_) { |
| 735 drop_remaining_touches_in_sequence_ = true; | 773 drop_remaining_touches_in_sequence_ = true; |
| 736 return ACK_WITH_NO_CONSUMER_EXISTS; | 774 return ACK_WITH_NO_CONSUMER_EXISTS; |
| 737 } | 775 } |
| 738 } | 776 } |
| 739 | 777 |
| 740 if (drop_remaining_touches_in_sequence_ && | 778 if (drop_remaining_touches_in_sequence_ && |
| 741 event.type != WebInputEvent::TouchCancel) { | 779 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) | 815 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) |
| 778 touch_consumer_states_.mark_bit(point.id); | 816 touch_consumer_states_.mark_bit(point.id); |
| 779 else | 817 else |
| 780 touch_consumer_states_.clear_bit(point.id); | 818 touch_consumer_states_.clear_bit(point.id); |
| 781 } | 819 } |
| 782 } | 820 } |
| 783 } | 821 } |
| 784 } | 822 } |
| 785 | 823 |
| 786 } // namespace content | 824 } // namespace content |
| OLD | NEW |