Element
Overview
Section titled “Overview”An Element is a single UI component drawn from the AT-SPI2 accessibility tree. Buttons, text fields, menu items, sliders, tables, and every other widget all become Element primitives. For applications without AT-SPI2 support, the compositor generates fallback elements from surface metadata.
Elements form a tree. Each element has a parent (except roots) and zero or more children. The root of the tree for a given surface is referenced by Surface.atspi2_root.
The Element primitive is the unit of interaction for PCP. When System Intelligence needs to click a button or read text from a field, it addresses the target by element ID.
JSON Schema
Section titled “JSON Schema”{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Element", "type": "object", "required": ["id", "surface_id", "app_id", "role", "name", "states", "geometry", "actions"], "properties": { "id": { "type": "string", "pattern": "^(atspi|surf|native):[a-z0-9-]+$", "description": "Globally unique element identifier. Prefix indicates source: atspi: (AT-SPI2), surf: (compositor-only), native: (Tier 1 app-defined)." }, "surface_id": { "type": "string" }, "app_id": { "type": "string" }, "role": { "type": "string", "description": "AT-SPI2 role enum string.", "examples": ["push_button", "entry", "document_text", "table", "list", "window"] }, "name": { "type": ["string", "null"], "description": "Accessible name (label). May be null for decorative elements." }, "description": { "type": ["string", "null"], "description": "Accessible description. Supplementary to name." }, "states": { "type": "array", "items": { "type": "string" }, "description": "Current AT-SPI2 states.", "examples": ["enabled", "visible", "focusable", "focused", "editable", "selected"] }, "geometry": { "type": "object", "required": ["x", "y", "w", "h"], "properties": { "x": { "type": "integer" }, "y": { "type": "integer" }, "w": { "type": "integer", "minimum": 0 }, "h": { "type": "integer", "minimum": 0 } } }, "parent": { "type": ["string", "null"], "description": "Parent element ID. null for root elements." }, "children": { "type": "array", "items": { "type": "string" }, "description": "Child element IDs. Populated when requesting the tree; omitted in element.get responses for non-leaf queries." }, "actions": { "type": "array", "items": { "type": "string" }, "description": "AT-SPI2 supported actions." }, "text": { "type": ["string", "null"], "description": "Current text content for text/entry/document roles. null for non-text elements." }, "text_selection": { "type": ["object", "null"], "properties": { "start": { "type": "integer" }, "end": { "type": "integer" }, "text": { "type": "string" } }, "description": "Current text selection, if any." }, "caret_position": { "type": ["integer", "null"], "description": "Current caret/cursor position in text content." }, "value": { "type": ["object", "null"], "properties": { "current": { "type": "number" }, "minimum": { "type": "number" }, "maximum": { "type": "number" }, "step": { "type": ["number", "null"] }, "text": { "type": ["string", "null"] } }, "description": "Current value for slider/progress/spin_button/checkbox roles." }, "table_info": { "type": ["object", "null"], "properties": { "rows": { "type": "integer" }, "columns": { "type": "integer" }, "selected_rows": { "type": "array", "items": { "type": "integer" } }, "selected_columns": { "type": "array", "items": { "type": "integer" } } }, "description": "Table/grid metadata for table roles." }, "relationships": { "type": "object", "properties": { "labelled_by": { "type": ["string", "null"] }, "label_for": { "type": ["string", "null"] }, "controller_of": { "type": ["string", "null"] }, "controlled_by": { "type": ["string", "null"] }, "member_of": { "type": ["array", "null"], "items": { "type": "string" } }, "node_parent_of": { "type": ["string", "null"] } } }, "fallback_note": { "type": ["string", "null"], "description": "Set when this element is a compositor-only fallback (no AT-SPI2 data). Describes the limitation." } }}Rust Type
Section titled “Rust Type”#[derive(Debug, Clone, Serialize, Deserialize)]pub struct Element { pub id: ElementId, pub surface_id: SurfaceId, pub app_id: AppId, pub role: AtspiRole, pub name: Option<String>, pub description: Option<String>, pub states: Vec<AtspiState>, pub geometry: Geometry, pub parent: Option<ElementId>, pub children: Vec<ElementId>, pub actions: Vec<String>, pub text: Option<String>, pub text_selection: Option<TextSelection>, pub caret_position: Option<usize>, pub value: Option<ValueInfo>, pub table_info: Option<TableInfo>, pub relationships: ElementRelationships, pub fallback_note: Option<String>,}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]#[serde(transparent)]pub struct ElementId(pub String);AtspiRole
Section titled “AtspiRole”Every element has exactly one role. The role determines what actions are available and what additional fields are populated.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]pub enum AtspiRole { // Window/container roles Window, Frame, Dialog, Alert, Panel, ScrollPane,
// Interactive controls PushButton, ToggleButton, CheckBox, RadioButton, ComboBox, SpinButton, Slider, ScrollBar, Dial, PageTab, PageTabList,
// Text elements Entry, Text, Paragraph, Heading, DocumentText, DocumentWeb, DocumentSpreadsheet, DocumentPresentation, DocumentEmail, Link, Terminal, Static, Label,
// Collection elements List, ListBox, ListItem, Tree, TreeTable, TreeItem, Table, TableCell, TableColumnHeader, TableRowHeader, Grid,
// Menu elements MenuBar, Menu, MenuItem, CheckMenuItem, RadioMenuItem, Separator,
// Specialized Canvas, Animation, Icon, Image, Chart, ProgressBar, StatusBar, ToolBar, ToolTip, Calendar, ColorChooser, FileChooser, FontChooser,
// Application Application, Embedded, Section,
// Fallback Unknown,}AtspiState
Section titled “AtspiState”An element can have any combination of states. The states array reflects the current runtime state of the widget.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]pub enum AtspiState { Enabled, Disabled, Visible, Invisible, Showing, Hidden, Focusable, Focused, Selected, Selectable, Checked, Unchecked, Indeterminate, Editable, ReadOnly, Expandable, Expanded, Collapsed, Multiselectable, Required, InvalidEntry, SupportsAutocompletion, Transient, Vertical, Horizontal, Modal, MultiLine, Protected, Stale, Busy, Resizable, Movable, Sizeable,}Supporting Types
Section titled “Supporting Types”#[derive(Debug, Clone, Serialize, Deserialize)]pub struct TextSelection { pub start: usize, pub end: usize, pub text: String,}
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct ValueInfo { pub current: f64, pub minimum: f64, pub maximum: f64, pub step: Option<f64>, pub text: Option<String>,}
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct TableInfo { pub rows: usize, pub columns: usize, pub selected_rows: Vec<usize>, pub selected_columns: Vec<usize>,}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]pub struct ElementRelationships { pub labelled_by: Option<ElementId>, pub label_for: Option<ElementId>, pub controller_of: Option<ElementId>, pub controlled_by: Option<ElementId>, pub member_of: Option<Vec<ElementId>>,}Field Reference
Section titled “Field Reference”Three prefixes indicate the element’s source:
| Prefix | Source | Description |
|---|---|---|
atspi: |
AT-SPI2 accessibility tree | Standard GTK/Qt applications |
surf: |
Compositor-only fallback | Apps without accessibility support |
native: |
Tier 1 app-defined | Applications that define their own element IDs |
relationships
Section titled “relationships”Element relationships express semantic connections that go beyond the parent/child tree structure:
| Relationship | Meaning |
|---|---|
labelled_by |
Another element provides the accessible label for this one |
label_for |
This element serves as a label for another element |
controller_of |
This element controls the state of another element |
controlled_by |
This element’s state is controlled by another element |
member_of |
This element belongs to a named group |
text_selection
Section titled “text_selection”Only populated for text-entry and document roles when a selection exists. The start and end indices are character offsets into the text field.
Only populated for roles that represent a scalar value: Slider, ProgressBar, SpinButton, CheckBox. The text field provides a human-readable representation when available.
table_info
Section titled “table_info”Only populated for Table, Grid, and TreeTable roles. Tracks the table dimensions and which rows and columns are currently selected.
fallback_note
Section titled “fallback_note”Present only on compositor-only fallback elements. Describes the specific limitation (no AT-SPI2 support, partial tree, etc.). When this field is set, interactions with the element require input simulation rather than AT-SPI2 action invocation.
Example: AT-SPI2 Button (Thunderbird Compose)
Section titled “Example: AT-SPI2 Button (Thunderbird Compose)”{ "id": "atspi:47-w1-btn-compose", "surface_id": "surf:47-w1", "app_id": "app:wl-47", "role": "push_button", "name": "Write", "description": "Compose a new email message", "states": ["enabled", "visible", "focusable"], "geometry": { "x": 150, "y": 598, "w": 120, "h": 36 }, "parent": "atspi:47-w1-toolbar", "children": [], "actions": ["activate"], "text": null, "text_selection": null, "caret_position": null, "value": null, "table_info": null, "relationships": { "labelled_by": null, "label_for": null, "controller_of": "atspi:47-w1-compose-window", "controlled_by": null, "member_of": null }, "fallback_note": null}This is a fully accessible button from Thunderbird’s AT-SPI2 tree. It has a role of push_button, one supported action (activate), and a controller_of relationship pointing to the compose window it opens.
Example: Compositor-Only Fallback
Section titled “Example: Compositor-Only Fallback”{ "id": "surf:47-w1-structural", "surface_id": "surf:47-w1", "app_id": "app:wl-47", "role": "window", "name": "Some Game — Main Menu", "states": ["visible"], "geometry": { "x": 0, "y": 0, "w": 1920, "h": 1080 }, "parent": null, "children": [], "actions": ["focus", "close", "minimize", "maximize", "move", "resize"], "text": null, "text_selection": null, "caret_position": null, "value": null, "table_info": null, "relationships": {}, "fallback_note": "structural-only: no AT-SPI2 support. Input simulation required for interaction."}This is a fallback element for a game with no accessibility support. The surf: prefix and the fallback_note field both indicate that the compositor generated this element from surface metadata. The available actions are limited to basic window management operations. Interacting with anything inside this window requires input simulation (mouse clicks, keyboard events) rather than AT-SPI2 action invocation.