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 <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 const int kSoundDelayInMS = 150; | 30 const int kSoundDelayInMS = 150; |
| 31 | 31 |
| 32 } // namespace | 32 } // namespace |
| 33 | 33 |
| 34 TouchExplorationController::TouchExplorationController( | 34 TouchExplorationController::TouchExplorationController( |
| 35 aura::Window* root_window, | 35 aura::Window* root_window, |
| 36 TouchExplorationControllerDelegate* delegate) | 36 TouchExplorationControllerDelegate* delegate) |
| 37 : root_window_(root_window), | 37 : root_window_(root_window), |
| 38 delegate_(delegate), | 38 delegate_(delegate), |
| 39 state_(NO_FINGERS_DOWN), | 39 state_(NO_FINGERS_DOWN), |
| 40 anchor_point_state_(ANCHOR_POINT_NONE), | |
| 40 gesture_provider_(new GestureProviderAura(this, this)), | 41 gesture_provider_(new GestureProviderAura(this, this)), |
| 41 prev_state_(NO_FINGERS_DOWN), | 42 prev_state_(NO_FINGERS_DOWN), |
| 42 VLOG_on_(true), | 43 VLOG_on_(true), |
| 43 tick_clock_(NULL) { | 44 tick_clock_(NULL) { |
| 44 DCHECK(root_window); | 45 DCHECK(root_window); |
| 45 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); | 46 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); |
| 46 } | 47 } |
| 47 | 48 |
| 48 TouchExplorationController::~TouchExplorationController() { | 49 TouchExplorationController::~TouchExplorationController() { |
| 49 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); | 50 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); |
| 50 } | 51 } |
| 51 | 52 |
| 53 void TouchExplorationController::SetTouchAccessibilityAnchorPoint( | |
| 54 const gfx::Point& anchor_point) { | |
| 55 gfx::Point native_point = anchor_point; | |
| 56 root_window_->GetHost()->ConvertPointToNativeScreen(&native_point); | |
| 57 | |
| 58 anchor_point_ = gfx::PointF(native_point.x(), native_point.y()); | |
| 59 anchor_point_state_ = ANCHOR_POINT_EXPLICITLY_SET; | |
| 60 } | |
| 61 | |
| 52 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( | 62 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( |
| 53 const ui::Event& event, | 63 const ui::Event& event, |
| 54 std::unique_ptr<ui::Event>* rewritten_event) { | 64 std::unique_ptr<ui::Event>* rewritten_event) { |
| 55 if (!event.IsTouchEvent()) { | 65 if (!event.IsTouchEvent()) { |
| 56 if (event.IsKeyEvent()) { | 66 if (event.IsKeyEvent()) { |
| 57 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); | 67 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); |
| 58 VLOG(0) << "\nKeyboard event: " << key_event.name() | 68 VLOG(0) << "\nKeyboard event: " << key_event.name() |
| 59 << "\n Key code: " << key_event.key_code() | 69 << "\n Key code: " << key_event.key_code() |
| 60 << ", Flags: " << key_event.flags() | 70 << ", Flags: " << key_event.flags() |
| 61 << ", Is char: " << key_event.is_char(); | 71 << ", Is char: " << key_event.is_char(); |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 SET_STATE(SLIDE_GESTURE); | 298 SET_STATE(SLIDE_GESTURE); |
| 289 return InSlideGesture(event, rewritten_event); | 299 return InSlideGesture(event, rewritten_event); |
| 290 } | 300 } |
| 291 | 301 |
| 292 // If the user moves fast enough from the initial touch location, start | 302 // If the user moves fast enough from the initial touch location, start |
| 293 // gesture detection. Otherwise, jump to the touch exploration mode early. | 303 // gesture detection. Otherwise, jump to the touch exploration mode early. |
| 294 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { | 304 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { |
| 295 SET_STATE(GESTURE_IN_PROGRESS); | 305 SET_STATE(GESTURE_IN_PROGRESS); |
| 296 return InGestureInProgress(event, rewritten_event); | 306 return InGestureInProgress(event, rewritten_event); |
| 297 } | 307 } |
| 308 anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION; | |
| 298 EnterTouchToMouseMode(); | 309 EnterTouchToMouseMode(); |
| 299 SET_STATE(TOUCH_EXPLORATION); | 310 SET_STATE(TOUCH_EXPLORATION); |
| 300 return InTouchExploration(event, rewritten_event); | 311 return InTouchExploration(event, rewritten_event); |
| 301 } | 312 } |
| 302 NOTREACHED(); | 313 NOTREACHED(); |
| 303 return ui::EVENT_REWRITE_CONTINUE; | 314 return ui::EVENT_REWRITE_CONTINUE; |
| 304 } | 315 } |
| 305 | 316 |
| 306 ui::EventRewriteStatus | 317 ui::EventRewriteStatus |
| 307 TouchExplorationController::InSingleTapOrTouchExploreReleased( | 318 TouchExplorationController::InSingleTapOrTouchExploreReleased( |
| 308 const ui::TouchEvent& event, | 319 const ui::TouchEvent& event, |
| 309 std::unique_ptr<ui::Event>* rewritten_event) { | 320 std::unique_ptr<ui::Event>* rewritten_event) { |
| 310 const ui::EventType type = event.type(); | 321 const ui::EventType type = event.type(); |
| 311 // If there is more than one finger down, then discard to wait until no | 322 // If there is more than one finger down, then discard to wait until no |
| 312 // fingers are down. | 323 // fingers are down. |
| 313 if (current_touch_ids_.size() > 1) { | 324 if (current_touch_ids_.size() > 1) { |
| 314 SET_STATE(WAIT_FOR_NO_FINGERS); | 325 SET_STATE(WAIT_FOR_NO_FINGERS); |
| 315 return ui::EVENT_REWRITE_DISCARD; | 326 return ui::EVENT_REWRITE_DISCARD; |
| 316 } | 327 } |
| 317 if (type == ui::ET_TOUCH_PRESSED) { | 328 if (type == ui::ET_TOUCH_PRESSED) { |
| 318 // If there is no touch exploration yet, we can't send a click, so discard. | 329 // If there is no anchor point for synthesized events because the |
| 319 if (!last_touch_exploration_) { | 330 // user hasn't touch-explored or focused anything yet, we can't |
| 331 // send a click, so discard. | |
| 332 if (anchor_point_state_ == ANCHOR_POINT_NONE) { | |
| 333 LOG(ERROR) << "*** NO ANCHOR POINT ***"; | |
| 334 | |
| 320 tap_timer_.Stop(); | 335 tap_timer_.Stop(); |
| 321 return ui::EVENT_REWRITE_DISCARD; | 336 return ui::EVENT_REWRITE_DISCARD; |
| 322 } | 337 } |
| 323 // This is the second tap in a double-tap (or double tap-hold). | 338 // This is the second tap in a double-tap (or double tap-hold). |
| 324 // We set the tap timer. If it fires before the user lifts their finger, | 339 // We set the tap timer. If it fires before the user lifts their finger, |
| 325 // one-finger passthrough begins. Otherwise, there is a touch press and | 340 // one-finger passthrough begins. Otherwise, there is a touch press and |
| 326 // release at the location of the last touch exploration. | 341 // release at the location of the last touch exploration. |
| 327 SET_STATE(DOUBLE_TAP_PENDING); | 342 SET_STATE(DOUBLE_TAP_PENDING); |
| 328 // The old tap timer (from the initial click) is stopped if it is still | 343 // The old tap timer (from the initial click) is stopped if it is still |
| 329 // going, and the new one is set. | 344 // going, and the new one is set. |
| 330 tap_timer_.Stop(); | 345 tap_timer_.Stop(); |
| 331 StartTapTimer(); | 346 StartTapTimer(); |
| 332 // This will update as the finger moves before a possible passthrough, and | 347 // This will update as the finger moves before a possible passthrough, and |
| 333 // will determine the offset. | 348 // will determine the offset. |
| 334 last_unused_finger_event_.reset(new ui::TouchEvent(event)); | 349 last_unused_finger_event_.reset(new ui::TouchEvent(event)); |
| 335 return ui::EVENT_REWRITE_DISCARD; | 350 return ui::EVENT_REWRITE_DISCARD; |
| 336 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) { | 351 } else if (type == ui::ET_TOUCH_RELEASED && |
| 352 anchor_point_state_ == ANCHOR_POINT_NONE) { | |
| 337 // If the previous press was discarded, we need to also handle its | 353 // If the previous press was discarded, we need to also handle its |
| 338 // release. | 354 // release. |
| 339 if (current_touch_ids_.size() == 0) { | 355 if (current_touch_ids_.size() == 0) { |
| 340 SET_STATE(NO_FINGERS_DOWN); | 356 SET_STATE(NO_FINGERS_DOWN); |
| 341 } | 357 } |
| 342 return ui::EVENT_REWRITE_DISCARD; | 358 return ui::EVENT_REWRITE_DISCARD; |
| 343 } else if (type == ui::ET_TOUCH_MOVED) { | 359 } else if (type == ui::ET_TOUCH_MOVED) { |
| 344 return ui::EVENT_REWRITE_DISCARD; | 360 return ui::EVENT_REWRITE_DISCARD; |
| 345 } | 361 } |
| 346 NOTREACHED(); | 362 NOTREACHED(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 359 float delta = (event.location() - initial_press_->location()).Length(); | 375 float delta = (event.location() - initial_press_->location()).Length(); |
| 360 if (delta > gesture_detector_config_.touch_slop) { | 376 if (delta > gesture_detector_config_.touch_slop) { |
| 361 tap_timer_.Stop(); | 377 tap_timer_.Stop(); |
| 362 OnTapTimerFired(); | 378 OnTapTimerFired(); |
| 363 } | 379 } |
| 364 return EVENT_REWRITE_DISCARD; | 380 return EVENT_REWRITE_DISCARD; |
| 365 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 381 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 366 if (current_touch_ids_.size() != 0) | 382 if (current_touch_ids_.size() != 0) |
| 367 return EVENT_REWRITE_DISCARD; | 383 return EVENT_REWRITE_DISCARD; |
| 368 | 384 |
| 369 std::unique_ptr<ui::TouchEvent> touch_press; | 385 SendSimulatedClick(); |
| 370 touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), | |
| 371 initial_press_->touch_id(), | |
| 372 event.time_stamp())); | |
| 373 touch_press->set_location_f(last_touch_exploration_->location_f()); | |
| 374 touch_press->set_root_location_f(last_touch_exploration_->location_f()); | |
| 375 DispatchEvent(touch_press.get()); | |
| 376 | 386 |
| 377 std::unique_ptr<ui::TouchEvent> new_event( | |
| 378 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(), | |
| 379 initial_press_->touch_id(), event.time_stamp())); | |
| 380 new_event->set_location_f(last_touch_exploration_->location_f()); | |
| 381 new_event->set_root_location_f(last_touch_exploration_->location_f()); | |
| 382 new_event->set_flags(event.flags()); | |
| 383 *rewritten_event = std::move(new_event); | |
| 384 SET_STATE(NO_FINGERS_DOWN); | 387 SET_STATE(NO_FINGERS_DOWN); |
| 385 return ui::EVENT_REWRITE_REWRITTEN; | 388 return ui::EVENT_REWRITE_DISCARD; |
| 386 } | 389 } |
| 387 NOTREACHED(); | 390 NOTREACHED(); |
| 388 return ui::EVENT_REWRITE_CONTINUE; | 391 return ui::EVENT_REWRITE_CONTINUE; |
| 389 } | 392 } |
| 390 | 393 |
| 391 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending( | 394 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending( |
| 392 const ui::TouchEvent& event, | 395 const ui::TouchEvent& event, |
| 393 std::unique_ptr<ui::Event>* rewritten_event) { | 396 std::unique_ptr<ui::Event>* rewritten_event) { |
| 394 const ui::EventType type = event.type(); | 397 const ui::EventType type = event.type(); |
| 395 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) { | 398 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) { |
| 396 return ui::EVENT_REWRITE_DISCARD; | 399 return ui::EVENT_REWRITE_DISCARD; |
| 397 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 400 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 398 if (current_touch_ids_.size() != 0) | 401 if (current_touch_ids_.size() != 0) |
| 399 return EVENT_REWRITE_DISCARD; | 402 return EVENT_REWRITE_DISCARD; |
| 400 | 403 |
| 401 std::unique_ptr<ui::TouchEvent> new_event( | 404 SendSimulatedClick(); |
| 402 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(), | |
| 403 initial_press_->touch_id(), event.time_stamp())); | |
| 404 new_event->set_location_f(last_touch_exploration_->location_f()); | |
| 405 new_event->set_root_location_f(last_touch_exploration_->location_f()); | |
| 406 new_event->set_flags(event.flags()); | |
| 407 *rewritten_event = std::move(new_event); | |
| 408 SET_STATE(NO_FINGERS_DOWN); | 405 SET_STATE(NO_FINGERS_DOWN); |
| 409 return ui::EVENT_REWRITE_REWRITTEN; | 406 return ui::EVENT_REWRITE_DISCARD; |
| 410 } | 407 } |
| 411 NOTREACHED(); | 408 NOTREACHED(); |
| 412 return ui::EVENT_REWRITE_CONTINUE; | 409 return ui::EVENT_REWRITE_CONTINUE; |
| 413 } | 410 } |
| 414 | 411 |
| 415 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( | 412 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( |
| 416 const ui::TouchEvent& event, | 413 const ui::TouchEvent& event, |
| 417 std::unique_ptr<ui::Event>* rewritten_event) { | 414 std::unique_ptr<ui::Event>* rewritten_event) { |
| 418 const ui::EventType type = event.type(); | 415 const ui::EventType type = event.type(); |
| 419 if (type == ui::ET_TOUCH_PRESSED) { | 416 if (type == ui::ET_TOUCH_PRESSED) { |
| 420 // Handle split-tap. | 417 // Enter split-tap mode. |
| 421 initial_press_.reset(new TouchEvent(event)); | 418 initial_press_.reset(new TouchEvent(event)); |
| 422 tap_timer_.Stop(); | 419 tap_timer_.Stop(); |
| 423 std::unique_ptr<ui::TouchEvent> new_event( | |
| 424 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), event.touch_id(), | |
| 425 event.time_stamp())); | |
| 426 new_event->set_location_f(last_touch_exploration_->location_f()); | |
| 427 new_event->set_root_location_f(last_touch_exploration_->location_f()); | |
| 428 new_event->set_flags(event.flags()); | |
| 429 *rewritten_event = std::move(new_event); | |
| 430 SET_STATE(TOUCH_EXPLORE_SECOND_PRESS); | 420 SET_STATE(TOUCH_EXPLORE_SECOND_PRESS); |
| 431 return ui::EVENT_REWRITE_REWRITTEN; | 421 return ui::EVENT_REWRITE_DISCARD; |
| 432 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 422 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 433 initial_press_.reset(new TouchEvent(event)); | 423 initial_press_.reset(new TouchEvent(event)); |
| 434 StartTapTimer(); | 424 StartTapTimer(); |
| 435 SET_STATE(TOUCH_EXPLORE_RELEASED); | 425 SET_STATE(TOUCH_EXPLORE_RELEASED); |
| 436 } else if (type != ui::ET_TOUCH_MOVED) { | 426 } else if (type != ui::ET_TOUCH_MOVED) { |
| 437 NOTREACHED(); | 427 NOTREACHED(); |
| 438 return ui::EVENT_REWRITE_CONTINUE; | 428 return ui::EVENT_REWRITE_CONTINUE; |
| 439 } | 429 } |
| 440 | 430 |
| 441 // Rewrite as a mouse-move event. | 431 // Rewrite as a mouse-move event. |
| 442 *rewritten_event = CreateMouseMoveEvent(event.location_f(), event.flags()); | 432 *rewritten_event = CreateMouseMoveEvent(event.location_f(), event.flags()); |
| 443 last_touch_exploration_.reset(new TouchEvent(event)); | 433 last_touch_exploration_.reset(new TouchEvent(event)); |
| 434 if (anchor_point_state_ != ANCHOR_POINT_EXPLICITLY_SET) | |
| 435 anchor_point_ = last_touch_exploration_->location_f(); | |
| 436 | |
| 444 return ui::EVENT_REWRITE_REWRITTEN; | 437 return ui::EVENT_REWRITE_REWRITTEN; |
| 445 } | 438 } |
| 446 | 439 |
| 447 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( | 440 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( |
| 448 const ui::TouchEvent& event, | 441 const ui::TouchEvent& event, |
| 449 std::unique_ptr<ui::Event>* rewritten_event) { | 442 std::unique_ptr<ui::Event>* rewritten_event) { |
| 450 // The events were sent to the gesture provider in RewriteEvent already. | 443 // The events were sent to the gesture provider in RewriteEvent already. |
| 451 // If no gesture is registered before the tap timer times out, the state | 444 // If no gesture is registered before the tap timer times out, the state |
| 452 // will change to "wait for no fingers down" or "touch exploration" depending | 445 // will change to "wait for no fingers down" or "touch exploration" depending |
| 453 // on the number of fingers down, and this function will stop being called. | 446 // on the number of fingers down, and this function will stop being called. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 ui::EventType type = event.type(); | 511 ui::EventType type = event.type(); |
| 519 gfx::PointF location = event.location_f(); | 512 gfx::PointF location = event.location_f(); |
| 520 if (type == ui::ET_TOUCH_PRESSED) { | 513 if (type == ui::ET_TOUCH_PRESSED) { |
| 521 // A third finger being pressed means that a split tap can no longer go | 514 // A third finger being pressed means that a split tap can no longer go |
| 522 // through. The user enters the wait state, Since there has already been | 515 // through. The user enters the wait state, Since there has already been |
| 523 // a press dispatched when split tap began, the touch needs to be | 516 // a press dispatched when split tap began, the touch needs to be |
| 524 // cancelled. | 517 // cancelled. |
| 525 std::unique_ptr<ui::TouchEvent> new_event( | 518 std::unique_ptr<ui::TouchEvent> new_event( |
| 526 new ui::TouchEvent(ui::ET_TOUCH_CANCELLED, gfx::Point(), | 519 new ui::TouchEvent(ui::ET_TOUCH_CANCELLED, gfx::Point(), |
| 527 initial_press_->touch_id(), event.time_stamp())); | 520 initial_press_->touch_id(), event.time_stamp())); |
| 528 new_event->set_location_f(last_touch_exploration_->location_f()); | 521 new_event->set_location_f(anchor_point_); |
| 529 new_event->set_root_location_f(last_touch_exploration_->location_f()); | 522 new_event->set_root_location_f(anchor_point_); |
| 530 new_event->set_flags(event.flags()); | 523 new_event->set_flags(event.flags()); |
| 531 *rewritten_event = std::move(new_event); | 524 *rewritten_event = std::move(new_event); |
| 532 SET_STATE(WAIT_FOR_NO_FINGERS); | 525 SET_STATE(WAIT_FOR_NO_FINGERS); |
| 533 return ui::EVENT_REWRITE_REWRITTEN; | 526 return ui::EVENT_REWRITE_REWRITTEN; |
| 534 } else if (type == ui::ET_TOUCH_MOVED) { | 527 } else if (type == ui::ET_TOUCH_MOVED) { |
| 535 // If the fingers have moved too far from their original locations, | 528 // If the fingers have moved too far from their original locations, |
| 536 // the user can no longer split tap. | 529 // the user can no longer split tap. |
| 537 ui::TouchEvent* original_touch; | 530 ui::TouchEvent* original_touch; |
| 538 if (event.touch_id() == last_touch_exploration_->touch_id()) { | 531 if (event.touch_id() == last_touch_exploration_->touch_id()) { |
| 539 original_touch = last_touch_exploration_.get(); | 532 original_touch = last_touch_exploration_.get(); |
| 540 } else if (event.touch_id() == initial_press_->touch_id()) { | 533 } else if (event.touch_id() == initial_press_->touch_id()) { |
| 541 original_touch = initial_press_.get(); | 534 original_touch = initial_press_.get(); |
| 542 } else { | 535 } else { |
| 543 NOTREACHED(); | 536 NOTREACHED(); |
| 544 SET_STATE(WAIT_FOR_NO_FINGERS); | 537 SET_STATE(WAIT_FOR_NO_FINGERS); |
| 545 return ui::EVENT_REWRITE_DISCARD; | 538 return ui::EVENT_REWRITE_DISCARD; |
| 546 } | 539 } |
| 547 // Check the distance between the current finger location and the original | 540 // Check the distance between the current finger location and the original |
| 548 // location. The slop for this is a bit more generous since keeping two | 541 // location. The slop for this is a bit more generous since keeping two |
| 549 // fingers in place is a bit harder. If the user has left the slop, the | 542 // fingers in place is a bit harder. If the user has left the slop, the |
| 550 // split tap press (which was previous dispatched) is lifted with a touch | 543 // user enters the wait state. |
| 551 // cancelled, and the user enters the wait state. | |
| 552 if ((event.location_f() - original_touch->location_f()).Length() > | 544 if ((event.location_f() - original_touch->location_f()).Length() > |
| 553 GetSplitTapTouchSlop()) { | 545 GetSplitTapTouchSlop()) { |
| 554 std::unique_ptr<ui::TouchEvent> new_event( | |
| 555 new ui::TouchEvent(ui::ET_TOUCH_CANCELLED, gfx::Point(), | |
| 556 initial_press_->touch_id(), event.time_stamp())); | |
| 557 new_event->set_location_f(last_touch_exploration_->location_f()); | |
| 558 new_event->set_root_location_f(last_touch_exploration_->location_f()); | |
| 559 new_event->set_flags(event.flags()); | |
| 560 *rewritten_event = std::move(new_event); | |
| 561 SET_STATE(WAIT_FOR_NO_FINGERS); | 546 SET_STATE(WAIT_FOR_NO_FINGERS); |
| 562 return ui::EVENT_REWRITE_REWRITTEN; | |
| 563 } | 547 } |
| 564 return ui::EVENT_REWRITE_DISCARD; | 548 return ui::EVENT_REWRITE_DISCARD; |
| 565 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 549 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 566 // If the touch exploration finger is lifted, there is no option to return | 550 // If the touch exploration finger is lifted, there is no option to return |
| 567 // to touch explore anymore. The remaining finger acts as a pending | 551 // to touch explore anymore. The remaining finger acts as a pending |
| 568 // tap or long tap for the last touch explore location. | 552 // tap or long tap for the last touch explore location. |
| 569 if (event.touch_id() == last_touch_exploration_->touch_id()) { | 553 if (event.touch_id() == last_touch_exploration_->touch_id()) { |
| 570 SET_STATE(TOUCH_RELEASE_PENDING); | 554 SET_STATE(TOUCH_RELEASE_PENDING); |
| 571 return EVENT_REWRITE_DISCARD; | 555 return EVENT_REWRITE_DISCARD; |
| 572 } | 556 } |
| 573 | 557 |
| 574 // Continue to release the touch only if the touch explore finger is the | 558 // Continue to release the touch only if the touch explore finger is the |
| 575 // only finger remaining. | 559 // only finger remaining. |
| 576 if (current_touch_ids_.size() != 1) | 560 if (current_touch_ids_.size() != 1) |
| 577 return EVENT_REWRITE_DISCARD; | 561 return EVENT_REWRITE_DISCARD; |
| 578 | 562 |
| 579 // Rewrite at location of last touch exploration. | 563 SendSimulatedClick(); |
| 580 std::unique_ptr<ui::TouchEvent> new_event( | 564 |
| 581 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(), | |
| 582 initial_press_->touch_id(), event.time_stamp())); | |
| 583 new_event->set_location_f(last_touch_exploration_->location_f()); | |
| 584 new_event->set_root_location_f(last_touch_exploration_->location_f()); | |
| 585 new_event->set_flags(event.flags()); | |
| 586 *rewritten_event = std::move(new_event); | |
| 587 SET_STATE(TOUCH_EXPLORATION); | 565 SET_STATE(TOUCH_EXPLORATION); |
| 588 EnterTouchToMouseMode(); | 566 EnterTouchToMouseMode(); |
| 589 return ui::EVENT_REWRITE_REWRITTEN; | 567 return ui::EVENT_REWRITE_DISCARD; |
| 590 } | 568 } |
| 591 NOTREACHED(); | 569 NOTREACHED(); |
| 592 return ui::EVENT_REWRITE_CONTINUE; | 570 return ui::EVENT_REWRITE_CONTINUE; |
| 593 } | 571 } |
| 594 | 572 |
| 595 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers( | 573 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers( |
| 596 const ui::TouchEvent& event, | 574 const ui::TouchEvent& event, |
| 597 std::unique_ptr<ui::Event>* rewritten_event) { | 575 std::unique_ptr<ui::Event>* rewritten_event) { |
| 598 if (current_touch_ids_.size() == 0) | 576 if (current_touch_ids_.size() == 0) |
| 599 SET_STATE(NO_FINGERS_DOWN); | 577 SET_STATE(NO_FINGERS_DOWN); |
| 600 return EVENT_REWRITE_DISCARD; | 578 return EVENT_REWRITE_DISCARD; |
| 601 } | 579 } |
| 602 | 580 |
| 603 void TouchExplorationController::PlaySoundForTimer() { | 581 void TouchExplorationController::PlaySoundForTimer() { |
| 604 delegate_->PlayVolumeAdjustEarcon(); | 582 delegate_->PlayVolumeAdjustEarcon(); |
| 605 } | 583 } |
| 606 | 584 |
| 585 void TouchExplorationController::SendSimulatedClick() { | |
| 586 // If we got an anchor point from ChromeVox, send a double-tap gesture | |
| 587 // and let ChromeVox handle the click. | |
| 588 if (anchor_point_state_ == ANCHOR_POINT_EXPLICITLY_SET) { | |
|
David Tseng
2016/05/26 22:48:24
I'm not entirely clear when the explicit vs touch
dmazzoni
2016/05/26 22:59:24
Yes, that's right.
If you touch-explore and Chrom
David Tseng
2016/06/01 00:36:15
This is a little surprising to me because a Chrome
| |
| 589 delegate_->HandleAccessibilityGesture(ui::AX_GESTURE_CLICK); | |
| 590 return; | |
| 591 } | |
| 592 | |
| 593 // If we don't have an anchor point, we can't send a simulated click. | |
| 594 if (anchor_point_state_ == ANCHOR_POINT_NONE) | |
| 595 return; | |
| 596 | |
| 597 // Otherwise send a simulated press/release at the anchor point. | |
| 598 std::unique_ptr<ui::TouchEvent> touch_press; | |
| 599 touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), | |
| 600 initial_press_->touch_id(), Now())); | |
| 601 touch_press->set_location_f(anchor_point_); | |
| 602 touch_press->set_root_location_f(anchor_point_); | |
| 603 DispatchEvent(touch_press.get()); | |
| 604 | |
| 605 std::unique_ptr<ui::TouchEvent> touch_release; | |
| 606 touch_release.reset(new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(), | |
| 607 initial_press_->touch_id(), Now())); | |
| 608 touch_release->set_location_f(anchor_point_); | |
| 609 touch_release->set_root_location_f(anchor_point_); | |
| 610 DispatchEvent(touch_release.get()); | |
| 611 } | |
| 612 | |
| 607 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( | 613 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( |
| 608 const ui::TouchEvent& event, | 614 const ui::TouchEvent& event, |
| 609 std::unique_ptr<ui::Event>* rewritten_event) { | 615 std::unique_ptr<ui::Event>* rewritten_event) { |
| 610 // The timer should not fire when sliding. | 616 // The timer should not fire when sliding. |
| 611 tap_timer_.Stop(); | 617 tap_timer_.Stop(); |
| 612 | 618 |
| 613 ui::EventType type = event.type(); | 619 ui::EventType type = event.type(); |
| 614 // If additional fingers are added before a swipe gesture has been registered, | 620 // If additional fingers are added before a swipe gesture has been registered, |
| 615 // then wait until all fingers have been lifted. | 621 // then wait until all fingers have been lifted. |
| 616 if (type == ui::ET_TOUCH_PRESSED || | 622 if (type == ui::ET_TOUCH_PRESSED || |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 } | 705 } |
| 700 | 706 |
| 701 void TouchExplorationController::StartTapTimer() { | 707 void TouchExplorationController::StartTapTimer() { |
| 702 tap_timer_.Start(FROM_HERE, | 708 tap_timer_.Start(FROM_HERE, |
| 703 gesture_detector_config_.double_tap_timeout, | 709 gesture_detector_config_.double_tap_timeout, |
| 704 this, | 710 this, |
| 705 &TouchExplorationController::OnTapTimerFired); | 711 &TouchExplorationController::OnTapTimerFired); |
| 706 } | 712 } |
| 707 | 713 |
| 708 void TouchExplorationController::OnTapTimerFired() { | 714 void TouchExplorationController::OnTapTimerFired() { |
| 715 LOG(ERROR) << "** OnTapTimerFired **"; | |
|
David Tseng
2016/05/26 22:48:24
nit: remove
dmazzoni
2016/05/26 22:59:24
Done.
| |
| 709 switch (state_) { | 716 switch (state_) { |
| 710 case SINGLE_TAP_RELEASED: | 717 case SINGLE_TAP_RELEASED: |
| 711 SET_STATE(NO_FINGERS_DOWN); | 718 SET_STATE(NO_FINGERS_DOWN); |
| 712 break; | 719 break; |
| 713 case TOUCH_EXPLORE_RELEASED: | 720 case TOUCH_EXPLORE_RELEASED: |
| 714 SET_STATE(NO_FINGERS_DOWN); | 721 SET_STATE(NO_FINGERS_DOWN); |
| 715 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 722 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
| 723 anchor_point_ = last_touch_exploration_->location_f(); | |
| 724 anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION; | |
| 716 return; | 725 return; |
| 717 case DOUBLE_TAP_PENDING: { | 726 case DOUBLE_TAP_PENDING: { |
| 718 SET_STATE(ONE_FINGER_PASSTHROUGH); | 727 SET_STATE(ONE_FINGER_PASSTHROUGH); |
| 719 passthrough_offset_ = last_unused_finger_event_->location_f() - | 728 passthrough_offset_ = |
| 720 last_touch_exploration_->location_f(); | 729 last_unused_finger_event_->location_f() - anchor_point_; |
| 721 std::unique_ptr<ui::TouchEvent> passthrough_press( | 730 std::unique_ptr<ui::TouchEvent> passthrough_press( |
| 722 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), | 731 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), |
| 723 last_unused_finger_event_->touch_id(), Now())); | 732 last_unused_finger_event_->touch_id(), Now())); |
| 724 passthrough_press->set_location_f(last_touch_exploration_->location_f()); | 733 passthrough_press->set_location_f(anchor_point_); |
| 725 passthrough_press->set_root_location_f( | 734 passthrough_press->set_root_location_f(anchor_point_); |
| 726 last_touch_exploration_->location_f()); | |
| 727 DispatchEvent(passthrough_press.get()); | 735 DispatchEvent(passthrough_press.get()); |
| 728 return; | 736 return; |
| 729 } | 737 } |
| 730 case SINGLE_TAP_PRESSED: | 738 case SINGLE_TAP_PRESSED: |
| 731 if (passthrough_timer_.IsRunning()) | 739 if (passthrough_timer_.IsRunning()) |
| 732 return; | 740 return; |
| 733 case GESTURE_IN_PROGRESS: | 741 case GESTURE_IN_PROGRESS: |
| 734 // If only one finger is down, go into touch exploration. | 742 // If only one finger is down, go into touch exploration. |
| 735 if (current_touch_ids_.size() == 1) { | 743 if (current_touch_ids_.size() == 1) { |
| 744 anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION; | |
| 736 EnterTouchToMouseMode(); | 745 EnterTouchToMouseMode(); |
| 737 SET_STATE(TOUCH_EXPLORATION); | 746 SET_STATE(TOUCH_EXPLORATION); |
| 738 break; | 747 break; |
| 739 } | 748 } |
| 740 // Otherwise wait for all fingers to be lifted. | 749 // Otherwise wait for all fingers to be lifted. |
| 741 SET_STATE(WAIT_FOR_NO_FINGERS); | 750 SET_STATE(WAIT_FOR_NO_FINGERS); |
| 742 return; | 751 return; |
| 743 case TWO_FINGER_TAP: | 752 case TWO_FINGER_TAP: |
| 744 SET_STATE(WAIT_FOR_NO_FINGERS); | 753 SET_STATE(WAIT_FOR_NO_FINGERS); |
| 745 break; | 754 break; |
| 746 default: | 755 default: |
| 747 return; | 756 return; |
| 748 } | 757 } |
| 749 EnterTouchToMouseMode(); | 758 EnterTouchToMouseMode(); |
| 750 std::unique_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( | 759 std::unique_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( |
| 751 initial_press_->location_f(), initial_press_->flags()); | 760 initial_press_->location_f(), initial_press_->flags()); |
| 752 DispatchEvent(mouse_move.get()); | 761 DispatchEvent(mouse_move.get()); |
| 753 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 762 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
| 763 anchor_point_ = last_touch_exploration_->location_f(); | |
| 764 anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION; | |
| 754 } | 765 } |
| 755 | 766 |
| 756 void TouchExplorationController::OnPassthroughTimerFired() { | 767 void TouchExplorationController::OnPassthroughTimerFired() { |
| 757 // The passthrough timer will only fire if if the user has held a finger in | 768 // The passthrough timer will only fire if if the user has held a finger in |
| 758 // one of the passthrough corners for the duration of the passthrough timeout. | 769 // one of the passthrough corners for the duration of the passthrough timeout. |
| 759 | 770 |
| 760 // Check that initial press isn't null. Also a check that if the initial | 771 // Check that initial press isn't null. Also a check that if the initial |
| 761 // corner press was released, then it should not be in corner passthrough. | 772 // corner press was released, then it should not be in corner passthrough. |
| 762 if (!initial_press_ || | 773 if (!initial_press_ || |
| 763 touch_locations_.find(initial_press_->touch_id()) != | 774 touch_locations_.find(initial_press_->touch_id()) != |
| 764 touch_locations_.end()) { | 775 touch_locations_.end()) { |
| 765 LOG(ERROR) << "No initial press or the initial press has been released."; | |
| 766 } | 776 } |
| 767 | 777 |
| 768 gfx::Point location = | 778 gfx::Point location = |
| 769 ToRoundedPoint(touch_locations_[initial_press_->touch_id()]); | 779 ToRoundedPoint(touch_locations_[initial_press_->touch_id()]); |
| 770 int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); | 780 int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); |
| 771 if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER) | 781 if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER) |
| 772 return; | 782 return; |
| 773 | 783 |
| 774 if (sound_timer_.IsRunning()) | 784 if (sound_timer_.IsRunning()) |
| 775 sound_timer_.Stop(); | 785 sound_timer_.Stop(); |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1142 return "TWO_FINGER_TAP"; | 1152 return "TWO_FINGER_TAP"; |
| 1143 } | 1153 } |
| 1144 return "Not a state"; | 1154 return "Not a state"; |
| 1145 } | 1155 } |
| 1146 | 1156 |
| 1147 float TouchExplorationController::GetSplitTapTouchSlop() { | 1157 float TouchExplorationController::GetSplitTapTouchSlop() { |
| 1148 return gesture_detector_config_.touch_slop * 3; | 1158 return gesture_detector_config_.touch_slop * 3; |
| 1149 } | 1159 } |
| 1150 | 1160 |
| 1151 } // namespace ui | 1161 } // namespace ui |
| OLD | NEW |