| 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 |