act — semantic actions on accessibility elements
act invokes an element’s action layer — the verbs the platform itself
exposes (press, toggle, expand, set_value, …) — instead of synthesizing
pointer motion. Where control reproduces what a hand would
do, act says what it MEANS: “press this button”, “set this field”, “open
this menu”.
Computer::act(&self, input: &ComputerAct) -> Result<ActOutput, String>
act(metadata, ComputerAct) -> Result<ActOutput, String>
The model: one step, then the next
A ComputerAct is ONE step of a pipeline. A semantic step carries:
- a target —
name/pid(an application) orsurface(a shell surface, seesurface) — plus aselectorwith optionalnth; - an action —
ActAction, defaulting topress. The full set:press,focus,blur,toggle,select,expand,collapse,show_menu,increment,decrement,scroll_into_view,set_value(+value),set_numeric_value(+numeric_value),select_text(+range, 0-based,endEXCLUSIVE),type_text(+value), andperform_action(+value, a platform-specific action name). - patience —
timeout_ms(default 3000) bounds the auto-wait for the app AND a visible+enabled match. Unlikesnapshot/screenshot, actions wait for actionability.
Steps chain via then with shell && semantics: each next step runs only
if the previous succeeded, and the output joins the per-step reports with
→ (set_value \entry` (app) → waited 400 ms → pressed `button``).
Keyboard steps inside an act chain
A step with key/text (or a bare wait) is a KEYBOARD/WAIT step — no
selector, typing goes into whatever holds keyboard focus. That is the
validator split to internalize:
- semantic steps carry
selector+ action — validated by the semantic validator (payload checks run BEFORE dispatch, so a malformed call fails fast instead of auto-waiting for an element that was never the problem); - keyboard steps carry
key/text/held— validated by the shared keyboard engine as the chain walks.
Feeding a keyboard step to the semantic validator is itself an error whose
guidance names the right engine. And because act has no pointer, a chain
that needs typing into a NEW field either uses set_value (which targets
an element directly) or does its focus move with a real
control click first.
Choosing between act and control
Reach for act when… |
Reach for control when… |
|---|---|
The element exposes the action (snapshot shows the role; buttons, fields, toggles usually do) |
You need a real OS click to move keyboard focus |
| The intent is semantic (“check this”, “set this”) | The intent is positional (hover, drag, scroll a canvas) |
| You want auto-wait for actionability | You need pointer choreography |
Edges
set_valuereplaces the text entirely;type_textinserts at the caret.select_textranges are 0-based with EXCLUSIVE end —[0, 3]selects three characters (the AT-SPI convention).perform_actionis the escape hatch for platform-specific verbs ("raise", macOSAXCustomThing-derived names).
See also
control for pointer pipelines · surface for
shell-level targets · cargo run --example computer-act