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 = |