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

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

Issue 429633002: Added multi-finger gestures to touch_exploration_controller (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@passthrough
Patch Set: from the original branch 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 "base/time/default_tick_clock.h"
9 #include "ui/aura/client/cursor_client.h" 10 #include "ui/aura/client/cursor_client.h"
10 #include "ui/aura/window.h" 11 #include "ui/aura/window.h"
11 #include "ui/aura/window_event_dispatcher.h" 12 #include "ui/aura/window_event_dispatcher.h"
12 #include "ui/aura/window_tree_host.h" 13 #include "ui/aura/window_tree_host.h"
13 #include "ui/events/event.h" 14 #include "ui/events/event.h"
14 #include "ui/events/event_processor.h" 15 #include "ui/events/event_processor.h"
15 #include "ui/events/event_utils.h" 16 #include "ui/events/event_utils.h"
16 #include "ui/gfx/geometry/rect.h" 17 #include "ui/gfx/geometry/rect.h"
17 18
18 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) 19 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__)
(...skipping 16 matching lines...) Expand all
35 : root_window_(root_window), 36 : root_window_(root_window),
36 delegate_(delegate), 37 delegate_(delegate),
37 state_(NO_FINGERS_DOWN), 38 state_(NO_FINGERS_DOWN),
38 event_handler_for_testing_(NULL), 39 event_handler_for_testing_(NULL),
39 gesture_provider_(this), 40 gesture_provider_(this),
40 prev_state_(NO_FINGERS_DOWN), 41 prev_state_(NO_FINGERS_DOWN),
41 VLOG_on_(true), 42 VLOG_on_(true),
42 tick_clock_(NULL) { 43 tick_clock_(NULL) {
43 CHECK(root_window); 44 CHECK(root_window);
44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 45 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
46 InitializeSwipeGestureMaps();
45 } 47 }
46 48
47 TouchExplorationController::~TouchExplorationController() { 49 TouchExplorationController::~TouchExplorationController() {
48 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); 50 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
49 } 51 }
50 52
51 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 53 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
52 const ui::Event& event, 54 const ui::Event& event,
53 scoped_ptr<ui::Event>* rewritten_event) { 55 scoped_ptr<ui::Event>* rewritten_event) {
54 if (!event.IsTouchEvent()) { 56 if (!event.IsTouchEvent()) {
57 if (event.IsKeyEvent()) {
58 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
59 VLOG(0) << "\nKeyboard event: " << key_event.name()
60 << "\n Key code: " << key_event.key_code()
61 << ", Flags: " << key_event.flags()
62 << ", Is char: " << key_event.is_char();
63 }
55 return ui::EVENT_REWRITE_CONTINUE; 64 return ui::EVENT_REWRITE_CONTINUE;
56 } 65 }
57 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); 66 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event);
58 67
59 // If the tap timer should have fired by now but hasn't, run it now and 68 // If the tap timer should have fired by now but hasn't, run it now and
60 // stop the timer. This is important so that behavior is consistent with 69 // stop the timer. This is important so that behavior is consistent with
61 // the timestamps of the events, and not dependent on the granularity of 70 // the timestamps of the events, and not dependent on the granularity of
62 // the timer. 71 // the timer.
63 if (tap_timer_.IsRunning() && 72 if (tap_timer_.IsRunning() &&
64 touch_event.time_stamp() - initial_press_->time_stamp() > 73 touch_event.time_stamp() - initial_press_->time_stamp() >
65 gesture_detector_config_.double_tap_timeout) { 74 gesture_detector_config_.double_tap_timeout) {
66 tap_timer_.Stop(); 75 tap_timer_.Stop();
67 OnTapTimerFired(); 76 OnTapTimerFired();
68 // Note: this may change the state. We should now continue and process 77 // Note: this may change the state. We should now continue and process
69 // this event under this new state. 78 // this event under this new state.
70 } 79 }
71 80
72 const ui::EventType type = touch_event.type(); 81 const ui::EventType type = touch_event.type();
73 const gfx::PointF& location = touch_event.location_f(); 82 const gfx::PointF& location = touch_event.location_f();
74 const int touch_id = touch_event.touch_id(); 83 const int touch_id = touch_event.touch_id();
75 84
85 // Always process gesture events in the gesture provider. After a swipe
mfomitchev 2014/08/06 16:11:49 Are you sure you want to do gesture recognition be
evy 2014/08/06 18:46:11 We wanted to process every event, and checking the
mfomitchev 2014/08/07 18:34:58 EVENT_REWRITE_CONTINUE should only be returned in
evy 2014/08/07 20:40:26 which EVENT_REWRITE_CONTINUE are you talking about
aboxhall 2014/08/07 20:53:21 IIRC, lisayin@ wrote the FindEdgesWithinBounds log
lisayin 2014/08/07 21:11:35 There's some conversion to DIPS within the actual
mfomitchev 2014/08/08 20:23:13 @evy: You said "checking the ids sometimes returns
86 // gesture is processed, gesture events will continue to be sent to the
87 // gesture provider but will not cause key events to be released again
88 // until after the user resets to no fingers down.
89 gesture_provider_.OnTouchEvent(touch_event);
mfomitchev 2014/08/06 16:11:49 Glad to see you are using GestureProviderAura for
evy 2014/08/06 18:46:12 Acknowledged.
90 gesture_provider_.OnTouchEventAck(false);
91 ProcessGestureEvents();
mfomitchev 2014/08/06 16:11:49 Seems like you only want to call ProcessGestureEve
mfomitchev 2014/08/06 16:11:49 Would it be worth making this return a bool for co
evy 2014/08/06 18:46:12 I put it here because if I only updated it when in
evy 2014/08/06 21:31:56 This is now right before the events are sent to be
92
76 // Always update touch ids and touch locations, so we can use those 93 // Always update touch ids and touch locations, so we can use those
77 // no matter what state we're in. 94 // no matter what state we're in.
78 if (type == ui::ET_TOUCH_PRESSED) { 95 if (type == ui::ET_TOUCH_PRESSED) {
79 current_touch_ids_.push_back(touch_id); 96 current_touch_ids_.push_back(touch_id);
80 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); 97 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
81 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 98 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
82 // In order to avoid accidentally double tapping when moving off the edge of 99 // In order to avoid accidentally double tapping when moving off the edge
83 // the screen, the state will be rewritten to NoFingersDown. 100 // of the screen, the state will be rewritten to NoFingersDown.
84 TouchEvent touch_event = static_cast<const TouchEvent&>(event); 101 TouchEvent touch_event = static_cast<const TouchEvent&>(event);
85 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != 102 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) !=
86 NO_EDGE) { 103 NO_EDGE) {
87 if (current_touch_ids_.size() == 0) { 104 if (current_touch_ids_.size() == 0) {
88 ResetToNoFingersDown(); 105 ResetToNoFingersDown();
89 } 106 }
90 } 107 }
91 108
92 std::vector<int>::iterator it = std::find( 109 std::vector<int>::iterator it = std::find(
93 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); 110 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id);
(...skipping 10 matching lines...) Expand all
104 121
105 // Can happen if touch exploration is enabled while fingers were down. 122 // Can happen if touch exploration is enabled while fingers were down.
106 if (it == current_touch_ids_.end()) 123 if (it == current_touch_ids_.end())
107 return ui::EVENT_REWRITE_CONTINUE; 124 return ui::EVENT_REWRITE_CONTINUE;
108 125
109 touch_locations_[*it] = location; 126 touch_locations_[*it] = location;
110 } 127 }
111 VLOG_STATE(); 128 VLOG_STATE();
112 VLOG_EVENT(touch_event); 129 VLOG_EVENT(touch_event);
113 // The rest of the processing depends on what state we're in. 130 // The rest of the processing depends on what state we're in.
114 switch(state_) { 131 switch (state_) {
115 case NO_FINGERS_DOWN: 132 case NO_FINGERS_DOWN:
116 return InNoFingersDown(touch_event, rewritten_event); 133 return InNoFingersDown(touch_event, rewritten_event);
117 case SINGLE_TAP_PRESSED: 134 case SINGLE_TAP_PRESSED:
118 return InSingleTapPressed(touch_event, rewritten_event); 135 return InSingleTapPressed(touch_event, rewritten_event);
119 case SINGLE_TAP_RELEASED: 136 case SINGLE_TAP_RELEASED:
120 case TOUCH_EXPLORE_RELEASED: 137 case TOUCH_EXPLORE_RELEASED:
121 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event); 138 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event);
122 case DOUBLE_TAP_PENDING: 139 case DOUBLE_TAP_PENDING:
123 return InDoubleTapPending(touch_event, rewritten_event); 140 return InDoubleTapPending(touch_event, rewritten_event);
124 case TOUCH_RELEASE_PENDING: 141 case TOUCH_RELEASE_PENDING:
125 return InTouchReleasePending(touch_event, rewritten_event); 142 return InTouchReleasePending(touch_event, rewritten_event);
126 case TOUCH_EXPLORATION: 143 case TOUCH_EXPLORATION:
127 return InTouchExploration(touch_event, rewritten_event); 144 return InTouchExploration(touch_event, rewritten_event);
128 case GESTURE_IN_PROGRESS: 145 case GESTURE_IN_PROGRESS:
129 return InGestureInProgress(touch_event, rewritten_event); 146 return InGestureInProgress(touch_event, rewritten_event);
130 case TOUCH_EXPLORE_SECOND_PRESS: 147 case TOUCH_EXPLORE_SECOND_PRESS:
131 return InTouchExploreSecondPress(touch_event, rewritten_event); 148 return InTouchExploreSecondPress(touch_event, rewritten_event);
149 case ONE_FINGER_PASSTHROUGH:
150 return InOneFingerPassthrough(touch_event, rewritten_event);
151 case WAIT_FOR_NO_FINGERS:
152 return InWaitForNoFingers(touch_event, rewritten_event);
132 case SLIDE_GESTURE: 153 case SLIDE_GESTURE:
133 return InSlideGesture(touch_event, rewritten_event); 154 return InSlideGesture(touch_event, rewritten_event);
134 case ONE_FINGER_PASSTHROUGH:
135 return InOneFingerPassthrough(touch_event, rewritten_event);
136 case WAIT_FOR_ONE_FINGER:
137 return InWaitForOneFinger(touch_event, rewritten_event);
138 } 155 }
139 NOTREACHED(); 156 NOTREACHED();
140 return ui::EVENT_REWRITE_CONTINUE; 157 return ui::EVENT_REWRITE_CONTINUE;
141 } 158 }
142 159
143 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 160 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
144 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 161 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
145 NOTREACHED(); 162 NOTREACHED();
146 return ui::EVENT_REWRITE_CONTINUE; 163 return ui::EVENT_REWRITE_CONTINUE;
147 } 164 }
148 165
149 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 166 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
150 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 167 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
151 const ui::EventType type = event.type(); 168 const ui::EventType type = event.type();
152 if (type == ui::ET_TOUCH_PRESSED) { 169 if (type == ui::ET_TOUCH_PRESSED) {
153 initial_press_.reset(new TouchEvent(event)); 170 initial_press_.reset(new TouchEvent(event));
154 last_unused_finger_event_.reset(new TouchEvent(event)); 171 last_unused_finger_event_.reset(new TouchEvent(event));
155 StartTapTimer(); 172 StartTapTimer();
156 gesture_provider_.OnTouchEvent(event);
157 gesture_provider_.OnTouchEventAck(false);
158 ProcessGestureEvents();
159 state_ = SINGLE_TAP_PRESSED; 173 state_ = SINGLE_TAP_PRESSED;
160 VLOG_STATE(); 174 VLOG_STATE();
161 return ui::EVENT_REWRITE_DISCARD; 175 return ui::EVENT_REWRITE_DISCARD;
162 } 176 }
163 NOTREACHED() << "Unexpected event type received: " << event.name(); 177 NOTREACHED() << "Unexpected event type received: " << event.name();
164 return ui::EVENT_REWRITE_CONTINUE; 178 return ui::EVENT_REWRITE_CONTINUE;
165 } 179 }
166 180
167 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 181 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
168 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 182 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
169 const ui::EventType type = event.type(); 183 const ui::EventType type = event.type();
170 184
171 if (type == ui::ET_TOUCH_PRESSED) { 185 if (type == ui::ET_TOUCH_PRESSED) {
172 // TODO (evy, lisayin) : add support for multifinger swipes. 186 // This is the start of a multifinger gesture.
173 // For now, we wait for there to be only one finger down again. 187 state_ = GESTURE_IN_PROGRESS;
174 state_ = WAIT_FOR_ONE_FINGER; 188 VLOG_STATE();
175 return EVENT_REWRITE_DISCARD; 189 return InGestureInProgress(event, rewritten_event);
mfomitchev 2014/08/06 16:11:49 Should we consider making 2-finger interactions su
evy 2014/08/06 18:46:12 Actually, two fingers are only used for gestures n
mfomitchev 2014/08/07 18:34:58 Ah, okay, this clears things up, thanks.
176 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 190 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
177 if (current_touch_ids_.size() == 0 && 191 if (current_touch_ids_.size() == 0 &&
178 event.touch_id() == initial_press_->touch_id()) { 192 event.touch_id() == initial_press_->touch_id()) {
179 state_ = SINGLE_TAP_RELEASED; 193 state_ = SINGLE_TAP_RELEASED;
180 VLOG_STATE(); 194 VLOG_STATE();
181 } else if (current_touch_ids_.size() == 0) { 195 } else if (current_touch_ids_.size() == 0) {
182 ResetToNoFingersDown(); 196 ResetToNoFingersDown();
183 } 197 }
184 return EVENT_REWRITE_DISCARD; 198 return EVENT_REWRITE_DISCARD;
185 } else if (type == ui::ET_TOUCH_MOVED) { 199 } else if (type == ui::ET_TOUCH_MOVED) {
(...skipping 26 matching lines...) Expand all
212 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 226 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
213 state_ = GESTURE_IN_PROGRESS; 227 state_ = GESTURE_IN_PROGRESS;
214 VLOG_STATE(); 228 VLOG_STATE();
215 return InGestureInProgress(event, rewritten_event); 229 return InGestureInProgress(event, rewritten_event);
216 } 230 }
217 EnterTouchToMouseMode(); 231 EnterTouchToMouseMode();
218 state_ = TOUCH_EXPLORATION; 232 state_ = TOUCH_EXPLORATION;
219 VLOG_STATE(); 233 VLOG_STATE();
220 return InTouchExploration(event, rewritten_event); 234 return InTouchExploration(event, rewritten_event);
221 } 235 }
222 NOTREACHED() << "Unexpected event type received: " << event.name(); 236 NOTREACHED() << "Unexpected event type received: " << event.name();
aboxhall 2014/08/07 20:53:21 What happened to these useful logs?
evy 2014/08/07 21:20:33 They're all in RewriteEvent now, before event send
223 return ui::EVENT_REWRITE_CONTINUE; 237 return ui::EVENT_REWRITE_CONTINUE;
224 } 238 }
225 239
226 ui::EventRewriteStatus 240 ui::EventRewriteStatus
227 TouchExplorationController::InSingleTapOrTouchExploreReleased( 241 TouchExplorationController::InSingleTapOrTouchExploreReleased(
228 const ui::TouchEvent& event, 242 const ui::TouchEvent& event,
229 scoped_ptr<ui::Event>* rewritten_event) { 243 scoped_ptr<ui::Event>* rewritten_event) {
230 const ui::EventType type = event.type(); 244 const ui::EventType type = event.type();
231 // If there is more than one finger down, then discard to wait until only one 245 // If there is more than one finger down, then discard to wait until no
232 // finger is or no fingers are down. 246 // fingers are down.
233 if (current_touch_ids_.size() > 1) { 247 if (current_touch_ids_.size() > 1) {
234 state_ = WAIT_FOR_ONE_FINGER; 248 state_ = WAIT_FOR_NO_FINGERS;
249 VLOG_STATE();
235 return ui::EVENT_REWRITE_DISCARD; 250 return ui::EVENT_REWRITE_DISCARD;
236 } 251 }
237 if (type == ui::ET_TOUCH_PRESSED) { 252 if (type == ui::ET_TOUCH_PRESSED) {
238 // If there is no touch exploration yet, we can't send a click, so discard. 253 // If there is no touch exploration yet, we can't send a click, so discard.
239 if (!last_touch_exploration_) { 254 if (!last_touch_exploration_) {
240 tap_timer_.Stop(); 255 tap_timer_.Stop();
241 return ui::EVENT_REWRITE_DISCARD; 256 return ui::EVENT_REWRITE_DISCARD;
242 } 257 }
243 // This is the second tap in a double-tap (or double tap-hold). 258 // This is the second tap in a double-tap (or double tap-hold).
244 // We set the tap timer. If it fires before the user lifts their finger, 259 // We set the tap timer. If it fires before the user lifts their finger,
245 // one-finger passthrough begins. Otherwise, there is a touch press and 260 // one-finger passthrough begins. Otherwise, there is a touch press and
246 // release at the location of the last touch exploration. 261 // release at the location of the last touch exploration.
247 state_ = DOUBLE_TAP_PENDING; 262 state_ = DOUBLE_TAP_PENDING;
248 VLOG_STATE(); 263 VLOG_STATE();
264 // The old tap timer (from the initial click) is stopped if it is still
265 // going, and the new one is set.
266 tap_timer_.Stop();
249 StartTapTimer(); 267 StartTapTimer();
250 // This will update as the finger moves before a possible passthrough, and 268 // This will update as the finger moves before a possible passthrough, and
251 // will determine the offset. 269 // will determine the offset.
252 last_unused_finger_event_.reset(new ui::TouchEvent(event)); 270 last_unused_finger_event_.reset(new ui::TouchEvent(event));
253 return ui::EVENT_REWRITE_DISCARD; 271 return ui::EVENT_REWRITE_DISCARD;
254 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) { 272 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) {
255 // If the previous press was discarded, we need to also handle its 273 // If the previous press was discarded, we need to also handle its
256 // release. 274 // release.
257 if (current_touch_ids_.size() == 0) { 275 if (current_touch_ids_.size() == 0) {
258 ResetToNoFingersDown(); 276 ResetToNoFingersDown();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 return ui::EVENT_REWRITE_CONTINUE; 345 return ui::EVENT_REWRITE_CONTINUE;
328 } 346 }
329 347
330 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( 348 ui::EventRewriteStatus TouchExplorationController::InTouchExploration(
331 const ui::TouchEvent& event, 349 const ui::TouchEvent& event,
332 scoped_ptr<ui::Event>* rewritten_event) { 350 scoped_ptr<ui::Event>* rewritten_event) {
333 const ui::EventType type = event.type(); 351 const ui::EventType type = event.type();
334 if (type == ui::ET_TOUCH_PRESSED) { 352 if (type == ui::ET_TOUCH_PRESSED) {
335 // Handle split-tap. 353 // Handle split-tap.
336 initial_press_.reset(new TouchEvent(event)); 354 initial_press_.reset(new TouchEvent(event));
337 if (tap_timer_.IsRunning()) 355 tap_timer_.Stop();
338 tap_timer_.Stop();
339 rewritten_event->reset( 356 rewritten_event->reset(
340 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 357 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
341 last_touch_exploration_->location(), 358 last_touch_exploration_->location(),
342 event.touch_id(), 359 event.touch_id(),
343 event.time_stamp())); 360 event.time_stamp()));
344 (*rewritten_event)->set_flags(event.flags()); 361 (*rewritten_event)->set_flags(event.flags());
345 state_ = TOUCH_EXPLORE_SECOND_PRESS; 362 state_ = TOUCH_EXPLORE_SECOND_PRESS;
346 VLOG_STATE(); 363 VLOG_STATE();
347 return ui::EVENT_REWRITE_REWRITTEN; 364 return ui::EVENT_REWRITE_REWRITTEN;
348 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 365 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
349 initial_press_.reset(new TouchEvent(event)); 366 initial_press_.reset(new TouchEvent(event));
350 StartTapTimer(); 367 StartTapTimer();
351 state_ = TOUCH_EXPLORE_RELEASED; 368 state_ = TOUCH_EXPLORE_RELEASED;
352 VLOG_STATE(); 369 VLOG_STATE();
353 } else if (type != ui::ET_TOUCH_MOVED) { 370 } else if (type != ui::ET_TOUCH_MOVED) {
354 NOTREACHED() << "Unexpected event type received: " << event.name(); 371 NOTREACHED() << "Unexpected event type received: " << event.name();
355 return ui::EVENT_REWRITE_CONTINUE; 372 return ui::EVENT_REWRITE_CONTINUE;
356 } 373 }
357 374
358 // Rewrite as a mouse-move event. 375 // Rewrite as a mouse-move event.
359 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); 376 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
360 last_touch_exploration_.reset(new TouchEvent(event)); 377 last_touch_exploration_.reset(new TouchEvent(event));
361 return ui::EVENT_REWRITE_REWRITTEN; 378 return ui::EVENT_REWRITE_REWRITTEN;
362 } 379 }
363 380
364 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( 381 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress(
365 const ui::TouchEvent& event, 382 const ui::TouchEvent& event,
366 scoped_ptr<ui::Event>* rewritten_event) { 383 scoped_ptr<ui::Event>* rewritten_event) {
367 ui::EventType type = event.type(); 384 ui::EventType type = event.type();
368 // If additional fingers are added before a swipe gesture has been 385 if (type != ui::ET_TOUCH_RELEASED && type != ui::ET_TOUCH_CANCELLED &&
mfomitchev 2014/08/06 16:11:49 This is done in a bunch of different places in sli
evy 2014/08/06 18:46:12 InTouchExploration checks each of them separately
369 // registered, then the state will no longer be GESTURE_IN_PROGRESS. 386 type != ui::ET_TOUCH_MOVED && type != ui::ET_TOUCH_PRESSED) {
370 if (type == ui::ET_TOUCH_PRESSED || 387 NOTREACHED() << "Unexpected event type received: " << event.name();
371 event.touch_id() != initial_press_->touch_id()) { 388 return ui::EVENT_REWRITE_CONTINUE;
372 if (tap_timer_.IsRunning())
373 tap_timer_.Stop();
374 // Discard any pending gestures.
375 delete gesture_provider_.GetAndResetPendingGestures();
376 state_ = WAIT_FOR_ONE_FINGER;
377 return EVENT_REWRITE_DISCARD;
378 } 389 }
379 390 // The events were sent to the gesture provider in RewriteEvent already.
380 // There should not be more than one finger down. 391 // If no gesture is registered before the tap timer times out, the state
381 DCHECK(current_touch_ids_.size() <= 1); 392 // will change to wait for no fingers down and this function will stop
382 if (type == ui::ET_TOUCH_MOVED) { 393 // being called.
383 gesture_provider_.OnTouchEvent(event); 394 if (current_touch_ids_.size() == 0) {
384 gesture_provider_.OnTouchEventAck(false); 395 ResetToNoFingersDown();
385 } 396 }
386 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
387 gesture_provider_.OnTouchEvent(event);
388 gesture_provider_.OnTouchEventAck(false);
389 if (current_touch_ids_.size() == 0) {
390 ResetToNoFingersDown();
391 }
392 }
393 ProcessGestureEvents();
394 return ui::EVENT_REWRITE_DISCARD; 397 return ui::EVENT_REWRITE_DISCARD;
395 } 398 }
396 399
397 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( 400 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough(
398 const ui::TouchEvent& event, 401 const ui::TouchEvent& event,
399 scoped_ptr<ui::Event>* rewritten_event) { 402 scoped_ptr<ui::Event>* rewritten_event) {
400 ui::EventType type = event.type(); 403 ui::EventType type = event.type();
401 404 if (type != ui::ET_TOUCH_RELEASED && type != ui::ET_TOUCH_CANCELLED &&
402 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED || 405 type != ui::ET_TOUCH_MOVED && type != ui::ET_TOUCH_PRESSED) {
403 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) {
404 NOTREACHED() << "Unexpected event type received: " << event.name(); 406 NOTREACHED() << "Unexpected event type received: " << event.name();
405 return ui::EVENT_REWRITE_CONTINUE; 407 return ui::EVENT_REWRITE_CONTINUE;
406 } 408 }
407 if (event.touch_id() != initial_press_->touch_id()) { 409 if (event.touch_id() != initial_press_->touch_id()) {
408 if (current_touch_ids_.size() == 0) { 410 if (current_touch_ids_.size() == 0) {
409 ResetToNoFingersDown(); 411 ResetToNoFingersDown();
410 } 412 }
411 return ui::EVENT_REWRITE_DISCARD; 413 return ui::EVENT_REWRITE_DISCARD;
412 } 414 }
413 rewritten_event->reset( 415 rewritten_event->reset(
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 (*rewritten_event)->set_flags(event.flags()); 461 (*rewritten_event)->set_flags(event.flags());
460 state_ = TOUCH_EXPLORATION; 462 state_ = TOUCH_EXPLORATION;
461 EnterTouchToMouseMode(); 463 EnterTouchToMouseMode();
462 VLOG_STATE(); 464 VLOG_STATE();
463 return ui::EVENT_REWRITE_REWRITTEN; 465 return ui::EVENT_REWRITE_REWRITTEN;
464 } 466 }
465 NOTREACHED() << "Unexpected event type received: " << event.name(); 467 NOTREACHED() << "Unexpected event type received: " << event.name();
466 return ui::EVENT_REWRITE_CONTINUE; 468 return ui::EVENT_REWRITE_CONTINUE;
467 } 469 }
468 470
469 ui::EventRewriteStatus TouchExplorationController::InWaitForOneFinger( 471 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers(
470 const ui::TouchEvent& event, 472 const ui::TouchEvent& event,
471 scoped_ptr<ui::Event>* rewritten_event) { 473 scoped_ptr<ui::Event>* rewritten_event) {
472 ui::EventType type = event.type(); 474 ui::EventType type = event.type();
473 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || 475 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED ||
474 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { 476 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) {
475 NOTREACHED() << "Unexpected event type received: " << event.name(); 477 NOTREACHED() << "Unexpected event type received: " << event.name();
476 return ui::EVENT_REWRITE_CONTINUE; 478 return ui::EVENT_REWRITE_CONTINUE;
477 } 479 }
478 if (current_touch_ids_.size() == 1) { 480
479 EnterTouchToMouseMode(); 481 if (current_touch_ids_.size() == 0)
480 state_ = TOUCH_EXPLORATION; 482 ResetToNoFingersDown();
481 VLOG_STATE(); 483
482 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
483 last_touch_exploration_.reset(new TouchEvent(event));
484 return ui::EVENT_REWRITE_REWRITTEN;
485 }
486 return EVENT_REWRITE_DISCARD; 484 return EVENT_REWRITE_DISCARD;
487 } 485 }
488 486
489 void TouchExplorationController::PlaySoundForTimer() { 487 void TouchExplorationController::PlaySoundForTimer() {
490 delegate_->PlayVolumeAdjustSound(); 488 delegate_->PlayVolumeAdjustSound();
491 } 489 }
492 490
493 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( 491 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
494 const ui::TouchEvent& event, 492 const ui::TouchEvent& event,
495 scoped_ptr<ui::Event>* rewritten_event) { 493 scoped_ptr<ui::Event>* rewritten_event) {
496 // The timer should not fire when sliding. 494 // The timer should not fire when sliding.
497 if (tap_timer_.IsRunning()) 495 tap_timer_.Stop();
498 tap_timer_.Stop();
499 496
500 ui::EventType type = event.type(); 497 ui::EventType type = event.type();
501 // If additional fingers are added before a swipe gesture has been registered, 498 // If additional fingers are added before a swipe gesture has been registered,
502 // then wait until all fingers have been lifted. 499 // then wait until all fingers have been lifted.
503 if (type == ui::ET_TOUCH_PRESSED || 500 if (type == ui::ET_TOUCH_PRESSED ||
504 event.touch_id() != initial_press_->touch_id()) { 501 event.touch_id() != initial_press_->touch_id()) {
505 if (sound_timer_.IsRunning()) 502 if (sound_timer_.IsRunning())
506 sound_timer_.Stop(); 503 sound_timer_.Stop();
507 // Discard any pending gestures. 504 // Discard any pending gestures.
508 delete gesture_provider_.GetAndResetPendingGestures(); 505 delete gesture_provider_.GetAndResetPendingGestures();
509 state_ = WAIT_FOR_ONE_FINGER; 506 state_ = WAIT_FOR_NO_FINGERS;
507 VLOG_STATE();
510 return EVENT_REWRITE_DISCARD; 508 return EVENT_REWRITE_DISCARD;
511 } 509 }
512 510
511 // There should not be more than one finger down.
512 DCHECK(current_touch_ids_.size() <= 1);
513
514
513 // Allows user to return to the edge to adjust the sound if they have left the 515 // Allows user to return to the edge to adjust the sound if they have left the
514 // boundaries. 516 // boundaries.
515 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge); 517 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
516 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) { 518 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) {
517 if (sound_timer_.IsRunning()) { 519 if (sound_timer_.IsRunning()) {
518 sound_timer_.Stop(); 520 sound_timer_.Stop();
519 } 521 }
520 return EVENT_REWRITE_DISCARD; 522 return EVENT_REWRITE_DISCARD;
521 } 523 }
522 524
523 // This can occur if the user leaves the screen edge and then returns to it to 525 // This can occur if the user leaves the screen edge and then returns to it to
524 // continue adjusting the sound. 526 // continue adjusting the sound.
525 if (!sound_timer_.IsRunning()) { 527 if (!sound_timer_.IsRunning()) {
526 sound_timer_.Start(FROM_HERE, 528 sound_timer_.Start(FROM_HERE,
527 kSoundDelay, 529 kSoundDelay,
528 this, 530 this,
529 &ui::TouchExplorationController::PlaySoundForTimer); 531 &ui::TouchExplorationController::PlaySoundForTimer);
530 delegate_->PlayVolumeAdjustSound(); 532 delegate_->PlayVolumeAdjustSound();
531 } 533 }
532 534
533 // There should not be more than one finger down. 535 if (current_touch_ids_.size() == 0) {
534 DCHECK(current_touch_ids_.size() <= 1); 536 ResetToNoFingersDown();
535 if (type == ui::ET_TOUCH_MOVED) {
536 gesture_provider_.OnTouchEvent(event);
537 gesture_provider_.OnTouchEventAck(false);
538 }
539 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
540 gesture_provider_.OnTouchEvent(event);
541 gesture_provider_.OnTouchEventAck(false);
542 delete gesture_provider_.GetAndResetPendingGestures();
543 if (current_touch_ids_.size() == 0) {
544 ResetToNoFingersDown();
545 }
546 return ui::EVENT_REWRITE_DISCARD;
547 } 537 }
548 538
549 ProcessGestureEvents();
550 return ui::EVENT_REWRITE_DISCARD; 539 return ui::EVENT_REWRITE_DISCARD;
551 } 540 }
552 541
553 base::TimeDelta TouchExplorationController::Now() { 542 base::TimeDelta TouchExplorationController::Now() {
554 if (tick_clock_) { 543 if (tick_clock_) {
555 // This is the same as what EventTimeForNow() does, but here we do it 544 // This is the same as what EventTimeForNow() does, but here we do it
556 // with a clock that can be replaced with a simulated clock for tests. 545 // with a clock that can be replaced with a simulated clock for tests.
557 return base::TimeDelta::FromInternalValue( 546 return base::TimeDelta::FromInternalValue(
558 tick_clock_->NowTicks().ToInternalValue()); 547 tick_clock_->NowTicks().ToInternalValue());
559 } 548 }
(...skipping 23 matching lines...) Expand all
583 last_touch_exploration_->location(); 572 last_touch_exploration_->location();
584 scoped_ptr<ui::TouchEvent> passthrough_press( 573 scoped_ptr<ui::TouchEvent> passthrough_press(
585 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 574 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
586 last_touch_exploration_->location(), 575 last_touch_exploration_->location(),
587 last_unused_finger_event_->touch_id(), 576 last_unused_finger_event_->touch_id(),
588 Now())); 577 Now()));
589 DispatchEvent(passthrough_press.get()); 578 DispatchEvent(passthrough_press.get());
590 return; 579 return;
591 } 580 }
592 case SINGLE_TAP_PRESSED: 581 case SINGLE_TAP_PRESSED:
582 EnterTouchToMouseMode();
583 state_ = TOUCH_EXPLORATION;
584 break;
593 case GESTURE_IN_PROGRESS: 585 case GESTURE_IN_PROGRESS:
594 // Discard any pending gestures. 586 // Discard any pending gestures.
595 delete gesture_provider_.GetAndResetPendingGestures(); 587 delete gesture_provider_.GetAndResetPendingGestures();
596 EnterTouchToMouseMode(); 588 // If only one finger is down, go into touch exploration.
597 state_ = TOUCH_EXPLORATION; 589 if (current_touch_ids_.size() == 1) {
590 EnterTouchToMouseMode();
591 state_ = TOUCH_EXPLORATION;
592 VLOG_STATE();
593 return;
594 }
595 // Otherwise wait for all fingers to be lifted.
596 state_ = WAIT_FOR_NO_FINGERS;
598 VLOG_STATE(); 597 VLOG_STATE();
599 break; 598 return;
600 default: 599 default:
601 return; 600 return;
602 } 601 }
603 scoped_ptr<ui::Event> mouse_move = 602 scoped_ptr<ui::Event> mouse_move =
604 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 603 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
605 DispatchEvent(mouse_move.get()); 604 DispatchEvent(mouse_move.get());
606 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 605 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
607 } 606 }
608 607
609 void TouchExplorationController::DispatchEvent(ui::Event* event) { 608 void TouchExplorationController::DispatchEvent(ui::Event* event) {
610 if (event_handler_for_testing_) { 609 if (event_handler_for_testing_) {
611 event_handler_for_testing_->OnEvent(event); 610 event_handler_for_testing_->OnEvent(event);
612 return; 611 return;
613 } 612 }
614 ui::EventDispatchDetails result ALLOW_UNUSED = 613 ui::EventDispatchDetails result ALLOW_UNUSED =
615 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 614 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
616 } 615 }
617 616
618 void TouchExplorationController::OnGestureEvent( 617 void TouchExplorationController::OnGestureEvent(
619 ui::GestureEvent* gesture) { 618 ui::GestureEvent* gesture) {
620 CHECK(gesture->IsGestureEvent()); 619 CHECK(gesture->IsGestureEvent());
621 ui::EventType type = gesture->type(); 620 ui::EventType type = gesture->type();
622 if (VLOG_on_) 621 if (type == ui::ET_GESTURE_SWIPE && state_ == GESTURE_IN_PROGRESS) {
623 VLOG(0) << " \n Gesture Triggered: " << gesture->name();
624 if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) {
625 if (VLOG_on_)
626 VLOG(0) << "Swipe!";
627 delete gesture_provider_.GetAndResetPendingGestures(); 622 delete gesture_provider_.GetAndResetPendingGestures();
mfomitchev 2014/08/06 16:11:49 This seems wrong. You've already done GetAndResetP
evy 2014/08/06 18:46:12 I thought I had deleted these because we're always
628 OnSwipeEvent(gesture); 623 OnSwipeEvent(gesture);
624 // The tap timer to leave gesture state is ended, and we now wait for all
625 // fingers to be released.
626 tap_timer_.Stop();
627 state_ = WAIT_FOR_NO_FINGERS;
628 VLOG_STATE();
629 return; 629 return;
630 } 630 }
631 } 631 }
632 632
633 void TouchExplorationController::ProcessGestureEvents() { 633 void TouchExplorationController::ProcessGestureEvents() {
mfomitchev 2014/08/06 16:11:49 return a bool?
evy 2014/08/06 21:31:56 I'm doing it a bit differently - tell me what you
634 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( 634 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures(
635 gesture_provider_.GetAndResetPendingGestures()); 635 gesture_provider_.GetAndResetPendingGestures());
636 if (gestures) { 636 if (gestures) {
637 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); 637 for (ScopedVector<GestureEvent>::iterator i = gestures->begin();
638 i != gestures->end(); 638 i != gestures->end();
639 ++i) { 639 ++i) {
640 if (VLOG_on_ &&
641 (state_ == SLIDE_GESTURE || state_ == GESTURE_IN_PROGRESS) &&
642 (*i)->type() == ui::ET_GESTURE_SWIPE)
643 VLOG(0) << " \n Gesture Triggered: " << (*i)->name();
640 if (state_ == SLIDE_GESTURE) 644 if (state_ == SLIDE_GESTURE)
641 SideSlideControl(*i); 645 SideSlideControl(*i);
642 else 646 else
643 OnGestureEvent(*i); 647 OnGestureEvent(*i);
mfomitchev 2014/08/06 16:11:49 break the loop if this returns true
evy 2014/08/06 21:31:57 breaks the loop on a return if a swipe or slide ge
644 } 648 }
645 } 649 }
646 } 650 }
647 651
648 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { 652 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) {
649 ui::EventType type = gesture->type(); 653 ui::EventType type = gesture->type();
650 if (!gesture->IsScrollGestureEvent()) 654 if (!gesture->IsScrollGestureEvent())
651 return; 655 return;
652 656
653 if (type == ET_GESTURE_SCROLL_BEGIN) { 657 if (type == ET_GESTURE_SCROLL_BEGIN) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; 690 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height;
687 float volume = 100 - 100 * ratio; 691 float volume = 100 - 100 * ratio;
688 if (VLOG_on_) { 692 if (VLOG_on_) {
689 VLOG(0) << "\n Volume = " << volume 693 VLOG(0) << "\n Volume = " << volume
690 << "\n Location = " << location.ToString() 694 << "\n Location = " << location.ToString()
691 << "\n Bounds = " << root_window_->bounds().right(); 695 << "\n Bounds = " << root_window_->bounds().right();
692 } 696 }
693 delegate_->SetOutputLevel(int(volume)); 697 delegate_->SetOutputLevel(int(volume));
694 } 698 }
695 699
696
697 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { 700 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) {
698 // A swipe gesture contains details for the direction in which the swipe 701 // A swipe gesture contains details for the direction in which the swipe
699 // occurred. 702 // occurred. TODO(evy) : Research which swipe results users most want and
703 // remap these swipes to the best events. Hopefully in the near future
704 // there will also be a menu for users to pick custom mappings.
700 GestureEventDetails event_details = swipe_gesture->details(); 705 GestureEventDetails event_details = swipe_gesture->details();
701 if (event_details.swipe_left()) { 706 int num_fingers = event_details.touch_points();
702 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); 707 if(VLOG_on_)
708 VLOG(0) << "\nSwipe with " << num_fingers << " fingers.";
709
710 if (num_fingers > 4)
703 return; 711 return;
704 } else if (event_details.swipe_right()) { 712
705 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); 713 if (event_details.swipe_left())
mfomitchev 2014/08/06 16:11:49 I'd check left_swipe_gestures_[num_fingers] to be
evy 2014/08/08 22:39:13 I did a check for is_null() - let me know if this
706 return; 714 left_swipe_gestures_[num_fingers].Run();
707 } else if (event_details.swipe_up()) { 715 else if (event_details.swipe_right())
708 DispatchShiftSearchKeyEvent(ui::VKEY_UP); 716 right_swipe_gestures_[num_fingers].Run();
709 return; 717 else if (event_details.swipe_up())
710 } else if (event_details.swipe_down()) { 718 up_swipe_gestures_[num_fingers].Run();
711 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); 719 else if (event_details.swipe_down())
712 return; 720 down_swipe_gestures_[num_fingers].Run();
713 }
714 } 721 }
715 722
716 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, 723 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point,
717 float bounds) { 724 float bounds) {
718 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be 725 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be
719 // converted. 726 // converted.
720 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); 727 root_window_->GetHost()->ConvertPointFromNativeScreen(&point);
721 gfx::Rect window = root_window_->GetBoundsInScreen(); 728 gfx::Rect window = root_window_->GetBoundsInScreen();
722 729
723 float left_edge_limit = window.x() + bounds; 730 float left_edge_limit = window.x() + bounds;
(...skipping 10 matching lines...) Expand all
734 result |= LEFT_EDGE; 741 result |= LEFT_EDGE;
735 if (point.x() > right_edge_limit) 742 if (point.x() > right_edge_limit)
736 result |= RIGHT_EDGE; 743 result |= RIGHT_EDGE;
737 if (point.y() < top_edge_limit) 744 if (point.y() < top_edge_limit)
738 result |= TOP_EDGE; 745 result |= TOP_EDGE;
739 if (point.y() > bottom_edge_limit) 746 if (point.y() > bottom_edge_limit)
740 result |= BOTTOM_EDGE; 747 result |= BOTTOM_EDGE;
741 return result; 748 return result;
742 } 749 }
743 750
744 void TouchExplorationController::DispatchShiftSearchKeyEvent( 751 void TouchExplorationController::DispatchShiftSearchKeyEvent(
mfomitchev 2014/08/06 16:11:49 Hmm.. I think it would be cleaner if TEC just call
evy 2014/08/08 22:39:13 This would be awesome - our team has talked about
745 const ui::KeyboardCode direction) { 752 const ui::KeyboardCode third_key) {
746 // In order to activate the shortcut shift+search+<arrow key> 753 // In order to activate the shortcut shift+search+<key>
747 // three KeyPressed events must be dispatched in succession along 754 // three KeyPressed events must be dispatched in succession along
748 // with three KeyReleased events. 755 // with three KeyReleased events.
749 ui::KeyEvent shift_down = ui::KeyEvent( 756
757 ui::KeyEvent shift_down(
750 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); 758 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN);
751 ui::KeyEvent search_down = ui::KeyEvent( 759 ui::KeyEvent search_down(
752 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); 760 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN);
753 ui::KeyEvent direction_down = 761 ui::KeyEvent third_key_down(ui::ET_KEY_PRESSED, third_key, ui::EF_SHIFT_DOWN);
754 ui::KeyEvent(ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN);
755 762
756 ui::KeyEvent direction_up = 763 ui::KeyEvent third_key_up(ui::ET_KEY_RELEASED, third_key, ui::EF_SHIFT_DOWN);
757 ui::KeyEvent(ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN); 764 ui::KeyEvent search_up(
758 ui::KeyEvent search_up = ui::KeyEvent(
759 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); 765 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN);
760 ui::KeyEvent shift_up = 766 ui ::KeyEvent shift_up(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE);
761 ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE);
762 767
763 DispatchEvent(&shift_down); 768 DispatchEvent(&shift_down);
764 DispatchEvent(&search_down); 769 DispatchEvent(&search_down);
765 DispatchEvent(&direction_down); 770 DispatchEvent(&third_key_down);
766 DispatchEvent(&direction_up); 771 DispatchEvent(&third_key_up);
767 DispatchEvent(&search_up); 772 DispatchEvent(&search_up);
768 DispatchEvent(&shift_up); 773 DispatchEvent(&shift_up);
769 } 774 }
770 775
776 void TouchExplorationController::DispatchKeyWithFlags(
777 const ui::KeyboardCode key,
778 int flags) {
779 ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags);
780 ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags);
781 DispatchEvent(&key_down);
782 DispatchEvent(&key_up);
783 if(VLOG_on_) {
784 VLOG(0) << "\nKey down: key code : " << key_down.key_code()
785 << ", flags: " << key_down.flags()
786 << "\nKey up: key code : " << key_up.key_code()
787 << ", flags: " << key_up.flags();
788 }
789 }
790
771 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( 791 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent(
772 const gfx::PointF& location, 792 const gfx::PointF& location,
773 int flags) { 793 int flags) {
774 // The "synthesized" flag should be set on all events that don't have a 794 // The "synthesized" flag should be set on all events that don't have a
775 // backing native event. 795 // backing native event.
776 flags |= ui::EF_IS_SYNTHESIZED; 796 flags |= ui::EF_IS_SYNTHESIZED;
777 797
778 // This flag is used to identify mouse move events that were generated from 798 // This flag is used to identify mouse move events that were generated from
779 // touch exploration in Chrome code. 799 // touch exploration in Chrome code.
780 flags |= ui::EF_TOUCH_ACCESSIBILITY; 800 flags |= ui::EF_TOUCH_ACCESSIBILITY;
(...skipping 21 matching lines...) Expand all
802 if (cursor_client && cursor_client->IsCursorVisible()) 822 if (cursor_client && cursor_client->IsCursorVisible())
803 cursor_client->HideCursor(); 823 cursor_client->HideCursor();
804 } 824 }
805 825
806 void TouchExplorationController::ResetToNoFingersDown() { 826 void TouchExplorationController::ResetToNoFingersDown() {
807 ProcessGestureEvents(); 827 ProcessGestureEvents();
808 if (sound_timer_.IsRunning()) 828 if (sound_timer_.IsRunning())
809 sound_timer_.Stop(); 829 sound_timer_.Stop();
810 state_ = NO_FINGERS_DOWN; 830 state_ = NO_FINGERS_DOWN;
811 VLOG_STATE(); 831 VLOG_STATE();
812 if (tap_timer_.IsRunning()) 832 tap_timer_.Stop();
813 tap_timer_.Stop();
814 } 833 }
815 834
816 void TouchExplorationController::VlogState(const char* function_name) { 835 void TouchExplorationController::VlogState(const char* function_name) {
817 if (!VLOG_on_) 836 if (!VLOG_on_)
818 return; 837 return;
819 if (prev_state_ == state_) 838 if (prev_state_ == state_)
820 return; 839 return;
821 prev_state_ = state_; 840 prev_state_ = state_;
822 const char* state_string = EnumStateToString(state_); 841 const char* state_string = EnumStateToString(state_);
823 VLOG(0) << "\n Function name: " << function_name 842 VLOG(0) << "\n Function name: " << function_name
(...skipping 12 matching lines...) Expand all
836 return; 855 return;
837 } 856 }
838 // The above statement prevents events of the same type and id from being 857 // The above statement prevents events of the same type and id from being
839 // printed in a row. However, if two fingers are down, they would both be 858 // printed in a row. However, if two fingers are down, they would both be
840 // moving and alternating printing move events unless we check for this. 859 // moving and alternating printing move events unless we check for this.
841 if (prev_event_ != NULL && 860 if (prev_event_ != NULL &&
842 prev_event_->type() == ET_TOUCH_MOVED && 861 prev_event_->type() == ET_TOUCH_MOVED &&
843 touch_event.type() == ET_TOUCH_MOVED){ 862 touch_event.type() == ET_TOUCH_MOVED){
844 return; 863 return;
845 } 864 }
865
846 const std::string& type = touch_event.name(); 866 const std::string& type = touch_event.name();
847 const gfx::PointF& location = touch_event.location_f(); 867 const gfx::PointF& location = touch_event.location_f();
848 const int touch_id = touch_event.touch_id(); 868 const int touch_id = touch_event.touch_id();
849 869
850 VLOG(0) << "\n Function name: " << function_name 870 VLOG(0) << "\n Function name: " << function_name
851 << "\n Event Type: " << type 871 << "\n Event Type: " << type
852 << "\n Location: " << location.ToString() 872 << "\n Location: " << location.ToString()
853 << "\n Touch ID: " << touch_id; 873 << "\n Touch ID: " << touch_id;
854 prev_event_.reset(new TouchEvent(touch_event)); 874 prev_event_.reset(new TouchEvent(touch_event));
855 } 875 }
(...skipping 11 matching lines...) Expand all
867 case DOUBLE_TAP_PENDING: 887 case DOUBLE_TAP_PENDING:
868 return "DOUBLE_TAP_PENDING"; 888 return "DOUBLE_TAP_PENDING";
869 case TOUCH_RELEASE_PENDING: 889 case TOUCH_RELEASE_PENDING:
870 return "TOUCH_RELEASE_PENDING"; 890 return "TOUCH_RELEASE_PENDING";
871 case TOUCH_EXPLORATION: 891 case TOUCH_EXPLORATION:
872 return "TOUCH_EXPLORATION"; 892 return "TOUCH_EXPLORATION";
873 case GESTURE_IN_PROGRESS: 893 case GESTURE_IN_PROGRESS:
874 return "GESTURE_IN_PROGRESS"; 894 return "GESTURE_IN_PROGRESS";
875 case TOUCH_EXPLORE_SECOND_PRESS: 895 case TOUCH_EXPLORE_SECOND_PRESS:
876 return "TOUCH_EXPLORE_SECOND_PRESS"; 896 return "TOUCH_EXPLORE_SECOND_PRESS";
897 case ONE_FINGER_PASSTHROUGH:
898 return "ONE_FINGER_PASSTHROUGH";
899 case WAIT_FOR_NO_FINGERS:
900 return "WAIT_FOR_NO_FINGERS";
877 case SLIDE_GESTURE: 901 case SLIDE_GESTURE:
878 return "SLIDE_GESTURE"; 902 return "SLIDE_GESTURE";
879 case ONE_FINGER_PASSTHROUGH:
880 return "ONE_FINGER_PASSTHROUGH";
881 case WAIT_FOR_ONE_FINGER:
882 return "WAIT_FOR_ONE_FINGER";
883 } 903 }
884 return "Not a state"; 904 return "Not a state";
885 } 905 }
886 906
907 void TouchExplorationController::InitializeSwipeGestureMaps() {
908 // Gestures with one finger are used for navigation.
909 left_swipe_gestures_[1] =
910 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
911 base::Unretained(this),
912 ui::VKEY_LEFT);
913 right_swipe_gestures_[1] =
914 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
915 base::Unretained(this),
916 ui::VKEY_RIGHT);
917 up_swipe_gestures_[1] =
918 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
919 base::Unretained(this),
920 ui::VKEY_UP);
921 down_swipe_gestures_[1] =
922 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
923 base::Unretained(this),
924 ui::VKEY_DOWN);
925
926 // Gestures with two fingers.
927 left_swipe_gestures_[2] =
928 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
929 base::Unretained(this),
930 ui::VKEY_BROWSER_BACK,
931 ui::EF_NONE);
932 right_swipe_gestures_[2] =
933 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
934 base::Unretained(this),
935 ui::VKEY_BROWSER_FORWARD,
936 ui::EF_NONE);
937 // Jump to top.
938 up_swipe_gestures_[2] =
939 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
940 base::Unretained(this),
941 ui::VKEY_A);
942 // Read from here.
943 down_swipe_gestures_[2] =
944 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent,
945 base::Unretained(this),
946 ui::VKEY_R);
947
948 // Gestures with three fingers switch tabs left/right and scroll up/down.
949 left_swipe_gestures_[3] =
950 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
951 base::Unretained(this),
952 ui::VKEY_TAB,
953 ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);
954 right_swipe_gestures_[3] =
955 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
956 base::Unretained(this),
957 ui::VKEY_TAB,
958 ui::EF_CONTROL_DOWN);
959 up_swipe_gestures_[3] =
960 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
961 base::Unretained(this),
962 ui::VKEY_NEXT,
963 ui::EF_NONE);
964 down_swipe_gestures_[3] =
965 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
966 base::Unretained(this),
967 ui::VKEY_PRIOR,
968 ui::EF_NONE);
969
970 // Gestures with four fingers should probably eventually be used for rare
971 // needs that are hard to access through menus.
972 // Note that brightness levels are here because they can be important for low
973 // vision users. However, none of these mappings are permanent.
974 left_swipe_gestures_[4] =
975 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
976 base::Unretained(this),
977 ui::VKEY_BRIGHTNESS_DOWN,
978 ui::EF_NONE);
979 right_swipe_gestures_[4] =
980 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
981 base::Unretained(this),
982 VKEY_BRIGHTNESS_UP,
983 ui::EF_NONE);
984 up_swipe_gestures_[4] =
985 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
986 base::Unretained(this),
987 VKEY_BROWSER_HOME,
988 ui::EF_NONE);
989 down_swipe_gestures_[4] =
990 base::Bind(&TouchExplorationController::DispatchKeyWithFlags,
991 base::Unretained(this),
992 VKEY_BROWSER_REFRESH,
993 ui::EF_NONE);
994
995 }
996
887 } // namespace ui 997 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698