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

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

Issue 330763007: Swipe Gestures for Accessibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gesture-vlogs
Patch Set: Fixed Memory Leak Created 6 years, 5 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 15
16 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) 16 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__)
17 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) 17 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__)
18 18
19 namespace ui { 19 namespace ui {
20 20
21 namespace {
22 // In ChromeOS, VKEY_LWIN is synonymous for the search key.
23 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
24 } // namespace
25
21 TouchExplorationController::TouchExplorationController( 26 TouchExplorationController::TouchExplorationController(
22 aura::Window* root_window) 27 aura::Window* root_window)
23 : root_window_(root_window), 28 : root_window_(root_window),
24 state_(NO_FINGERS_DOWN), 29 state_(NO_FINGERS_DOWN),
25 event_handler_for_testing_(NULL), 30 event_handler_for_testing_(NULL),
31 gesture_provider_(this),
26 prev_state_(NO_FINGERS_DOWN) { 32 prev_state_(NO_FINGERS_DOWN) {
27 CHECK(root_window); 33 CHECK(root_window);
28 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 34 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
29 } 35 }
30 36
31 37
32 TouchExplorationController::~TouchExplorationController() { 38 TouchExplorationController::~TouchExplorationController() {
33 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); 39 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
34 } 40 }
35 41
36 void TouchExplorationController::CallTapTimerNowForTesting() { 42 void TouchExplorationController::CallTapTimerNowForTesting() {
37 DCHECK(tap_timer_.IsRunning()); 43 DCHECK(tap_timer_.IsRunning());
38 tap_timer_.Stop(); 44 tap_timer_.Stop();
39 OnTapTimerFired(); 45 OnTapTimerFired();
40 } 46 }
41 47
42 void TouchExplorationController::SetEventHandlerForTesting( 48 void TouchExplorationController::SetEventHandlerForTesting(
43 ui::EventHandler* event_handler_for_testing) { 49 ui::EventHandler* event_handler_for_testing) {
44 event_handler_for_testing_ = event_handler_for_testing; 50 event_handler_for_testing_ = event_handler_for_testing;
45 } 51 }
46 52
47 bool TouchExplorationController::IsInNoFingersDownStateForTesting() const { 53 bool TouchExplorationController::IsInNoFingersDownStateForTesting() const {
48 return state_ == NO_FINGERS_DOWN; 54 return state_ == NO_FINGERS_DOWN;
49 } 55 }
50 56
57 bool TouchExplorationController::IsInGestureInProgressStateForTesting() const {
58 return state_ == GESTURE_IN_PROGRESS;
59 }
60
51 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 61 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
52 const ui::Event& event, 62 const ui::Event& event,
53 scoped_ptr<ui::Event>* rewritten_event) { 63 scoped_ptr<ui::Event>* rewritten_event) {
54 if (!event.IsTouchEvent()) { 64 if (!event.IsTouchEvent()) {
55 if (event.IsKeyEvent()) { 65 if (event.IsKeyEvent()) {
56 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); 66 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
57 VLOG(0) << "\nKeyboard event: " << key_event.name() << "\n" 67 VLOG(0) << "\nKeyboard event: " << key_event.name() << "\n"
58 << " Key code: " << key_event.key_code() 68 << " Key code: " << key_event.key_code()
59 << ", Flags: " << key_event.flags() 69 << ", Flags: " << key_event.flags()
60 << ", Is char: " << key_event.is_char(); 70 << ", Is char: " << key_event.is_char();
61 } 71 }
62 if(event.IsGestureEvent()){
63 VLOG(0) << "\n Gesture event " << event.name();
64 }
65 return ui::EVENT_REWRITE_CONTINUE; 72 return ui::EVENT_REWRITE_CONTINUE;
66 } 73 }
67 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); 74 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event);
68 75
69 // If the tap timer should have fired by now but hasn't, run it now and 76 // If the tap timer should have fired by now but hasn't, run it now and
70 // stop the timer. This is important so that behavior is consistent with 77 // stop the timer. This is important so that behavior is consistent with
71 // the timestamps of the events, and not dependent on the granularity of 78 // the timestamps of the events, and not dependent on the granularity of
72 // the timer. 79 // the timer.
73 if (tap_timer_.IsRunning() && 80 if (tap_timer_.IsRunning() &&
74 touch_event.time_stamp() - initial_press_->time_stamp() > 81 touch_event.time_stamp() - initial_press_->time_stamp() >
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 return InNoFingersDown(touch_event, rewritten_event); 123 return InNoFingersDown(touch_event, rewritten_event);
117 case SINGLE_TAP_PRESSED: 124 case SINGLE_TAP_PRESSED:
118 return InSingleTapPressed(touch_event, rewritten_event); 125 return InSingleTapPressed(touch_event, rewritten_event);
119 case SINGLE_TAP_RELEASED: 126 case SINGLE_TAP_RELEASED:
120 case TOUCH_EXPLORE_RELEASED: 127 case TOUCH_EXPLORE_RELEASED:
121 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event); 128 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event);
122 case DOUBLE_TAP_PRESSED: 129 case DOUBLE_TAP_PRESSED:
123 return InDoubleTapPressed(touch_event, rewritten_event); 130 return InDoubleTapPressed(touch_event, rewritten_event);
124 case TOUCH_EXPLORATION: 131 case TOUCH_EXPLORATION:
125 return InTouchExploration(touch_event, rewritten_event); 132 return InTouchExploration(touch_event, rewritten_event);
133 case GESTURE_IN_PROGRESS:
134 return InGestureInProgress(touch_event, rewritten_event);
126 case TOUCH_EXPLORE_SECOND_PRESS: 135 case TOUCH_EXPLORE_SECOND_PRESS:
127 return InTouchExploreSecondPress(touch_event, rewritten_event); 136 return InTouchExploreSecondPress(touch_event, rewritten_event);
128 case TWO_TO_ONE_FINGER: 137 case TWO_TO_ONE_FINGER:
129 return InTwoToOneFinger(touch_event, rewritten_event); 138 return InTwoToOneFinger(touch_event, rewritten_event);
130 case PASSTHROUGH: 139 case PASSTHROUGH:
131 return InPassthrough(touch_event, rewritten_event); 140 return InPassthrough(touch_event, rewritten_event);
132 case WAIT_FOR_RELEASE: 141 case WAIT_FOR_RELEASE:
133 return InWaitForRelease(touch_event, rewritten_event); 142 return InWaitForRelease(touch_event, rewritten_event);
134 } 143 }
135 NOTREACHED(); 144 NOTREACHED();
136 return ui::EVENT_REWRITE_CONTINUE; 145 return ui::EVENT_REWRITE_CONTINUE;
137 } 146 }
138 147
139 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 148 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
140 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 149 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
141 NOTREACHED(); 150 NOTREACHED();
142 return ui::EVENT_REWRITE_CONTINUE; 151 return ui::EVENT_REWRITE_CONTINUE;
143 } 152 }
144 153
145 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 154 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
146 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 155 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
147 const ui::EventType type = event.type(); 156 const ui::EventType type = event.type();
148 if (type == ui::ET_TOUCH_PRESSED) { 157 if (type == ui::ET_TOUCH_PRESSED) {
149 initial_press_.reset(new TouchEvent(event)); 158 initial_press_.reset(new TouchEvent(event));
150 last_unused_finger_event_.reset(new TouchEvent(event)); 159 last_unused_finger_event_.reset(new TouchEvent(event));
151 tap_timer_.Start(FROM_HERE, 160 tap_timer_.Start(FROM_HERE,
152 gesture_detector_config_.double_tap_timeout, 161 gesture_detector_config_.double_tap_timeout,
153 this, 162 this,
154 &TouchExplorationController::OnTapTimerFired); 163 &TouchExplorationController::OnTapTimerFired);
164 gesture_provider_.OnTouchEvent(event);
165 gesture_provider_.OnTouchEventAck(false);
166 ProcessGestureEvents();
155 state_ = SINGLE_TAP_PRESSED; 167 state_ = SINGLE_TAP_PRESSED;
156 VLOG_STATE(); 168 VLOG_STATE();
157 return ui::EVENT_REWRITE_DISCARD; 169 return ui::EVENT_REWRITE_DISCARD;
158 } 170 }
159 NOTREACHED() << "Unexpected event type received."; 171 NOTREACHED() << "Unexpected event type received.";
160 return ui::EVENT_REWRITE_CONTINUE; 172 return ui::EVENT_REWRITE_CONTINUE;
161 } 173 }
162 174
163 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 175 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
164 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 176 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
(...skipping 10 matching lines...) Expand all
175 event.touch_id(), 187 event.touch_id(),
176 event.time_stamp())); 188 event.time_stamp()));
177 (*rewritten_event)->set_flags(event.flags()); 189 (*rewritten_event)->set_flags(event.flags());
178 return EVENT_REWRITE_REWRITTEN; 190 return EVENT_REWRITE_REWRITTEN;
179 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 191 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
180 DCHECK_EQ(0U, current_touch_ids_.size()); 192 DCHECK_EQ(0U, current_touch_ids_.size());
181 state_ = SINGLE_TAP_RELEASED; 193 state_ = SINGLE_TAP_RELEASED;
182 VLOG_STATE(); 194 VLOG_STATE();
183 return EVENT_REWRITE_DISCARD; 195 return EVENT_REWRITE_DISCARD;
184 } else if (type == ui::ET_TOUCH_MOVED) { 196 } else if (type == ui::ET_TOUCH_MOVED) {
185 // If the user moves far enough from the initial touch location (outside 197 float distance = (event.location() - initial_press_->location()).Length();
186 // the "slop" region, jump to the touch exploration mode early. 198 // If the user does not move far enough from the original position, then the
187 // TODO(evy, lisayin): Add gesture recognition here instead - 199 // resulting movement should not be considered to be a deliberate gesture or
188 // we should probably jump to gesture mode here if the velocity is 200 // touch exploration.
189 // high enough, and touch exploration if the velocity is lower. 201 if (distance <= gesture_detector_config_.touch_slop)
190 float delta = (event.location() - initial_press_->location()).Length(); 202 return EVENT_REWRITE_DISCARD;
191 if (delta > gesture_detector_config_.touch_slop) { 203
192 EnterTouchToMouseMode(); 204 float delta_time =
193 state_ = TOUCH_EXPLORATION; 205 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF();
206 float velocity = distance / delta_time;
207 VLOG(0) << "\n Delta time: " << delta_time
208 << "\n Distance: " << distance
209 << "\n Velocity of click: " << velocity
210 << "\n Minimum swipe velocity: "
211 << gesture_detector_config_.minimum_swipe_velocity;
212
213 // If the user moves fast enough from the initial touch location, start
214 // gesture detection. Otherwise, jump to the touch exploration mode early.
215 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
216 state_ = GESTURE_IN_PROGRESS;
194 VLOG_STATE(); 217 VLOG_STATE();
195 return InTouchExploration(event, rewritten_event); 218 return InGestureInProgress(event, rewritten_event);
196 } 219 }
197 return EVENT_REWRITE_DISCARD; 220 EnterTouchToMouseMode();
221 state_ = TOUCH_EXPLORATION;
222 VLOG_STATE();
223 return InTouchExploration(event, rewritten_event);
198 } 224 }
199 NOTREACHED() << "Unexpected event type received."; 225 NOTREACHED() << "Unexpected event type received.";
200 return ui::EVENT_REWRITE_CONTINUE; 226 return ui::EVENT_REWRITE_CONTINUE;
201 } 227 }
202 228
203 ui::EventRewriteStatus 229 ui::EventRewriteStatus
204 TouchExplorationController::InSingleTapOrTouchExploreReleased( 230 TouchExplorationController::InSingleTapOrTouchExploreReleased(
205 const ui::TouchEvent& event, 231 const ui::TouchEvent& event,
206 scoped_ptr<ui::Event>* rewritten_event) { 232 scoped_ptr<ui::Event>* rewritten_event) {
207 const ui::EventType type = event.type(); 233 const ui::EventType type = event.type();
234 // If there is more than one finger down, then discard to wait until only one
235 // finger is or no fingers are down.
236 if (current_touch_ids_.size() > 1) {
237 state_ = WAIT_FOR_RELEASE;
238 return ui::EVENT_REWRITE_DISCARD;
239 }
240 // If there is no touch exploration yet, discard.
241 if (!last_touch_exploration_ || type == ui::ET_TOUCH_RELEASED) {
242 if (current_touch_ids_.size() == 0) {
243 ResetToNoFingersDown();
244 }
245 return ui::EVENT_REWRITE_DISCARD;
246 }
247
208 if (type == ui::ET_TOUCH_PRESSED) { 248 if (type == ui::ET_TOUCH_PRESSED) {
209 // This is the second tap in a double-tap (or double tap-hold). 249 // This is the second tap in a double-tap (or double tap-hold).
210 // Rewrite at location of last touch exploration. 250 // Rewrite at location of last touch exploration.
211 // If there is no touch exploration yet, discard instead.
212 if (!last_touch_exploration_) {
213 return ui::EVENT_REWRITE_DISCARD;
214 }
215 rewritten_event->reset( 251 rewritten_event->reset(
216 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 252 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
217 last_touch_exploration_->location(), 253 last_touch_exploration_->location(),
218 event.touch_id(), 254 event.touch_id(),
219 event.time_stamp())); 255 event.time_stamp()));
220 (*rewritten_event)->set_flags(event.flags()); 256 (*rewritten_event)->set_flags(event.flags());
221 state_ = DOUBLE_TAP_PRESSED; 257 state_ = DOUBLE_TAP_PRESSED;
222 VLOG_STATE(); 258 VLOG_STATE();
223 return ui::EVENT_REWRITE_REWRITTEN; 259 return ui::EVENT_REWRITE_REWRITTEN;
224 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) {
225 // If the previous press was discarded, we need to also handle its
226 // release.
227 if (current_touch_ids_.size() == 0) {
228 ResetToNoFingersDown();
229 }
230 return ui::EVENT_REWRITE_DISCARD;
231 } 260 }
232 NOTREACHED() << "Unexpected event type received."; 261 NOTREACHED() << "Unexpected event type received.";
233 return ui::EVENT_REWRITE_CONTINUE; 262 return ui::EVENT_REWRITE_CONTINUE;
234 } 263 }
235 264
236 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed( 265 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed(
237 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 266 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
238 const ui::EventType type = event.type(); 267 const ui::EventType type = event.type();
239 if (type == ui::ET_TOUCH_PRESSED) { 268 if (type == ui::ET_TOUCH_PRESSED) {
240 return ui::EVENT_REWRITE_DISCARD; 269 return ui::EVENT_REWRITE_DISCARD;
241 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 270 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
242 if (current_touch_ids_.size() != 0) 271 if (current_touch_ids_.size() != 0)
243 return EVENT_REWRITE_DISCARD; 272 return EVENT_REWRITE_DISCARD;
244 273
245 // Rewrite release at location of last touch exploration with the same 274 // Rewrite release at location of last touch exploration with the same
246 // id as the prevoius press. 275 // id as the previous press.
247 rewritten_event->reset( 276 rewritten_event->reset(
248 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 277 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
249 last_touch_exploration_->location(), 278 last_touch_exploration_->location(),
250 initial_press_->touch_id(), 279 initial_press_->touch_id(),
251 event.time_stamp())); 280 event.time_stamp()));
252 (*rewritten_event)->set_flags(event.flags()); 281 (*rewritten_event)->set_flags(event.flags());
253 ResetToNoFingersDown(); 282 ResetToNoFingersDown();
254 return ui::EVENT_REWRITE_REWRITTEN; 283 return ui::EVENT_REWRITE_REWRITTEN;
255 } else if (type == ui::ET_TOUCH_MOVED) { 284 } else if (type == ui::ET_TOUCH_MOVED) {
256 return ui::EVENT_REWRITE_DISCARD; 285 return ui::EVENT_REWRITE_DISCARD;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 NOTREACHED() << "Unexpected event type received."; 318 NOTREACHED() << "Unexpected event type received.";
290 return ui::EVENT_REWRITE_CONTINUE; 319 return ui::EVENT_REWRITE_CONTINUE;
291 } 320 }
292 321
293 // Rewrite as a mouse-move event. 322 // Rewrite as a mouse-move event.
294 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); 323 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
295 last_touch_exploration_.reset(new TouchEvent(event)); 324 last_touch_exploration_.reset(new TouchEvent(event));
296 return ui::EVENT_REWRITE_REWRITTEN; 325 return ui::EVENT_REWRITE_REWRITTEN;
297 } 326 }
298 327
328 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress(
329 const ui::TouchEvent& event,
330 scoped_ptr<ui::Event>* rewritten_event) {
331 ui::EventType type = event.type();
332 // If additional fingers are added before a swipe gesture has been registered,
333 // then the state will no longer be GESTURE_IN_PROGRESS.
334 if (type == ui::ET_TOUCH_PRESSED ||
335 event.touch_id() != initial_press_->touch_id()) {
336 if (tap_timer_.IsRunning())
337 tap_timer_.Stop();
338 // Discard any pending gestures.
339 ignore_result(gesture_provider_.GetAndResetPendingGestures());
340 state_ = TWO_TO_ONE_FINGER;
341 last_two_to_one_.reset(new TouchEvent(event));
342 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
343 event.location(),
344 event.touch_id(),
345 event.time_stamp()));
346 (*rewritten_event)->set_flags(event.flags());
347 return EVENT_REWRITE_REWRITTEN;
348 }
349
350 // There should not be more than one finger down.
351 DCHECK(current_touch_ids_.size() <= 1);
352 if (type == ui::ET_TOUCH_MOVED) {
353 gesture_provider_.OnTouchEvent(event);
354 gesture_provider_.OnTouchEventAck(false);
355 }
356 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
357 gesture_provider_.OnTouchEvent(event);
358 gesture_provider_.OnTouchEventAck(false);
359 if (current_touch_ids_.size() == 0)
360 ResetToNoFingersDown();
361 }
362
363 ProcessGestureEvents();
364 return ui::EVENT_REWRITE_DISCARD;
365 }
299 366
300 ui::EventRewriteStatus TouchExplorationController::InTwoToOneFinger( 367 ui::EventRewriteStatus TouchExplorationController::InTwoToOneFinger(
301 const ui::TouchEvent& event, 368 const ui::TouchEvent& event,
302 scoped_ptr<ui::Event>* rewritten_event) { 369 scoped_ptr<ui::Event>* rewritten_event) {
303 // The user should only ever be in TWO_TO_ONE_FINGER with two fingers down. 370 // The user should only ever be in TWO_TO_ONE_FINGER with two fingers down.
304 // If the user added or removed a finger, the state is changed. 371 // If the user added or removed a finger, the state is changed.
305 ui::EventType type = event.type(); 372 ui::EventType type = event.type();
306 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 373 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
307 DCHECK(current_touch_ids_.size() == 1); 374 DCHECK(current_touch_ids_.size() == 1);
308 // Stop passing through the second finger and go to the wait state. 375 // Stop passing through the second finger and go to the wait state.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 if (current_touch_ids_.size() != 1) 474 if (current_touch_ids_.size() != 1)
408 return EVENT_REWRITE_DISCARD; 475 return EVENT_REWRITE_DISCARD;
409 476
410 // Rewrite at location of last touch exploration. 477 // Rewrite at location of last touch exploration.
411 rewritten_event->reset( 478 rewritten_event->reset(
412 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, 479 new ui::TouchEvent(ui::ET_TOUCH_RELEASED,
413 last_touch_exploration_->location(), 480 last_touch_exploration_->location(),
414 initial_press_->touch_id(), 481 initial_press_->touch_id(),
415 event.time_stamp())); 482 event.time_stamp()));
416 (*rewritten_event)->set_flags(event.flags()); 483 (*rewritten_event)->set_flags(event.flags());
484 EnterTouchToMouseMode();
417 state_ = TOUCH_EXPLORATION; 485 state_ = TOUCH_EXPLORATION;
418 VLOG_STATE(); 486 VLOG_STATE();
419 return ui::EVENT_REWRITE_REWRITTEN; 487 return ui::EVENT_REWRITE_REWRITTEN;
420 } 488 }
421 NOTREACHED() << "Unexpected event type received."; 489 NOTREACHED() << "Unexpected event type received.";
422 return ui::EVENT_REWRITE_CONTINUE; 490 return ui::EVENT_REWRITE_CONTINUE;
423 } 491 }
424 492
425 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease( 493 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease(
426 const ui::TouchEvent& event, 494 const ui::TouchEvent& event,
427 scoped_ptr<ui::Event>* rewritten_event) { 495 scoped_ptr<ui::Event>* rewritten_event) {
428 ui::EventType type = event.type(); 496 ui::EventType type = event.type();
429 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || 497 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED ||
430 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { 498 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) {
431 NOTREACHED() << "Unexpected event type received."; 499 NOTREACHED() << "Unexpected event type received.";
432 return ui::EVENT_REWRITE_CONTINUE; 500 return ui::EVENT_REWRITE_CONTINUE;
433 } 501 }
434 if (current_touch_ids_.size() == 0) { 502 if (current_touch_ids_.size() == 0) {
435 state_ = NO_FINGERS_DOWN; 503 state_ = NO_FINGERS_DOWN;
504 VLOG_STATE();
436 ResetToNoFingersDown(); 505 ResetToNoFingersDown();
437 } 506 }
438 return EVENT_REWRITE_DISCARD; 507 return EVENT_REWRITE_DISCARD;
439 } 508 }
440 509
441 void TouchExplorationController::OnTapTimerFired() { 510 void TouchExplorationController::OnTapTimerFired() {
442 switch (state_) { 511 switch (state_) {
443 case SINGLE_TAP_RELEASED: 512 case SINGLE_TAP_RELEASED:
444 ResetToNoFingersDown(); 513 ResetToNoFingersDown();
445 break; 514 break;
446 case TOUCH_EXPLORE_RELEASED: 515 case TOUCH_EXPLORE_RELEASED:
447 ResetToNoFingersDown(); 516 ResetToNoFingersDown();
448 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 517 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
449 return; 518 return;
450 case SINGLE_TAP_PRESSED: 519 case SINGLE_TAP_PRESSED:
520 case GESTURE_IN_PROGRESS:
521 // Discard any pending gestures.
522 ignore_result(gesture_provider_.GetAndResetPendingGestures());
451 EnterTouchToMouseMode(); 523 EnterTouchToMouseMode();
452 state_ = TOUCH_EXPLORATION; 524 state_ = TOUCH_EXPLORATION;
453 VLOG_STATE(); 525 VLOG_STATE();
454 break; 526 break;
455 default: 527 default:
456 return; 528 return;
457 } 529 }
458 530 scoped_ptr<ui::Event> mouse_move =
459 scoped_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( 531 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
460 initial_press_->location(), initial_press_->flags());
461 DispatchEvent(mouse_move.get()); 532 DispatchEvent(mouse_move.get());
462 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 533 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
463 } 534 }
464 535
465 void TouchExplorationController::DispatchEvent(ui::Event* event) { 536 void TouchExplorationController::DispatchEvent(ui::Event* event) {
466 if (event_handler_for_testing_) { 537 if (event_handler_for_testing_) {
467 event_handler_for_testing_->OnEvent(event); 538 event_handler_for_testing_->OnEvent(event);
468 return; 539 return;
469 } 540 }
470 ui::EventDispatchDetails result ALLOW_UNUSED = 541 ui::EventDispatchDetails result ALLOW_UNUSED =
471 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 542 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
472 } 543 }
473 544
545 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) {
546 CHECK(gesture->IsGestureEvent());
547 VLOG(0) << " \n Gesture Triggered: " << gesture->name();
548 if (gesture->type() == ui::ET_GESTURE_SWIPE) {
549 if (tap_timer_.IsRunning())
550 tap_timer_.Stop();
551 OnSwipeEvent(gesture);
552 return;
553 }
554 }
555
556 void TouchExplorationController::ProcessGestureEvents() {
557 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures(
558 gesture_provider_.GetAndResetPendingGestures());
559 if (gestures) {
560 for (ScopedVector<GestureEvent>::iterator i = gestures->begin();
561 i != gestures->end();
562 ++i) {
563 OnGestureEvent(*i);
564 }
565 }
566 }
567
568 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) {
569 // A swipe gesture contains details for the direction in which the swipe
570 // occurred.
571 GestureEventDetails event_details = swipe_gesture->details();
572 if (event_details.swipe_left()) {
573 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT);
574 return;
575 } else if (event_details.swipe_right()) {
576 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT);
577 return;
578 } else if (event_details.swipe_up()) {
579 DispatchShiftSearchKeyEvent(ui::VKEY_UP);
580 return;
581 } else if (event_details.swipe_down()) {
582 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN);
583 return;
584 }
585 }
586
587 void TouchExplorationController::DispatchShiftSearchKeyEvent(
588 const ui::KeyboardCode direction) {
589 // In order to activate the shortcut shift+search+<arrow key>
590 // three KeyPressed events must be dispatched in succession along
591 // with three KeyReleased events.
592 ui::KeyEvent shift_down = ui::KeyEvent(
593 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN, false);
594 ui::KeyEvent search_down = ui::KeyEvent(
595 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false);
596 ui::KeyEvent direction_down =
597 ui::KeyEvent(ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN, false);
598
599 ui::KeyEvent direction_up =
600 ui::KeyEvent(ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN, false);
601 ui::KeyEvent search_up = ui::KeyEvent(
602 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false);
603 ui::KeyEvent shift_up =
604 ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE, false);
605
606 DispatchEvent(&shift_down);
607 DispatchEvent(&search_down);
608 DispatchEvent(&direction_down);
609 DispatchEvent(&direction_up);
610 DispatchEvent(&search_up);
611 DispatchEvent(&shift_up);
612 }
613
474 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( 614 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent(
475 const gfx::PointF& location, 615 const gfx::PointF& location,
476 int flags) { 616 int flags) {
477 return scoped_ptr<ui::Event>( 617 return scoped_ptr<ui::Event>(
478 new ui::MouseEvent( 618 new ui::MouseEvent(
479 ui::ET_MOUSE_MOVED, 619 ui::ET_MOUSE_MOVED,
480 location, 620 location,
481 location, 621 location,
482 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY, 622 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY,
483 0)); 623 0));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 case SINGLE_TAP_PRESSED: 682 case SINGLE_TAP_PRESSED:
543 return "SINGLE_TAP_PRESSED"; 683 return "SINGLE_TAP_PRESSED";
544 case SINGLE_TAP_RELEASED: 684 case SINGLE_TAP_RELEASED:
545 return "SINGLE_TAP_RELEASED"; 685 return "SINGLE_TAP_RELEASED";
546 case TOUCH_EXPLORE_RELEASED: 686 case TOUCH_EXPLORE_RELEASED:
547 return "TOUCH_EXPLORE_RELEASED"; 687 return "TOUCH_EXPLORE_RELEASED";
548 case DOUBLE_TAP_PRESSED: 688 case DOUBLE_TAP_PRESSED:
549 return "DOUBLE_TAP_PRESSED"; 689 return "DOUBLE_TAP_PRESSED";
550 case TOUCH_EXPLORATION: 690 case TOUCH_EXPLORATION:
551 return "TOUCH_EXPLORATION"; 691 return "TOUCH_EXPLORATION";
692 case GESTURE_IN_PROGRESS:
693 return "GESTURE_IN_PROGRESS";
552 case TOUCH_EXPLORE_SECOND_PRESS: 694 case TOUCH_EXPLORE_SECOND_PRESS:
553 return "TOUCH_EXPLORE_SECOND_PRESS"; 695 return "TOUCH_EXPLORE_SECOND_PRESS";
554 case TWO_TO_ONE_FINGER: 696 case TWO_TO_ONE_FINGER:
555 return "TWO_TO_ONE_FINGER"; 697 return "TWO_TO_ONE_FINGER";
556 case PASSTHROUGH: 698 case PASSTHROUGH:
557 return "PASSTHROUGH"; 699 return "PASSTHROUGH";
558 case WAIT_FOR_RELEASE: 700 case WAIT_FOR_RELEASE:
559 return "WAIT_FOR_RELEASE"; 701 return "WAIT_FOR_RELEASE";
560 } 702 }
561 return "Not a state"; 703 return "Not a state";
562 } 704 }
563 705
564 } // namespace ui 706 } // 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