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 { | |
aboxhall
2014/07/02 16:45:57
suggestion: should we just have a GetStateForTesti
lisayin
2014/07/02 17:09:50
The state enum is private so I don't think that we
aboxhall
2014/07/02 18:00:13
Ahh, that makes sense, thanks.
| |
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); | |
155 state_ = SINGLE_TAP_PRESSED; | 166 state_ = SINGLE_TAP_PRESSED; |
156 VLOG_STATE(); | 167 VLOG_STATE(); |
157 return ui::EVENT_REWRITE_DISCARD; | 168 return ui::EVENT_REWRITE_DISCARD; |
158 } | 169 } |
159 NOTREACHED() << "Unexpected event type received."; | 170 NOTREACHED() << "Unexpected event type received."; |
160 return ui::EVENT_REWRITE_CONTINUE; | 171 return ui::EVENT_REWRITE_CONTINUE; |
161 } | 172 } |
162 | 173 |
163 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( | 174 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
164 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 175 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
(...skipping 10 matching lines...) Expand all Loading... | |
175 event.touch_id(), | 186 event.touch_id(), |
176 event.time_stamp())); | 187 event.time_stamp())); |
177 (*rewritten_event)->set_flags(event.flags()); | 188 (*rewritten_event)->set_flags(event.flags()); |
178 return EVENT_REWRITE_REWRITTEN; | 189 return EVENT_REWRITE_REWRITTEN; |
179 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 190 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
180 DCHECK_EQ(0U, current_touch_ids_.size()); | 191 DCHECK_EQ(0U, current_touch_ids_.size()); |
181 state_ = SINGLE_TAP_RELEASED; | 192 state_ = SINGLE_TAP_RELEASED; |
182 VLOG_STATE(); | 193 VLOG_STATE(); |
183 return EVENT_REWRITE_DISCARD; | 194 return EVENT_REWRITE_DISCARD; |
184 } else if (type == ui::ET_TOUCH_MOVED) { | 195 } else if (type == ui::ET_TOUCH_MOVED) { |
185 // If the user moves far enough from the initial touch location (outside | 196 float delta_time = |
186 // the "slop" region, jump to the touch exploration mode early. | 197 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); |
187 // TODO(evy, lisayin): Add gesture recognition here instead - | 198 float delta_distance = |
aboxhall
2014/07/02 16:45:57
nit: I think this should just be 'distance'
lisayin
2014/07/02 17:19:43
Done.
| |
188 // we should probably jump to gesture mode here if the velocity is | 199 (event.location() - initial_press_->location()).Length(); |
189 // high enough, and touch exploration if the velocity is lower. | 200 float velocity = delta_distance / delta_time; |
190 float delta = (event.location() - initial_press_->location()).Length(); | 201 VLOG(0) << "\n Delta time: " << delta_time |
191 if (delta > gesture_detector_config_.touch_slop) { | 202 << "\n Delta distance: " << delta_distance |
192 EnterTouchToMouseMode(); | 203 << "\n Velocity of click: " << velocity |
193 state_ = TOUCH_EXPLORATION; | 204 << "\n Minimum swipe velocity: " |
205 << gesture_detector_config_.minimum_swipe_velocity; | |
206 if (delta_distance <= gesture_detector_config_.touch_slop) | |
aboxhall
2014/07/02 16:45:57
Presumably we don't need to compute delta_time and
lisayin
2014/07/02 17:19:43
Done.
| |
207 return EVENT_REWRITE_DISCARD; | |
208 | |
209 // If the user moves fast enough and far enough | |
aboxhall
2014/07/02 16:45:57
Re-flow this comment (I think tab should do it)
A
lisayin
2014/07/02 17:19:43
Done.
| |
210 // from the initial touch location, start gesture detection. | |
211 // Otherwise, if the user moves far enough from the initial touch location | |
212 // outside the "slop" region, jump to the touch exploration mode early. | |
213 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { | |
214 state_ = GESTURE_IN_PROGRESS; | |
194 VLOG_STATE(); | 215 VLOG_STATE(); |
195 return InTouchExploration(event, rewritten_event); | 216 return InGestureInProgress(event, rewritten_event); |
196 } | 217 } |
197 return EVENT_REWRITE_DISCARD; | 218 EnterTouchToMouseMode(); |
219 state_ = TOUCH_EXPLORATION; | |
220 VLOG_STATE(); | |
221 return InTouchExploration(event, rewritten_event); | |
198 } | 222 } |
199 NOTREACHED() << "Unexpected event type received."; | 223 NOTREACHED() << "Unexpected event type received."; |
200 return ui::EVENT_REWRITE_CONTINUE; | 224 return ui::EVENT_REWRITE_CONTINUE; |
201 } | 225 } |
202 | 226 |
203 ui::EventRewriteStatus | 227 ui::EventRewriteStatus |
204 TouchExplorationController::InSingleTapOrTouchExploreReleased( | 228 TouchExplorationController::InSingleTapOrTouchExploreReleased( |
205 const ui::TouchEvent& event, | 229 const ui::TouchEvent& event, |
206 scoped_ptr<ui::Event>* rewritten_event) { | 230 scoped_ptr<ui::Event>* rewritten_event) { |
207 const ui::EventType type = event.type(); | 231 const ui::EventType type = event.type(); |
232 // If there is more than one finger down, then discard to wait until only one | |
233 // finger is or no fingers are down (should be replaced with wait_state). | |
234 if (current_touch_ids_.size() > 1) { | |
235 state_ = WAIT_FOR_RELEASE; | |
236 return ui::EVENT_REWRITE_DISCARD; | |
237 } | |
238 // If there is no touch exploration yet, discard. | |
239 if (last_touch_exploration_ == NULL || type == ui::ET_TOUCH_RELEASED) { | |
240 if (current_touch_ids_.size() == 0) { | |
241 ResetToNoFingersDown(); | |
242 } | |
243 return ui::EVENT_REWRITE_DISCARD; | |
244 } | |
245 | |
208 if (type == ui::ET_TOUCH_PRESSED) { | 246 if (type == ui::ET_TOUCH_PRESSED) { |
209 // This is the second tap in a double-tap (or double tap-hold). | 247 // This is the second tap in a double-tap (or double tap-hold). |
210 // Rewrite at location of last touch exploration. | 248 // 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( | 249 rewritten_event->reset( |
216 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | 250 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
217 last_touch_exploration_->location(), | 251 last_touch_exploration_->location(), |
218 event.touch_id(), | 252 event.touch_id(), |
219 event.time_stamp())); | 253 event.time_stamp())); |
220 (*rewritten_event)->set_flags(event.flags()); | 254 (*rewritten_event)->set_flags(event.flags()); |
221 state_ = DOUBLE_TAP_PRESSED; | 255 state_ = DOUBLE_TAP_PRESSED; |
222 VLOG_STATE(); | 256 VLOG_STATE(); |
223 return ui::EVENT_REWRITE_REWRITTEN; | 257 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 } | 258 } |
232 NOTREACHED() << "Unexpected event type received."; | 259 NOTREACHED() << "Unexpected event type received."; |
233 return ui::EVENT_REWRITE_CONTINUE; | 260 return ui::EVENT_REWRITE_CONTINUE; |
234 } | 261 } |
235 | 262 |
236 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed( | 263 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPressed( |
237 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 264 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
238 const ui::EventType type = event.type(); | 265 const ui::EventType type = event.type(); |
239 if (type == ui::ET_TOUCH_PRESSED) { | 266 if (type == ui::ET_TOUCH_PRESSED) { |
240 return ui::EVENT_REWRITE_DISCARD; | 267 return ui::EVENT_REWRITE_DISCARD; |
241 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 268 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
242 if (current_touch_ids_.size() != 0) | 269 if (current_touch_ids_.size() != 0) |
243 return EVENT_REWRITE_DISCARD; | 270 return EVENT_REWRITE_DISCARD; |
244 | 271 |
245 // Rewrite release at location of last touch exploration with the same | 272 // Rewrite release at location of last touch exploration with the same |
246 // id as the prevoius press. | 273 // id as the previous press. |
247 rewritten_event->reset( | 274 rewritten_event->reset( |
248 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, | 275 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, |
249 last_touch_exploration_->location(), | 276 last_touch_exploration_->location(), |
250 initial_press_->touch_id(), | 277 initial_press_->touch_id(), |
251 event.time_stamp())); | 278 event.time_stamp())); |
252 (*rewritten_event)->set_flags(event.flags()); | 279 (*rewritten_event)->set_flags(event.flags()); |
253 ResetToNoFingersDown(); | 280 ResetToNoFingersDown(); |
254 return ui::EVENT_REWRITE_REWRITTEN; | 281 return ui::EVENT_REWRITE_REWRITTEN; |
255 } else if (type == ui::ET_TOUCH_MOVED) { | 282 } else if (type == ui::ET_TOUCH_MOVED) { |
256 return ui::EVENT_REWRITE_DISCARD; | 283 return ui::EVENT_REWRITE_DISCARD; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 NOTREACHED() << "Unexpected event type received."; | 316 NOTREACHED() << "Unexpected event type received."; |
290 return ui::EVENT_REWRITE_CONTINUE; | 317 return ui::EVENT_REWRITE_CONTINUE; |
291 } | 318 } |
292 | 319 |
293 // Rewrite as a mouse-move event. | 320 // Rewrite as a mouse-move event. |
294 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); | 321 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); |
295 last_touch_exploration_.reset(new TouchEvent(event)); | 322 last_touch_exploration_.reset(new TouchEvent(event)); |
296 return ui::EVENT_REWRITE_REWRITTEN; | 323 return ui::EVENT_REWRITE_REWRITTEN; |
297 } | 324 } |
298 | 325 |
326 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( | |
327 const ui::TouchEvent& event, | |
328 scoped_ptr<ui::Event>* rewritten_event) { | |
329 ui::EventType type = event.type(); | |
330 if (type == ui::ET_TOUCH_PRESSED || | |
331 event.touch_id() != initial_press_->touch_id()) { | |
332 // Should go to passthrough mode. | |
333 if (tap_timer_.IsRunning()) | |
334 tap_timer_.Stop(); | |
335 // Discard any pending gestures. | |
336 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( | |
aboxhall
2014/07/02 16:45:58
Since you're not using |gestures|, you can use ign
lisayin
2014/07/02 17:09:50
Will I still need to cast the return from GetAndRe
aboxhall
2014/07/02 18:00:13
I see you figured this out :)
| |
337 gesture_provider_.GetAndResetPendingGestures()); | |
338 state_ = TWO_TO_ONE_FINGER; | |
339 last_two_to_one_.reset(new TouchEvent(event)); | |
340 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | |
341 event.location(), | |
342 event.touch_id(), | |
343 event.time_stamp())); | |
344 (*rewritten_event)->set_flags(event.flags()); | |
345 return EVENT_REWRITE_REWRITTEN; | |
346 } | |
347 /* | |
348 if (last_touch_exploration_ == NULL) { | |
aboxhall
2014/07/02 16:45:57
Should this be uncommented or removed?
lisayin
2014/07/02 17:19:44
Done.
| |
349 last_touch_exploration_.reset(initial_press_.get()); | |
350 }*/ | |
351 if (type == ui::ET_TOUCH_MOVED) { | |
352 gesture_provider_.OnTouchEvent(event); | |
353 gesture_provider_.OnTouchEventAck(false); | |
354 } | |
355 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | |
356 gesture_provider_.OnTouchEvent(event); | |
357 gesture_provider_.OnTouchEventAck(false); | |
358 if (current_touch_ids_.size() == 0) | |
359 ResetToNoFingersDown(); | |
360 } | |
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 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( | |
aboxhall
2014/07/02 16:45:57
Similarly, you can use ignore_result() here.
lisayin
2014/07/02 17:19:43
Done.
| |
520 gesture_provider_.GetAndResetPendingGestures()); | |
451 EnterTouchToMouseMode(); | 521 EnterTouchToMouseMode(); |
452 state_ = TOUCH_EXPLORATION; | 522 state_ = TOUCH_EXPLORATION; |
453 VLOG_STATE(); | 523 VLOG_STATE(); |
454 break; | 524 } break; |
455 default: | 525 default: |
456 return; | 526 return; |
457 } | 527 } |
458 | 528 scoped_ptr<ui::Event> mouse_move = |
459 scoped_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( | 529 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); |
460 initial_press_->location(), initial_press_->flags()); | |
461 DispatchEvent(mouse_move.get()); | 530 DispatchEvent(mouse_move.get()); |
462 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 531 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
463 } | 532 } |
464 | 533 |
465 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 534 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
466 if (event_handler_for_testing_) { | 535 if (event_handler_for_testing_) { |
467 event_handler_for_testing_->OnEvent(event); | 536 event_handler_for_testing_->OnEvent(event); |
468 return; | 537 return; |
469 } | 538 } |
470 ui::EventDispatchDetails result ALLOW_UNUSED = | 539 ui::EventDispatchDetails result ALLOW_UNUSED = |
471 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 540 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
472 } | 541 } |
473 | 542 |
543 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) { | |
544 if (tap_timer_.IsRunning()) | |
545 tap_timer_.Stop(); | |
546 | |
547 CHECK(gesture->IsGestureEvent()); | |
548 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); | |
549 | |
550 if (gesture->type() == ui::ET_GESTURE_SWIPE) { | |
551 OnSwipeEvent(gesture); | |
552 return; | |
553 } | |
554 // If the event processed was not a swipe gesture, then determine the next | |
555 // state by the number of fingers currently down. | |
556 if (current_touch_ids_.size() == 0) { | |
557 ResetToNoFingersDown(); | |
558 } else if (current_touch_ids_.size() == 1) { | |
559 EnterTouchToMouseMode(); | |
560 state_ = TOUCH_EXPLORATION; | |
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)); |
484 } | 613 } |
485 | 614 |
486 void TouchExplorationController::EnterTouchToMouseMode() { | 615 void TouchExplorationController::EnterTouchToMouseMode() { |
487 aura::client::CursorClient* cursor_client = | 616 aura::client::CursorClient* cursor_client = |
488 aura::client::GetCursorClient(root_window_); | 617 aura::client::GetCursorClient(root_window_); |
489 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) | 618 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) |
490 cursor_client->EnableMouseEvents(); | 619 cursor_client->EnableMouseEvents(); |
491 if (cursor_client && cursor_client->IsCursorVisible()) | 620 if (cursor_client && cursor_client->IsCursorVisible()) |
492 cursor_client->HideCursor(); | 621 cursor_client->HideCursor(); |
493 } | 622 } |
494 | 623 |
495 void TouchExplorationController::ResetToNoFingersDown() { | 624 void TouchExplorationController::ResetToNoFingersDown() { |
625 // Process the gestures. | |
626 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures; | |
aboxhall
2014/07/02 16:45:57
You can initialise gestures with GetAndResetPendin
lisayin
2014/07/02 17:19:43
Done.
| |
627 gestures.reset(gesture_provider_.GetAndResetPendingGestures()); | |
628 if (gestures != NULL) { | |
aboxhall
2014/07/02 16:45:57
if (gestures)
should work I think...
lisayin
2014/07/02 17:19:44
Done.
| |
629 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); | |
630 i != gestures->end(); | |
631 ++i) { | |
632 OnGestureEvent(*i); | |
633 } | |
634 } | |
496 state_ = NO_FINGERS_DOWN; | 635 state_ = NO_FINGERS_DOWN; |
497 VLOG_STATE(); | 636 VLOG_STATE(); |
498 if (tap_timer_.IsRunning()) | 637 if (tap_timer_.IsRunning()) |
499 tap_timer_.Stop(); | 638 tap_timer_.Stop(); |
500 } | 639 } |
501 | 640 |
502 void TouchExplorationController::VlogState(const char* function_name) { | 641 void TouchExplorationController::VlogState(const char* function_name) { |
503 if (prev_state_ == state_) | 642 if (prev_state_ == state_) |
504 return; | 643 return; |
505 prev_state_ = state_; | 644 prev_state_ = state_; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 case SINGLE_TAP_PRESSED: | 681 case SINGLE_TAP_PRESSED: |
543 return "SINGLE_TAP_PRESSED"; | 682 return "SINGLE_TAP_PRESSED"; |
544 case SINGLE_TAP_RELEASED: | 683 case SINGLE_TAP_RELEASED: |
545 return "SINGLE_TAP_RELEASED"; | 684 return "SINGLE_TAP_RELEASED"; |
546 case TOUCH_EXPLORE_RELEASED: | 685 case TOUCH_EXPLORE_RELEASED: |
547 return "TOUCH_EXPLORE_RELEASED"; | 686 return "TOUCH_EXPLORE_RELEASED"; |
548 case DOUBLE_TAP_PRESSED: | 687 case DOUBLE_TAP_PRESSED: |
549 return "DOUBLE_TAP_PRESSED"; | 688 return "DOUBLE_TAP_PRESSED"; |
550 case TOUCH_EXPLORATION: | 689 case TOUCH_EXPLORATION: |
551 return "TOUCH_EXPLORATION"; | 690 return "TOUCH_EXPLORATION"; |
691 case GESTURE_IN_PROGRESS: | |
692 return "GESTURE_IN_PROGRESS"; | |
552 case TOUCH_EXPLORE_SECOND_PRESS: | 693 case TOUCH_EXPLORE_SECOND_PRESS: |
553 return "TOUCH_EXPLORE_SECOND_PRESS"; | 694 return "TOUCH_EXPLORE_SECOND_PRESS"; |
554 case TWO_TO_ONE_FINGER: | 695 case TWO_TO_ONE_FINGER: |
555 return "TWO_TO_ONE_FINGER"; | 696 return "TWO_TO_ONE_FINGER"; |
556 case PASSTHROUGH: | 697 case PASSTHROUGH: |
557 return "PASSTHROUGH"; | 698 return "PASSTHROUGH"; |
558 case WAIT_FOR_RELEASE: | 699 case WAIT_FOR_RELEASE: |
559 return "WAIT_FOR_RELEASE"; | 700 return "WAIT_FOR_RELEASE"; |
560 } | 701 } |
561 return "Not a state"; | 702 return "Not a state"; |
562 } | 703 } |
563 | 704 |
564 } // namespace ui | 705 } // namespace ui |
OLD | NEW |