blob: 1dd6f480ec0905f56945a25eda996346e628913a [file] [log] [blame] [view]
Katie Db05e9c52019-07-23 01:10:141# Automatic clicks (for developers)
2
3Automatic clicks is a Chrome OS feature to automatically generate mouse events
4when the cursor dwells in one location.
5
6
7Dwell control supports users with motor impairments. A user who is unable to
8use a mouse or unable to click with a mouse, but who is able to control the
9cursor position (often using an alternative input method) will need to use
10dwell control to perform mouse or trackpad actions, including left-click,
11right-click, double-click, click-and-drag and scroll.
12
13## Using automatic clicks
14
15Go to Chrome settings, Accessibility settings, Manage accessibility Features”,
16and in the mouse and input section enable Automatically click when the
17cursor stops”. You can adjust timing, radius, stabilization, and whether to
18revert to a left-click after another type of action has been taken from the
19settings page.
20
21
22A on-screen menu bubble will appear in the corner. Dwell over this menu to
23change the action taken, or pause the feature. There is also a button to
24re-position the menu to another corner of the screen.
25
26## Reporting bugs
27
28Use bugs.chromium.org, filing bugs under the component UI>Accessibility with
29the label autoclick (or, use
30[this template](https://bugs.chromium.org/p/chromium/issues/entry?summary=Autoclick%20-%20&status=Available&cc=katie%40chromium.org%2C%20qqwangxin%40google.com&labels=Pri-3%2C%20autoclick%2C&components=UI>Accessibility)).
31
32
Anatoliy Potapchukae8526c2020-04-09 12:52:0133Open bugs have the label
Katie Db05e9c52019-07-23 01:10:1434“[autoclick](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=label%3Aautoclick)”.
35
36## Developing
37
38### Code location
39
40Automatic clicks code lives mainly in three places:
41
42- A controller, event-rewriter, and widgets to draw around click locations, in
Nick Yamanedea69892023-09-20 15:11:3943ash/accessibility/autoclick/
Katie Db05e9c52019-07-23 01:10:1444
45- UI through menu bubbles and their controllers, in
46ash/system/accessibility/autoclick*
47
48- A component extension to provide Accessibility tree information, in
Katie D38d4421b2020-06-22 18:50:4649chrome/browser/resources/chromeos/accessibility/accessibility_common/
Katie Db05e9c52019-07-23 01:10:1450
51In addition, there are settings for automatic clicks in
Josiah Krutz07abfcc42023-08-01 20:47:0652chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.*
Katie Db05e9c52019-07-23 01:10:1453
54### Tests
55
56Tests are in ash_unittests and in browser_tests:
57
58```
59out/Release/ash_unittests --gtest_filter=”Autoclick*”
60out/Release/browser_tests --gtest_filter=”Autoclick*”
61```
62
63### Debugging
64
65Developers can add log lines to any of the autoclick C++ files and see output
Katie D38d4421b2020-06-22 18:50:4666in the console. To debug the Accessibility Common extension, the easiest way is
67from an external browser. Start Chrome OS on Linux with this command-line flag:
Katie Db05e9c52019-07-23 01:10:1468
69```
70out/Release/chrome --remote-debugging-port=9222
71```
72
73Now open http://localhost:9222 in a separate instance of the browser, and debug
Katie D38d4421b2020-06-22 18:50:4674the Accessibility Common extension background page from there.
Katie Db05e9c52019-07-23 01:10:1475
76## How it works
77
78AutoclickController is a pre-target EventHandler with very high priority,
79which means it can receive and act on mouse events before other parts of
80Chrome OS get them.
81
82
83AutoclickController::OnMouseEvent receives mouse events and checks whether
84the event is close to the current dwell target (in which case dwell count-down
85should continue), or far enough away to clear the target and set a new one.
86
87
88There is a small delay before the user sees the count-down timer ring UI appear
89(AutoclickRingHandler) show up, which is controlled by the start_gesture_timer_.
90Performing the click is controlled by the autoclick_timer_.
91
92
93When the autoclick_timer_ completes it calls
94AutoclickController::DoAutoclickAction. This function first checks if the
95target point is over either of the autoclick bubbles, the menu or the scroll
96bubble. If it is over a bubble the gesture will not be handled with a synthetic
97event, but instead sent directly to that menu. This keeps focus from shifting
98and things like dialogs or context menus from closing when the user interacts
99with an autoclick bubble. But, if the target was not over the bubble, a
100synthetic event is generated as follows:
101
102### Left-click, right-click and double-click
103
Avi Drissmanae99ae282024-07-22 20:44:28104Synthetic mouse events for ui::EventType::kMousePressed and
105ui::EventType::kMouseReleased are created with the appropriate mouse button
106flags, and sent to the WindowTreeHost under the target point for processing.
107For double-click, a second press and release pair are also sent.
Katie Db05e9c52019-07-23 01:10:14108
109### Click-and-drag
110
Avi Drissmanae99ae282024-07-22 20:44:28111A synthetic mouse event for ui::EventType::kMousePressed is created at the first
112dwell. An AutoclickDragEventRewriter is enabled and begins re-writing all
113ui::EventType::kMouseMoved events to ui::EventType::kMouseDragged events to
114create the illusion of a drag. This occurs in
115AutoclickDragEventRewriter::RewriteEvent.
Katie Db05e9c52019-07-23 01:10:14116
Avi Drissmanae99ae282024-07-22 20:44:28117A final synthetic mouse event for ui::EventType::kMouseReleased is created at
118the second dwell, and the AutoclickDragEventRewriter is disabled.
Katie Db05e9c52019-07-23 01:10:14119
120### Scroll
121
122On a dwell during scroll, the scroll target point is changed. No scroll events
123are generated from AutoclickController until the user hovers over the scroll
124pad buttons (AutoclickScrollButton class). The AutoclickScrollButtons track
125whether they are currently hovered, and while hovered they fire a repeating
126timer to ask the AutoclickController to do a scroll event.
127
128#### Scroll location
129
130By default, the scroll position is at the center of the active screen. Users
131may dwell anywhere on the screen to change the scroll location.
132
133
134When the scroll location is changed, the AutoclickController will request the
Katie D38d4421b2020-06-22 18:50:46135bounds of the nearest scrollable view from the Accessibility Common extension
136via the AccessibilityPrivate API. The Accessibility Common component extension
137has access to accessibility tree information, and using a HitTest is able to
138find the view at the scroll location, then walks up the tree to find the first
139view which can scroll, or stops at the nearest window or dialog bounds. This
140logic takes place in autoclick.js, onAutomationHitTestResult_. When the
141scrolling location is found, the bounds of the scrollable area are highlighted
142with a focus ring. In addition, the bounds are sent back through the
143AccessibilityPrivate API, routed to the AutoclickController, which passes it via
144the AutoclickMenuBubbleController to the AutoclickScrollBubbleController, which
Katie Db05e9c52019-07-23 01:10:14145does layout accordingly.
146
147### Bubble Menus: interface and positioning
148
149The AutoclickController owns the AutoclickMenuBubbleController, which controls
150the widget and AutoclickMenuView view for the autoclick bubble menu.
151AutoclickMenuView inherits from TrayBubbleView for styling, and contains all
152the buttons to change click types, pause, and update the menu position.
153
154
155Similarly, AutoclickMenuBubbleController also owns
156AutoclickScrollBubbleController so that it can pass on messages about
157positioning and activation from AutoclickController.
158AutoclickScrollBubbleController owns the widgets and AutoclickScrollView for
159the autoclick scroll bubble. AutoclickScrollView inherits from TrayBubbleView
160for styling, and contains the scroll pad buttons, including all the logic to
161draw the custom shape buttons for left/right/up/down scrolling.
162
163#### Menu positioning
164
165The autoclick bubble menu can be positioned in the four corners of the screen
166and defaults to the same location as the volume widget (which depends on
167LTR/RTL language). AutoclickMenuBubbleController takes a preferred
Anatoliy Potapchukae8526c2020-04-09 12:52:01168FloatingMenuPosition enum and uses that to determine the best position for
Katie Db05e9c52019-07-23 01:10:14169the menu in AutoclickMenuBubbleController::SetPosition. This function finds
Anatoliy Potapchukae8526c2020-04-09 12:52:01170the ideal corner of the screen, then uses CollisionDetectionUtils (also used
Katie Db05e9c52019-07-23 01:10:14171by Picture-in-Picture) to refine the position to avoid collisions with system
172UI.
173
174#### Scroll bubble positioning
175
176The scroll bubble starts out anchored to the automatic clicks bubble menu, but
177if the user selects a new scroll point it will move. When a scroll point is
Katie D38d4421b2020-06-22 18:50:46178selected, if the scrollable region found by the Accessibility Common extension
Katie Db05e9c52019-07-23 01:10:14179is large enough, the scroll bubble will be anchored near the scroll point
180itself, similarly to the way the context menu is anchored near the cursor on
Anatoliy Potapchukae8526c2020-04-09 12:52:01181a right click. When the scrollable region is small, the scroll bubble will be
Katie Db05e9c52019-07-23 01:10:14182anchored to the closest side of the scrollable region to the scroll point, as
183long as there is space for it on that side.
184
185#### Clicking on the bubble menus
186
Nick Yamanedea69892023-09-20 15:11:39187The AutoclickController cannot generate synthetic click events over the
Katie Db05e9c52019-07-23 01:10:14188bubbles, because that would cause context and focus changes. For example, if
189the user has a drop-down menu open, clicking the autoclick menu bubble will
190cause the drop-down to close. Instead, the AutoclickController must check to
Anatoliy Potapchukae8526c2020-04-09 12:52:01191see if an event will take place over a bubble menu, and if so, request that
192AutoclickMenuBubbleController forward the event to the bubble via
Katie Db05e9c52019-07-23 01:10:14193AutoclickMenuBubbleController::ClickOnBubble. This generates a synthetic mouse
Anatoliy Potapchukae8526c2020-04-09 12:52:01194event which does not propagate through the system, so there is no focus or
Katie Db05e9c52019-07-23 01:10:14195context change, allowing users to continue to interact with whatever was on
196screen.
197
198## For Googlers
199
200Googlers could check out the automatic clicks feature design docs for more
201details on design as well as autoclicks UMA.
202
203- Overall product design, [go/chromeos-dwell-design](go/chromeos-dwell-design)
204
205- On-screen menu design,
206[go/chromeos-dwell-menu-design](go/chromeos-dwell-menu-design)
207
208- Scrolling design,
209[go/chromeos-dwell-scroll-design](go/chromeos-dwell-scroll-design)
210
211- UX mocks, [go/cros-dwell-ux](go/cros-dwell-ux)