Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: ui/chromeos/touch_exploration_controller.cc

Issue 410783002: Corner Passthrough for Accessibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@side-gestures
Patch Set: Added tests and Rebase off Master Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/chromeos/touch_exploration_controller.cc
diff --git a/ui/chromeos/touch_exploration_controller.cc b/ui/chromeos/touch_exploration_controller.cc
index 0a63014062c19cbb9580426b5854b23c3a2008b7..233f544b8d6c0a5c735df55483c1083800b86279 100644
--- a/ui/chromeos/touch_exploration_controller.cc
+++ b/ui/chromeos/touch_exploration_controller.cc
@@ -23,6 +23,10 @@ namespace {
// Delay between adjustment sounds.
const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150);
+// Delay before corner passthrough activates.
+const base::TimeDelta kCornerPassthroughDelay =
+ base::TimeDelta::FromMilliseconds(500);
+
// In ChromeOS, VKEY_LWIN is synonymous for the search key.
const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
} // namespace
@@ -36,7 +40,8 @@ TouchExplorationController::TouchExplorationController(
event_handler_for_testing_(NULL),
gesture_provider_(this),
prev_state_(NO_FINGERS_DOWN),
- VLOG_on_(true) {
+ VLOG_on_(true),
+ waiting_for_corner_passthrough_(false) {
CHECK(root_window);
root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
}
@@ -132,6 +137,8 @@ ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
return InTouchExploreSecondPress(touch_event, rewritten_event);
case TWO_TO_ONE_FINGER:
return InTwoToOneFinger(touch_event, rewritten_event);
+ case CORNER_PASSTHROUGH:
+ return InCornerPassthrough(touch_event, rewritten_event);
case PASSTHROUGH:
return InPassthrough(touch_event, rewritten_event);
case WAIT_FOR_RELEASE:
@@ -152,28 +159,60 @@ ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
const ui::EventType type = event.type();
- if (type == ui::ET_TOUCH_PRESSED) {
- initial_press_.reset(new TouchEvent(event));
- last_unused_finger_event_.reset(new TouchEvent(event));
- tap_timer_.Start(FROM_HERE,
- gesture_detector_config_.double_tap_timeout,
- this,
- &TouchExplorationController::OnTapTimerFired);
- gesture_provider_.OnTouchEvent(event);
- gesture_provider_.OnTouchEventAck(false);
- ProcessGestureEvents();
- state_ = SINGLE_TAP_PRESSED;
- VLOG_STATE();
- return ui::EVENT_REWRITE_DISCARD;
+ if (type != ui::ET_TOUCH_PRESSED) {
+ NOTREACHED() << "Unexpected event type received: " << event.name();
+ return ui::EVENT_REWRITE_CONTINUE;
}
- NOTREACHED() << "Unexpected event type received: " << event.name();;
- return ui::EVENT_REWRITE_CONTINUE;
+ int location = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
+ base::TimeDelta timeout;
+
+ // If the press was at a corner, the user might go into corner passthrough
+ // instead.
+ bool in_a_bottom_corner =
+ (BOTTOM_LEFT_CORNER == location) || (BOTTOM_RIGHT_CORNER == location);
+ if (in_a_bottom_corner) {
+ VLOG(0) << "Location: " << location;
+ timeout = kCornerPassthroughDelay;
+ waiting_for_corner_passthrough_ = true;
+ } else {
+ timeout = gesture_detector_config_.double_tap_timeout;
+ waiting_for_corner_passthrough_ = false;
+ }
+
+ initial_press_.reset(new TouchEvent(event));
+ last_unused_finger_event_.reset(new TouchEvent(event));
+ tap_timer_.Start(
+ FROM_HERE, timeout, this, &TouchExplorationController::OnTapTimerFired);
+ gesture_provider_.OnTouchEvent(event);
+ gesture_provider_.OnTouchEventAck(false);
+ ProcessGestureEvents();
+ state_ = SINGLE_TAP_PRESSED;
+ VLOG_STATE();
+ return ui::EVENT_REWRITE_DISCARD;
}
ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
const ui::EventType type = event.type();
+ int location = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
+ bool in_a_bottom_corner =
+ (location == BOTTOM_LEFT_CORNER) || (location == BOTTOM_RIGHT_CORNER);
+ // If the event is from the initial press and the location is no longer in the
+ // corner, then we are not waiting for a corner passthrough anymore.
+ if (event.touch_id() == initial_press_->touch_id() && in_a_bottom_corner) {
aboxhall 2014/07/24 18:26:34 I think |in_a_bottom_corner| should be negated...
lisayin 2014/07/25 20:11:57 Opps...
+ waiting_for_corner_passthrough_ = false;
+ // If the initial press was in a corner, then more than the double tap
+ // timeout could have elapsed.
+ if (tap_timer_.IsRunning() &&
+ event.time_stamp() - initial_press_->time_stamp() >
+ gesture_detector_config_.double_tap_timeout) {
+ tap_timer_.Stop();
+ OnTapTimerFired();
+ return EVENT_REWRITE_DISCARD;
+ }
+ }
+
if (type == ui::ET_TOUCH_PRESSED) {
// Adding a second finger within the timeout period switches to
// passing through every event from the second finger and none form the
@@ -402,7 +441,7 @@ ui::EventRewriteStatus TouchExplorationController::InTwoToOneFinger(
// If a third finger is pressed, we are now going into passthrough mode
// and now need to dispatch the first finger into a press, as well as the
// recent press.
- if (current_touch_ids_.size() == 3){
+ if (current_touch_ids_.size() == 3) {
state_ = PASSTHROUGH;
scoped_ptr<ui::TouchEvent> first_finger_press;
first_finger_press.reset(
@@ -441,6 +480,33 @@ ui::EventRewriteStatus TouchExplorationController::InTwoToOneFinger(
return ui::EVENT_REWRITE_CONTINUE;
}
+ui::EventRewriteStatus TouchExplorationController::InCornerPassthrough(
+ const ui::TouchEvent& event,
+ scoped_ptr<ui::Event>* rewritten_event) {
+ ui::EventType type = event.type();
+ if (current_touch_ids_.size() == 0) {
+ ResetToNoFingersDown();
+ }
+
+ if (event.touch_id() == initial_press_->touch_id()) {
aboxhall 2014/07/24 18:26:34 Some comments explaining this block would be helpf
lisayin 2014/07/25 20:11:57 Done.
+ int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
aboxhall 2014/07/24 18:26:34 suggestion: s/edge/edges/
lisayin 2014/07/25 20:11:57 Done.
+ bool in_a_bottom_corner = (edge == BOTTOM_LEFT_CORNER) ||
+ (edge == BOTTOM_RIGHT_CORNER);
+ if (type == ui::ET_TOUCH_MOVED && in_a_bottom_corner)
+ return ui::EVENT_REWRITE_DISCARD;
+
+ waiting_for_corner_passthrough_ = false;
+ state_ = WAIT_FOR_RELEASE;
+ return ui::EVENT_REWRITE_DISCARD;
+ }
+
+ rewritten_event->reset(new ui::TouchEvent(
+ type, event.location(), event.touch_id(), event.time_stamp()));
+ (*rewritten_event)->set_flags(event.flags());
+
+ return ui::EVENT_REWRITE_REWRITTEN;
+}
+
ui::EventRewriteStatus TouchExplorationController::InPassthrough(
const ui::TouchEvent& event,
scoped_ptr<ui::Event>* rewritten_event) {
@@ -586,6 +652,14 @@ ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
}
void TouchExplorationController::OnTapTimerFired() {
+ if (waiting_for_corner_passthrough_) {
+ delegate_->PlayEarCon();
+ delete gesture_provider_.GetAndResetPendingGestures();
+ state_ = CORNER_PASSTHROUGH;
+ VLOG_STATE();
+ return;
+ }
+
switch (state_) {
case SINGLE_TAP_RELEASED:
ResetToNoFingersDown();
@@ -805,6 +879,7 @@ void TouchExplorationController::EnterTouchToMouseMode() {
}
void TouchExplorationController::ResetToNoFingersDown() {
+ waiting_for_corner_passthrough_ = false;
ProcessGestureEvents();
if (sound_timer_.IsRunning())
sound_timer_.Stop();
@@ -875,6 +950,8 @@ const char* TouchExplorationController::EnumStateToString(State state) {
return "TOUCH_EXPLORE_SECOND_PRESS";
case TWO_TO_ONE_FINGER:
return "TWO_TO_ONE_FINGER";
+ case CORNER_PASSTHROUGH:
+ return "CORNER_PASSTHROUGH";
case PASSTHROUGH:
return "PASSTHROUGH";
case WAIT_FOR_RELEASE:

Powered by Google App Engine
This is Rietveld 408576698