Chromium Code Reviews| Index: ui/chromeos/touch_exploration_controller.cc |
| diff --git a/ui/chromeos/touch_exploration_controller.cc b/ui/chromeos/touch_exploration_controller.cc |
| index 8b91009ce21777f02d766b1be1f78b34714dba6d..d54b5361d80596b3edfe3f00389413fed5478ba0 100644 |
| --- a/ui/chromeos/touch_exploration_controller.cc |
| +++ b/ui/chromeos/touch_exploration_controller.cc |
| @@ -313,31 +313,46 @@ TouchExplorationController::InSingleTapOrTouchExploreReleased( |
| return ui::EVENT_REWRITE_DISCARD; |
| } |
| if (type == ui::ET_TOUCH_PRESSED) { |
| - // If there is no touch exploration yet, we can't send a click, so discard. |
| + // If there is no touch exploration yet, we can't send a click, so discard |
| + // and wait for no fingers. |
| if (!last_touch_exploration_) { |
| tap_timer_.Stop(); |
| + SET_STATE(WAIT_FOR_NO_FINGERS); |
| return ui::EVENT_REWRITE_DISCARD; |
| } |
| - // This is the second tap in a double-tap (or double tap-hold). |
| - // We set the tap timer. If it fires before the user lifts their finger, |
| - // one-finger passthrough begins. Otherwise, there is a touch press and |
| - // release at the location of the last touch exploration. |
| - SET_STATE(DOUBLE_TAP_PENDING); |
| - // The old tap timer (from the initial click) is stopped if it is still |
| - // going, and the new one is set. |
| - tap_timer_.Stop(); |
| - StartTapTimer(); |
| - // This will update as the finger moves before a possible passthrough, and |
| - // will determine the offset. |
| - last_unused_finger_event_.reset(new ui::TouchEvent(event)); |
| - return ui::EVENT_REWRITE_DISCARD; |
| - } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) { |
| - // If the previous press was discarded, we need to also handle its |
| - // release. |
| - if (current_touch_ids_.size() == 0) { |
| - SET_STATE(NO_FINGERS_DOWN); |
| + if (state_ == SINGLE_TAP_RELEASED) { |
|
dmazzoni
2014/08/15 15:34:01
This "if/else" block is now more than half of the
evy
2014/08/15 16:14:57
Done.
|
| + // This is the second tap in a double-tap (or double tap-hold). |
| + // We set the passthrough timer. If it fires before the user lifts their |
| + // finger, one-finger passthrough begins. Otherwise, there is a touch |
| + // press and release at the location of the last touch exploration. |
| + SET_STATE(DOUBLE_TAP_PENDING); |
| + // Initial press now holds the intial double tap press - this event. |
| + initial_press_.reset(new ui::TouchEvent(event)); |
| + // The old tap timer (from the initial click) is stopped if it is still |
| + // going, and the passthrough timer is set. |
| + tap_timer_.Stop(); |
| + passthrough_timer_.Start( |
| + FROM_HERE, |
| + gesture_detector_config_.longpress_timeout, |
| + this, |
| + &TouchExplorationController::OnPassthroughTimerFired); |
| + // This will update as the finger moves before a possible passthrough, and |
| + // will determine the offset. |
| + last_unused_finger_event_.reset(new ui::TouchEvent(event)); |
| + return ui::EVENT_REWRITE_DISCARD; |
| + } else if (state_ == TOUCH_EXPLORE_RELEASED) { |
| + // This is the initial "press" (location, time, and touch id) of a single |
| + // tap click. |
| + initial_press_.reset(new ui::TouchEvent(event)); |
| + rewritten_event->reset( |
| + new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
| + last_touch_exploration_->location(), |
| + initial_press_->touch_id(), |
| + event.time_stamp())); |
| + (*rewritten_event)->set_flags(event.flags()); |
| + SET_STATE(TOUCH_RELEASE_PENDING); |
| + return ui::EVENT_REWRITE_REWRITTEN; |
| } |
| - return ui::EVENT_REWRITE_DISCARD; |
| } else if (type == ui::ET_TOUCH_MOVED) { |
| return ui::EVENT_REWRITE_DISCARD; |
| } |
| @@ -356,14 +371,21 @@ ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending( |
| // the "slop" region, jump to passthrough mode early. |
| float delta = (event.location() - initial_press_->location()).Length(); |
| if (delta > gesture_detector_config_.touch_slop) { |
| - tap_timer_.Stop(); |
| - OnTapTimerFired(); |
| + passthrough_timer_.Stop(); |
| + if (VLOG_on_) |
| + VLOG(0) << "Finger left slop and is entering passthrough"; |
| + OnPassthroughTimerFired(); |
| } |
| return EVENT_REWRITE_DISCARD; |
| } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| if (current_touch_ids_.size() != 0) |
| return EVENT_REWRITE_DISCARD; |
| + // Now it is recognized that the user was doing a double tap to click. |
| + // The passthrough timer is stopped and a touch press and release are |
| + // dispatched. |
| + passthrough_timer_.Stop(); |
| + |
| scoped_ptr<ui::TouchEvent> touch_press; |
| touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
| last_touch_exploration_->location(), |
| @@ -667,18 +689,6 @@ void TouchExplorationController::OnTapTimerFired() { |
| SET_STATE(NO_FINGERS_DOWN); |
| last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
| return; |
| - case DOUBLE_TAP_PENDING: { |
| - SET_STATE(ONE_FINGER_PASSTHROUGH); |
| - passthrough_offset_ = last_unused_finger_event_->location() - |
| - last_touch_exploration_->location(); |
| - scoped_ptr<ui::TouchEvent> passthrough_press( |
| - new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
| - last_touch_exploration_->location(), |
| - last_unused_finger_event_->touch_id(), |
| - Now())); |
| - DispatchEvent(passthrough_press.get()); |
| - return; |
| - } |
| case SINGLE_TAP_PRESSED: |
| if (passthrough_timer_.IsRunning()) |
| return; |
| @@ -695,6 +705,7 @@ void TouchExplorationController::OnTapTimerFired() { |
| SET_STATE(WAIT_FOR_NO_FINGERS); |
| break; |
| default: |
| + NOTREACHED() << "tap timer fired in unrecognized state"; |
| return; |
| } |
| EnterTouchToMouseMode(); |
| @@ -705,28 +716,52 @@ void TouchExplorationController::OnTapTimerFired() { |
| } |
| void TouchExplorationController::OnPassthroughTimerFired() { |
| - // The passthrough timer will only fire if if the user has held a finger in |
| - // one of the passthrough corners for the duration of the passthrough timeout. |
| - |
| - // Check that initial press isn't null. Also a check that if the initial |
| - // corner press was released, then it should not be in corner passthrough. |
| - if (!initial_press_ || |
| - touch_locations_.find(initial_press_->touch_id()) != |
| - touch_locations_.end()) { |
| - LOG(ERROR) << "No initial press or the initial press has been released."; |
| - } |
| + switch (state_) { |
| + case SINGLE_TAP_PRESSED: |
| + case TOUCH_EXPLORATION: |
| + case GESTURE_IN_PROGRESS: { |
| + // The timer will only fire in this state if if the user has held a finger |
| + // in one of the passthrough corners for the duration of the passthrough |
| + // timeout. |
| + |
| + // Check that initial press isn't null. Also a check that if the initial |
| + // corner press was released, then it should not be in corner passthrough. |
| + if (!initial_press_ || |
| + touch_locations_.find(initial_press_->touch_id()) != |
| + touch_locations_.end()) { |
| + LOG(ERROR) |
| + << "No initial press or the initial press has been released."; |
| + } |
| - gfx::Point location = |
| - ToRoundedPoint(touch_locations_[initial_press_->touch_id()]); |
| - int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); |
| - if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER) |
| - return; |
| + gfx::Point location = |
| + ToRoundedPoint(touch_locations_[initial_press_->touch_id()]); |
| + int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); |
| + if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER) |
| + return; |
| + SET_STATE(CORNER_PASSTHROUGH); |
| + break; |
| + } |
| + case DOUBLE_TAP_PENDING: { |
| + // Enter one finger passthrough mode. |
| + SET_STATE(ONE_FINGER_PASSTHROUGH); |
| + passthrough_offset_ = last_unused_finger_event_->location() - |
| + last_touch_exploration_->location(); |
| + scoped_ptr<ui::TouchEvent> passthrough_press( |
| + new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
| + last_touch_exploration_->location(), |
| + last_unused_finger_event_->touch_id(), |
| + Now())); |
| + DispatchEvent(passthrough_press.get()); |
| + break; |
| + } |
| + default: |
| + NOTREACHED() << "passthrough timer fired in unrecognized state"; |
| + return; |
| + } |
| if (sound_timer_.IsRunning()) |
| sound_timer_.Stop(); |
| delegate_->PlayPassthroughEarcon(); |
| - SET_STATE(CORNER_PASSTHROUGH); |
| - return; |
| } |
| void TouchExplorationController::DispatchEvent(ui::Event* event) { |