Chromium Code Reviews| 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 |