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 27 matching lines...) Expand all Loading... |
38 WebInputEvent::TouchCancel, | 38 WebInputEvent::TouchCancel, |
39 // TODO(rbyers): Shouldn't we use a fresh timestamp? | 39 // TODO(rbyers): Shouldn't we use a fresh timestamp? |
40 event.event.timeStampSeconds, | 40 event.event.timeStampSeconds, |
41 &event.event); | 41 &event.event); |
42 return event; | 42 return event; |
43 } | 43 } |
44 | 44 |
45 bool ShouldTouchTriggerTimeout(const WebTouchEvent& event) { | 45 bool ShouldTouchTriggerTimeout(const WebTouchEvent& event) { |
46 return (event.type == WebInputEvent::TouchStart || | 46 return (event.type == WebInputEvent::TouchStart || |
47 event.type == WebInputEvent::TouchMove) && | 47 event.type == WebInputEvent::TouchMove) && |
48 WebInputEventTraits::ShouldBlockEventStream(event) && event.cancelable; | 48 event.dispatchType == WebInputEvent::Blocking; |
49 } | 49 } |
50 | 50 |
51 // Compare all properties of touch points to determine the state. | 51 // Compare all properties of touch points to determine the state. |
52 bool HasPointChanged(const WebTouchPoint& point_1, | 52 bool HasPointChanged(const WebTouchPoint& point_1, |
53 const WebTouchPoint& point_2) { | 53 const WebTouchPoint& point_2) { |
54 DCHECK_EQ(point_1.id, point_2.id); | 54 DCHECK_EQ(point_1.id, point_2.id); |
55 if (point_1.screenPosition != point_2.screenPosition || | 55 if (point_1.screenPosition != point_2.screenPosition || |
56 point_1.position != point_2.position || | 56 point_1.position != point_2.position || |
57 point_1.radiusX != point_2.radiusX || | 57 point_1.radiusX != point_2.radiusX || |
58 point_1.radiusY != point_2.radiusY || | 58 point_1.radiusY != point_2.radiusY || |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 // However, for the (integration) tests in RenderWidgetHostTest that trigger | 502 // However, for the (integration) tests in RenderWidgetHostTest that trigger |
503 // this method indirectly, they push the TouchScrollStarted event into | 503 // this method indirectly, they push the TouchScrollStarted event into |
504 // TouchEventQueue without any way to dispatch it. Below we added a check for | 504 // TouchEventQueue without any way to dispatch it. Below we added a check for |
505 // non-empty queue to keep those tests as-is w/o exposing internals of this | 505 // non-empty queue to keep those tests as-is w/o exposing internals of this |
506 // class all the way up. | 506 // class all the way up. |
507 if (!touch_queue_.empty()) { | 507 if (!touch_queue_.empty()) { |
508 TouchEventWithLatencyInfo touch; | 508 TouchEventWithLatencyInfo touch; |
509 touch.event.type = WebInputEvent::TouchScrollStarted; | 509 touch.event.type = WebInputEvent::TouchScrollStarted; |
510 touch.event.uniqueTouchEventId = 0; | 510 touch.event.uniqueTouchEventId = 0; |
511 touch.event.touchesLength = 0; | 511 touch.event.touchesLength = 0; |
| 512 touch.event.dispatchType = WebInputEvent::EventNonBlocking; |
512 | 513 |
513 auto it = touch_queue_.begin(); | 514 auto it = touch_queue_.begin(); |
514 DCHECK(it != touch_queue_.end()); | 515 DCHECK(it != touch_queue_.end()); |
515 touch_queue_.insert(++it, new CoalescedWebTouchEvent(touch, false)); | 516 touch_queue_.insert(++it, new CoalescedWebTouchEvent(touch, false)); |
516 } | 517 } |
517 } | 518 } |
518 | 519 |
519 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, | 520 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, |
520 const LatencyInfo& latency_info, | 521 const LatencyInfo& latency_info, |
521 const uint32_t unique_touch_event_id) { | 522 const uint32_t unique_touch_event_id) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 } | 628 } |
628 | 629 |
629 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds; | 630 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds; |
630 | 631 |
631 // Flush any pending async touch move. If it can be combined with the current | 632 // Flush any pending async touch move. If it can be combined with the current |
632 // (touchmove) event, great, otherwise send it immediately but separately. Its | 633 // (touchmove) event, great, otherwise send it immediately but separately. Its |
633 // ack will trigger forwarding of the original |touch| event. | 634 // ack will trigger forwarding of the original |touch| event. |
634 if (pending_async_touchmove_) { | 635 if (pending_async_touchmove_) { |
635 if (pending_async_touchmove_->CanCoalesceWith(touch)) { | 636 if (pending_async_touchmove_->CanCoalesceWith(touch)) { |
636 pending_async_touchmove_->CoalesceWith(touch); | 637 pending_async_touchmove_->CoalesceWith(touch); |
637 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; | 638 pending_async_touchmove_->event.dispatchType = |
| 639 send_touch_events_async_ ? WebInputEvent::EventNonBlocking |
| 640 : WebInputEvent::Blocking; |
638 touch = *pending_async_touchmove_; | 641 touch = *pending_async_touchmove_; |
639 pending_async_touchmove_.reset(); | 642 pending_async_touchmove_.reset(); |
640 } else { | 643 } else { |
641 FlushPendingAsyncTouchmove(); | 644 FlushPendingAsyncTouchmove(); |
642 return; | 645 return; |
643 } | 646 } |
644 } | 647 } |
645 | 648 |
646 // Note: Touchstart events are marked cancelable to allow transitions between | 649 // Note: Touchstart events are marked cancelable to allow transitions between |
647 // platform scrolling and JS pinching. Touchend events, however, remain | 650 // platform scrolling and JS pinching. Touchend events, however, remain |
648 // uncancelable, mitigating the risk of jank when transitioning to a fling. | 651 // uncancelable, mitigating the risk of jank when transitioning to a fling. |
649 if (send_touch_events_async_ && touch.event.type != WebInputEvent::TouchStart) | 652 if (send_touch_events_async_ && touch.event.type != WebInputEvent::TouchStart) |
650 touch.event.cancelable = false; | 653 touch.event.dispatchType = WebInputEvent::EventNonBlocking; |
651 | 654 |
652 SendTouchEventImmediately(&touch); | 655 SendTouchEventImmediately(&touch); |
653 } | 656 } |
654 | 657 |
655 void TouchEventQueue::FlushPendingAsyncTouchmove() { | 658 void TouchEventQueue::FlushPendingAsyncTouchmove() { |
656 DCHECK(!dispatching_touch_); | 659 DCHECK(!dispatching_touch_); |
657 std::unique_ptr<TouchEventWithLatencyInfo> touch = | 660 std::unique_ptr<TouchEventWithLatencyInfo> touch = |
658 std::move(pending_async_touchmove_); | 661 std::move(pending_async_touchmove_); |
659 touch->event.cancelable = false; | 662 touch->event.dispatchType = WebInputEvent::EventNonBlocking; |
660 touch_queue_.push_front(new CoalescedWebTouchEvent(*touch, true)); | 663 touch_queue_.push_front(new CoalescedWebTouchEvent(*touch, true)); |
661 SendTouchEventImmediately(touch.get()); | 664 SendTouchEventImmediately(touch.get()); |
662 } | 665 } |
663 | 666 |
664 void TouchEventQueue::OnGestureScrollEvent( | 667 void TouchEventQueue::OnGestureScrollEvent( |
665 const GestureEventWithLatencyInfo& gesture_event) { | 668 const GestureEventWithLatencyInfo& gesture_event) { |
666 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { | 669 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { |
667 if (has_handler_for_current_sequence_ && | 670 if (has_handler_for_current_sequence_ && |
668 !drop_remaining_touches_in_sequence_) { | 671 !drop_remaining_touches_in_sequence_) { |
669 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) | 672 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 } | 821 } |
819 | 822 |
820 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); | 823 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); |
821 | 824 |
822 client_->SendTouchEventImmediately(*touch); | 825 client_->SendTouchEventImmediately(*touch); |
823 | 826 |
824 // A synchronous ack will reset |dispatching_touch_|, in which case the touch | 827 // A synchronous ack will reset |dispatching_touch_|, in which case the touch |
825 // timeout should not be started and the count also should not be increased. | 828 // timeout should not be started and the count also should not be increased. |
826 if (dispatching_touch_) { | 829 if (dispatching_touch_) { |
827 if (touch->event.type == WebInputEvent::TouchMove && | 830 if (touch->event.type == WebInputEvent::TouchMove && |
828 !touch->event.cancelable) { | 831 touch->event.dispatchType != WebInputEvent::Blocking) { |
829 // When we send out a uncancelable touch move, we increase the count and | 832 // When we send out a uncancelable touch move, we increase the count and |
830 // we do not process input event ack any more, we will just ack to client | 833 // we do not process input event ack any more, we will just ack to client |
831 // and wait for the ack from render. Also we will remove it from the front | 834 // and wait for the ack from render. Also we will remove it from the front |
832 // of the queue. | 835 // of the queue. |
833 ack_pending_async_touchmove_ids_.push_back( | 836 ack_pending_async_touchmove_ids_.push_back( |
834 touch->event.uniqueTouchEventId); | 837 touch->event.uniqueTouchEventId); |
835 dispatching_touch_ = false; | 838 dispatching_touch_ = false; |
836 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_IGNORED); | 839 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_IGNORED); |
837 TryForwardNextEventToRenderer(); | 840 TryForwardNextEventToRenderer(); |
838 return; | 841 return; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) | 926 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) |
924 send_touch_events_async_ = false; | 927 send_touch_events_async_ = false; |
925 has_handler_for_current_sequence_ |= | 928 has_handler_for_current_sequence_ |= |
926 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; | 929 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; |
927 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { | 930 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { |
928 has_handler_for_current_sequence_ = false; | 931 has_handler_for_current_sequence_ = false; |
929 } | 932 } |
930 } | 933 } |
931 | 934 |
932 } // namespace content | 935 } // namespace content |
OLD | NEW |