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

Unified Diff: ui/chromeos/touch_exploration_controller.cc

Issue 2007863004: Fix the double-tap to click gesture in touch accessibility mode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 d4399b1eb45969144fce501748b6a6d8eeca3d21..d26f5ecbd7c3bba5e504f54a5b6890871941d0d1 100644
--- a/ui/chromeos/touch_exploration_controller.cc
+++ b/ui/chromeos/touch_exploration_controller.cc
@@ -37,6 +37,7 @@ TouchExplorationController::TouchExplorationController(
: root_window_(root_window),
delegate_(delegate),
state_(NO_FINGERS_DOWN),
+ anchor_point_state_(ANCHOR_POINT_NONE),
gesture_provider_(new GestureProviderAura(this, this)),
prev_state_(NO_FINGERS_DOWN),
VLOG_on_(true),
@@ -49,6 +50,15 @@ TouchExplorationController::~TouchExplorationController() {
root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
}
+void TouchExplorationController::SetTouchAccessibilityAnchorPoint(
+ const gfx::Point& anchor_point) {
+ gfx::Point native_point = anchor_point;
+ root_window_->GetHost()->ConvertPointToNativeScreen(&native_point);
+
+ anchor_point_ = gfx::PointF(native_point.x(), native_point.y());
+ anchor_point_state_ = ANCHOR_POINT_EXPLICITLY_SET;
+}
+
ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
const ui::Event& event,
std::unique_ptr<ui::Event>* rewritten_event) {
@@ -295,6 +305,7 @@ ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
SET_STATE(GESTURE_IN_PROGRESS);
return InGestureInProgress(event, rewritten_event);
}
+ anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION;
EnterTouchToMouseMode();
SET_STATE(TOUCH_EXPLORATION);
return InTouchExploration(event, rewritten_event);
@@ -315,8 +326,12 @@ TouchExplorationController::InSingleTapOrTouchExploreReleased(
return ui::EVENT_REWRITE_DISCARD;
}
if (type == ui::ET_TOUCH_PRESSED) {
- // If there is no touch exploration yet, we can't send a click, so discard.
- if (!last_touch_exploration_) {
+ // If there is no anchor point for synthesized events because the
+ // user hasn't touch-explored or focused anything yet, we can't
+ // send a click, so discard.
+ if (anchor_point_state_ == ANCHOR_POINT_NONE) {
+ LOG(ERROR) << "*** NO ANCHOR POINT ***";
+
tap_timer_.Stop();
return ui::EVENT_REWRITE_DISCARD;
}
@@ -333,7 +348,8 @@ TouchExplorationController::InSingleTapOrTouchExploreReleased(
// will determine the offset.
last_unused_finger_event_.reset(new ui::TouchEvent(event));
return ui::EVENT_REWRITE_DISCARD;
- } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) {
+ } else if (type == ui::ET_TOUCH_RELEASED &&
+ anchor_point_state_ == ANCHOR_POINT_NONE) {
// If the previous press was discarded, we need to also handle its
// release.
if (current_touch_ids_.size() == 0) {
@@ -366,23 +382,10 @@ ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending(
if (current_touch_ids_.size() != 0)
return EVENT_REWRITE_DISCARD;
- std::unique_ptr<ui::TouchEvent> touch_press;
- touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(),
- initial_press_->touch_id(),
- event.time_stamp()));
- touch_press->set_location_f(last_touch_exploration_->location_f());
- touch_press->set_root_location_f(last_touch_exploration_->location_f());
- DispatchEvent(touch_press.get());
+ SendSimulatedClick();
- std::unique_ptr<ui::TouchEvent> new_event(
- new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(),
- initial_press_->touch_id(), event.time_stamp()));
- new_event->set_location_f(last_touch_exploration_->location_f());
- new_event->set_root_location_f(last_touch_exploration_->location_f());
- new_event->set_flags(event.flags());
- *rewritten_event = std::move(new_event);
SET_STATE(NO_FINGERS_DOWN);
- return ui::EVENT_REWRITE_REWRITTEN;
+ return ui::EVENT_REWRITE_DISCARD;
}
NOTREACHED();
return ui::EVENT_REWRITE_CONTINUE;
@@ -398,15 +401,9 @@ ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending(
if (current_touch_ids_.size() != 0)
return EVENT_REWRITE_DISCARD;
- std::unique_ptr<ui::TouchEvent> new_event(
- new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(),
- initial_press_->touch_id(), event.time_stamp()));
- new_event->set_location_f(last_touch_exploration_->location_f());
- new_event->set_root_location_f(last_touch_exploration_->location_f());
- new_event->set_flags(event.flags());
- *rewritten_event = std::move(new_event);
+ SendSimulatedClick();
SET_STATE(NO_FINGERS_DOWN);
- return ui::EVENT_REWRITE_REWRITTEN;
+ return ui::EVENT_REWRITE_DISCARD;
}
NOTREACHED();
return ui::EVENT_REWRITE_CONTINUE;
@@ -417,18 +414,11 @@ ui::EventRewriteStatus TouchExplorationController::InTouchExploration(
std::unique_ptr<ui::Event>* rewritten_event) {
const ui::EventType type = event.type();
if (type == ui::ET_TOUCH_PRESSED) {
- // Handle split-tap.
+ // Enter split-tap mode.
initial_press_.reset(new TouchEvent(event));
tap_timer_.Stop();
- std::unique_ptr<ui::TouchEvent> new_event(
- new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), event.touch_id(),
- event.time_stamp()));
- new_event->set_location_f(last_touch_exploration_->location_f());
- new_event->set_root_location_f(last_touch_exploration_->location_f());
- new_event->set_flags(event.flags());
- *rewritten_event = std::move(new_event);
SET_STATE(TOUCH_EXPLORE_SECOND_PRESS);
- return ui::EVENT_REWRITE_REWRITTEN;
+ return ui::EVENT_REWRITE_DISCARD;
} else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
initial_press_.reset(new TouchEvent(event));
StartTapTimer();
@@ -441,6 +431,9 @@ ui::EventRewriteStatus TouchExplorationController::InTouchExploration(
// Rewrite as a mouse-move event.
*rewritten_event = CreateMouseMoveEvent(event.location_f(), event.flags());
last_touch_exploration_.reset(new TouchEvent(event));
+ if (anchor_point_state_ != ANCHOR_POINT_EXPLICITLY_SET)
+ anchor_point_ = last_touch_exploration_->location_f();
+
return ui::EVENT_REWRITE_REWRITTEN;
}
@@ -525,8 +518,8 @@ ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress(
std::unique_ptr<ui::TouchEvent> new_event(
new ui::TouchEvent(ui::ET_TOUCH_CANCELLED, gfx::Point(),
initial_press_->touch_id(), event.time_stamp()));
- new_event->set_location_f(last_touch_exploration_->location_f());
- new_event->set_root_location_f(last_touch_exploration_->location_f());
+ new_event->set_location_f(anchor_point_);
+ new_event->set_root_location_f(anchor_point_);
new_event->set_flags(event.flags());
*rewritten_event = std::move(new_event);
SET_STATE(WAIT_FOR_NO_FINGERS);
@@ -547,19 +540,10 @@ ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress(
// Check the distance between the current finger location and the original
// location. The slop for this is a bit more generous since keeping two
// fingers in place is a bit harder. If the user has left the slop, the
- // split tap press (which was previous dispatched) is lifted with a touch
- // cancelled, and the user enters the wait state.
+ // user enters the wait state.
if ((event.location_f() - original_touch->location_f()).Length() >
GetSplitTapTouchSlop()) {
- std::unique_ptr<ui::TouchEvent> new_event(
- new ui::TouchEvent(ui::ET_TOUCH_CANCELLED, gfx::Point(),
- initial_press_->touch_id(), event.time_stamp()));
- new_event->set_location_f(last_touch_exploration_->location_f());
- new_event->set_root_location_f(last_touch_exploration_->location_f());
- new_event->set_flags(event.flags());
- *rewritten_event = std::move(new_event);
SET_STATE(WAIT_FOR_NO_FINGERS);
- return ui::EVENT_REWRITE_REWRITTEN;
}
return ui::EVENT_REWRITE_DISCARD;
} else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
@@ -576,17 +560,11 @@ ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress(
if (current_touch_ids_.size() != 1)
return EVENT_REWRITE_DISCARD;
- // Rewrite at location of last touch exploration.
- std::unique_ptr<ui::TouchEvent> new_event(
- new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(),
- initial_press_->touch_id(), event.time_stamp()));
- new_event->set_location_f(last_touch_exploration_->location_f());
- new_event->set_root_location_f(last_touch_exploration_->location_f());
- new_event->set_flags(event.flags());
- *rewritten_event = std::move(new_event);
+ SendSimulatedClick();
+
SET_STATE(TOUCH_EXPLORATION);
EnterTouchToMouseMode();
- return ui::EVENT_REWRITE_REWRITTEN;
+ return ui::EVENT_REWRITE_DISCARD;
}
NOTREACHED();
return ui::EVENT_REWRITE_CONTINUE;
@@ -604,6 +582,34 @@ void TouchExplorationController::PlaySoundForTimer() {
delegate_->PlayVolumeAdjustEarcon();
}
+void TouchExplorationController::SendSimulatedClick() {
+ // If we got an anchor point from ChromeVox, send a double-tap gesture
+ // and let ChromeVox handle the click.
+ 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
+ delegate_->HandleAccessibilityGesture(ui::AX_GESTURE_CLICK);
+ return;
+ }
+
+ // If we don't have an anchor point, we can't send a simulated click.
+ if (anchor_point_state_ == ANCHOR_POINT_NONE)
+ return;
+
+ // Otherwise send a simulated press/release at the anchor point.
+ std::unique_ptr<ui::TouchEvent> touch_press;
+ touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(),
+ initial_press_->touch_id(), Now()));
+ touch_press->set_location_f(anchor_point_);
+ touch_press->set_root_location_f(anchor_point_);
+ DispatchEvent(touch_press.get());
+
+ std::unique_ptr<ui::TouchEvent> touch_release;
+ touch_release.reset(new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(),
+ initial_press_->touch_id(), Now()));
+ touch_release->set_location_f(anchor_point_);
+ touch_release->set_root_location_f(anchor_point_);
+ DispatchEvent(touch_release.get());
+}
+
ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
const ui::TouchEvent& event,
std::unique_ptr<ui::Event>* rewritten_event) {
@@ -706,6 +712,7 @@ void TouchExplorationController::StartTapTimer() {
}
void TouchExplorationController::OnTapTimerFired() {
+ LOG(ERROR) << "** OnTapTimerFired **";
David Tseng 2016/05/26 22:48:24 nit: remove
dmazzoni 2016/05/26 22:59:24 Done.
switch (state_) {
case SINGLE_TAP_RELEASED:
SET_STATE(NO_FINGERS_DOWN);
@@ -713,17 +720,18 @@ void TouchExplorationController::OnTapTimerFired() {
case TOUCH_EXPLORE_RELEASED:
SET_STATE(NO_FINGERS_DOWN);
last_touch_exploration_.reset(new TouchEvent(*initial_press_));
+ anchor_point_ = last_touch_exploration_->location_f();
+ anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION;
return;
case DOUBLE_TAP_PENDING: {
SET_STATE(ONE_FINGER_PASSTHROUGH);
- passthrough_offset_ = last_unused_finger_event_->location_f() -
- last_touch_exploration_->location_f();
+ passthrough_offset_ =
+ last_unused_finger_event_->location_f() - anchor_point_;
std::unique_ptr<ui::TouchEvent> passthrough_press(
new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(),
last_unused_finger_event_->touch_id(), Now()));
- passthrough_press->set_location_f(last_touch_exploration_->location_f());
- passthrough_press->set_root_location_f(
- last_touch_exploration_->location_f());
+ passthrough_press->set_location_f(anchor_point_);
+ passthrough_press->set_root_location_f(anchor_point_);
DispatchEvent(passthrough_press.get());
return;
}
@@ -733,6 +741,7 @@ void TouchExplorationController::OnTapTimerFired() {
case GESTURE_IN_PROGRESS:
// If only one finger is down, go into touch exploration.
if (current_touch_ids_.size() == 1) {
+ anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION;
EnterTouchToMouseMode();
SET_STATE(TOUCH_EXPLORATION);
break;
@@ -751,6 +760,8 @@ void TouchExplorationController::OnTapTimerFired() {
initial_press_->location_f(), initial_press_->flags());
DispatchEvent(mouse_move.get());
last_touch_exploration_.reset(new TouchEvent(*initial_press_));
+ anchor_point_ = last_touch_exploration_->location_f();
+ anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION;
}
void TouchExplorationController::OnPassthroughTimerFired() {
@@ -762,7 +773,6 @@ void TouchExplorationController::OnPassthroughTimerFired() {
if (!initial_press_ ||
touch_locations_.find(initial_press_->touch_id()) !=
touch_locations_.end()) {
- LOG(ERROR) << "No initial press or the initial press has been released.";
}
gfx::Point location =

Powered by Google App Engine
This is Rietveld 408576698