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