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 |