Chromium Code Reviews| Index: content/browser/renderer_host/input/touch_emulator.cc |
| diff --git a/content/browser/renderer_host/input/touch_emulator.cc b/content/browser/renderer_host/input/touch_emulator.cc |
| index 6e4f26bc3acff17b82cb61d04fc83a0e800f893c..ad2ba9884bcd725949709e385ff80c08d778516c 100644 |
| --- a/content/browser/renderer_host/input/touch_emulator.cc |
| +++ b/content/browser/renderer_host/input/touch_emulator.cc |
| @@ -47,7 +47,9 @@ TouchEmulator::TouchEmulator(TouchEmulatorClient* client) |
| : client_(client), |
| gesture_provider_(GetGestureProviderConfig(), this), |
| enabled_(false), |
| - allow_pinch_(false) { |
| + allow_pinch_(false), |
| + emulated_stream_active_sequence_count_(0), |
|
jdduke (slow)
2014/07/18 15:01:05
Good catch.
|
| + native_stream_active_sequence_count_(0) { |
| DCHECK(client_); |
| ResetState(); |
| @@ -85,7 +87,6 @@ void TouchEmulator::ResetState() { |
| last_mouse_move_timestamp_ = 0; |
| mouse_pressed_ = false; |
| shift_pressed_ = false; |
| - touch_active_ = false; |
| suppress_next_fling_cancel_ = false; |
| pinch_scale_ = 1.f; |
| pinch_gesture_active_ = false; |
| @@ -155,7 +156,7 @@ bool TouchEmulator::HandleMouseEvent(const WebMouseEvent& mouse_event) { |
| if (FillTouchEventAndPoint(mouse_event) && |
| gesture_provider_.OnTouchEvent(MotionEventWeb(touch_event_))) { |
| - client_->ForwardTouchEvent(touch_event_); |
| + ForwardTouchEventToClient(); |
| } |
| // Do not pass mouse events to the renderer. |
| @@ -167,7 +168,7 @@ bool TouchEmulator::HandleMouseWheelEvent(const WebMouseWheelEvent& event) { |
| return false; |
| // Send mouse wheel for easy scrolling when there is no active touch. |
| - return touch_active_; |
| + return emulated_stream_active_sequence_count_ > 0; |
| } |
| bool TouchEmulator::HandleKeyboardEvent(const WebKeyboardEvent& event) { |
| @@ -193,11 +194,59 @@ bool TouchEmulator::HandleKeyboardEvent(const WebKeyboardEvent& event) { |
| return false; |
| } |
| -bool TouchEmulator::HandleTouchEventAck(InputEventAckState ack_result) { |
| - const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; |
| - gesture_provider_.OnTouchEventAck(event_consumed); |
| - // TODO(dgozman): Disable emulation when real touch events are available. |
| - return true; |
| +bool TouchEmulator::HandleTouchEvent(const blink::WebTouchEvent& event) { |
| + // Block native event when emulated touch stream is active. |
| + if (emulated_stream_active_sequence_count_) |
| + return true; |
| + |
| + bool is_sequence_start = WebTouchEventTraits::IsTouchSequenceStart(event); |
| + // Do not allow middle-sequence event to pass through, if start was blocked. |
| + if (!native_stream_active_sequence_count_ && !is_sequence_start) |
| + return true; |
| + |
| + if (is_sequence_start) |
| + native_stream_active_sequence_count_++; |
| + return false; |
| +} |
| + |
| +void TouchEmulator::ForwardTouchEventToClient() { |
| + const bool event_consumed = true; |
| + // Block emulated event when emulated native stream is active. |
| + if (native_stream_active_sequence_count_) { |
| + gesture_provider_.OnTouchEventAck(event_consumed); |
| + return; |
| + } |
| + |
| + bool is_sequence_start = |
| + WebTouchEventTraits::IsTouchSequenceStart(touch_event_); |
| + // Do not allow middle-sequence event to pass through, if start was blocked. |
| + if (!emulated_stream_active_sequence_count_ && !is_sequence_start) { |
| + gesture_provider_.OnTouchEventAck(event_consumed); |
| + return; |
| + } |
| + |
| + if (is_sequence_start) |
| + emulated_stream_active_sequence_count_++; |
| + client_->ForwardEmulatedTouchEvent(touch_event_); |
| +} |
| + |
| +bool TouchEmulator::HandleTouchEventAck( |
| + const blink::WebTouchEvent& event, InputEventAckState ack_result) { |
| + bool is_sequence_end = WebTouchEventTraits::IsTouchSequenceEnd(event); |
| + if (emulated_stream_active_sequence_count_) { |
| + if (is_sequence_end) |
| + emulated_stream_active_sequence_count_--; |
| + |
| + const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; |
| + gesture_provider_.OnTouchEventAck(event_consumed); |
| + return true; |
| + } |
| + |
| + // We may have not seen native touch sequence start (when created in the |
| + // middle of a sequence), so don't decrement sequence count below zero. |
| + if (is_sequence_end && native_stream_active_sequence_count_) |
| + native_stream_active_sequence_count_--; |
| + return false; |
| } |
| void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) { |
| @@ -267,16 +316,15 @@ void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) { |
| } |
| void TouchEmulator::CancelTouch() { |
| - if (!touch_active_) |
| + if (!emulated_stream_active_sequence_count_) |
| return; |
| WebTouchEventTraits::ResetTypeAndTouchStates( |
| WebInputEvent::TouchCancel, |
| (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(), |
| &touch_event_); |
| - touch_active_ = false; |
| if (gesture_provider_.OnTouchEvent(MotionEventWeb(touch_event_))) |
| - client_->ForwardTouchEvent(touch_event_); |
| + ForwardTouchEventToClient(); |
| } |
| void TouchEmulator::UpdateCursor() { |
| @@ -352,14 +400,12 @@ bool TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event) { |
| switch (mouse_event.type) { |
| case WebInputEvent::MouseDown: |
| eventType = WebInputEvent::TouchStart; |
| - touch_active_ = true; |
| break; |
| case WebInputEvent::MouseMove: |
| eventType = WebInputEvent::TouchMove; |
| break; |
| case WebInputEvent::MouseUp: |
| eventType = WebInputEvent::TouchEnd; |
| - touch_active_ = false; |
| break; |
| default: |
| eventType = WebInputEvent::Undefined; |