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

Side by Side Diff: ui/chromeos/touch_exploration_controller.h

Issue 296403011: Support double-tap to click in touch accessibility controller. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #ifndef UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ 5 #ifndef UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
6 #define UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ 6 #define UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
7 7
8 #include "base/timer/timer.h"
8 #include "base/values.h" 9 #include "base/values.h"
9 #include "ui/chromeos/ui_chromeos_export.h" 10 #include "ui/chromeos/ui_chromeos_export.h"
10 #include "ui/events/event_rewriter.h" 11 #include "ui/events/event_rewriter.h"
12 #include "ui/events/gesture_detection/gesture_detector.h"
11 #include "ui/gfx/geometry/point.h" 13 #include "ui/gfx/geometry/point.h"
12 14
13 namespace aura { 15 namespace aura {
14 class Window; 16 class Window;
15 } 17 }
16 18
17 namespace ui { 19 namespace ui {
18 20
19 class Event; 21 class Event;
22 class TouchEvent;
20 23
21 // TouchExplorationController is used in tandem with "Spoken Feedback" to 24 // TouchExplorationController is used in tandem with "Spoken Feedback" to
22 // make the touch UI accessible. TouchExplorationController rewrites the 25 // make the touch UI accessible.
23 // incoming touch events as follows: 26 //
24 // - When one finger is touching the screen, touch events are converted to mouse 27 // At a high-level, single-finger events are used for accessibility -
25 // moves. This is the "Touch Exploration Mode". (The idea is that mouse moves 28 // exploring the screen gets turned into mouse moves (which can then be
26 // will be subsequently used by another component to move focus between UI 29 // spoken by an accessibility service running), a double-tap simulates a
27 // elements, and the elements will be read out to the user.) 30 // click, and gestures can be used to send high-level accessibility commands.
28 // - When more than one finger is touching the screen, touches from the 31 // Whenever two or more fingers are pressed, the events are passed through
mfomitchev 2014/05/28 17:47:45 This doesn't seem entirely accurate - the minus on
dmazzoni 2014/06/04 22:46:27 I tried to clarify, and I also tried to make it mo
29 // first (i.e. "oldest") finger are ignored, and the other touches go through 32 // withone finger removed - so if you swipe down with two fingers, the
mfomitchev 2014/05/28 17:47:45 "withone" - missing space
dmazzoni 2014/06/04 22:46:27 Done.
30 // as is. 33 // running app will see a one-finger swipe.
34 //
35 // Here are the details of the implementation:
36 //
37 // When the first touch is pressed, a 300 ms grace period timer starts.
38 //
39 // If the user keeps their finger down for more than 300 ms and doesn't
40 // perform a gesture in that time, they enter touch exploration mode, and
mfomitchev 2014/05/28 17:47:45 I'd say smth like "supported accessibility gesture
dmazzoni 2014/06/04 22:46:27 Done.
41 // all movements are translated into synthesized mouse move events.
42 //
43 // Also, if the user moves their single finger outside a certain slop region
mfomitchev 2014/05/28 17:47:45 This won't be accurate once we support swipe gestu
dmazzoni 2014/06/04 22:46:27 True, but let's update the comment then.
44 // (without performing a gesture), they enter touch exploration mode earlier
45 // than 300 ms.
46 //
47 // If the user taps and releases their finger, after 300 ms from the initial
48 // touch, a single mouse move is fired.
49 //
50 // If the user double-taps, the second tap is passed through, allowing the
51 // user to click - however, the double-tap location is changed to the location
52 // of the last successful touch exploration - that allows the user to explore
53 // anywhere on the screen, hear its description, then double-tap anywhere
54 // to activate it.
55 //
56 // If the user adds a second finger during the grace period, they enter
57 // passthrough mode. In this mode, the first finger is ignored but all
58 // additional touch events are mostly passed through unmodified. So a
59 // two-finger scroll gets passed through as a one-finger scroll. However,
60 // once in passthrough mode, if one finger is released, the remaining finger
mfomitchev 2014/05/28 17:47:45 "remaining fingers continue"
dmazzoni 2014/06/04 22:46:27 Done.
61 // continues to pass through events, allowing the user to start a scroll
62 // with two fingers but finish it with one. Sometimes this requires rewriting
63 // the touch ids.
64 //
65 // Once either touch exploration or passthrough mode has been activated,
66 // it remains in that mode until all fingers have been released.
67 //
31 // The caller is expected to retain ownership of instances of this class and 68 // The caller is expected to retain ownership of instances of this class and
32 // destroy them before |root_window| is destroyed. 69 // destroy them before |root_window| is destroyed.
33 class UI_CHROMEOS_EXPORT TouchExplorationController : 70 class UI_CHROMEOS_EXPORT TouchExplorationController :
34 public ui::EventRewriter { 71 public ui::EventRewriter {
35 public: 72 public:
36 explicit TouchExplorationController(aura::Window* root_window); 73 explicit TouchExplorationController(aura::Window* root_window);
37 virtual ~TouchExplorationController(); 74 virtual ~TouchExplorationController();
38 75
39 private: 76 private:
40 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location, 77 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location,
41 int flags); 78 int flags);
42 79
43 void EnterTouchToMouseMode(); 80 void EnterTouchToMouseMode();
44 81
45 // Overridden from ui::EventRewriter 82 // Overridden from ui::EventRewriter
46 virtual ui::EventRewriteStatus RewriteEvent( 83 virtual ui::EventRewriteStatus RewriteEvent(
47 const ui::Event& event, scoped_ptr<ui::Event>* rewritten_event) OVERRIDE; 84 const ui::Event& event, scoped_ptr<ui::Event>* rewritten_event) OVERRIDE;
48 virtual ui::EventRewriteStatus NextDispatchEvent( 85 virtual ui::EventRewriteStatus NextDispatchEvent(
49 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE; 86 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE;
50 87
88 // Event handlers based on the current state - see State, below.
89 ui::EventRewriteStatus OnNoFingersDown(
90 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
91 ui::EventRewriteStatus OnGracePeriod(
92 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
93 ui::EventRewriteStatus OnTouchExploration(
94 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
95 ui::EventRewriteStatus OnPassthroughMinusOne(
96 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
97 ui::EventRewriteStatus OnSingleTapPending(
98 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
99 ui::EventRewriteStatus OnDoubleTapPressed(
100 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
101
102 // This timer is started every time we get the first press event, and
103 // it fires after the double-click timeout elapses (300 ms by default).
104 // If the user taps and releases within 300 ms and doesn't press again,
105 // we treat that as a single mouse move (touch exploration) event.
106 void OnTapTimerFired();
107
108 enum State {
109 // No fingers are down and no events are pending.
110 NO_FINGERS_DOWN,
111
112 // A single finger is down, but we're not yet sure if this is going
113 // to be touch exploration or something else.
114 GRACE_PERIOD,
mfomitchev 2014/05/28 17:47:45 IMHO the naming is a bit confusing, since GRACE_PE
dmazzoni 2014/06/04 22:46:27 I like that, thanks.
115
116 // A single finger is down and after the grace period the user
mfomitchev 2014/05/28 17:47:45 You could have multiple fingers down in this mode,
dmazzoni 2014/06/04 22:46:27 Done.
117 // hasn't added a second finger or moved the finger too rapidly.
118 // We're now in touch exploration mode until this finger is lifted.
mfomitchev 2014/05/28 17:47:45 "until all fingers are lifted"
dmazzoni 2014/06/04 22:46:27 Done.
119 TOUCH_EXPLORATION,
mfomitchev 2014/05/28 17:47:45 I'd move this down next to PASSTHROUGH_MINUS_ONE -
dmazzoni 2014/06/04 22:46:27 Done.
120
121 // The user pressed and released a single finger - a tap - but we have
mfomitchev 2014/05/28 17:47:45 This sounds a bit confusing IMHO. I'd say like "..
dmazzoni 2014/06/04 22:46:27 Done.
122 // to wait until the end of the grace period before we will rewrite this
123 // as touch exploration, in case it's actually the first tap of a mouse
124 // move.
125 SINGLE_TAP_PENDING,
126
127 // The user tapped once, and before the grace period expired, pressed
128 // one finger down to begin a double-tap, but has not released it yet.
129 DOUBLE_TAP_PRESSED,
130
131 // The user placed two or more fingers down within the grace period.
132 // We're now in passthrough mode until all fingers are lifted. When
133 // two ore more fingers are down, we subtract one finger but otherwise
mfomitchev 2014/05/28 17:47:45 Doesn't seem like this is entirely accurate - base
dmazzoni 2014/06/04 22:46:27 Fixed. FWIW, we may need to tweak this -the mouse
134 // pass through all events unchanged.
135 PASSTHROUGH_MINUS_ONE,
136 };
137
138 aura::Window* root_window_;
139
51 // A set of touch ids for fingers currently touching the screen. 140 // A set of touch ids for fingers currently touching the screen.
52 std::vector<int> touch_ids_; 141 std::vector<int> touch_ids_;
53 142
54 // Map of touch ids to their last known location. 143 // Map of touch ids to their last known location.
55 std::map<int, gfx::PointF> touch_locations_; 144 std::map<int, gfx::PointF> touch_locations_;
56 145
57 // Initialized from RewriteEvent() and dispatched in NextDispatchEvent(). 146 // A map from the actual touch ids to the rewritten touch ids when in
mfomitchev 2014/05/28 17:47:45 Hmm.. why change touch ids?
58 scoped_ptr<ui::Event> next_dispatch_event_; 147 // "passthrough minus one" mode, where we pass through two-finger gestures
148 // as if they were one, and so on.
149 std::map<int, int> touch_id_map_;
59 150
60 aura::Window* root_window_; 151 // The current state.
152 State state_;
153
154 // A copy of the event from the initial touch press.
155 scoped_ptr<ui::TouchEvent> initial_press_;
156
157 // The last location where we synthesized a mouse move event.
158 // When the user double-taps, we send the passed-through tap here.
159 gfx::PointF last_touch_exploration_location_;
160
161 // A timer to fire the mouse move event after the double-tap delay.
162 base::OneShotTimer<TouchExplorationController> tap_timer_;
163
164 // A default gesture detector config, so we can share the same
165 // timeout and pixel slop constants.
166 ui::GestureDetector::Config gesture_detector_config_;
61 167
62 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); 168 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController);
63 }; 169 };
64 170
65 } // namespace ui 171 } // namespace ui
66 172
67 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ 173 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698