atspi

package
v0.16.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: BSD-3-Clause Imports: 6 Imported by: 0

Documentation

Overview

Package atspi is the Linux accessibility bridge: it publishes the widget tree on the AT-SPI bus, where Orca and every other Linux screen reader read it.

A go-widgets window presents ONE surface holding a rasterised widget tree. To AT-SPI that is an opaque rectangle with no structure at all, so without this the application is unreadable and unnavigable. macOS subclasses a view and Windows answers WM_GETOBJECT with a COM object; here an application EXPORTS D-Bus objects and registers them with a registry daemon.

The package is shared by the X11 and Wayland backends because AT-SPI is a D-Bus protocol and knows nothing about either display server.

This file is the OS-independent half — role numbers, filtering, coordinates — so the whole decision layer is exercised by ordinary tests on any host, the split the x11, wayland, cocoa and win32 packages all use.

Index

Constants

View Source
const (
	RoleInvalid      uint32 = 0
	RoleAlert        uint32 = 2
	RoleCheckBox     uint32 = 7
	RoleComboBox     uint32 = 11
	RoleFiller       uint32 = 20
	RoleImage        uint32 = 27
	RoleLabel        uint32 = 29
	RoleList         uint32 = 31
	RoleListItem     uint32 = 32
	RoleMenu         uint32 = 33
	RoleMenuBar      uint32 = 34
	RolePageTab      uint32 = 37
	RolePanel        uint32 = 39
	RoleProgressBar  uint32 = 41
	RolePushButton   uint32 = 43
	RoleRadioButton  uint32 = 44
	RoleScrollBar    uint32 = 47
	RoleSlider       uint32 = 51
	RoleSpinButton   uint32 = 52
	RoleStatusBar    uint32 = 54
	RoleTable        uint32 = 55
	RoleText         uint32 = 61
	RoleToggleButton uint32 = 62
	RoleToolBar      uint32 = 63
	RoleTree         uint32 = 66
	RoleWindow       uint32 = 69
	RoleApplication  uint32 = 75
	RoleEntry        uint32 = 79
	RoleDocFrame     uint32 = 82
)

AT-SPI role numbers, read out of pyatspi on a live system rather than guessed: a client ANNOUNCES the role, so a wrong number renames every element for the user.

View Source
const (
	StateEnabled   uint32 = 8
	StateFocusable uint32 = 11
	StateSensitive uint32 = 24
	StateShowing   uint32 = 25
	StateVisible   uint32 = 30
)

AT-SPI state numbers (same provenance as the roles).

Variables

This section is empty.

Functions

func Nodes

func Nodes(root toolkit.Widget) []toolkit.A11yNode

Nodes is the tree to publish for a widget root: every meaningful element, in visual order, with the ones no reader could use already removed.

func ParsePressPoint

func ParsePressPoint(s string) (x, y int, ok bool)

ParsePressPoint reads back what PressPoint wrote. A malformed value REFUSES rather than defaulting to (0,0), which is a real and usually clickable place.

func PressPoint

func PressPoint(n toolkit.A11yNode) string

PressPoint encodes an element's centre, in the coordinates the input path speaks, so an activation can be replayed as an ordinary click.

Carrying the point ON the element beats a table keyed by index: the tree is rebuilt whenever the frame changes, and an index goes stale the moment content scrolls under a screen-reader user's cursor.

func Publish

func Publish(root toolkit.Widget, title string, originX, originY int)

Publish republishes the tree for the frame just drawn. The back-end calls it from the same place that presents pixels, so the description never lags them.

activate is how an AT-SPI action reaches the widget tree; it is stored on every call because the back-end owns it and this package must not import a back-end.

func Role

func Role(r toolkit.Role) uint32

Role maps a toolkit role to its AT-SPI number. Anything unrecognised becomes a panel — AT-SPI's "a thing containing things", the honest answer for a role this table does not know, and never a wrong announcement.

func RoleName

func RoleName(r uint32) string

RoleName is the human-readable role a client may read instead of the number. The strings are AT-SPI's own spelling, not ours.

func ScreenRect

func ScreenRect(n toolkit.A11yNode, originX, originY int) (x, y, w, h int32)

ScreenRect converts a node's window-relative rectangle to screen coordinates. AT-SPI asks for extents in BOTH spaces on the same interface, and only the back-end knows where the window sits, so the origin arrives from the caller.

A Wayland client cannot know its own position on screen — the protocol does not tell it — so that back-end passes a zero origin and the two spaces coincide. Reporting a made-up screen position would be worse: a screen reader would point somewhere real and wrong.

func Skip

func Skip(n toolkit.A11yNode) bool

Skip reports whether a node should be left out of the published tree. An element with no name says nothing a reader could announce and one with no area cannot be pointed at; either is a stop the user has to skip past.

func TakePending

func TakePending() []struct{ X, Y int }

TakePending hands the back-end the activations a client asked for since the last call, to be applied on the thread that owns the widget tree.

KNOWN LIMITATION: the back-end drains this while painting, and the X11 loop blocks on the display socket, so an action taken while the application is otherwise idle is applied on the NEXT event rather than immediately. The click itself lands correctly — measured, clicks: 0 to clicks: 1 — the tree simply republishes a beat later. Closing that needs the loop woken from outside, e.g. a self-addressed X ClientMessage.

It returns nothing when the bridge never came up, which is the normal case on a machine with no accessibility stack running.

Types

type Bridge

type Bridge struct {
	// contains filtered or unexported fields
}

Bridge is the live connection and the snapshot being described.

type Ref

type Ref struct {
	Name string
	Path dbus.ObjectPath
}

Ref is AT-SPI's object reference: the bus name that owns it and its path — the "(so)" every AT-SPI method passes around.

Name is a plain string. In godbus, against which this bridge was first written, dbus.Sender is an ANNOTATION type meaning "inject the caller's name" rather than "a string on the wire", and using it there silently changed this struct's signature so the registry never listed the application. The owned D-Bus has no such type, and the signature is checked rather than assumed: SignatureOfType reports (so) for this and a((so)(so)(so)iiassusau) for the cache item.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL