OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/chromeos/touch_exploration_controller.h" | 5 #include "ui/chromeos/touch_exploration_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "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 13 matching lines...) Expand all Loading... | |
32 TouchExplorationController::TouchExplorationController( | 33 TouchExplorationController::TouchExplorationController( |
33 aura::Window* root_window, | 34 aura::Window* root_window, |
34 TouchExplorationControllerDelegate* delegate) | 35 TouchExplorationControllerDelegate* delegate) |
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), |
43 send_gesture_events_(false), | |
42 tick_clock_(NULL) { | 44 tick_clock_(NULL) { |
43 CHECK(root_window); | 45 CHECK(root_window); |
44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); | 46 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); |
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 |
81 // If a gesture has ended, we need to keep proccessing touch events so that | |
82 // the gesture provider can keep track of how many fingers are down. | |
83 if (send_gesture_events_) { | |
84 gesture_provider_.OnTouchEvent(touch_event); | |
85 gesture_provider_.OnTouchEventAck(false); | |
86 delete gesture_provider_.GetAndResetPendingGestures(); | |
87 } | |
88 | |
72 const ui::EventType type = touch_event.type(); | 89 const ui::EventType type = touch_event.type(); |
73 const gfx::PointF& location = touch_event.location_f(); | 90 const gfx::PointF& location = touch_event.location_f(); |
74 const int touch_id = touch_event.touch_id(); | 91 const int touch_id = touch_event.touch_id(); |
75 | 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 Loading... | |
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); |
132 case SLIDE_GESTURE: | |
133 return InSlideGesture(touch_event, rewritten_event); | |
134 case ONE_FINGER_PASSTHROUGH: | 149 case ONE_FINGER_PASSTHROUGH: |
135 return InOneFingerPassthrough(touch_event, rewritten_event); | 150 return InOneFingerPassthrough(touch_event, rewritten_event); |
136 case WAIT_FOR_ONE_FINGER: | 151 case WAIT_FOR_ONE_FINGER: |
137 return InWaitForOneFinger(touch_event, rewritten_event); | 152 return InWaitForOneFinger(touch_event, rewritten_event); |
153 case SLIDE_GESTURE: | |
154 return InSlideGesture(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 } |
(...skipping 14 matching lines...) Expand all Loading... | |
162 } | 179 } |
163 NOTREACHED() << "Unexpected event type received: " << event.name(); | 180 NOTREACHED() << "Unexpected event type received: " << event.name(); |
164 return ui::EVENT_REWRITE_CONTINUE; | 181 return ui::EVENT_REWRITE_CONTINUE; |
165 } | 182 } |
166 | 183 |
167 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( | 184 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
168 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 185 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
169 const ui::EventType type = event.type(); | 186 const ui::EventType type = event.type(); |
170 | 187 |
171 if (type == ui::ET_TOUCH_PRESSED) { | 188 if (type == ui::ET_TOUCH_PRESSED) { |
172 // TODO (evy, lisayin) : add support for multifinger swipes. | 189 // This is the start of a multifinger gesture. |
173 // For now, we wait for there to be only one finger down again. | 190 state_ = GESTURE_IN_PROGRESS; |
174 state_ = WAIT_FOR_ONE_FINGER; | 191 VLOG_STATE(); |
175 return EVENT_REWRITE_DISCARD; | 192 return InGestureInProgress(event, rewritten_event); |
176 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 193 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
177 if (current_touch_ids_.size() == 0 && | 194 if (current_touch_ids_.size() == 0 && |
178 event.touch_id() == initial_press_->touch_id()) { | 195 event.touch_id() == initial_press_->touch_id()) { |
179 state_ = SINGLE_TAP_RELEASED; | 196 state_ = SINGLE_TAP_RELEASED; |
180 VLOG_STATE(); | 197 VLOG_STATE(); |
181 } else if (current_touch_ids_.size() == 0) { | 198 } else if (current_touch_ids_.size() == 0) { |
182 ResetToNoFingersDown(); | 199 ResetToNoFingersDown(); |
183 } | 200 } |
184 return EVENT_REWRITE_DISCARD; | 201 return EVENT_REWRITE_DISCARD; |
185 } else if (type == ui::ET_TOUCH_MOVED) { | 202 } else if (type == ui::ET_TOUCH_MOVED) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
225 | 242 |
226 ui::EventRewriteStatus | 243 ui::EventRewriteStatus |
227 TouchExplorationController::InSingleTapOrTouchExploreReleased( | 244 TouchExplorationController::InSingleTapOrTouchExploreReleased( |
228 const ui::TouchEvent& event, | 245 const ui::TouchEvent& event, |
229 scoped_ptr<ui::Event>* rewritten_event) { | 246 scoped_ptr<ui::Event>* rewritten_event) { |
230 const ui::EventType type = event.type(); | 247 const ui::EventType type = event.type(); |
231 // If there is more than one finger down, then discard to wait until only one | 248 // If there is more than one finger down, then discard to wait until only one |
232 // finger is or no fingers are down. | 249 // finger is or no fingers are down. |
233 if (current_touch_ids_.size() > 1) { | 250 if (current_touch_ids_.size() > 1) { |
234 state_ = WAIT_FOR_ONE_FINGER; | 251 state_ = WAIT_FOR_ONE_FINGER; |
252 VLOG_STATE(); | |
235 return ui::EVENT_REWRITE_DISCARD; | 253 return ui::EVENT_REWRITE_DISCARD; |
236 } | 254 } |
237 if (type == ui::ET_TOUCH_PRESSED) { | 255 if (type == ui::ET_TOUCH_PRESSED) { |
238 // If there is no touch exploration yet, we can't send a click, so discard. | 256 // If there is no touch exploration yet, we can't send a click, so discard. |
239 if (!last_touch_exploration_) { | 257 if (!last_touch_exploration_) { |
240 tap_timer_.Stop(); | 258 tap_timer_.Stop(); |
241 return ui::EVENT_REWRITE_DISCARD; | 259 return ui::EVENT_REWRITE_DISCARD; |
242 } | 260 } |
243 // This is the second tap in a double-tap (or double tap-hold). | 261 // 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, | 262 // We set the tap timer. If it fires before the user lifts their finger, |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 // Rewrite as a mouse-move event. | 376 // Rewrite as a mouse-move event. |
359 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); | 377 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); |
360 last_touch_exploration_.reset(new TouchEvent(event)); | 378 last_touch_exploration_.reset(new TouchEvent(event)); |
361 return ui::EVENT_REWRITE_REWRITTEN; | 379 return ui::EVENT_REWRITE_REWRITTEN; |
362 } | 380 } |
363 | 381 |
364 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( | 382 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( |
365 const ui::TouchEvent& event, | 383 const ui::TouchEvent& event, |
366 scoped_ptr<ui::Event>* rewritten_event) { | 384 scoped_ptr<ui::Event>* rewritten_event) { |
367 ui::EventType type = event.type(); | 385 ui::EventType type = event.type(); |
368 // If additional fingers are added before a swipe gesture has been | 386 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED || |
aboxhall
2014/07/30 00:25:15
nit: this can be simplified to
if (type != ui::ET_
evy
2014/08/04 23:06:30
Done.
| |
369 // registered, then the state will no longer be GESTURE_IN_PROGRESS. | 387 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) { |
370 if (type == ui::ET_TOUCH_PRESSED || | 388 NOTREACHED() << "Unexpected event type received: " << event.name(); |
371 event.touch_id() != initial_press_->touch_id()) { | 389 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 } | 390 } |
379 | 391 // Send events to the gesture provider. If no gesture is registered before |
380 // There should not be more than one finger down. | 392 // the tap timer times out, the state will change to wait for one finger |
381 DCHECK(current_touch_ids_.size() <= 1); | 393 // and this function will stop being called. |
382 if (type == ui::ET_TOUCH_MOVED) { | 394 gesture_provider_.OnTouchEvent(event); |
383 gesture_provider_.OnTouchEvent(event); | 395 gesture_provider_.OnTouchEventAck(false); |
384 gesture_provider_.OnTouchEventAck(false); | 396 if (current_touch_ids_.size() == 0) { |
385 } | 397 ResetToNoFingersDown(); |
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 } | 398 } |
393 ProcessGestureEvents(); | 399 ProcessGestureEvents(); |
394 return ui::EVENT_REWRITE_DISCARD; | 400 return ui::EVENT_REWRITE_DISCARD; |
395 } | 401 } |
396 | 402 |
397 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( | 403 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( |
398 const ui::TouchEvent& event, | 404 const ui::TouchEvent& event, |
399 scoped_ptr<ui::Event>* rewritten_event) { | 405 scoped_ptr<ui::Event>* rewritten_event) { |
400 ui::EventType type = event.type(); | 406 ui::EventType type = event.type(); |
401 | 407 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
468 | 474 |
469 ui::EventRewriteStatus TouchExplorationController::InWaitForOneFinger( | 475 ui::EventRewriteStatus TouchExplorationController::InWaitForOneFinger( |
470 const ui::TouchEvent& event, | 476 const ui::TouchEvent& event, |
471 scoped_ptr<ui::Event>* rewritten_event) { | 477 scoped_ptr<ui::Event>* rewritten_event) { |
472 ui::EventType type = event.type(); | 478 ui::EventType type = event.type(); |
473 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || | 479 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || |
474 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { | 480 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { |
475 NOTREACHED() << "Unexpected event type received: " << event.name(); | 481 NOTREACHED() << "Unexpected event type received: " << event.name(); |
476 return ui::EVENT_REWRITE_CONTINUE; | 482 return ui::EVENT_REWRITE_CONTINUE; |
477 } | 483 } |
484 | |
478 if (current_touch_ids_.size() == 1) { | 485 if (current_touch_ids_.size() == 1) { |
479 EnterTouchToMouseMode(); | 486 EnterTouchToMouseMode(); |
480 state_ = TOUCH_EXPLORATION; | 487 state_ = TOUCH_EXPLORATION; |
481 VLOG_STATE(); | 488 VLOG_STATE(); |
482 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); | 489 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); |
483 last_touch_exploration_.reset(new TouchEvent(event)); | 490 last_touch_exploration_.reset(new TouchEvent(event)); |
484 return ui::EVENT_REWRITE_REWRITTEN; | 491 return ui::EVENT_REWRITE_REWRITTEN; |
485 } | 492 } |
486 return EVENT_REWRITE_DISCARD; | 493 return EVENT_REWRITE_DISCARD; |
487 } | 494 } |
(...skipping 12 matching lines...) Expand all Loading... | |
500 ui::EventType type = event.type(); | 507 ui::EventType type = event.type(); |
501 // If additional fingers are added before a swipe gesture has been registered, | 508 // If additional fingers are added before a swipe gesture has been registered, |
502 // then wait until all fingers have been lifted. | 509 // then wait until all fingers have been lifted. |
503 if (type == ui::ET_TOUCH_PRESSED || | 510 if (type == ui::ET_TOUCH_PRESSED || |
504 event.touch_id() != initial_press_->touch_id()) { | 511 event.touch_id() != initial_press_->touch_id()) { |
505 if (sound_timer_.IsRunning()) | 512 if (sound_timer_.IsRunning()) |
506 sound_timer_.Stop(); | 513 sound_timer_.Stop(); |
507 // Discard any pending gestures. | 514 // Discard any pending gestures. |
508 delete gesture_provider_.GetAndResetPendingGestures(); | 515 delete gesture_provider_.GetAndResetPendingGestures(); |
509 state_ = WAIT_FOR_ONE_FINGER; | 516 state_ = WAIT_FOR_ONE_FINGER; |
517 VLOG_STATE(); | |
510 return EVENT_REWRITE_DISCARD; | 518 return EVENT_REWRITE_DISCARD; |
511 } | 519 } |
512 | 520 |
513 // Allows user to return to the edge to adjust the sound if they have left the | 521 // Allows user to return to the edge to adjust the sound if they have left the |
514 // boundaries. | 522 // boundaries. |
515 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge); | 523 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge); |
516 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) { | 524 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) { |
517 if (sound_timer_.IsRunning()) { | 525 if (sound_timer_.IsRunning()) { |
518 sound_timer_.Stop(); | 526 sound_timer_.Stop(); |
519 } | 527 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
586 last_touch_exploration_->location(), | 594 last_touch_exploration_->location(), |
587 last_unused_finger_event_->touch_id(), | 595 last_unused_finger_event_->touch_id(), |
588 Now())); | 596 Now())); |
589 DispatchEvent(passthrough_press.get()); | 597 DispatchEvent(passthrough_press.get()); |
590 return; | 598 return; |
591 } | 599 } |
592 case SINGLE_TAP_PRESSED: | 600 case SINGLE_TAP_PRESSED: |
593 case GESTURE_IN_PROGRESS: | 601 case GESTURE_IN_PROGRESS: |
594 // Discard any pending gestures. | 602 // Discard any pending gestures. |
595 delete gesture_provider_.GetAndResetPendingGestures(); | 603 delete gesture_provider_.GetAndResetPendingGestures(); |
596 EnterTouchToMouseMode(); | 604 // Wait for one finger before returning to touch exploration. |
597 state_ = TOUCH_EXPLORATION; | 605 send_gesture_events_ = true; |
606 state_ = WAIT_FOR_ONE_FINGER; | |
598 VLOG_STATE(); | 607 VLOG_STATE(); |
599 break; | 608 break; |
600 default: | 609 default: |
601 return; | 610 return; |
602 } | 611 } |
603 scoped_ptr<ui::Event> mouse_move = | 612 scoped_ptr<ui::Event> mouse_move = |
604 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); | 613 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); |
605 DispatchEvent(mouse_move.get()); | 614 DispatchEvent(mouse_move.get()); |
606 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 615 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
607 } | 616 } |
608 | 617 |
609 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 618 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
610 if (event_handler_for_testing_) { | 619 if (event_handler_for_testing_) { |
611 event_handler_for_testing_->OnEvent(event); | 620 event_handler_for_testing_->OnEvent(event); |
612 return; | 621 return; |
613 } | 622 } |
614 ui::EventDispatchDetails result ALLOW_UNUSED = | 623 ui::EventDispatchDetails result ALLOW_UNUSED = |
615 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 624 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
616 } | 625 } |
617 | 626 |
618 void TouchExplorationController::OnGestureEvent( | 627 void TouchExplorationController::OnGestureEvent( |
619 ui::GestureEvent* gesture) { | 628 ui::GestureEvent* gesture) { |
620 CHECK(gesture->IsGestureEvent()); | 629 CHECK(gesture->IsGestureEvent()); |
621 ui::EventType type = gesture->type(); | 630 ui::EventType type = gesture->type(); |
622 if (VLOG_on_) | 631 if (VLOG_on_) |
623 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); | 632 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); |
624 if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) { | 633 if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) { |
625 if (VLOG_on_) | |
626 VLOG(0) << "Swipe!"; | |
627 delete gesture_provider_.GetAndResetPendingGestures(); | 634 delete gesture_provider_.GetAndResetPendingGestures(); |
628 OnSwipeEvent(gesture); | 635 OnSwipeEvent(gesture); |
636 send_gesture_events_ = true; | |
637 state_ = WAIT_FOR_ONE_FINGER; | |
638 VLOG_STATE(); | |
639 tap_timer_.Stop(); | |
629 return; | 640 return; |
630 } | 641 } |
631 } | 642 } |
632 | 643 |
633 void TouchExplorationController::ProcessGestureEvents() { | 644 void TouchExplorationController::ProcessGestureEvents() { |
634 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( | 645 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( |
635 gesture_provider_.GetAndResetPendingGestures()); | 646 gesture_provider_.GetAndResetPendingGestures()); |
636 if (gestures) { | 647 if (gestures) { |
637 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); | 648 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); |
638 i != gestures->end(); | 649 i != gestures->end(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; | 697 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; |
687 float volume = 100 - 100 * ratio; | 698 float volume = 100 - 100 * ratio; |
688 if (VLOG_on_) { | 699 if (VLOG_on_) { |
689 VLOG(0) << "\n Volume = " << volume | 700 VLOG(0) << "\n Volume = " << volume |
690 << "\n Location = " << location.ToString() | 701 << "\n Location = " << location.ToString() |
691 << "\n Bounds = " << root_window_->bounds().right(); | 702 << "\n Bounds = " << root_window_->bounds().right(); |
692 } | 703 } |
693 delegate_->SetOutputLevel(int(volume)); | 704 delegate_->SetOutputLevel(int(volume)); |
694 } | 705 } |
695 | 706 |
696 | |
697 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { | 707 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { |
698 // A swipe gesture contains details for the direction in which the swipe | 708 // A swipe gesture contains details for the direction in which the swipe |
699 // occurred. | 709 // occurred. |
700 GestureEventDetails event_details = swipe_gesture->details(); | 710 GestureEventDetails event_details = swipe_gesture->details(); |
701 if (event_details.swipe_left()) { | 711 int num_fingers = event_details.touch_points(); |
702 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); | 712 if(VLOG_on_) |
703 return; | 713 VLOG(0) << "\nSwipe with " << num_fingers << " fingers."; |
704 } else if (event_details.swipe_right()) { | 714 switch (num_fingers) { |
705 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); | 715 case 1: |
706 return; | 716 if (event_details.swipe_left()) { |
707 } else if (event_details.swipe_up()) { | 717 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); |
aboxhall
2014/07/30 00:25:15
Speculation: it might be nice to keep track of the
evy
2014/08/04 23:06:30
This is pretty cool! I'm not that familiar with ma
| |
708 DispatchShiftSearchKeyEvent(ui::VKEY_UP); | 718 return; |
709 return; | 719 } else if (event_details.swipe_right()) { |
710 } else if (event_details.swipe_down()) { | 720 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); |
711 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); | 721 return; |
712 return; | 722 } else if (event_details.swipe_up()) { |
723 DispatchShiftSearchKeyEvent(ui::VKEY_UP); | |
724 return; | |
725 } else if (event_details.swipe_down()) { | |
726 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); | |
727 return; | |
728 } | |
729 case 2: | |
730 if (event_details.swipe_left()) { | |
731 DispatchKeyWithNoFlags(VKEY_BROWSER_BACK); | |
732 return; | |
733 } else if (event_details.swipe_right()) { | |
734 DispatchKeyWithNoFlags(VKEY_BROWSER_FORWARD); | |
735 return; | |
736 } else if (event_details.swipe_up()) { | |
737 DispatchShiftSearchKeyEvent(ui::VKEY_A); | |
738 return; | |
739 } else if (event_details.swipe_down()) { | |
740 DispatchShiftSearchKeyEvent(ui::VKEY_R); | |
741 return; | |
742 } | |
743 case 3: | |
744 if (event_details.swipe_up()) { | |
745 DispatchKeyWithNoFlags(ui::VKEY_PRIOR); | |
746 return; | |
747 } else if (event_details.swipe_down()) { | |
748 DispatchKeyWithNoFlags(ui::VKEY_NEXT); | |
749 return; | |
750 } | |
751 // Left/right gestures mapping? | |
752 return; | |
753 case 4: | |
754 if (event_details.swipe_left()) { | |
755 // TODO: scroll through tabs | |
756 return; | |
757 } else if (event_details.swipe_right()) { | |
758 // TODO: scroll through tabs | |
759 return; | |
760 } else if (event_details.swipe_up()) { | |
761 DispatchKeyWithNoFlags(VKEY_BROWSER_HOME); | |
762 return; | |
763 } else if (event_details.swipe_down()) { | |
764 DispatchKeyWithNoFlags(VKEY_BROWSER_REFRESH); | |
765 return; | |
766 } | |
713 } | 767 } |
768 // If the user is swiping with more than the supported number of fingers, | |
769 // none of these cases will be hit. | |
770 // TODO: add some checks so the gesture doesn't get proccessed if there are | |
771 // more fingers than supported. | |
772 return; | |
714 } | 773 } |
715 | 774 |
716 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, | 775 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, |
717 float bounds) { | 776 float bounds) { |
718 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be | 777 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be |
719 // converted. | 778 // converted. |
720 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); | 779 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); |
721 gfx::Rect window = root_window_->GetBoundsInScreen(); | 780 gfx::Rect window = root_window_->GetBoundsInScreen(); |
722 | 781 |
723 float left_edge_limit = window.x() + bounds; | 782 float left_edge_limit = window.x() + bounds; |
(...skipping 11 matching lines...) Expand all Loading... | |
735 if (point.x() > right_edge_limit) | 794 if (point.x() > right_edge_limit) |
736 result |= RIGHT_EDGE; | 795 result |= RIGHT_EDGE; |
737 if (point.y() < top_edge_limit) | 796 if (point.y() < top_edge_limit) |
738 result |= TOP_EDGE; | 797 result |= TOP_EDGE; |
739 if (point.y() > bottom_edge_limit) | 798 if (point.y() > bottom_edge_limit) |
740 result |= BOTTOM_EDGE; | 799 result |= BOTTOM_EDGE; |
741 return result; | 800 return result; |
742 } | 801 } |
743 | 802 |
744 void TouchExplorationController::DispatchShiftSearchKeyEvent( | 803 void TouchExplorationController::DispatchShiftSearchKeyEvent( |
745 const ui::KeyboardCode direction) { | 804 const ui::KeyboardCode third_key) { |
746 // In order to activate the shortcut shift+search+<arrow key> | 805 // In order to activate the shortcut shift+search+<key> |
747 // three KeyPressed events must be dispatched in succession along | 806 // three KeyPressed events must be dispatched in succession along |
748 // with three KeyReleased events. | 807 // with three KeyReleased events. |
749 ui::KeyEvent shift_down = ui::KeyEvent( | 808 ui::KeyEvent shift_down = ui::KeyEvent( |
750 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); | 809 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); |
751 ui::KeyEvent search_down = ui::KeyEvent( | 810 ui::KeyEvent search_down = ui::KeyEvent( |
752 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); | 811 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); |
753 ui::KeyEvent direction_down = | 812 ui::KeyEvent third_key_down = |
754 ui::KeyEvent(ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN); | 813 ui::KeyEvent(ui::ET_KEY_PRESSED, third_key, ui::EF_SHIFT_DOWN); |
755 | 814 |
756 ui::KeyEvent direction_up = | 815 ui::KeyEvent third_key_up = |
757 ui::KeyEvent(ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN); | 816 ui::KeyEvent(ui::ET_KEY_RELEASED, third_key, ui::EF_SHIFT_DOWN); |
758 ui::KeyEvent search_up = ui::KeyEvent( | 817 ui::KeyEvent search_up = ui::KeyEvent( |
759 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); | 818 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); |
760 ui::KeyEvent shift_up = | 819 ui::KeyEvent shift_up = |
761 ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE); | 820 ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE); |
762 | 821 |
763 DispatchEvent(&shift_down); | 822 DispatchEvent(&shift_down); |
764 DispatchEvent(&search_down); | 823 DispatchEvent(&search_down); |
765 DispatchEvent(&direction_down); | 824 DispatchEvent(&third_key_down); |
766 DispatchEvent(&direction_up); | 825 DispatchEvent(&third_key_up); |
767 DispatchEvent(&search_up); | 826 DispatchEvent(&search_up); |
768 DispatchEvent(&shift_up); | 827 DispatchEvent(&shift_up); |
769 } | 828 } |
770 | 829 |
830 void TouchExplorationController::DispatchKeyWithNoFlags( | |
831 const ui::KeyboardCode key) { | |
832 ui::KeyEvent key_down = ui::KeyEvent(ui::ET_KEY_PRESSED, key, ui::EF_NONE); | |
833 ui::KeyEvent key_up = ui::KeyEvent(ui::ET_KEY_RELEASED, key, ui::EF_NONE); | |
834 DispatchEvent(&key_down); | |
835 DispatchEvent(&key_up); | |
836 if(VLOG_on_) { | |
837 VLOG(0) << "\nKey down: key code : " << key_down.key_code() | |
838 << ", flags: " << key_down.flags() | |
839 << "\nKey up: key code : " << key_up.key_code() | |
840 << ", flags: " << key_up.flags(); | |
841 } | |
842 } | |
843 | |
771 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( | 844 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( |
772 const gfx::PointF& location, | 845 const gfx::PointF& location, |
773 int flags) { | 846 int flags) { |
774 // The "synthesized" flag should be set on all events that don't have a | 847 // The "synthesized" flag should be set on all events that don't have a |
775 // backing native event. | 848 // backing native event. |
776 flags |= ui::EF_IS_SYNTHESIZED; | 849 flags |= ui::EF_IS_SYNTHESIZED; |
777 | 850 |
778 // This flag is used to identify mouse move events that were generated from | 851 // This flag is used to identify mouse move events that were generated from |
779 // touch exploration in Chrome code. | 852 // touch exploration in Chrome code. |
780 flags |= ui::EF_TOUCH_ACCESSIBILITY; | 853 flags |= ui::EF_TOUCH_ACCESSIBILITY; |
(...skipping 23 matching lines...) Expand all Loading... | |
804 } | 877 } |
805 | 878 |
806 void TouchExplorationController::ResetToNoFingersDown() { | 879 void TouchExplorationController::ResetToNoFingersDown() { |
807 ProcessGestureEvents(); | 880 ProcessGestureEvents(); |
808 if (sound_timer_.IsRunning()) | 881 if (sound_timer_.IsRunning()) |
809 sound_timer_.Stop(); | 882 sound_timer_.Stop(); |
810 state_ = NO_FINGERS_DOWN; | 883 state_ = NO_FINGERS_DOWN; |
811 VLOG_STATE(); | 884 VLOG_STATE(); |
812 if (tap_timer_.IsRunning()) | 885 if (tap_timer_.IsRunning()) |
813 tap_timer_.Stop(); | 886 tap_timer_.Stop(); |
887 send_gesture_events_ = false; | |
814 } | 888 } |
815 | 889 |
816 void TouchExplorationController::VlogState(const char* function_name) { | 890 void TouchExplorationController::VlogState(const char* function_name) { |
817 if (!VLOG_on_) | 891 if (!VLOG_on_) |
818 return; | 892 return; |
819 if (prev_state_ == state_) | 893 if (prev_state_ == state_) |
820 return; | 894 return; |
821 prev_state_ = state_; | 895 prev_state_ = state_; |
822 const char* state_string = EnumStateToString(state_); | 896 const char* state_string = EnumStateToString(state_); |
823 VLOG(0) << "\n Function name: " << function_name | 897 VLOG(0) << "\n Function name: " << function_name |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
867 case DOUBLE_TAP_PENDING: | 941 case DOUBLE_TAP_PENDING: |
868 return "DOUBLE_TAP_PENDING"; | 942 return "DOUBLE_TAP_PENDING"; |
869 case TOUCH_RELEASE_PENDING: | 943 case TOUCH_RELEASE_PENDING: |
870 return "TOUCH_RELEASE_PENDING"; | 944 return "TOUCH_RELEASE_PENDING"; |
871 case TOUCH_EXPLORATION: | 945 case TOUCH_EXPLORATION: |
872 return "TOUCH_EXPLORATION"; | 946 return "TOUCH_EXPLORATION"; |
873 case GESTURE_IN_PROGRESS: | 947 case GESTURE_IN_PROGRESS: |
874 return "GESTURE_IN_PROGRESS"; | 948 return "GESTURE_IN_PROGRESS"; |
875 case TOUCH_EXPLORE_SECOND_PRESS: | 949 case TOUCH_EXPLORE_SECOND_PRESS: |
876 return "TOUCH_EXPLORE_SECOND_PRESS"; | 950 return "TOUCH_EXPLORE_SECOND_PRESS"; |
877 case SLIDE_GESTURE: | |
878 return "SLIDE_GESTURE"; | |
879 case ONE_FINGER_PASSTHROUGH: | 951 case ONE_FINGER_PASSTHROUGH: |
880 return "ONE_FINGER_PASSTHROUGH"; | 952 return "ONE_FINGER_PASSTHROUGH"; |
881 case WAIT_FOR_ONE_FINGER: | 953 case WAIT_FOR_ONE_FINGER: |
882 return "WAIT_FOR_ONE_FINGER"; | 954 return "WAIT_FOR_ONE_FINGER"; |
955 case SLIDE_GESTURE: | |
956 return "SLIDE_GESTURE"; | |
883 } | 957 } |
884 return "Not a state"; | 958 return "Not a state"; |
885 } | 959 } |
886 | 960 |
887 } // namespace ui | 961 } // namespace ui |
OLD | NEW |