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 "base/time/default_tick_clock.h" | 9 #include "base/time/default_tick_clock.h" |
10 #include "ui/aura/client/cursor_client.h" | 10 #include "ui/aura/client/cursor_client.h" |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 const ui::TouchEvent& event, | 306 const ui::TouchEvent& event, |
307 scoped_ptr<ui::Event>* rewritten_event) { | 307 scoped_ptr<ui::Event>* rewritten_event) { |
308 const ui::EventType type = event.type(); | 308 const ui::EventType type = event.type(); |
309 // If there is more than one finger down, then discard to wait until no | 309 // If there is more than one finger down, then discard to wait until no |
310 // fingers are down. | 310 // fingers are down. |
311 if (current_touch_ids_.size() > 1) { | 311 if (current_touch_ids_.size() > 1) { |
312 SET_STATE(WAIT_FOR_NO_FINGERS); | 312 SET_STATE(WAIT_FOR_NO_FINGERS); |
313 return ui::EVENT_REWRITE_DISCARD; | 313 return ui::EVENT_REWRITE_DISCARD; |
314 } | 314 } |
315 if (type == ui::ET_TOUCH_PRESSED) { | 315 if (type == ui::ET_TOUCH_PRESSED) { |
316 // If there is no touch exploration yet, we can't send a click, so discard. | 316 // If there is no touch exploration yet, we can't send a click, so discard |
317 // and wait for no fingers. | |
317 if (!last_touch_exploration_) { | 318 if (!last_touch_exploration_) { |
318 tap_timer_.Stop(); | 319 tap_timer_.Stop(); |
320 SET_STATE(WAIT_FOR_NO_FINGERS); | |
319 return ui::EVENT_REWRITE_DISCARD; | 321 return ui::EVENT_REWRITE_DISCARD; |
320 } | 322 } |
321 // This is the second tap in a double-tap (or double tap-hold). | 323 if (state_ == SINGLE_TAP_RELEASED) { |
dmazzoni
2014/08/15 15:34:01
This "if/else" block is now more than half of the
evy
2014/08/15 16:14:57
Done.
| |
322 // We set the tap timer. If it fires before the user lifts their finger, | 324 // This is the second tap in a double-tap (or double tap-hold). |
323 // one-finger passthrough begins. Otherwise, there is a touch press and | 325 // We set the passthrough timer. If it fires before the user lifts their |
324 // release at the location of the last touch exploration. | 326 // finger, one-finger passthrough begins. Otherwise, there is a touch |
325 SET_STATE(DOUBLE_TAP_PENDING); | 327 // press and release at the location of the last touch exploration. |
326 // The old tap timer (from the initial click) is stopped if it is still | 328 SET_STATE(DOUBLE_TAP_PENDING); |
327 // going, and the new one is set. | 329 // Initial press now holds the intial double tap press - this event. |
328 tap_timer_.Stop(); | 330 initial_press_.reset(new ui::TouchEvent(event)); |
329 StartTapTimer(); | 331 // The old tap timer (from the initial click) is stopped if it is still |
330 // This will update as the finger moves before a possible passthrough, and | 332 // going, and the passthrough timer is set. |
331 // will determine the offset. | 333 tap_timer_.Stop(); |
332 last_unused_finger_event_.reset(new ui::TouchEvent(event)); | 334 passthrough_timer_.Start( |
333 return ui::EVENT_REWRITE_DISCARD; | 335 FROM_HERE, |
334 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) { | 336 gesture_detector_config_.longpress_timeout, |
335 // If the previous press was discarded, we need to also handle its | 337 this, |
336 // release. | 338 &TouchExplorationController::OnPassthroughTimerFired); |
337 if (current_touch_ids_.size() == 0) { | 339 // This will update as the finger moves before a possible passthrough, and |
338 SET_STATE(NO_FINGERS_DOWN); | 340 // will determine the offset. |
341 last_unused_finger_event_.reset(new ui::TouchEvent(event)); | |
342 return ui::EVENT_REWRITE_DISCARD; | |
343 } else if (state_ == TOUCH_EXPLORE_RELEASED) { | |
344 // This is the initial "press" (location, time, and touch id) of a single | |
345 // tap click. | |
346 initial_press_.reset(new ui::TouchEvent(event)); | |
347 rewritten_event->reset( | |
348 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | |
349 last_touch_exploration_->location(), | |
350 initial_press_->touch_id(), | |
351 event.time_stamp())); | |
352 (*rewritten_event)->set_flags(event.flags()); | |
353 SET_STATE(TOUCH_RELEASE_PENDING); | |
354 return ui::EVENT_REWRITE_REWRITTEN; | |
339 } | 355 } |
340 return ui::EVENT_REWRITE_DISCARD; | |
341 } else if (type == ui::ET_TOUCH_MOVED) { | 356 } else if (type == ui::ET_TOUCH_MOVED) { |
342 return ui::EVENT_REWRITE_DISCARD; | 357 return ui::EVENT_REWRITE_DISCARD; |
343 } | 358 } |
344 NOTREACHED(); | 359 NOTREACHED(); |
345 return ui::EVENT_REWRITE_CONTINUE; | 360 return ui::EVENT_REWRITE_CONTINUE; |
346 } | 361 } |
347 | 362 |
348 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending( | 363 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending( |
349 const ui::TouchEvent& event, | 364 const ui::TouchEvent& event, |
350 scoped_ptr<ui::Event>* rewritten_event) { | 365 scoped_ptr<ui::Event>* rewritten_event) { |
351 const ui::EventType type = event.type(); | 366 const ui::EventType type = event.type(); |
352 if (type == ui::ET_TOUCH_PRESSED) { | 367 if (type == ui::ET_TOUCH_PRESSED) { |
353 return ui::EVENT_REWRITE_DISCARD; | 368 return ui::EVENT_REWRITE_DISCARD; |
354 } else if (type == ui::ET_TOUCH_MOVED) { | 369 } else if (type == ui::ET_TOUCH_MOVED) { |
355 // If the user moves far enough from the initial touch location (outside | 370 // If the user moves far enough from the initial touch location (outside |
356 // the "slop" region, jump to passthrough mode early. | 371 // the "slop" region, jump to passthrough mode early. |
357 float delta = (event.location() - initial_press_->location()).Length(); | 372 float delta = (event.location() - initial_press_->location()).Length(); |
358 if (delta > gesture_detector_config_.touch_slop) { | 373 if (delta > gesture_detector_config_.touch_slop) { |
359 tap_timer_.Stop(); | 374 passthrough_timer_.Stop(); |
360 OnTapTimerFired(); | 375 if (VLOG_on_) |
376 VLOG(0) << "Finger left slop and is entering passthrough"; | |
377 OnPassthroughTimerFired(); | |
361 } | 378 } |
362 return EVENT_REWRITE_DISCARD; | 379 return EVENT_REWRITE_DISCARD; |
363 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 380 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
364 if (current_touch_ids_.size() != 0) | 381 if (current_touch_ids_.size() != 0) |
365 return EVENT_REWRITE_DISCARD; | 382 return EVENT_REWRITE_DISCARD; |
366 | 383 |
384 // Now it is recognized that the user was doing a double tap to click. | |
385 // The passthrough timer is stopped and a touch press and release are | |
386 // dispatched. | |
387 passthrough_timer_.Stop(); | |
388 | |
367 scoped_ptr<ui::TouchEvent> touch_press; | 389 scoped_ptr<ui::TouchEvent> touch_press; |
368 touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | 390 touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
369 last_touch_exploration_->location(), | 391 last_touch_exploration_->location(), |
370 initial_press_->touch_id(), | 392 initial_press_->touch_id(), |
371 event.time_stamp())); | 393 event.time_stamp())); |
372 DispatchEvent(touch_press.get()); | 394 DispatchEvent(touch_press.get()); |
373 | 395 |
374 rewritten_event->reset( | 396 rewritten_event->reset( |
375 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, | 397 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, |
376 last_touch_exploration_->location(), | 398 last_touch_exploration_->location(), |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
660 | 682 |
661 void TouchExplorationController::OnTapTimerFired() { | 683 void TouchExplorationController::OnTapTimerFired() { |
662 switch (state_) { | 684 switch (state_) { |
663 case SINGLE_TAP_RELEASED: | 685 case SINGLE_TAP_RELEASED: |
664 SET_STATE(NO_FINGERS_DOWN); | 686 SET_STATE(NO_FINGERS_DOWN); |
665 break; | 687 break; |
666 case TOUCH_EXPLORE_RELEASED: | 688 case TOUCH_EXPLORE_RELEASED: |
667 SET_STATE(NO_FINGERS_DOWN); | 689 SET_STATE(NO_FINGERS_DOWN); |
668 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 690 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
669 return; | 691 return; |
670 case DOUBLE_TAP_PENDING: { | |
671 SET_STATE(ONE_FINGER_PASSTHROUGH); | |
672 passthrough_offset_ = last_unused_finger_event_->location() - | |
673 last_touch_exploration_->location(); | |
674 scoped_ptr<ui::TouchEvent> passthrough_press( | |
675 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | |
676 last_touch_exploration_->location(), | |
677 last_unused_finger_event_->touch_id(), | |
678 Now())); | |
679 DispatchEvent(passthrough_press.get()); | |
680 return; | |
681 } | |
682 case SINGLE_TAP_PRESSED: | 692 case SINGLE_TAP_PRESSED: |
683 if (passthrough_timer_.IsRunning()) | 693 if (passthrough_timer_.IsRunning()) |
684 return; | 694 return; |
685 case GESTURE_IN_PROGRESS: | 695 case GESTURE_IN_PROGRESS: |
686 // If only one finger is down, go into touch exploration. | 696 // If only one finger is down, go into touch exploration. |
687 if (current_touch_ids_.size() == 1) { | 697 if (current_touch_ids_.size() == 1) { |
688 SET_STATE(TOUCH_EXPLORATION); | 698 SET_STATE(TOUCH_EXPLORATION); |
689 break; | 699 break; |
690 } | 700 } |
691 // Otherwise wait for all fingers to be lifted. | 701 // Otherwise wait for all fingers to be lifted. |
692 SET_STATE(WAIT_FOR_NO_FINGERS); | 702 SET_STATE(WAIT_FOR_NO_FINGERS); |
693 return; | 703 return; |
694 case TWO_FINGER_TAP: | 704 case TWO_FINGER_TAP: |
695 SET_STATE(WAIT_FOR_NO_FINGERS); | 705 SET_STATE(WAIT_FOR_NO_FINGERS); |
696 break; | 706 break; |
697 default: | 707 default: |
708 NOTREACHED() << "tap timer fired in unrecognized state"; | |
698 return; | 709 return; |
699 } | 710 } |
700 EnterTouchToMouseMode(); | 711 EnterTouchToMouseMode(); |
701 scoped_ptr<ui::Event> mouse_move = | 712 scoped_ptr<ui::Event> mouse_move = |
702 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); | 713 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); |
703 DispatchEvent(mouse_move.get()); | 714 DispatchEvent(mouse_move.get()); |
704 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 715 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
705 } | 716 } |
706 | 717 |
707 void TouchExplorationController::OnPassthroughTimerFired() { | 718 void TouchExplorationController::OnPassthroughTimerFired() { |
708 // The passthrough timer will only fire if if the user has held a finger in | 719 switch (state_) { |
709 // one of the passthrough corners for the duration of the passthrough timeout. | 720 case SINGLE_TAP_PRESSED: |
721 case TOUCH_EXPLORATION: | |
722 case GESTURE_IN_PROGRESS: { | |
723 // The timer will only fire in this state if if the user has held a finger | |
724 // in one of the passthrough corners for the duration of the passthrough | |
725 // timeout. | |
710 | 726 |
711 // Check that initial press isn't null. Also a check that if the initial | 727 // Check that initial press isn't null. Also a check that if the initial |
712 // corner press was released, then it should not be in corner passthrough. | 728 // corner press was released, then it should not be in corner passthrough. |
713 if (!initial_press_ || | 729 if (!initial_press_ || |
714 touch_locations_.find(initial_press_->touch_id()) != | 730 touch_locations_.find(initial_press_->touch_id()) != |
715 touch_locations_.end()) { | 731 touch_locations_.end()) { |
716 LOG(ERROR) << "No initial press or the initial press has been released."; | 732 LOG(ERROR) |
733 << "No initial press or the initial press has been released."; | |
734 } | |
735 | |
736 gfx::Point location = | |
737 ToRoundedPoint(touch_locations_[initial_press_->touch_id()]); | |
738 int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); | |
739 if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER) | |
740 return; | |
741 | |
742 SET_STATE(CORNER_PASSTHROUGH); | |
743 break; | |
744 } | |
745 case DOUBLE_TAP_PENDING: { | |
746 // Enter one finger passthrough mode. | |
747 SET_STATE(ONE_FINGER_PASSTHROUGH); | |
748 passthrough_offset_ = last_unused_finger_event_->location() - | |
749 last_touch_exploration_->location(); | |
750 scoped_ptr<ui::TouchEvent> passthrough_press( | |
751 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | |
752 last_touch_exploration_->location(), | |
753 last_unused_finger_event_->touch_id(), | |
754 Now())); | |
755 DispatchEvent(passthrough_press.get()); | |
756 break; | |
757 } | |
758 default: | |
759 NOTREACHED() << "passthrough timer fired in unrecognized state"; | |
760 return; | |
717 } | 761 } |
718 | |
719 gfx::Point location = | |
720 ToRoundedPoint(touch_locations_[initial_press_->touch_id()]); | |
721 int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); | |
722 if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER) | |
723 return; | |
724 | |
725 if (sound_timer_.IsRunning()) | 762 if (sound_timer_.IsRunning()) |
726 sound_timer_.Stop(); | 763 sound_timer_.Stop(); |
727 delegate_->PlayPassthroughEarcon(); | 764 delegate_->PlayPassthroughEarcon(); |
728 SET_STATE(CORNER_PASSTHROUGH); | |
729 return; | |
730 } | 765 } |
731 | 766 |
732 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 767 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
733 ui::EventDispatchDetails result ALLOW_UNUSED = | 768 ui::EventDispatchDetails result ALLOW_UNUSED = |
734 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 769 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
735 } | 770 } |
736 | 771 |
737 // This is an override for a function that is only called for timer-based events | 772 // This is an override for a function that is only called for timer-based events |
738 // like long press. Events that are created synchronously as a result of | 773 // like long press. Events that are created synchronously as a result of |
739 // certain touch events are added to the vector accessible via | 774 // certain touch events are added to the vector accessible via |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1105 left_swipe_gestures_[4] = | 1140 left_swipe_gestures_[4] = |
1106 BindKeyEventWithFlags(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE); | 1141 BindKeyEventWithFlags(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE); |
1107 right_swipe_gestures_[4] = | 1142 right_swipe_gestures_[4] = |
1108 BindKeyEventWithFlags(VKEY_BRIGHTNESS_UP, ui::EF_NONE); | 1143 BindKeyEventWithFlags(VKEY_BRIGHTNESS_UP, ui::EF_NONE); |
1109 up_swipe_gestures_[4] = BindKeyEventWithFlags(VKEY_BROWSER_HOME, ui::EF_NONE); | 1144 up_swipe_gestures_[4] = BindKeyEventWithFlags(VKEY_BROWSER_HOME, ui::EF_NONE); |
1110 down_swipe_gestures_[4] = | 1145 down_swipe_gestures_[4] = |
1111 BindKeyEventWithFlags(VKEY_BROWSER_REFRESH, ui::EF_NONE); | 1146 BindKeyEventWithFlags(VKEY_BROWSER_REFRESH, ui::EF_NONE); |
1112 } | 1147 } |
1113 | 1148 |
1114 } // namespace ui | 1149 } // namespace ui |
OLD | NEW |