| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/chromeos/touch_exploration_controller.h" | 5 #include "ui/chromeos/touch_exploration_controller.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "ui/aura/client/cursor_client.h" | 9 #include "ui/aura/client/cursor_client.h" |
| 10 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 case GESTURE_IN_PROGRESS: | 127 case GESTURE_IN_PROGRESS: |
| 128 return InGestureInProgress(touch_event, rewritten_event); | 128 return InGestureInProgress(touch_event, rewritten_event); |
| 129 case TOUCH_EXPLORE_SECOND_PRESS: | 129 case TOUCH_EXPLORE_SECOND_PRESS: |
| 130 return InTouchExploreSecondPress(touch_event, rewritten_event); | 130 return InTouchExploreSecondPress(touch_event, rewritten_event); |
| 131 case SLIDE_GESTURE: | 131 case SLIDE_GESTURE: |
| 132 return InSlideGesture(touch_event, rewritten_event); | 132 return InSlideGesture(touch_event, rewritten_event); |
| 133 case ONE_FINGER_PASSTHROUGH: | 133 case ONE_FINGER_PASSTHROUGH: |
| 134 return InOneFingerPassthrough(touch_event, rewritten_event); | 134 return InOneFingerPassthrough(touch_event, rewritten_event); |
| 135 case WAIT_FOR_ONE_FINGER: | 135 case WAIT_FOR_ONE_FINGER: |
| 136 return InWaitForOneFinger(touch_event, rewritten_event); | 136 return InWaitForOneFinger(touch_event, rewritten_event); |
| 137 case TWO_FINGER_TAP: |
| 138 return InTwoFingerTap(touch_event, rewritten_event); |
| 137 } | 139 } |
| 138 NOTREACHED(); | 140 NOTREACHED(); |
| 139 return ui::EVENT_REWRITE_CONTINUE; | 141 return ui::EVENT_REWRITE_CONTINUE; |
| 140 } | 142 } |
| 141 | 143 |
| 142 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( | 144 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( |
| 143 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { | 145 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { |
| 144 NOTREACHED(); | 146 NOTREACHED(); |
| 145 return ui::EVENT_REWRITE_CONTINUE; | 147 return ui::EVENT_REWRITE_CONTINUE; |
| 146 } | 148 } |
| 147 | 149 |
| 148 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( | 150 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( |
| 149 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 151 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
| 150 const ui::EventType type = event.type(); | 152 const ui::EventType type = event.type(); |
| 151 if (type == ui::ET_TOUCH_PRESSED) { | 153 if (type != ui::ET_TOUCH_PRESSED) { |
| 152 initial_press_.reset(new TouchEvent(event)); | 154 NOTREACHED() << "Unexpected event type received: " << event.name(); |
| 153 last_unused_finger_event_.reset(new TouchEvent(event)); | 155 return ui::EVENT_REWRITE_CONTINUE; |
| 154 StartTapTimer(); | |
| 155 gesture_provider_.OnTouchEvent(event); | |
| 156 gesture_provider_.OnTouchEventAck(false); | |
| 157 ProcessGestureEvents(); | |
| 158 state_ = SINGLE_TAP_PRESSED; | |
| 159 VLOG_STATE(); | |
| 160 return ui::EVENT_REWRITE_DISCARD; | |
| 161 } | 156 } |
| 162 NOTREACHED() << "Unexpected event type received: " << event.name(); | 157 initial_press_.reset(new TouchEvent(event)); |
| 163 return ui::EVENT_REWRITE_CONTINUE; | 158 initial_presses_[event.touch_id()] = event.location(); |
| 159 last_unused_finger_event_.reset(new TouchEvent(event)); |
| 160 StartTapTimer(); |
| 161 gesture_provider_.OnTouchEvent(event); |
| 162 gesture_provider_.OnTouchEventAck(false); |
| 163 ProcessGestureEvents(); |
| 164 state_ = SINGLE_TAP_PRESSED; |
| 165 VLOG_STATE(); |
| 166 return ui::EVENT_REWRITE_DISCARD; |
| 164 } | 167 } |
| 165 | 168 |
| 166 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( | 169 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
| 167 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 170 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
| 168 const ui::EventType type = event.type(); | 171 const ui::EventType type = event.type(); |
| 169 | 172 |
| 170 if (type == ui::ET_TOUCH_PRESSED) { | 173 if (type == ui::ET_TOUCH_PRESSED) { |
| 171 // TODO (evy, lisayin) : add support for multifinger swipes. | 174 initial_presses_[event.touch_id()] = event.location(); |
| 172 // For now, we wait for there to be only one finger down again. | 175 state_ = TWO_FINGER_TAP; |
| 173 state_ = WAIT_FOR_ONE_FINGER; | 176 VLOG_STATE(); |
| 174 return EVENT_REWRITE_DISCARD; | 177 return EVENT_REWRITE_DISCARD; |
| 175 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 178 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 176 if (current_touch_ids_.size() == 0 && | 179 if (current_touch_ids_.size() == 0 && |
| 177 event.touch_id() == initial_press_->touch_id()) { | 180 event.touch_id() == initial_press_->touch_id()) { |
| 178 state_ = SINGLE_TAP_RELEASED; | 181 state_ = SINGLE_TAP_RELEASED; |
| 179 VLOG_STATE(); | 182 VLOG_STATE(); |
| 180 } else if (current_touch_ids_.size() == 0) { | 183 } else if (current_touch_ids_.size() == 0) { |
| 181 ResetToNoFingersDown(); | 184 ResetToNoFingersDown(); |
| 182 } | 185 } |
| 183 return EVENT_REWRITE_DISCARD; | 186 return EVENT_REWRITE_DISCARD; |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 if (current_touch_ids_.size() == 0) { | 545 if (current_touch_ids_.size() == 0) { |
| 543 ResetToNoFingersDown(); | 546 ResetToNoFingersDown(); |
| 544 } | 547 } |
| 545 return ui::EVENT_REWRITE_DISCARD; | 548 return ui::EVENT_REWRITE_DISCARD; |
| 546 } | 549 } |
| 547 | 550 |
| 548 ProcessGestureEvents(); | 551 ProcessGestureEvents(); |
| 549 return ui::EVENT_REWRITE_DISCARD; | 552 return ui::EVENT_REWRITE_DISCARD; |
| 550 } | 553 } |
| 551 | 554 |
| 555 ui::EventRewriteStatus TouchExplorationController::InTwoFingerTap( |
| 556 const ui::TouchEvent& event, |
| 557 scoped_ptr<ui::Event>* rewritten_event) { |
| 558 ui::EventType type = event.type(); |
| 559 if (type == ui::ET_TOUCH_PRESSED) { |
| 560 // TODO(evy): Process three finger gestures here. |
| 561 state_ = WAIT_FOR_ONE_FINGER; |
| 562 VLOG_STATE(); |
| 563 return ui::EVENT_REWRITE_DISCARD; |
| 564 } |
| 565 |
| 566 if (type == ui::ET_TOUCH_MOVED) { |
| 567 // Determine if it was a swipe. |
| 568 gfx::Point original_location = initial_presses_[event.touch_id()]; |
| 569 float distance = (event.location() - original_location).Length(); |
| 570 // If the user moves too far from the original position, consider the |
| 571 // movement a swipe. |
| 572 // TODO(evy, lisayin): Add multifinger swipe processing. |
| 573 if (distance > gesture_detector_config_.touch_slop) { |
| 574 state_ = WAIT_FOR_ONE_FINGER; |
| 575 } |
| 576 return ui::EVENT_REWRITE_DISCARD; |
| 577 } |
| 578 |
| 579 if (current_touch_ids_.size() != 0) |
| 580 return ui::EVENT_REWRITE_DISCARD; |
| 581 |
| 582 if (type == ui::ET_TOUCH_RELEASED) { |
| 583 // In ChromeVox, pressing control will stop ChromeVox from speaking. |
| 584 ui::KeyEvent control_down( |
| 585 ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN); |
| 586 ui::KeyEvent control_up(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, ui::EF_NONE); |
| 587 |
| 588 DispatchEvent(&control_down); |
| 589 DispatchEvent(&control_up); |
| 590 |
| 591 ResetToNoFingersDown(); |
| 592 return ui::EVENT_REWRITE_DISCARD; |
| 593 } |
| 594 return ui::EVENT_REWRITE_DISCARD; |
| 595 } |
| 596 |
| 552 base::TimeDelta TouchExplorationController::Now() { | 597 base::TimeDelta TouchExplorationController::Now() { |
| 553 if (tick_clock_) { | 598 if (tick_clock_) { |
| 554 // This is the same as what EventTimeForNow() does, but here we do it | 599 // This is the same as what EventTimeForNow() does, but here we do it |
| 555 // with a clock that can be replaced with a simulated clock for tests. | 600 // with a clock that can be replaced with a simulated clock for tests. |
| 556 return base::TimeDelta::FromInternalValue( | 601 return base::TimeDelta::FromInternalValue( |
| 557 tick_clock_->NowTicks().ToInternalValue()); | 602 tick_clock_->NowTicks().ToInternalValue()); |
| 558 } | 603 } |
| 559 return ui::EventTimeForNow(); | 604 return ui::EventTimeForNow(); |
| 560 } | 605 } |
| 561 | 606 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 588 DispatchEvent(passthrough_press.get()); | 633 DispatchEvent(passthrough_press.get()); |
| 589 return; | 634 return; |
| 590 } | 635 } |
| 591 case SINGLE_TAP_PRESSED: | 636 case SINGLE_TAP_PRESSED: |
| 592 case GESTURE_IN_PROGRESS: | 637 case GESTURE_IN_PROGRESS: |
| 593 // Discard any pending gestures. | 638 // Discard any pending gestures. |
| 594 delete gesture_provider_.GetAndResetPendingGestures(); | 639 delete gesture_provider_.GetAndResetPendingGestures(); |
| 595 state_ = TOUCH_EXPLORATION; | 640 state_ = TOUCH_EXPLORATION; |
| 596 VLOG_STATE(); | 641 VLOG_STATE(); |
| 597 break; | 642 break; |
| 643 case TWO_FINGER_TAP: |
| 644 state_ = WAIT_FOR_ONE_FINGER; |
| 645 VLOG_STATE(); |
| 646 break; |
| 598 default: | 647 default: |
| 599 return; | 648 return; |
| 600 } | 649 } |
| 601 EnterTouchToMouseMode(); | 650 EnterTouchToMouseMode(); |
| 602 scoped_ptr<ui::Event> mouse_move = | 651 scoped_ptr<ui::Event> mouse_move = |
| 603 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); | 652 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); |
| 604 DispatchEvent(mouse_move.get()); | 653 DispatchEvent(mouse_move.get()); |
| 605 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 654 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
| 606 } | 655 } |
| 607 | 656 |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 aura::client::CursorClient* cursor_client = | 842 aura::client::CursorClient* cursor_client = |
| 794 aura::client::GetCursorClient(root_window_); | 843 aura::client::GetCursorClient(root_window_); |
| 795 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) | 844 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) |
| 796 cursor_client->EnableMouseEvents(); | 845 cursor_client->EnableMouseEvents(); |
| 797 if (cursor_client && cursor_client->IsCursorVisible()) | 846 if (cursor_client && cursor_client->IsCursorVisible()) |
| 798 cursor_client->HideCursor(); | 847 cursor_client->HideCursor(); |
| 799 } | 848 } |
| 800 | 849 |
| 801 void TouchExplorationController::ResetToNoFingersDown() { | 850 void TouchExplorationController::ResetToNoFingersDown() { |
| 802 ProcessGestureEvents(); | 851 ProcessGestureEvents(); |
| 852 initial_presses_.clear(); |
| 803 if (sound_timer_.IsRunning()) | 853 if (sound_timer_.IsRunning()) |
| 804 sound_timer_.Stop(); | 854 sound_timer_.Stop(); |
| 805 state_ = NO_FINGERS_DOWN; | 855 state_ = NO_FINGERS_DOWN; |
| 806 VLOG_STATE(); | 856 VLOG_STATE(); |
| 807 if (tap_timer_.IsRunning()) | 857 if (tap_timer_.IsRunning()) |
| 808 tap_timer_.Stop(); | 858 tap_timer_.Stop(); |
| 809 } | 859 } |
| 810 | 860 |
| 811 void TouchExplorationController::VlogState(const char* function_name) { | 861 void TouchExplorationController::VlogState(const char* function_name) { |
| 812 if (!VLOG_on_) | 862 if (!VLOG_on_) |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 case GESTURE_IN_PROGRESS: | 918 case GESTURE_IN_PROGRESS: |
| 869 return "GESTURE_IN_PROGRESS"; | 919 return "GESTURE_IN_PROGRESS"; |
| 870 case TOUCH_EXPLORE_SECOND_PRESS: | 920 case TOUCH_EXPLORE_SECOND_PRESS: |
| 871 return "TOUCH_EXPLORE_SECOND_PRESS"; | 921 return "TOUCH_EXPLORE_SECOND_PRESS"; |
| 872 case SLIDE_GESTURE: | 922 case SLIDE_GESTURE: |
| 873 return "SLIDE_GESTURE"; | 923 return "SLIDE_GESTURE"; |
| 874 case ONE_FINGER_PASSTHROUGH: | 924 case ONE_FINGER_PASSTHROUGH: |
| 875 return "ONE_FINGER_PASSTHROUGH"; | 925 return "ONE_FINGER_PASSTHROUGH"; |
| 876 case WAIT_FOR_ONE_FINGER: | 926 case WAIT_FOR_ONE_FINGER: |
| 877 return "WAIT_FOR_ONE_FINGER"; | 927 return "WAIT_FOR_ONE_FINGER"; |
| 928 case TWO_FINGER_TAP: |
| 929 return "TWO_FINGER_TAP"; |
| 878 } | 930 } |
| 879 return "Not a state"; | 931 return "Not a state"; |
| 880 } | 932 } |
| 881 | 933 |
| 882 } // namespace ui | 934 } // namespace ui |
| OLD | NEW |