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 66023b1e9cbdb980d194f2a7d20814d2154bea27..d0ccc065ffb8b14080bef9feb0a5f1c9d86ff80e 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,26 @@ 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. |
| + 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 +544,11 @@ 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 can happen, for example, |
| + // when A is acked from renderer but B isn't, so the ack for B is synthesized |
| + // "locally" in InputRouter. |
|
tdresser
2016/04/11 14:43:37
This should never happen.
Does this still happen n
mustaq
2016/04/11 16:03:12
Yes, this can happen even when we avoid reentry to
|
| PopTouchEventToClient(ack_result, latency_info); |
| TryForwardNextEventToRenderer(); |
| @@ -719,38 +741,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, |
| - scoped_ptr<CoalescedWebTouchEvent> acked_event, |
| const ui::LatencyInfo* optional_latency_info) { |
| - DCHECK(acked_event); |
| DCHECK(!dispatching_touch_ack_); |
| + DCHECK(!touch_queue_.empty()); |
| + scoped_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_); |
| -} |
| -scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { |
| - DCHECK(!touch_queue_.empty()); |
| - scoped_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) { |
| + // crbug.com(600773): Hack to avoid cyclic reentry to this method. |
|
tdresser
2016/04/11 14:43:37
Let's format the bug as a url.
mustaq
2016/04/11 16:03:12
Done.
|
| + 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 +801,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 +836,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; |