Files
cthulhu/docs/testing/background-events.md

128 lines
7.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Background accessibility events
On Xorg, Cthulhu rejects known background control updates before resolving
selected descendants or capturing their text, values, attributes and geometry.
The native adapter owns this decision on the GLib thread. It uses the existing
foreground window and epoch; there is no additional window ownership cache.
Events from another provider first resolve their containing window: GTK socket
children can belong to the foreground host while using a different provider
bus. Unrelated providers are then rejected using the resolved window and copied
bus identities, before any content queries.
Events from another window on the same provider undergo the existing window
correlation before content capture. Lifecycle invalidation still runs, but a
background provider no longer clears another provider's cached document lines.
Window creation, activation, deactivation, destruction and defunct events keep
their existing handling. Announcement events are explicit requests to speak
and also bypass the filter; see [announcements](announcements.md). Native alerts, notification daemons and supported
Steam toasts retain their notification paths. Menu popups retain existing
foreground checks. Verified active/showing `mate-panel` menu windows may pass
across provider boundaries, including over an empty desktop. Embedded panel
controls use their host's normal X11 correlation; unrelated panel windows and
hidden menus remain filtered. See [MATE desktop](mate-desktop.md).
Same-provider autocomplete relations and tooltip candidates
continue through the existing event-loop ownership checks; they do not acquire
focus merely by passing the early filter.
When notification metadata or a detached document's containing window is
unknown, the adapter retains the existing validation path. The optimization
does not introduce an X11 ownership requirement for native Wayland sessions.
Orca's `src/orca/event_manager.py` was used as a reference for keeping global
window monitoring and filtering noisy content events before presentation.
## Automated checks
Run from the repository root with the normal native build dependencies:
```sh
go test ./... -count=1
go test -race ./internal/atspi ./internal/app ./internal/review -count=1
python3 tests/native_test_session.py env CTHULHU_NATIVE_BACKGROUND_EVENTS=1 CTHULHU_NATIVE_WAYLAND_POLICY=1 go test -race ./internal/atspi -run '^TestNative(BackgroundEventFiltering|WaylandForegroundPolicy)$' -count=1 -v -timeout=40s
python3 tests/native_webscripts.py
CTHULHU_NATIVE_BROWSER_TESTS=browser,tabs,live,tooltips python3 tests/native_browser.py
go build -o /tmp/cthulhu-background-events ./cmd/cthulhu
CTHULHU_BINARY=/tmp/cthulhu-background-events python3 tests/native_ownership.py
```
The flood regression uses two real GTK providers, then two windows on one
provider. Each burst changes the table selection 300 times. A private D-Bus
monitor asserts that the rejected updates cause no Selection, Table, Text or
Value interface calls. The explicit alert used as a completion marker is
excluded from this content-query assertion. Returning to the noisy window must
deliver its current table selection. The separate cache regression verifies
that invalidation preserves other providers' document lines.
All native checks use disposable X servers and private D-Bus/runtime sockets.
They do not replace the active desktop reader. Browser checks cover address
suggestions, page controls, tabs, live regions and tooltips. Ownership checks
cover GTK/Qt menus, a GTK menu popup, dialogs, same-process windows, empty
workspaces and Brave window recovery. Notification checks preserve Steam toast
capture while rejecting ordinary background Chromium text changes.
## Live acceptance
Private fixtures do not establish audible speech, physical Braille or actual
FastSMRW update latency. After reviewing the diff, preserve the current debug
log and rebuild/start the candidate through the normal local launcher when
ready to replace the reader.
1. Read headings and lines in Brave while FastSMRW receives new items. Compare
responsiveness with quiet periods. Background selection changes should not
delay reading or take speech/focus ownership.
2. Switch to FastSMRW and move through results. Confirm the current selection
is spoken; open its Open Links popup, move between links, and close it.
3. Switch between two windows from the same application. Open and close a
dialog and a menu; confirm speech follows the active control.
4. In Brave, type into the address bar and move through suggestions. Return to
the page, switch tabs, and verify normal editing and reading still work.
5. Check supported background notifications. If using Braille, confirm it
follows the foreground control and still displays supported notifications.
Preserve a fresh log if lag or a missing announcement remains, with the time
and the key or update that triggered it. Debug logs can contain private text.
## Window frame geometry
GTK can report the window manager's enclosing frame while X11's active client
reports only its content area. Slint/i3 exposed this as an active, showing
1916×994 accessible frame at (0,0) rejected against a 1912×974 client at (2,18).
Missing or stale `_NET_FRAME_EXTENTS` can make the advertised outer bounds
identical to those client bounds.
Foreground matching also accepts the actual immediate enclosing X11 frame.
It must contain the client, have bounded decoration edges, and contain no other
managed client. The desktop root, a parent that is itself a managed client,
and shared containers are excluded. Existing process, active/showing state,
iconification, foreground epoch and same-process sibling checks still apply.
This covers frame/client discrepancies across applications; arbitrary incorrect
AT-SPI geometry still requires diagnosis. Rejected activation diagnostics now
include `x_frame_bounds` alongside client and advertised outer bounds.
i3 marks its decoration frames `override_redirect`; these frames must pass
the same tree and containment checks. Rejecting that flag discarded the real
frame even after frame lookup was added. A later Slint log showed the Run
dialog and application menu at (0,24), 1916×989, against a client at (2,24),
1912×987, with no recorded frame. This caused control events to be filtered,
while explicit suggestion-count announcements still passed.
```sh
python3 tests/native_test_session.py env CTHULHU_NATIVE_FRAME_FOREGROUND=1 CTHULHU_NATIVE_GRAB_FOREGROUND=1 go test ./internal/platform/xorg -run '^TestNative(ReparentedFrameForeground|InputOnlyGrabForeground)$' -count=1 -v
```
The frame fixture covers i3 override-redirect frames (including the reported
Run dialog geometry), missing, zero and stale extents, borders, moving,
resizing, switching to a sibling frame, shared containers and empty workspaces.
On Slint, listen while switching between two windows from one application,
another application's window, dialogs and menus. Move and resize them, switch
away to an empty workspace and return, and check preferences again. Confirm
speech and Braille follow the foreground control and background activity does
not take focus. Keep the first rejected activation from a fresh debug log if a
window remains silent; private X11 results do not prove affected-host acceptance.
On Slint/I38, open the Run dialog, type a command, and use Left/Right, Home/End
and Control+Left/Right to review it. Check suggestion navigation as well as
counts. Open Alt+F1 and move through categories and applications, then close
it and verify speech returns to the previous window.