6 Commits
Author SHA1 Message Date
Martín Lucas Golini e8e0a26727 perf(a11y): incrementally index text and bound AT-SPI dispatch
- Replace global line caches with lazy, per-manager document indexes
- Update affected line lengths without allocations on ordinary edits
- Preserve indexes across muted edits and recover ambiguous nested changes
- Count semantic children without materializing node identities
- Add a 2 ms AT-SPI dispatch budget while preserving backlog wakeups
- Add opt-in AT-SPI/UIA profiling and active performance benchmarks
- Cover shared documents, lifecycle, Unicode and nested-edit regressions
- Document measurements, scalability limits and native-host follow-ups
2026-10-10 23:59:58 -03:00
Martín Lucas Golini d27eae5927 Harden accessibility lifecycle, events and native backends
Teardown and identity:
- Detach native backends before scene children are destroyed and clear
  mRoot afterwards, fixing a use-after-free when an AT-SPI client is
  connected while a window closes.
- Invalidate a deleted widget's subtree once, top-down, before OnClose
  handlers run (NODE_FLAG_DESTROYING). Descendants never walk into
  destroyed parents, and deleted identities cannot be re-registered.
- Closing scenes expose no accessibility manager through either accessor.
- Deleting widgets no client has seen allocates no identity and emits no
  events.
- Ignore events from widgets not yet attached to a scene.

Events:
- Keep the order of state and structural events; coalesce only adjacent
  query-again hints.
- Stop emitting per-widget BoundsChanged; bounds are queried on demand.
- Report the Focused state and keyboard focus only on the projected focus
  owner, through a shared helper used by both paths.

Model views:
- Lazy child count and child queries, cached sibling indexes, selection
  and hit testing without enumerating rows.
- Row identities follow inserted and removed rows; removed rows are
  pruned from native wrapper caches.
- Expose the active cell editor as the child of the row or cell it edits.

AT-SPI:
- Correct state bits (EXPANDABLE/EXPANDED, SENSITIVE, CHECKABLE,
  SELECTABLE, READ_ONLY, SINGLE/MULTI_LINE, SELECTABLE_TEXT) and the
  password-text and panel roles.
- Emit text-changed insert/delete, caret-moved and selection-changed
  events, diffed once per frame. Support line granularity,
  SetCaretOffset and selection editing.
- Track clients by bus name so the active flag clears on disconnect.
- Fix the I/O thread busy-spin and stranded dispatch backlog, flush
  queued signals, and type-check Properties.Set values.

UIA:
- Raise focus only for the focused element.
- Defer UiaDisconnectProvider out of widget destruction.
- Keep providers alive for in-flight cross-thread requests.
- Reject unknown interfaces without a UI-thread round trip.
- Require window-specific client activity.

macOS:
- Avoid repeated full node info builds.
- Use sibling indexes and lazy child access.
- Fix label/value deduplication for list items.

Tests and docs:
- Add regression tests for focus ownership, teardown, event ordering,
  lazy model identities, nested scenes and cell editors.
- Extend the AT-SPI validation scripts and document the current
  performance characteristics and limitations.
2026-10-09 00:06:36 -03:00
Martín Lucas Golini 5b2085616f Move accessibility initialization off the main thread
Add optional ThreadPool support to UISceneNode and UIApplication settings,
sharing the configured pool with secondary application windows.

Initialize the Linux AT-SPI transport asynchronously when a pool is
available, keeping D-Bus connection, registration, and I/O setup away
from the UI thread. Publish the initialized backend safely and retain
synchronous initialization as the compatibility fallback.

Defer accessibility manager creation to root scenes and make nested
UISceneNodes delegate accessibility state and manager access to their
host scene.

Cache active-client state on UISceneNode to make inactive widget
notifications a minimal fast-path check.

Exercise asynchronous initialization in the accessibility example and
verify thread-pool propagation and nested-scene delegation in tests.

Keep hidden AT-SPI benchmarks focused on timing, and validate component
hit-testing separately through the visible semantic test.
2026-09-11 19:25:29 -03:00
Martín Lucas Golini c921f332db Test fix. 2026-09-11 18:14:31 -03:00
Martín Lucas Golini d6d52032b0 Add accessibility performance regression coverage
- Add inactive and active accessibility benchmarks to protect against startup, notification, and AT-SPI scaling regressions.

  - Extend the AT-SPI benchmark with text, focus, action, value, geometry, hit-testing, and model-update operations. Run both benchmarks in Linux CI and preserve their JSON results as artifacts.

  - Add an explicit null accessibility backend for baseline measurements and optional accessibility disabling.

  - Harden the Windows UIA backend by caching client availability per update, validating root providers, and preventing recursive window procedure forwarding.
2026-09-11 14:57:16 -03:00
Martín Lucas Golini 3751e05df6 Improve native accessibility reliability and performance
Harden the AT-SPI protocol implementation, application discovery, multi-window routing, request handling, and model invalidation. Keep inactive accessibility effectively tax-free and update UIA structure notifications.

Add hidden AT-SPI performance and integration benchmarks, expand the accessibility example, and cover model replacement and multi-window behavior with regression tests.
2026-09-11 11:25:15 -03:00