Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: ui/chromeos/touch_exploration_controller.cc

Issue 420073003: Two Finger Tap (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed determining swipe gestures Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "ui/aura/window_event_dispatcher.h" 11 #include "ui/aura/window_event_dispatcher.h"
12 #include "ui/aura/window_tree_host.h" 12 #include "ui/aura/window_tree_host.h"
13 #include "ui/events/event.h" 13 #include "ui/events/event.h"
14 #include "ui/events/event_processor.h" 14 #include "ui/events/event_processor.h"
15 #include "ui/events/event_utils.h" 15 #include "ui/events/event_utils.h"
16 #include "ui/gfx/geometry/rect.h" 16 #include "ui/gfx/geometry/rect.h"
17 17
18 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) 18 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__)
19 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) 19 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__)
20 20
21 namespace ui { 21 namespace ui {
22 22
23 namespace { 23 namespace {
24 24
25 // Delay between adjustment sounds. 25 // Delay between adjustment sounds.
26 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150); 26 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150);
27 27
28 // In ChromeOS, VKEY_LWIN is synonymous for the search key. 28 // In ChromeOS, VKEY_LWIN is synonymous for the search key.
29 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; 29 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
30
31 // Delay to indicate that a two finger tap has occured.
32 const base::TimeDelta kTwoFingerTap = base::TimeDelta::FromMilliseconds(50);
33
30 } // namespace 34 } // namespace
31 35
32 TouchExplorationController::TouchExplorationController( 36 TouchExplorationController::TouchExplorationController(
33 aura::Window* root_window, 37 aura::Window* root_window,
34 TouchExplorationControllerDelegate* delegate) 38 TouchExplorationControllerDelegate* delegate)
35 : root_window_(root_window), 39 : root_window_(root_window),
36 delegate_(delegate), 40 delegate_(delegate),
37 state_(NO_FINGERS_DOWN), 41 state_(NO_FINGERS_DOWN),
38 gesture_provider_(this), 42 gesture_provider_(this),
39 prev_state_(NO_FINGERS_DOWN), 43 prev_state_(NO_FINGERS_DOWN),
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 case GESTURE_IN_PROGRESS: 131 case GESTURE_IN_PROGRESS:
128 return InGestureInProgress(touch_event, rewritten_event); 132 return InGestureInProgress(touch_event, rewritten_event);
129 case TOUCH_EXPLORE_SECOND_PRESS: 133 case TOUCH_EXPLORE_SECOND_PRESS:
130 return InTouchExploreSecondPress(touch_event, rewritten_event); 134 return InTouchExploreSecondPress(touch_event, rewritten_event);
131 case SLIDE_GESTURE: 135 case SLIDE_GESTURE:
132 return InSlideGesture(touch_event, rewritten_event); 136 return InSlideGesture(touch_event, rewritten_event);
133 case ONE_FINGER_PASSTHROUGH: 137 case ONE_FINGER_PASSTHROUGH:
134 return InOneFingerPassthrough(touch_event, rewritten_event); 138 return InOneFingerPassthrough(touch_event, rewritten_event);
135 case WAIT_FOR_ONE_FINGER: 139 case WAIT_FOR_ONE_FINGER:
136 return InWaitForOneFinger(touch_event, rewritten_event); 140 return InWaitForOneFinger(touch_event, rewritten_event);
141 case TWO_FINGER_TAP:
142 return InTwoFingerTap(touch_event, rewritten_event);
137 } 143 }
138 NOTREACHED(); 144 NOTREACHED();
139 return ui::EVENT_REWRITE_CONTINUE; 145 return ui::EVENT_REWRITE_CONTINUE;
140 } 146 }
141 147
142 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 148 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
143 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 149 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
144 NOTREACHED(); 150 NOTREACHED();
145 return ui::EVENT_REWRITE_CONTINUE; 151 return ui::EVENT_REWRITE_CONTINUE;
146 } 152 }
147 153
148 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 154 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
149 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 155 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
150 const ui::EventType type = event.type(); 156 const ui::EventType type = event.type();
151 if (type == ui::ET_TOUCH_PRESSED) { 157 if (type != ui::ET_TOUCH_PRESSED) {
152 initial_press_.reset(new TouchEvent(event)); 158 NOTREACHED() << "Unexpected event type received: " << event.name();
153 last_unused_finger_event_.reset(new TouchEvent(event)); 159 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 } 160 }
162 NOTREACHED() << "Unexpected event type received: " << event.name(); 161 initial_press_.reset(new TouchEvent(event));
163 return ui::EVENT_REWRITE_CONTINUE; 162 initial_presses_[event.touch_id()] = event.location();
163 last_unused_finger_event_.reset(new TouchEvent(event));
164 StartTapTimer();
165 gesture_provider_.OnTouchEvent(event);
166 gesture_provider_.OnTouchEventAck(false);
167 ProcessGestureEvents();
168 state_ = SINGLE_TAP_PRESSED;
169 VLOG_STATE();
170 return ui::EVENT_REWRITE_DISCARD;
164 } 171 }
165 172
166 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 173 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
167 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 174 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
168 const ui::EventType type = event.type(); 175 const ui::EventType type = event.type();
169 176
170 if (type == ui::ET_TOUCH_PRESSED) { 177 if (type == ui::ET_TOUCH_PRESSED) {
171 // TODO (evy, lisayin) : add support for multifinger swipes. 178 initial_presses_[event.touch_id()] = event.location();
179 if ((event.time_stamp() - initial_press_->time_stamp()) < kTwoFingerTap) {
180 state_ = TWO_FINGER_TAP;
181 VLOG_STATE();
182 return EVENT_REWRITE_DISCARD;
183 }
172 // For now, we wait for there to be only one finger down again. 184 // For now, we wait for there to be only one finger down again.
173 state_ = WAIT_FOR_ONE_FINGER; 185 state_ = WAIT_FOR_ONE_FINGER;
174 return EVENT_REWRITE_DISCARD; 186 return EVENT_REWRITE_DISCARD;
175 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 187 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
176 if (current_touch_ids_.size() == 0 && 188 if (current_touch_ids_.size() == 0 &&
177 event.touch_id() == initial_press_->touch_id()) { 189 event.touch_id() == initial_press_->touch_id()) {
178 state_ = SINGLE_TAP_RELEASED; 190 state_ = SINGLE_TAP_RELEASED;
179 VLOG_STATE(); 191 VLOG_STATE();
180 } else if (current_touch_ids_.size() == 0) { 192 } else if (current_touch_ids_.size() == 0) {
181 ResetToNoFingersDown(); 193 ResetToNoFingersDown();
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 if (current_touch_ids_.size() == 0) { 554 if (current_touch_ids_.size() == 0) {
543 ResetToNoFingersDown(); 555 ResetToNoFingersDown();
544 } 556 }
545 return ui::EVENT_REWRITE_DISCARD; 557 return ui::EVENT_REWRITE_DISCARD;
546 } 558 }
547 559
548 ProcessGestureEvents(); 560 ProcessGestureEvents();
549 return ui::EVENT_REWRITE_DISCARD; 561 return ui::EVENT_REWRITE_DISCARD;
550 } 562 }
551 563
564 ui::EventRewriteStatus TouchExplorationController::InTwoFingerTap(
565 const ui::TouchEvent& event,
566 scoped_ptr<ui::Event>* rewritten_event) {
567 ui::EventType type = event.type();
568 if (type == ui::ET_TOUCH_PRESSED) {
569 // TODO(evy): Process three finger gestures here.
570 state_ = WAIT_FOR_ONE_FINGER;
571 VLOG_STATE();
572 return ui::EVENT_REWRITE_DISCARD;
573 }
574
575 if (type == ui::ET_TOUCH_MOVED) {
576 // Determine if it was a swipe.
577 gfx::Point original_location = initial_presses_[event.touch_id()];
578 float distance = (event.location() - original_location).Length();
579 // If the user moves too far from the original position, consider the
580 // movement a swipe.
aboxhall 2014/08/07 22:45:19 Does this logic need extra testing?
lisayin 2014/08/08 02:12:24 Done.
581 // TODO(evy, lisayin): Add multifinger swipe processing.
582 if (distance <= gesture_detector_config_.touch_slop) {
583 state_ = WAIT_FOR_ONE_FINGER;
584 }
585 return ui::EVENT_REWRITE_DISCARD;
586 }
587
588 if (current_touch_ids_.size() != 0)
589 return ui::EVENT_REWRITE_DISCARD;
590
591 if (type == ui::ET_TOUCH_RELEASED) {
592 ui::KeyEvent control_down(
593 ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN);
594 ui::KeyEvent control_up(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, ui::EF_NONE);
595
596 DispatchEvent(&control_down);
597 DispatchEvent(&control_up);
598
599 ResetToNoFingersDown();
600 return ui::EVENT_REWRITE_DISCARD;
601 }
602 return ui::EVENT_REWRITE_DISCARD;
603 }
604
552 base::TimeDelta TouchExplorationController::Now() { 605 base::TimeDelta TouchExplorationController::Now() {
553 if (tick_clock_) { 606 if (tick_clock_) {
554 // This is the same as what EventTimeForNow() does, but here we do it 607 // 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. 608 // with a clock that can be replaced with a simulated clock for tests.
556 return base::TimeDelta::FromInternalValue( 609 return base::TimeDelta::FromInternalValue(
557 tick_clock_->NowTicks().ToInternalValue()); 610 tick_clock_->NowTicks().ToInternalValue());
558 } 611 }
559 return ui::EventTimeForNow(); 612 return ui::EventTimeForNow();
560 } 613 }
561 614
(...skipping 26 matching lines...) Expand all
588 DispatchEvent(passthrough_press.get()); 641 DispatchEvent(passthrough_press.get());
589 return; 642 return;
590 } 643 }
591 case SINGLE_TAP_PRESSED: 644 case SINGLE_TAP_PRESSED:
592 case GESTURE_IN_PROGRESS: 645 case GESTURE_IN_PROGRESS:
593 // Discard any pending gestures. 646 // Discard any pending gestures.
594 delete gesture_provider_.GetAndResetPendingGestures(); 647 delete gesture_provider_.GetAndResetPendingGestures();
595 state_ = TOUCH_EXPLORATION; 648 state_ = TOUCH_EXPLORATION;
596 VLOG_STATE(); 649 VLOG_STATE();
597 break; 650 break;
651 case TWO_FINGER_TAP:
652 state_ = WAIT_FOR_ONE_FINGER;
653 VLOG_STATE();
654 break;
598 default: 655 default:
599 return; 656 return;
600 } 657 }
601 EnterTouchToMouseMode(); 658 EnterTouchToMouseMode();
602 scoped_ptr<ui::Event> mouse_move = 659 scoped_ptr<ui::Event> mouse_move =
603 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 660 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
604 DispatchEvent(mouse_move.get()); 661 DispatchEvent(mouse_move.get());
605 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 662 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
606 } 663 }
607 664
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 aura::client::CursorClient* cursor_client = 850 aura::client::CursorClient* cursor_client =
794 aura::client::GetCursorClient(root_window_); 851 aura::client::GetCursorClient(root_window_);
795 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) 852 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
796 cursor_client->EnableMouseEvents(); 853 cursor_client->EnableMouseEvents();
797 if (cursor_client && cursor_client->IsCursorVisible()) 854 if (cursor_client && cursor_client->IsCursorVisible())
798 cursor_client->HideCursor(); 855 cursor_client->HideCursor();
799 } 856 }
800 857
801 void TouchExplorationController::ResetToNoFingersDown() { 858 void TouchExplorationController::ResetToNoFingersDown() {
802 ProcessGestureEvents(); 859 ProcessGestureEvents();
860 initial_presses_.clear();
803 if (sound_timer_.IsRunning()) 861 if (sound_timer_.IsRunning())
804 sound_timer_.Stop(); 862 sound_timer_.Stop();
805 state_ = NO_FINGERS_DOWN; 863 state_ = NO_FINGERS_DOWN;
806 VLOG_STATE(); 864 VLOG_STATE();
807 if (tap_timer_.IsRunning()) 865 if (tap_timer_.IsRunning())
808 tap_timer_.Stop(); 866 tap_timer_.Stop();
809 } 867 }
810 868
811 void TouchExplorationController::VlogState(const char* function_name) { 869 void TouchExplorationController::VlogState(const char* function_name) {
812 if (!VLOG_on_) 870 if (!VLOG_on_)
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 case GESTURE_IN_PROGRESS: 926 case GESTURE_IN_PROGRESS:
869 return "GESTURE_IN_PROGRESS"; 927 return "GESTURE_IN_PROGRESS";
870 case TOUCH_EXPLORE_SECOND_PRESS: 928 case TOUCH_EXPLORE_SECOND_PRESS:
871 return "TOUCH_EXPLORE_SECOND_PRESS"; 929 return "TOUCH_EXPLORE_SECOND_PRESS";
872 case SLIDE_GESTURE: 930 case SLIDE_GESTURE:
873 return "SLIDE_GESTURE"; 931 return "SLIDE_GESTURE";
874 case ONE_FINGER_PASSTHROUGH: 932 case ONE_FINGER_PASSTHROUGH:
875 return "ONE_FINGER_PASSTHROUGH"; 933 return "ONE_FINGER_PASSTHROUGH";
876 case WAIT_FOR_ONE_FINGER: 934 case WAIT_FOR_ONE_FINGER:
877 return "WAIT_FOR_ONE_FINGER"; 935 return "WAIT_FOR_ONE_FINGER";
936 case TWO_FINGER_TAP:
937 return "TWO_FINGER_TAP";
878 } 938 }
879 return "Not a state"; 939 return "Not a state";
880 } 940 }
881 941
882 } // namespace ui 942 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/touch_exploration_controller.h ('k') | ui/chromeos/touch_exploration_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698