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