Chromium Code Reviews| Index: content/browser/renderer_host/input/gesture_event_queue.cc |
| diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc |
| index 6333de09646b4921801840f7026e742ee3888241..87d45efd9bcfd6a22a29ee770bf50469b103a3b7 100644 |
| --- a/content/browser/renderer_host/input/gesture_event_queue.cc |
| +++ b/content/browser/renderer_host/input/gesture_event_queue.cc |
| @@ -31,7 +31,9 @@ WebGestureEvent CreateGesture(WebInputEvent::Type type) { |
| GestureEventQueue::GestureEventQueue(GestureEventQueueClient* client) |
| : client_(client), |
| needs_tap_ending_event_(false), |
| - needs_fling_ending_event_(false) { |
| + needs_fling_ending_event_(false), |
| + needs_scroll_ending_event_(false), |
| + needs_pinch_ending_event_(false) { |
| DCHECK(client_); |
| } |
| @@ -50,8 +52,8 @@ void GestureEventQueue::OnGestureEventPacket(const GestureEventPacket& packet) { |
| // Handle the timeout packet immediately if the packet preceding the |
| // timeout has already been dispatched. |
| if (Tail().IsEmpty()) { |
| - if (!Tail().IsGesturePrevented()) |
| - SendPacket(packet); |
| + FilterAndSendPacket(packet, Tail().IsGesturePrevented(), |
| + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| return; |
| } |
| break; |
| @@ -72,7 +74,6 @@ void GestureEventQueue::OnTouchEventAck(InputEventAckState ack_state) { |
| } |
| GestureSequence& sequence = Head(); |
| - sequence.UpdateState(ack_state); |
| // Dispatch the packet corresponding to the ack'ed touch, as well as any |
| // additional timeout-based packets queued before the ack was received. |
| @@ -86,11 +87,11 @@ void GestureEventQueue::OnTouchEventAck(InputEventAckState ack_state) { |
| // given ack. |
| if (touch_packet_for_current_ack_handled) |
| break; |
| + if (!packet.is_independent() || packet.gesture_count() == 0) |
| + sequence.UpdateState(ack_state); |
| touch_packet_for_current_ack_handled = true; |
| } |
| - |
| - if (!sequence.IsGesturePrevented()) |
| - SendPacket(packet); |
| + FilterAndSendPacket(packet, sequence.IsGesturePrevented(), ack_state); |
| sequence.Pop(); |
| } |
| @@ -102,18 +103,45 @@ void GestureEventQueue::OnTouchEventAck(InputEventAckState ack_state) { |
| CancelTapIfNecessary(); |
| } |
| -void GestureEventQueue::SendPacket(const GestureEventPacket& packet) { |
| - for (size_t i = 0; i < packet.gesture_count(); ++i) |
| - SendGesture(packet.gesture(i)); |
| +void GestureEventQueue::FilterAndSendPacket( |
| + const GestureEventPacket& packet, |
| + bool gesturePrevented, |
| + InputEventAckState ack_state) { |
| + for (size_t i = 0; i < packet.gesture_count(); ++i) { |
| + const blink::WebGestureEvent& gesture = packet.gesture(i); |
| + |
| + // Scroll and pinch ending events are sent if and only if their |
| + // corresponding begin event was sent, regardless of the filtering state. |
| + bool send = false; |
|
tdresser
2014/02/03 15:52:58
Need {} in this conditional.
tdresser
2014/02/03 18:55:14
Done.
|
| + if (needs_scroll_ending_event_ && |
| + (gesture.type == WebInputEvent::GestureScrollEnd || |
| + gesture.type == WebInputEvent::GestureFlingStart)) |
| + send = true; |
| + else if (needs_pinch_ending_event_ && |
| + gesture.type == WebInputEvent::GesturePinchEnd) |
| + send = true; |
| + // Other gestures are sent only when the current filtering state allows. |
| + else if (!gesturePrevented) { |
| + // Independent packets can be suppressed by the current ack state. |
| + if (!(packet.is_independent() && |
| + ack_state == INPUT_EVENT_ACK_STATE_CONSUMED)) |
| + send = true; |
| + } |
| + |
| + if (send) |
| + SendGesture(gesture); |
| + } |
| } |
| void GestureEventQueue::SendGesture(const WebGestureEvent& event) { |
| + |
| switch (event.type) { |
| case WebInputEvent::GestureLongTap: |
| CancelTapIfNecessary(); |
| CancelFlingIfNecessary(); |
| break; |
| case WebInputEvent::GestureTapDown: |
| + DCHECK(!needs_tap_ending_event_); |
| needs_tap_ending_event_ = true; |
| break; |
| case WebInputEvent::GestureTapCancel: |
| @@ -125,14 +153,28 @@ void GestureEventQueue::SendGesture(const WebGestureEvent& event) { |
| case WebInputEvent::GestureScrollBegin: |
| CancelTapIfNecessary(); |
| CancelFlingIfNecessary(); |
| + DCHECK(!needs_scroll_ending_event_); |
| + needs_scroll_ending_event_ = true; |
| break; |
| case WebInputEvent::GestureFlingStart: |
| CancelFlingIfNecessary(); |
| needs_fling_ending_event_ = true; |
| + // FALL THROUGH |
| + case WebInputEvent::GestureScrollEnd: |
| + DCHECK(needs_scroll_ending_event_); |
| + needs_scroll_ending_event_ = false; |
| break; |
| case WebInputEvent::GestureFlingCancel: |
| needs_fling_ending_event_ = false; |
| break; |
| + case WebInputEvent::GesturePinchBegin: |
| + DCHECK(!needs_pinch_ending_event_); |
| + needs_pinch_ending_event_ = true; |
| + break; |
| + case WebInputEvent::GesturePinchEnd: |
| + DCHECK(needs_pinch_ending_event_); |
| + needs_pinch_ending_event_ = false; |
| + break; |
| default: |
| break; |
| } |