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 3670f1e948f213908d1884d9f844eacf35916a5c..dfab0d4ae1e5cb977011833fe221239f38a68ef8 100644 |
| --- a/ui/chromeos/touch_exploration_controller.cc |
| +++ b/ui/chromeos/touch_exploration_controller.cc |
| @@ -27,6 +27,10 @@ const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150); |
| // In ChromeOS, VKEY_LWIN is synonymous for the search key. |
| const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; |
| + |
| +// Delay to indicate that a two finger tap has occured. |
| +const base::TimeDelta kTwoFingerTap = base::TimeDelta::FromMilliseconds(50); |
| + |
| } // namespace |
| TouchExplorationController::TouchExplorationController( |
| @@ -134,6 +138,8 @@ ui::EventRewriteStatus TouchExplorationController::RewriteEvent( |
| return InOneFingerPassthrough(touch_event, rewritten_event); |
| case WAIT_FOR_ONE_FINGER: |
| return InWaitForOneFinger(touch_event, rewritten_event); |
| + case TWO_FINGER_TAP: |
| + return InTwoFingerTap(touch_event, rewritten_event); |
| } |
| NOTREACHED(); |
| return ui::EVENT_REWRITE_CONTINUE; |
| @@ -148,19 +154,20 @@ ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( |
| ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( |
| const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
| const ui::EventType type = event.type(); |
| - if (type == ui::ET_TOUCH_PRESSED) { |
| - initial_press_.reset(new TouchEvent(event)); |
| - last_unused_finger_event_.reset(new TouchEvent(event)); |
| - StartTapTimer(); |
| - gesture_provider_.OnTouchEvent(event); |
| - gesture_provider_.OnTouchEventAck(false); |
| - ProcessGestureEvents(); |
| - state_ = SINGLE_TAP_PRESSED; |
| - VLOG_STATE(); |
| - return ui::EVENT_REWRITE_DISCARD; |
| + if (type != ui::ET_TOUCH_PRESSED) { |
| + NOTREACHED() << "Unexpected event type received: " << event.name(); |
| + return ui::EVENT_REWRITE_CONTINUE; |
| } |
| - NOTREACHED() << "Unexpected event type received: " << event.name(); |
| - return ui::EVENT_REWRITE_CONTINUE; |
| + initial_press_.reset(new TouchEvent(event)); |
| + initial_presses_[event.touch_id()] = event.location(); |
| + last_unused_finger_event_.reset(new TouchEvent(event)); |
| + StartTapTimer(); |
| + gesture_provider_.OnTouchEvent(event); |
| + gesture_provider_.OnTouchEventAck(false); |
| + ProcessGestureEvents(); |
| + state_ = SINGLE_TAP_PRESSED; |
| + VLOG_STATE(); |
| + return ui::EVENT_REWRITE_DISCARD; |
| } |
| ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
| @@ -168,7 +175,12 @@ ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
| const ui::EventType type = event.type(); |
| if (type == ui::ET_TOUCH_PRESSED) { |
| - // TODO (evy, lisayin) : add support for multifinger swipes. |
| + initial_presses_[event.touch_id()] = event.location(); |
| + if ((event.time_stamp() - initial_press_->time_stamp()) < kTwoFingerTap) { |
| + state_ = TWO_FINGER_TAP; |
| + VLOG_STATE(); |
| + return EVENT_REWRITE_DISCARD; |
| + } |
| // For now, we wait for there to be only one finger down again. |
| state_ = WAIT_FOR_ONE_FINGER; |
| return EVENT_REWRITE_DISCARD; |
| @@ -549,6 +561,47 @@ ui::EventRewriteStatus TouchExplorationController::InSlideGesture( |
| return ui::EVENT_REWRITE_DISCARD; |
| } |
| +ui::EventRewriteStatus TouchExplorationController::InTwoFingerTap( |
| + const ui::TouchEvent& event, |
| + scoped_ptr<ui::Event>* rewritten_event) { |
| + ui::EventType type = event.type(); |
| + if (type == ui::ET_TOUCH_PRESSED) { |
| + // TODO(evy): Process three finger gestures here. |
| + state_ = WAIT_FOR_ONE_FINGER; |
| + VLOG_STATE(); |
| + return ui::EVENT_REWRITE_DISCARD; |
| + } |
| + |
| + if (type == ui::ET_TOUCH_MOVED) { |
| + // Determine if it was a swipe. |
| + gfx::Point original_location = initial_presses_[event.touch_id()]; |
| + float distance = (event.location() - original_location).Length(); |
| + // If the user moves too far from the original position, consider the |
| + // movement a swipe. |
| + // TODO(evy, lisayin): Add multifinger swipe processing. |
| + if (distance > gesture_detector_config_.touch_slop) { |
| + state_ = WAIT_FOR_ONE_FINGER; |
| + } |
| + return ui::EVENT_REWRITE_DISCARD; |
| + } |
| + |
| + if (current_touch_ids_.size() != 0) |
| + return ui::EVENT_REWRITE_DISCARD; |
| + |
| + if (type == ui::ET_TOUCH_RELEASED) { |
| + ui::KeyEvent control_down( |
| + ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN); |
| + ui::KeyEvent control_up(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, ui::EF_NONE); |
| + |
| + DispatchEvent(&control_down); |
|
James Cook
2014/08/08 18:06:30
I'm not that familiar with a11y -- maybe a comment
lisayin
2014/08/08 19:06:15
Done.
|
| + DispatchEvent(&control_up); |
| + |
| + ResetToNoFingersDown(); |
| + return ui::EVENT_REWRITE_DISCARD; |
| + } |
| + return ui::EVENT_REWRITE_DISCARD; |
| +} |
| + |
| base::TimeDelta TouchExplorationController::Now() { |
| if (tick_clock_) { |
| // This is the same as what EventTimeForNow() does, but here we do it |
| @@ -595,6 +648,10 @@ void TouchExplorationController::OnTapTimerFired() { |
| state_ = TOUCH_EXPLORATION; |
| VLOG_STATE(); |
| break; |
| + case TWO_FINGER_TAP: |
| + state_ = WAIT_FOR_ONE_FINGER; |
| + VLOG_STATE(); |
| + break; |
| default: |
| return; |
| } |
| @@ -800,6 +857,7 @@ void TouchExplorationController::EnterTouchToMouseMode() { |
| void TouchExplorationController::ResetToNoFingersDown() { |
| ProcessGestureEvents(); |
| + initial_presses_.clear(); |
|
James Cook
2014/08/08 18:06:30
Hooray for clearing out data structures!
lisayin
2014/08/08 19:06:15
:)
|
| if (sound_timer_.IsRunning()) |
| sound_timer_.Stop(); |
| state_ = NO_FINGERS_DOWN; |
| @@ -875,6 +933,8 @@ const char* TouchExplorationController::EnumStateToString(State state) { |
| return "ONE_FINGER_PASSTHROUGH"; |
| case WAIT_FOR_ONE_FINGER: |
| return "WAIT_FOR_ONE_FINGER"; |
| + case TWO_FINGER_TAP: |
| + return "TWO_FINGER_TAP"; |
| } |
| return "Not a state"; |
| } |