OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/chromeos/touch_exploration_controller.h" | 5 #include "ui/chromeos/touch_exploration_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "ui/aura/client/cursor_client.h" | 9 #include "ui/aura/client/cursor_client.h" |
10 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
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 Loading... | |
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 Loading... | |
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 (should be replaced with wait_state). | |
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 Loading... | |
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 if (type == ui::ET_TOUCH_MOVED) { | |
350 gesture_provider_.OnTouchEvent(event); | |
351 gesture_provider_.OnTouchEventAck(false); | |
352 } | |
353 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | |
354 gesture_provider_.OnTouchEvent(event); | |
355 gesture_provider_.OnTouchEventAck(false); | |
356 if (current_touch_ids_.size() == 0) | |
357 ResetToNoFingersDown(); | |
358 } | |
359 | |
360 ProcessGestureEvents(); | |
361 return ui::EVENT_REWRITE_DISCARD; | |
362 } | |
299 | 363 |
300 ui::EventRewriteStatus TouchExplorationController::InTwoToOneFinger( | 364 ui::EventRewriteStatus TouchExplorationController::InTwoToOneFinger( |
301 const ui::TouchEvent& event, | 365 const ui::TouchEvent& event, |
302 scoped_ptr<ui::Event>* rewritten_event) { | 366 scoped_ptr<ui::Event>* rewritten_event) { |
303 // The user should only ever be in TWO_TO_ONE_FINGER with two fingers down. | 367 // 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. | 368 // If the user added or removed a finger, the state is changed. |
305 ui::EventType type = event.type(); | 369 ui::EventType type = event.type(); |
306 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 370 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
307 DCHECK(current_touch_ids_.size() == 1); | 371 DCHECK(current_touch_ids_.size() == 1); |
308 // Stop passing through the second finger and go to the wait state. | 372 // Stop passing through the second finger and go to the wait state. |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
407 if (current_touch_ids_.size() != 1) | 471 if (current_touch_ids_.size() != 1) |
408 return EVENT_REWRITE_DISCARD; | 472 return EVENT_REWRITE_DISCARD; |
409 | 473 |
410 // Rewrite at location of last touch exploration. | 474 // Rewrite at location of last touch exploration. |
411 rewritten_event->reset( | 475 rewritten_event->reset( |
412 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, | 476 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, |
413 last_touch_exploration_->location(), | 477 last_touch_exploration_->location(), |
414 initial_press_->touch_id(), | 478 initial_press_->touch_id(), |
415 event.time_stamp())); | 479 event.time_stamp())); |
416 (*rewritten_event)->set_flags(event.flags()); | 480 (*rewritten_event)->set_flags(event.flags()); |
481 EnterTouchToMouseMode(); | |
417 state_ = TOUCH_EXPLORATION; | 482 state_ = TOUCH_EXPLORATION; |
418 VLOG_STATE(); | 483 VLOG_STATE(); |
419 return ui::EVENT_REWRITE_REWRITTEN; | 484 return ui::EVENT_REWRITE_REWRITTEN; |
420 } | 485 } |
421 NOTREACHED() << "Unexpected event type received."; | 486 NOTREACHED() << "Unexpected event type received."; |
422 return ui::EVENT_REWRITE_CONTINUE; | 487 return ui::EVENT_REWRITE_CONTINUE; |
423 } | 488 } |
424 | 489 |
425 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease( | 490 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease( |
426 const ui::TouchEvent& event, | 491 const ui::TouchEvent& event, |
427 scoped_ptr<ui::Event>* rewritten_event) { | 492 scoped_ptr<ui::Event>* rewritten_event) { |
428 ui::EventType type = event.type(); | 493 ui::EventType type = event.type(); |
429 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || | 494 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || |
430 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { | 495 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { |
431 NOTREACHED() << "Unexpected event type received."; | 496 NOTREACHED() << "Unexpected event type received."; |
432 return ui::EVENT_REWRITE_CONTINUE; | 497 return ui::EVENT_REWRITE_CONTINUE; |
433 } | 498 } |
434 if (current_touch_ids_.size() == 0) { | 499 if (current_touch_ids_.size() == 0) { |
435 state_ = NO_FINGERS_DOWN; | 500 state_ = NO_FINGERS_DOWN; |
501 VLOG_STATE(); | |
436 ResetToNoFingersDown(); | 502 ResetToNoFingersDown(); |
437 } | 503 } |
438 return EVENT_REWRITE_DISCARD; | 504 return EVENT_REWRITE_DISCARD; |
439 } | 505 } |
440 | 506 |
441 void TouchExplorationController::OnTapTimerFired() { | 507 void TouchExplorationController::OnTapTimerFired() { |
442 switch (state_) { | 508 switch (state_) { |
443 case SINGLE_TAP_RELEASED: | 509 case SINGLE_TAP_RELEASED: |
444 ResetToNoFingersDown(); | 510 ResetToNoFingersDown(); |
445 break; | 511 break; |
446 case TOUCH_EXPLORE_RELEASED: | 512 case TOUCH_EXPLORE_RELEASED: |
447 ResetToNoFingersDown(); | 513 ResetToNoFingersDown(); |
448 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 514 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
449 return; | 515 return; |
450 case SINGLE_TAP_PRESSED: | 516 case SINGLE_TAP_PRESSED: |
517 case GESTURE_IN_PROGRESS: { | |
518 // Discard any pending gestures. | |
519 ignore_result(gesture_provider_.GetAndResetPendingGestures()); | |
451 EnterTouchToMouseMode(); | 520 EnterTouchToMouseMode(); |
452 state_ = TOUCH_EXPLORATION; | 521 state_ = TOUCH_EXPLORATION; |
453 VLOG_STATE(); | 522 VLOG_STATE(); |
454 break; | 523 } break; |
455 default: | 524 default: |
456 return; | 525 return; |
457 } | 526 } |
458 | 527 scoped_ptr<ui::Event> mouse_move = |
459 scoped_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( | 528 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); |
460 initial_press_->location(), initial_press_->flags()); | |
461 DispatchEvent(mouse_move.get()); | 529 DispatchEvent(mouse_move.get()); |
462 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 530 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
463 } | 531 } |
464 | 532 |
465 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 533 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
466 if (event_handler_for_testing_) { | 534 if (event_handler_for_testing_) { |
467 event_handler_for_testing_->OnEvent(event); | 535 event_handler_for_testing_->OnEvent(event); |
468 return; | 536 return; |
469 } | 537 } |
470 ui::EventDispatchDetails result ALLOW_UNUSED = | 538 ui::EventDispatchDetails result ALLOW_UNUSED = |
471 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 539 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
472 } | 540 } |
473 | 541 |
542 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) { | |
543 CHECK(gesture->IsGestureEvent()); | |
544 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); | |
545 if (gesture->type() == ui::ET_GESTURE_SWIPE) { | |
546 if (tap_timer_.IsRunning()) | |
547 tap_timer_.Stop(); | |
548 OnSwipeEvent(gesture); | |
549 return; | |
550 } | |
551 } | |
552 | |
553 void TouchExplorationController::ProcessGestureEvents() { | |
554 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( | |
555 gesture_provider_.GetAndResetPendingGestures()); | |
556 if (gestures) { | |
aboxhall
2014/07/02 18:00:13
nit: weird indent
lisayin
2014/07/02 18:21:04
Done.
| |
557 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); | |
558 i != gestures->end(); | |
559 ++i) { | |
560 OnGestureEvent(*i); | |
561 } | |
562 } | |
563 } | |
564 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { | |
565 // A swipe gesture contains details for the direction in which the swipe | |
566 // occurred. | |
567 GestureEventDetails event_details = swipe_gesture->details(); | |
568 if (event_details.swipe_left()) { | |
569 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); | |
570 return; | |
571 } else if (event_details.swipe_right()) { | |
572 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); | |
573 return; | |
574 } else if (event_details.swipe_up()) { | |
575 DispatchShiftSearchKeyEvent(ui::VKEY_UP); | |
576 return; | |
577 } else if (event_details.swipe_down()) { | |
578 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); | |
579 return; | |
580 } | |
581 } | |
582 | |
583 void TouchExplorationController::DispatchShiftSearchKeyEvent( | |
584 const ui::KeyboardCode direction) { | |
585 // In order to activate the shortcut shift+search+<arrow key> | |
586 // three KeyPressed events must be dispatched in succession along | |
587 // with three KeyReleased events. | |
588 DispatchEvent(new ui::KeyEvent( | |
589 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN, false)); | |
590 DispatchEvent(new ui::KeyEvent( | |
591 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false)); | |
592 DispatchEvent(new ui::KeyEvent( | |
593 ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN, false)); | |
594 | |
595 DispatchEvent(new ui::KeyEvent( | |
596 ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN, false)); | |
597 DispatchEvent(new ui::KeyEvent( | |
598 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false)); | |
599 DispatchEvent(new ui::KeyEvent( | |
600 ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE, false)); | |
601 } | |
602 | |
474 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( | 603 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( |
475 const gfx::PointF& location, | 604 const gfx::PointF& location, |
476 int flags) { | 605 int flags) { |
477 return scoped_ptr<ui::Event>( | 606 return scoped_ptr<ui::Event>( |
478 new ui::MouseEvent( | 607 new ui::MouseEvent( |
479 ui::ET_MOUSE_MOVED, | 608 ui::ET_MOUSE_MOVED, |
480 location, | 609 location, |
481 location, | 610 location, |
482 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY, | 611 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY, |
483 0)); | 612 0)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 case SINGLE_TAP_PRESSED: | 671 case SINGLE_TAP_PRESSED: |
543 return "SINGLE_TAP_PRESSED"; | 672 return "SINGLE_TAP_PRESSED"; |
544 case SINGLE_TAP_RELEASED: | 673 case SINGLE_TAP_RELEASED: |
545 return "SINGLE_TAP_RELEASED"; | 674 return "SINGLE_TAP_RELEASED"; |
546 case TOUCH_EXPLORE_RELEASED: | 675 case TOUCH_EXPLORE_RELEASED: |
547 return "TOUCH_EXPLORE_RELEASED"; | 676 return "TOUCH_EXPLORE_RELEASED"; |
548 case DOUBLE_TAP_PRESSED: | 677 case DOUBLE_TAP_PRESSED: |
549 return "DOUBLE_TAP_PRESSED"; | 678 return "DOUBLE_TAP_PRESSED"; |
550 case TOUCH_EXPLORATION: | 679 case TOUCH_EXPLORATION: |
551 return "TOUCH_EXPLORATION"; | 680 return "TOUCH_EXPLORATION"; |
681 case GESTURE_IN_PROGRESS: | |
682 return "GESTURE_IN_PROGRESS"; | |
552 case TOUCH_EXPLORE_SECOND_PRESS: | 683 case TOUCH_EXPLORE_SECOND_PRESS: |
553 return "TOUCH_EXPLORE_SECOND_PRESS"; | 684 return "TOUCH_EXPLORE_SECOND_PRESS"; |
554 case TWO_TO_ONE_FINGER: | 685 case TWO_TO_ONE_FINGER: |
555 return "TWO_TO_ONE_FINGER"; | 686 return "TWO_TO_ONE_FINGER"; |
556 case PASSTHROUGH: | 687 case PASSTHROUGH: |
557 return "PASSTHROUGH"; | 688 return "PASSTHROUGH"; |
558 case WAIT_FOR_RELEASE: | 689 case WAIT_FOR_RELEASE: |
559 return "WAIT_FOR_RELEASE"; | 690 return "WAIT_FOR_RELEASE"; |
560 } | 691 } |
561 return "Not a state"; | 692 return "Not a state"; |
562 } | 693 } |
563 | 694 |
564 } // namespace ui | 695 } // namespace ui |
OLD | NEW |