linux

package
v0.703.4 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package linux implements the Linux AT-SPI2 accessibility backend for the Pando Desktop Controller (internal/uiauto). It talks to the AT-SPI2 registry and applications over D-Bus using github.com/godbus/dbus/v5 — no cgo, no external process.

Design notes:

  • Every accessibility object is identified by a (bus name, object path) pair (accessibleRef). core.Element stores both in Native.Data so a later Children/Perform call can act on it without re-searching.

  • Traversal is selector-driven (see traverse.go): Find never walks the whole tree. It carries a small per-DFS-branch set of "pending selector steps" down the tree, testing only what could still complete a match, and stops as soon as it has `limit` results, a depth cap is hit, or ctx is cancelled.

  • Property reads are batched with org.freedesktop.DBus.Properties.GetAll instead of one round-trip per attribute, and a per-call memo cache (traverseCache) makes sure a single Find/Children/Observe call never re-fetches the same object twice.

This package purposefully depends only on a small busConn interface (conn.go) rather than *dbus.Conn directly, so the traversal and matching logic can be exercised in unit tests against a fake in-memory tree with no real accessibility bus involved.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewBackend

func NewBackend() (core.Backend, error)

NewBackend constructs an AtspiBackend. It never fails: connecting to the accessibility bus happens lazily on the first real operation.

Types

type AtspiBackend

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

AtspiBackend is the core.Backend implementation talking to Linux AT-SPI2 over D-Bus. The bus connection is established lazily on first use (not in NewBackend, so backend construction itself can never fail) and cached; Available reports honestly instead of erroring when the accessibility bus/session is unreachable, matching the contract NullBackend and Manager document.

func (*AtspiBackend) Apps

func (b *AtspiBackend) Apps(ctx context.Context) ([]core.AppInfo, error)

Apps implements core.Backend by listing the AT-SPI2 registry's top-level children, one per running (a11y-registered) application.

func (*AtspiBackend) Available

func (b *AtspiBackend) Available(ctx context.Context) (core.Capabilities, error)

Available implements core.Backend. It never returns an error: a reachable a11y bus reports Accessibility/UIInspection/UIActions true; anything else degrades to an all-false Capabilities so callers fall back gracefully (see the Manager/NullBackend contract this mirrors).

func (*AtspiBackend) Children

func (b *AtspiBackend) Children(ctx context.Context, el *core.Element) ([]*core.Element, error)

Children implements core.Backend: the direct children of el, built from a single GetChildren call plus one batched fetch per child.

func (*AtspiBackend) Close

func (b *AtspiBackend) Close() error

Close implements core.Backend.

func (*AtspiBackend) Find

func (b *AtspiBackend) Find(ctx context.Context, scope core.Scope, sel *core.Selector, limit int) ([]*core.Element, error)

Find implements core.Backend with the selector-driven, depth-capped, limit-capped, ctx-aware traversal in traverse.go — it never walks the whole tree.

func (*AtspiBackend) Name

func (b *AtspiBackend) Name() string

Name implements core.Backend.

func (*AtspiBackend) Perform

func (b *AtspiBackend) Perform(ctx context.Context, el *core.Element, action core.Action) error

Perform implements core.Backend.

func (*AtspiBackend) Properties

func (b *AtspiBackend) Properties(ctx context.Context, el *core.Element, props []string) (map[string]any, error)

Properties implements core.Backend. When props is empty it returns the cheap attributes already gathered by a normal node fetch (raw role, interfaces, child count, decoded state extras); "text" and "actions" are only fetched on request since they cost an extra round trip each.

func (*AtspiBackend) Subscribe

func (b *AtspiBackend) Subscribe(ctx context.Context, scope core.Scope) (<-chan events.Event, func(), error)

Subscribe implements events.Subscriber for AtspiBackend: it lazily connects to the a11y bus (same as every other operation), lazily starts the shared eventSource, and hands the caller a fresh fan-out channel from its EventBus. scope is currently not used to filter server-side (AT-SPI2's Event.Object signals are not natively scopable that way); events.WaitFor always re-evaluates the actual locator/condition against the backend on every received event, so an unrelated event only costs one harmless extra Find call, never an incorrect result.

func (*AtspiBackend) Windows

func (b *AtspiBackend) Windows(ctx context.Context, appID string) ([]core.WindowInfo, error)

Windows implements core.Backend by listing the direct children (frames/ windows/dialogs) of the matching application(s).

Jump to

Keyboard shortcuts

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