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" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 // touch id remapping yet. | 24 // touch id remapping yet. |
| 25 const int kTouchIdUnassigned = 0; | 25 const int kTouchIdUnassigned = 0; |
| 26 | 26 |
| 27 // The value for initial_touch_id_passthrough_mapping_ if the user has | 27 // The value for initial_touch_id_passthrough_mapping_ if the user has |
| 28 // released the first finger but some other fingers are held down. In this | 28 // released the first finger but some other fingers are held down. In this |
| 29 // state we don't do any touch id remapping, but we distinguish it from the | 29 // state we don't do any touch id remapping, but we distinguish it from the |
| 30 // kTouchIdUnassigned state because we don't want to assign | 30 // kTouchIdUnassigned state because we don't want to assign |
| 31 // initial_touch_id_passthrough_mapping_ a touch id anymore, | 31 // initial_touch_id_passthrough_mapping_ a touch id anymore, |
| 32 // until all fingers are released. | 32 // until all fingers are released. |
| 33 const int kTouchIdNone = -1; | 33 const int kTouchIdNone = -1; |
| 34 | |
| 35 // In ChromeOS, VKEY_LWIN is synonymous for the search key. | |
| 36 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; | |
| 34 } // namespace | 37 } // namespace |
| 35 | 38 |
| 36 TouchExplorationController::TouchExplorationController( | 39 TouchExplorationController::TouchExplorationController( |
| 37 aura::Window* root_window) | 40 aura::Window* root_window) |
| 38 : root_window_(root_window), | 41 : root_window_(root_window), |
| 39 initial_touch_id_passthrough_mapping_(kTouchIdUnassigned), | 42 initial_touch_id_passthrough_mapping_(kTouchIdUnassigned), |
| 40 state_(NO_FINGERS_DOWN), | 43 state_(NO_FINGERS_DOWN), |
| 41 event_handler_for_testing_(NULL), | 44 event_handler_for_testing_(NULL), |
| 45 gesture_provider_(this), | |
| 42 prev_state_(NO_FINGERS_DOWN) { | 46 prev_state_(NO_FINGERS_DOWN) { |
| 43 CHECK(root_window); | 47 CHECK(root_window); |
| 44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); | 48 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); |
| 45 } | 49 } |
| 46 | 50 |
| 47 TouchExplorationController::~TouchExplorationController() { | 51 TouchExplorationController::~TouchExplorationController() { |
| 48 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); | 52 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); |
| 49 } | 53 } |
| 50 | 54 |
| 51 void TouchExplorationController::CallTapTimerNowForTesting() { | 55 void TouchExplorationController::CallTapTimerNowForTesting() { |
| 52 DCHECK(tap_timer_.IsRunning()); | 56 DCHECK(tap_timer_.IsRunning()); |
| 53 tap_timer_.Stop(); | 57 tap_timer_.Stop(); |
| 54 OnTapTimerFired(); | 58 OnTapTimerFired(); |
| 55 } | 59 } |
| 56 | 60 |
| 57 void TouchExplorationController::SetEventHandlerForTesting( | 61 void TouchExplorationController::SetEventHandlerForTesting( |
| 58 ui::EventHandler* event_handler_for_testing) { | 62 ui::EventHandler* event_handler_for_testing) { |
| 59 event_handler_for_testing_ = event_handler_for_testing; | 63 event_handler_for_testing_ = event_handler_for_testing; |
| 60 } | 64 } |
| 61 | 65 |
| 62 bool TouchExplorationController::IsInNoFingersDownStateForTesting() const { | 66 bool TouchExplorationController::IsInNoFingersDownStateForTesting() const { |
| 63 return state_ == NO_FINGERS_DOWN; | 67 return state_ == NO_FINGERS_DOWN; |
| 64 } | 68 } |
| 65 | 69 |
| 70 bool TouchExplorationController::IsInGestureInProgressStateForTesting() const { | |
| 71 return state_ == GESTURE_IN_PROGRESS; | |
| 72 } | |
| 73 | |
| 66 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( | 74 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( |
| 67 const ui::Event& event, | 75 const ui::Event& event, |
| 68 scoped_ptr<ui::Event>* rewritten_event) { | 76 scoped_ptr<ui::Event>* rewritten_event) { |
| 69 if (!event.IsTouchEvent()) | 77 if (!event.IsTouchEvent()) |
| 70 return ui::EVENT_REWRITE_CONTINUE; | 78 return ui::EVENT_REWRITE_CONTINUE; |
| 71 const ui::TouchEvent& touch_event = | 79 const ui::TouchEvent& touch_event = |
| 72 static_cast<const ui::TouchEvent&>(event); | 80 static_cast<const ui::TouchEvent&>(event); |
| 73 | 81 |
| 74 // If the tap timer should have fired by now but hasn't, run it now and | 82 // If the tap timer should have fired by now but hasn't, run it now and |
| 75 // stop the timer. This is important so that behavior is consistent with | 83 // stop the timer. This is important so that behavior is consistent with |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 return InNoFingersDown(touch_event, rewritten_event); | 129 return InNoFingersDown(touch_event, rewritten_event); |
| 122 case SINGLE_TAP_PRESSED: | 130 case SINGLE_TAP_PRESSED: |
| 123 return InSingleTapPressed(touch_event, rewritten_event); | 131 return InSingleTapPressed(touch_event, rewritten_event); |
| 124 case SINGLE_TAP_RELEASED: | 132 case SINGLE_TAP_RELEASED: |
| 125 case TOUCH_EXPLORE_RELEASED: | 133 case TOUCH_EXPLORE_RELEASED: |
| 126 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event); | 134 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event); |
| 127 case DOUBLE_TAP_PRESSED: | 135 case DOUBLE_TAP_PRESSED: |
| 128 return InDoubleTapPressed(touch_event, rewritten_event); | 136 return InDoubleTapPressed(touch_event, rewritten_event); |
| 129 case TOUCH_EXPLORATION: | 137 case TOUCH_EXPLORATION: |
| 130 return InTouchExploration(touch_event, rewritten_event); | 138 return InTouchExploration(touch_event, rewritten_event); |
| 139 case GESTURE_IN_PROGRESS: | |
| 140 return InGestureInProgress(touch_event, rewritten_event); | |
| 131 case PASSTHROUGH_MINUS_ONE: | 141 case PASSTHROUGH_MINUS_ONE: |
| 132 return InPassthroughMinusOne(touch_event, rewritten_event); | 142 return InPassthroughMinusOne(touch_event, rewritten_event); |
| 133 case TOUCH_EXPLORE_SECOND_PRESS: | 143 case TOUCH_EXPLORE_SECOND_PRESS: |
| 134 return InTouchExploreSecondPress(touch_event, rewritten_event); | 144 return InTouchExploreSecondPress(touch_event, rewritten_event); |
| 135 } | 145 } |
| 136 | 146 |
| 137 NOTREACHED(); | 147 NOTREACHED(); |
| 138 return ui::EVENT_REWRITE_CONTINUE; | 148 return ui::EVENT_REWRITE_CONTINUE; |
| 139 } | 149 } |
| 140 | 150 |
| 141 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( | 151 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( |
| 142 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { | 152 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { |
| 143 NOTREACHED(); | 153 NOTREACHED(); |
| 144 return ui::EVENT_REWRITE_CONTINUE; | 154 return ui::EVENT_REWRITE_CONTINUE; |
| 145 } | 155 } |
| 146 | 156 |
| 147 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( | 157 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( |
| 148 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 158 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
| 149 const ui::EventType type = event.type(); | 159 const ui::EventType type = event.type(); |
| 150 if (type == ui::ET_TOUCH_PRESSED) { | 160 if (type == ui::ET_TOUCH_PRESSED) { |
| 151 initial_press_.reset(new TouchEvent(event)); | 161 initial_press_.reset(new TouchEvent(event)); |
| 152 tap_timer_.Start(FROM_HERE, | 162 tap_timer_.Start(FROM_HERE, |
| 153 gesture_detector_config_.double_tap_timeout, | 163 gesture_detector_config_.double_tap_timeout, |
| 154 this, | 164 this, |
| 155 &TouchExplorationController::OnTapTimerFired); | 165 &TouchExplorationController::OnTapTimerFired); |
| 166 gesture_provider_.OnTouchEvent(event); | |
| 167 gesture_provider_.OnTouchEventAck(false); | |
| 156 state_ = SINGLE_TAP_PRESSED; | 168 state_ = SINGLE_TAP_PRESSED; |
| 157 VLOG_STATE(); | 169 VLOG_STATE(); |
| 158 return ui::EVENT_REWRITE_DISCARD; | 170 return ui::EVENT_REWRITE_DISCARD; |
| 159 } | 171 } |
| 160 | 172 |
| 161 NOTREACHED(); | 173 NOTREACHED(); |
| 162 return ui::EVENT_REWRITE_CONTINUE; | 174 return ui::EVENT_REWRITE_CONTINUE; |
| 163 } | 175 } |
| 164 | 176 |
| 165 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( | 177 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
| 166 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 178 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
| 167 const ui::EventType type = event.type(); | 179 const ui::EventType type = event.type(); |
| 168 | 180 |
| 169 if (type == ui::ET_TOUCH_PRESSED) { | 181 if (type == ui::ET_TOUCH_PRESSED) { |
| 170 // Adding a second finger within the timeout period switches to | 182 // Adding a second finger within the timeout period switches to |
| 171 // passthrough. | 183 // passthrough. |
| 172 state_ = PASSTHROUGH_MINUS_ONE; | 184 state_ = PASSTHROUGH_MINUS_ONE; |
| 173 VLOG_STATE(); | 185 VLOG_STATE(); |
| 174 return InPassthroughMinusOne(event, rewritten_event); | 186 return InPassthroughMinusOne(event, rewritten_event); |
| 175 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 187 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 176 DCHECK_EQ(0U, current_touch_ids_.size()); | 188 DCHECK_EQ(0U, current_touch_ids_.size()); |
| 177 state_ = SINGLE_TAP_RELEASED; | 189 state_ = SINGLE_TAP_RELEASED; |
| 178 VLOG_STATE(); | 190 VLOG_STATE(); |
| 179 return EVENT_REWRITE_DISCARD; | 191 return EVENT_REWRITE_DISCARD; |
| 180 } else if (type == ui::ET_TOUCH_MOVED) { | 192 } else if (type == ui::ET_TOUCH_MOVED) { |
| 181 // If the user moves far enough from the initial touch location (outside | 193 float delta_time = |
| 182 // the "slop" region, jump to the touch exploration mode early. | 194 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); |
| 183 // TODO(evy, lisayin): Add gesture recognition here instead - | 195 float delta_distance = |
| 184 // we should probably jump to gesture mode here if the velocity is | 196 (event.location() - initial_press_->location()).Length(); |
| 185 // high enough, and touch exploration if the velocity is lower. | 197 float velocity = delta_distance / delta_time; |
| 186 float delta = (event.location() - initial_press_->location()).Length(); | 198 VLOG(0) << "\n Delta time: " << delta_time |
| 187 if (delta > gesture_detector_config_.touch_slop) { | 199 << "\n Delta distance: " << delta_distance |
| 188 EnterTouchToMouseMode(); | 200 << "\n Velocity of click: " << velocity |
| 189 state_ = TOUCH_EXPLORATION; | 201 << "\n Minimum swipe velocity: " |
| 190 VLOG_STATE(); | 202 << gesture_detector_config_.minimum_swipe_velocity; |
| 191 return InTouchExploration(event, rewritten_event); | 203 if (delta_distance > gesture_detector_config_.touch_slop) { |
|
tdresser
2014/06/25 14:48:40
Invert this condition to reduce nesting.
if (delt
lisayin
2014/06/25 22:51:05
Done.
| |
| 204 // If the user moves fast enough and far enough | |
| 205 // from the initial touch location, start gesture detection | |
|
dmazzoni
2014/06/25 05:06:02
Nit: end sentence with period.
lisayin
2014/06/25 22:51:04
Done.
| |
| 206 // Otherwise, if the user moves far enough from the initial touch location | |
| 207 // outside the "slop" region, jump to the touch exploration mode early. | |
| 208 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { | |
| 209 state_ = GESTURE_IN_PROGRESS; | |
| 210 VLOG_STATE(); | |
| 211 return InGestureInProgress(event, rewritten_event); | |
| 212 } else { | |
|
tdresser
2014/06/25 14:48:40
This "else" is unnecessary.
lisayin
2014/06/25 22:51:05
Done.
| |
| 213 EnterTouchToMouseMode(); | |
| 214 state_ = TOUCH_EXPLORATION; | |
| 215 VLOG_STATE(); | |
| 216 return InTouchExploration(event, rewritten_event); | |
| 217 } | |
| 192 } | 218 } |
| 193 | 219 |
| 194 return EVENT_REWRITE_DISCARD; | 220 return EVENT_REWRITE_DISCARD; |
| 195 } | 221 } |
| 196 NOTREACHED() << "Unexpected event type received."; | 222 NOTREACHED() << "Unexpected event type received."; |
| 197 return ui::EVENT_REWRITE_CONTINUE; | 223 return ui::EVENT_REWRITE_CONTINUE; |
| 198 } | 224 } |
| 199 | 225 |
| 200 ui::EventRewriteStatus | 226 ui::EventRewriteStatus |
| 201 TouchExplorationController::InSingleTapOrTouchExploreReleased( | 227 TouchExplorationController::InSingleTapOrTouchExploreReleased( |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 NOTREACHED() << "Unexpected event type received."; | 311 NOTREACHED() << "Unexpected event type received."; |
| 286 return ui::EVENT_REWRITE_CONTINUE; | 312 return ui::EVENT_REWRITE_CONTINUE; |
| 287 } | 313 } |
| 288 | 314 |
| 289 // Rewrite as a mouse-move event. | 315 // Rewrite as a mouse-move event. |
| 290 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); | 316 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); |
| 291 last_touch_exploration_.reset(new TouchEvent(event)); | 317 last_touch_exploration_.reset(new TouchEvent(event)); |
| 292 return ui::EVENT_REWRITE_REWRITTEN; | 318 return ui::EVENT_REWRITE_REWRITTEN; |
| 293 } | 319 } |
| 294 | 320 |
| 321 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( | |
| 322 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | |
| 323 ui::EventType type = event.type(); | |
| 324 if (type == ui::ET_TOUCH_PRESSED || | |
| 325 event.touch_id() != initial_press_->touch_id()) { | |
| 326 return ui::EVENT_REWRITE_DISCARD; | |
| 327 } | |
| 328 if (type == ui::ET_TOUCH_MOVED) { | |
| 329 gesture_provider_.OnTouchEvent(event); | |
| 330 gesture_provider_.OnTouchEventAck(false); | |
| 331 } | |
|
tdresser
2014/06/25 14:48:40
Indentation.
lisayin
2014/06/25 22:51:05
Done.
| |
| 332 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | |
| 333 gesture_provider_.OnTouchEvent(event); | |
| 334 gesture_provider_.OnTouchEventAck(true); | |
|
dmazzoni
2014/06/25 05:06:02
Are you sure you want to pass true here and false
tdresser
2014/06/25 14:48:40
I'm fairly certain this should be "false".
lisayin
2014/06/25 22:51:05
Done.
| |
| 335 if (current_touch_ids_.size() == 0) | |
| 336 ResetToNoFingersDown(); | |
| 337 } | |
| 338 return ui::EVENT_REWRITE_DISCARD; | |
| 339 } | |
| 340 | |
| 295 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne( | 341 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne( |
| 296 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 342 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
| 297 ui::EventType type = event.type(); | 343 ui::EventType type = event.type(); |
| 298 gfx::PointF location = event.location_f(); | 344 gfx::PointF location = event.location_f(); |
| 299 | 345 |
| 300 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 346 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 301 if (current_touch_ids_.size() == 0) | 347 if (current_touch_ids_.size() == 0) |
| 302 ResetToNoFingersDown(); | 348 ResetToNoFingersDown(); |
| 303 | 349 |
| 304 if (initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) { | 350 if (initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 if (current_touch_ids_.size() != 1) | 414 if (current_touch_ids_.size() != 1) |
| 369 return EVENT_REWRITE_DISCARD; | 415 return EVENT_REWRITE_DISCARD; |
| 370 | 416 |
| 371 // Rewrite at location of last touch exploration. | 417 // Rewrite at location of last touch exploration. |
| 372 rewritten_event->reset( | 418 rewritten_event->reset( |
| 373 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, | 419 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, |
| 374 last_touch_exploration_->location(), | 420 last_touch_exploration_->location(), |
| 375 initial_press_->touch_id(), | 421 initial_press_->touch_id(), |
| 376 event.time_stamp())); | 422 event.time_stamp())); |
| 377 (*rewritten_event)->set_flags(event.flags()); | 423 (*rewritten_event)->set_flags(event.flags()); |
| 424 EnterTouchToMouseMode(); | |
| 378 state_ = TOUCH_EXPLORATION; | 425 state_ = TOUCH_EXPLORATION; |
| 379 VLOG_STATE(); | 426 VLOG_STATE(); |
| 380 return ui::EVENT_REWRITE_REWRITTEN; | 427 return ui::EVENT_REWRITE_REWRITTEN; |
| 381 } | 428 } |
| 382 NOTREACHED() << "Unexpected event type received."; | 429 NOTREACHED() << "Unexpected event type received."; |
| 383 return ui::EVENT_REWRITE_CONTINUE; | 430 return ui::EVENT_REWRITE_CONTINUE; |
| 384 } | 431 } |
| 385 | 432 |
| 386 void TouchExplorationController::OnTapTimerFired() { | 433 void TouchExplorationController::OnTapTimerFired() { |
| 387 switch (state_) { | 434 switch (state_) { |
| 388 case SINGLE_TAP_RELEASED: | 435 case SINGLE_TAP_RELEASED: |
| 389 ResetToNoFingersDown(); | 436 ResetToNoFingersDown(); |
| 390 break; | 437 break; |
| 391 case TOUCH_EXPLORE_RELEASED: | 438 case TOUCH_EXPLORE_RELEASED: |
| 392 ResetToNoFingersDown(); | 439 ResetToNoFingersDown(); |
| 393 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 440 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
| 394 return; | 441 return; |
| 395 case SINGLE_TAP_PRESSED: | 442 case SINGLE_TAP_PRESSED: |
| 443 case GESTURE_IN_PROGRESS: | |
| 396 EnterTouchToMouseMode(); | 444 EnterTouchToMouseMode(); |
| 445 // Discard any pending gestures. | |
| 446 delete gesture_provider_.GetAndResetPendingGestures(); | |
| 397 state_ = TOUCH_EXPLORATION; | 447 state_ = TOUCH_EXPLORATION; |
| 398 VLOG_STATE(); | 448 VLOG_STATE(); |
| 399 break; | 449 break; |
| 400 default: | 450 default: |
| 401 return; | 451 return; |
| 402 } | 452 } |
| 403 | 453 |
| 404 scoped_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( | 454 scoped_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( |
| 405 initial_press_->location(), initial_press_->flags()); | 455 initial_press_->location(), initial_press_->flags()); |
| 406 DispatchEvent(mouse_move.get()); | 456 DispatchEvent(mouse_move.get()); |
| 407 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 457 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
| 408 } | 458 } |
| 409 | 459 |
| 410 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 460 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
| 411 if (event_handler_for_testing_) { | 461 if (event_handler_for_testing_) { |
| 412 event_handler_for_testing_->OnEvent(event); | 462 event_handler_for_testing_->OnEvent(event); |
| 413 return; | 463 return; |
| 414 } | 464 } |
| 415 | 465 |
| 416 ui::EventDispatchDetails result ALLOW_UNUSED = | 466 ui::EventDispatchDetails result ALLOW_UNUSED = |
| 417 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 467 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
| 418 } | 468 } |
| 419 | 469 |
| 470 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) { | |
| 471 CHECK(gesture->IsGestureEvent()); | |
| 472 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); | |
| 473 if (tap_timer_.IsRunning()) | |
| 474 tap_timer_.Stop(); | |
| 475 switch (gesture->type()) { | |
|
tdresser
2014/06/25 14:48:40
Unless you're likely to support other gestures, it
lisayin
2014/06/25 22:51:04
Done.
| |
| 476 case ET_GESTURE_SWIPE: | |
| 477 OnSwipeEvent(gesture); | |
| 478 return; | |
| 479 default: | |
| 480 if (current_touch_ids_.size() != 0) { | |
|
tdresser
2014/06/25 14:48:40
From the style guide: "if one part of an if-else s
lisayin
2014/06/25 22:51:05
Done.
| |
| 481 EnterTouchToMouseMode(); | |
| 482 state_ = TOUCH_EXPLORATION; | |
| 483 } else | |
| 484 ResetToNoFingersDown(); | |
| 485 break; | |
| 486 } | |
| 487 } | |
| 488 | |
| 489 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { | |
| 490 // A swipe gesture contains details for the direction in which the swipe | |
| 491 // occurred. | |
| 492 GestureEventDetails event_details = swipe_gesture->details(); | |
| 493 if (event_details.swipe_left()) { | |
| 494 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); | |
| 495 return; | |
| 496 } else if (event_details.swipe_right()) { | |
| 497 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); | |
| 498 return; | |
| 499 } else if (event_details.swipe_up()) { | |
| 500 DispatchShiftSearchKeyEvent(ui::VKEY_UP); | |
| 501 return; | |
| 502 } else if (event_details.swipe_down()) { | |
| 503 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); | |
| 504 return; | |
| 505 } | |
| 506 } | |
| 507 | |
| 508 void TouchExplorationController::DispatchShiftSearchKeyEvent( | |
| 509 const ui::KeyboardCode direction) { | |
| 510 // In order to activate the shortcut shift+search+<arrow key> | |
| 511 // three KeyPressed events must be dispatched in succession along | |
| 512 // with three KeyReleased events. | |
| 513 DispatchEvent(new ui::KeyEvent( | |
| 514 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN, false)); | |
| 515 DispatchEvent(new ui::KeyEvent( | |
| 516 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false)); | |
| 517 DispatchEvent(new ui::KeyEvent( | |
| 518 ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN, false)); | |
| 519 | |
| 520 DispatchEvent(new ui::KeyEvent( | |
| 521 ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN, false)); | |
| 522 DispatchEvent(new ui::KeyEvent( | |
| 523 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN, false)); | |
| 524 DispatchEvent(new ui::KeyEvent( | |
| 525 ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE, false)); | |
| 526 } | |
| 527 | |
| 420 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( | 528 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( |
| 421 const gfx::PointF& location, | 529 const gfx::PointF& location, |
| 422 int flags) { | 530 int flags) { |
| 423 return scoped_ptr<ui::Event>( | 531 return scoped_ptr<ui::Event>( |
| 424 new ui::MouseEvent( | 532 new ui::MouseEvent( |
| 425 ui::ET_MOUSE_MOVED, | 533 ui::ET_MOUSE_MOVED, |
| 426 location, | 534 location, |
| 427 location, | 535 location, |
| 428 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY, | 536 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY, |
| 429 0)); | 537 0)); |
| 430 } | 538 } |
| 431 | 539 |
| 432 void TouchExplorationController::EnterTouchToMouseMode() { | 540 void TouchExplorationController::EnterTouchToMouseMode() { |
| 433 aura::client::CursorClient* cursor_client = | 541 aura::client::CursorClient* cursor_client = |
| 434 aura::client::GetCursorClient(root_window_); | 542 aura::client::GetCursorClient(root_window_); |
| 435 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) | 543 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) |
| 436 cursor_client->EnableMouseEvents(); | 544 cursor_client->EnableMouseEvents(); |
| 437 if (cursor_client && cursor_client->IsCursorVisible()) | 545 if (cursor_client && cursor_client->IsCursorVisible()) |
| 438 cursor_client->HideCursor(); | 546 cursor_client->HideCursor(); |
| 439 } | 547 } |
| 440 | 548 |
| 441 void TouchExplorationController::ResetToNoFingersDown() { | 549 void TouchExplorationController::ResetToNoFingersDown() { |
| 550 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures; | |
| 551 gestures.reset(gesture_provider_.GetAndResetPendingGestures()); | |
| 552 if (gestures != NULL) { | |
| 553 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); | |
| 554 i != gestures->end(); | |
| 555 ++i) { | |
| 556 OnGestureEvent(*i); | |
|
tdresser
2014/06/25 14:48:40
Just making sure - there's no way that OnGestureEv
dmazzoni
2014/06/25 15:39:44
As of this change, no - but in the future you shou
tdresser
2014/06/25 15:57:31
That would make things tricky.
If GetAndResetPend
tdresser
2014/06/25 16:06:12
Though depending on how you target the command to
| |
| 557 } | |
| 558 } | |
| 442 state_ = NO_FINGERS_DOWN; | 559 state_ = NO_FINGERS_DOWN; |
| 443 initial_touch_id_passthrough_mapping_ = kTouchIdUnassigned; | 560 initial_touch_id_passthrough_mapping_ = kTouchIdUnassigned; |
| 444 VLOG_STATE(); | 561 VLOG_STATE(); |
| 445 if (tap_timer_.IsRunning()) | 562 if (tap_timer_.IsRunning()) |
| 446 tap_timer_.Stop(); | 563 tap_timer_.Stop(); |
| 447 } | 564 } |
| 448 | 565 |
| 449 void TouchExplorationController::VlogState(const char* function_name) { | 566 void TouchExplorationController::VlogState(const char* function_name) { |
| 450 if (prev_state_ == state_) | 567 if (prev_state_ == state_) |
| 451 return; | 568 return; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 480 case SINGLE_TAP_PRESSED: | 597 case SINGLE_TAP_PRESSED: |
| 481 return "SINGLE_TAP_PRESSED"; | 598 return "SINGLE_TAP_PRESSED"; |
| 482 case SINGLE_TAP_RELEASED: | 599 case SINGLE_TAP_RELEASED: |
| 483 return "SINGLE_TAP_RELEASED"; | 600 return "SINGLE_TAP_RELEASED"; |
| 484 case TOUCH_EXPLORE_RELEASED: | 601 case TOUCH_EXPLORE_RELEASED: |
| 485 return "TOUCH_EXPLORE_RELEASED"; | 602 return "TOUCH_EXPLORE_RELEASED"; |
| 486 case DOUBLE_TAP_PRESSED: | 603 case DOUBLE_TAP_PRESSED: |
| 487 return "DOUBLE_TAP_PRESSED"; | 604 return "DOUBLE_TAP_PRESSED"; |
| 488 case TOUCH_EXPLORATION: | 605 case TOUCH_EXPLORATION: |
| 489 return "TOUCH_EXPLORATION"; | 606 return "TOUCH_EXPLORATION"; |
| 607 case GESTURE_IN_PROGRESS: | |
| 608 return "GESTURE_IN_PROGRESS"; | |
| 490 case PASSTHROUGH_MINUS_ONE: | 609 case PASSTHROUGH_MINUS_ONE: |
| 491 return "PASSTHROUGH_MINUS_ONE"; | 610 return "PASSTHROUGH_MINUS_ONE"; |
| 492 case TOUCH_EXPLORE_SECOND_PRESS: | 611 case TOUCH_EXPLORE_SECOND_PRESS: |
| 493 return "TOUCH_EXPLORE_SECOND_PRESS"; | 612 return "TOUCH_EXPLORE_SECOND_PRESS"; |
| 494 } | 613 } |
| 495 return "Not a state"; | 614 return "Not a state"; |
| 496 } | 615 } |
| 497 | 616 |
| 498 std::string TouchExplorationController::EnumEventTypeToString( | 617 std::string TouchExplorationController::EnumEventTypeToString( |
| 499 ui::EventType type) { | 618 ui::EventType type) { |
| 500 // Add more cases later. For now, these are the most frequently seen | 619 // Add more cases later. For now, these are the most frequently seen |
| 501 // event types. | 620 // event types. |
| 502 switch (type) { | 621 switch (type) { |
| 503 case ET_TOUCH_RELEASED: | 622 case ET_TOUCH_RELEASED: |
| 504 return "ET_TOUCH_RELEASED"; | 623 return "ET_TOUCH_RELEASED"; |
| 505 case ET_TOUCH_PRESSED: | 624 case ET_TOUCH_PRESSED: |
| 506 return "ET_TOUCH_PRESSED"; | 625 return "ET_TOUCH_PRESSED"; |
| 507 case ET_TOUCH_MOVED: | 626 case ET_TOUCH_MOVED: |
| 508 return "ET_TOUCH_MOVED"; | 627 return "ET_TOUCH_MOVED"; |
| 509 case ET_TOUCH_CANCELLED: | 628 case ET_TOUCH_CANCELLED: |
| 510 return "ET_TOUCH_CANCELLED"; | 629 return "ET_TOUCH_CANCELLED"; |
| 511 default: | 630 default: |
| 512 return base::IntToString(type); | 631 return base::IntToString(type); |
| 513 } | 632 } |
| 514 } | 633 } |
| 515 | 634 |
| 516 } // namespace ui | 635 } // namespace ui |
| OLD | NEW |