Chromium Code Reviews| Index: content/browser/renderer_host/input/touch_event_queue.cc |
| diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc |
| index a36520fdcb1df30f6bc05fbd2274c6c61b983a30..bebf6efa57a5a4de5fa2c55ccb3a6d65873b60d4 100644 |
| --- a/content/browser/renderer_host/input/touch_event_queue.cc |
| +++ b/content/browser/renderer_host/input/touch_event_queue.cc |
| @@ -28,8 +28,7 @@ namespace { |
| const double kAsyncTouchMoveIntervalSec = .2; |
| // A sanity check on touches received to ensure that touch movement outside |
| -// the platform slop region will cause scrolling, as indicated by the event's |
| -// |causesScrollingIfUncanceled| bit. |
| +// the platform slop region will cause scrolling. |
| const double kMaxConceivablePlatformSlopRegionLengthDipsSquared = 60. * 60.; |
| TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( |
| @@ -491,6 +490,25 @@ void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { |
| touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); |
| } |
| +void TouchEventQueue::PrependTouchScrollNotification() { |
| + TRACE_EVENT0("input", "TouchEventQueue::PrependTouchScrollNotification"); |
| + |
| + TouchEventWithLatencyInfo touch; |
| + touch.event.type = WebInputEvent::TouchScrollStarted; |
| + touch.event.uniqueTouchEventId = 0; |
| + touch.event.touchesLength = 0; |
| + |
| + // Leave the head of the queue untouched since it is an in-flight event. The |
| + // queue should have an in-flight event at this moment because this method is |
| + // triggered by InputRouterImpl::SendGestureEvent, which is triggered by |
| + // TouchEventQueue::AckTouchEventToClient, which has just received an ack for |
| + // the in-flight event. |
|
tdresser
2016/04/11 18:19:38
Should we DCHECK this here?
mustaq
2016/04/11 18:40:41
Didn't add a DCHECK here because I am not 100% sur
|
| + auto it = touch_queue_.begin(); |
| + if (it != touch_queue_.end()) |
| + ++it; |
| + touch_queue_.insert(it, new CoalescedWebTouchEvent(touch, false)); |
| +} |
| + |
| void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, |
| const LatencyInfo& latency_info, |
| const uint32_t unique_touch_event_id) { |
| @@ -525,8 +543,14 @@ void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, |
| if (touch_queue_.empty()) |
| return; |
| - DCHECK_EQ(touch_queue_.front()->coalesced_event().event.uniqueTouchEventId, |
| - unique_touch_event_id); |
| + // We don't care about the ordering of the acks vs the ordering of the |
| + // dispatched events because we can receive the ack for event B before the ack |
| + // for event A even though A was sent before B. This seems to be happening |
| + // when, for example, A is acked from renderer but B isn't, so the ack for B |
| + // is synthesized "locally" in InputRouter. |
| + // |
| + // TODO(crbug.com/600773): Bring the id checks back when dispatch triggering |
| + // is sane. |
| PopTouchEventToClient(ack_result, latency_info); |
| TryForwardNextEventToRenderer(); |
| @@ -719,38 +743,45 @@ void TouchEventQueue::FlushQueue() { |
| } |
| void TouchEventQueue::PopTouchEventToClient(InputEventAckState ack_result) { |
| - AckTouchEventToClient(ack_result, PopTouchEvent(), nullptr); |
| + AckTouchEventToClient(ack_result, nullptr); |
| } |
| void TouchEventQueue::PopTouchEventToClient( |
| InputEventAckState ack_result, |
| const LatencyInfo& renderer_latency_info) { |
| - AckTouchEventToClient(ack_result, PopTouchEvent(), &renderer_latency_info); |
| + AckTouchEventToClient(ack_result, &renderer_latency_info); |
| } |
| void TouchEventQueue::AckTouchEventToClient( |
| InputEventAckState ack_result, |
| - std::unique_ptr<CoalescedWebTouchEvent> acked_event, |
| const ui::LatencyInfo* optional_latency_info) { |
| - DCHECK(acked_event); |
| DCHECK(!dispatching_touch_ack_); |
| + DCHECK(!touch_queue_.empty()); |
| + std::unique_ptr<CoalescedWebTouchEvent> acked_event(touch_queue_.front()); |
| + DCHECK(acked_event); |
| + |
| UpdateTouchConsumerStates(acked_event->coalesced_event().event, ack_result); |
| // Note that acking the touch-event may result in multiple gestures being sent |
| // to the renderer, or touch-events being queued. |
| base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true); |
| - acked_event->DispatchAckToClient(ack_result, optional_latency_info, client_); |
| -} |
| -std::unique_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { |
| - DCHECK(!touch_queue_.empty()); |
| - std::unique_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); |
| + // Skip ack for TouchScrollStarted since it was synthesized within the queue. |
| + if (acked_event->coalesced_event().event.type != |
| + WebInputEvent::TouchScrollStarted) { |
| + acked_event->DispatchAckToClient(ack_result, optional_latency_info, |
| + client_); |
| + } |
| + |
| touch_queue_.pop_front(); |
| - return event; |
| } |
| void TouchEventQueue::SendTouchEventImmediately( |
| TouchEventWithLatencyInfo* touch) { |
| + // TODO(crbug.com/600773): Hack to avoid cyclic reentry to this method. |
| + if (dispatching_touch_) |
| + return; |
| + |
| // For touchmove events, compare touch points position from current event |
| // to last sent event and update touch points state. |
| if (touch->event.type == WebInputEvent::TouchMove) { |
| @@ -772,10 +803,12 @@ void TouchEventQueue::SendTouchEventImmediately( |
| } |
| } |
| - if (last_sent_touchevent_) |
| - *last_sent_touchevent_ = touch->event; |
| - else |
| - last_sent_touchevent_.reset(new WebTouchEvent(touch->event)); |
| + if (touch->event.type != WebInputEvent::TouchScrollStarted) { |
| + if (last_sent_touchevent_) |
| + *last_sent_touchevent_ = touch->event; |
| + else |
| + last_sent_touchevent_.reset(new WebTouchEvent(touch->event)); |
| + } |
| base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); |
| @@ -805,6 +838,9 @@ void TouchEventQueue::SendTouchEventImmediately( |
| TouchEventQueue::PreFilterResult |
| TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { |
| + if (event.type == WebInputEvent::TouchScrollStarted) |
| + return FORWARD_TO_RENDERER; |
| + |
| if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
| has_handler_for_current_sequence_ = false; |
| send_touch_events_async_ = false; |