Files

132 lines
8.6 KiB
Markdown

# MATE desktop accessibility
The MATE menu report was captured on X11 with Cthulhu revision
`4d29f2bb235a4e0131ea44ddac368a8148bc594f`. At 18:40:45 the active, showing
`mate-panel` popup was rejected because X11 still identified the previous
application as foreground. Routine panel events could then be discarded by
the native background filter before debug logging. This establishes a reader
filtering gap; the log does not establish a Fedora packaging defect.
## Orca comparison
Reviewed the local `orca/` checkout at revision `a8a851800`:
| Behavior | Orca source | Cthulhu handling |
| --- | --- | --- |
| Panel popup activation and selected menu item | `scripts/default.py:_on_window_activated`, `ax_utilities.py:can_be_active_window` | Adapted active/showing menu handling across the panel/application process boundary. |
| GTK menu focus | `scripts/toolkits/gtk/script.py:locus_of_focus_changed` | Existing window ownership and menu focus/selection handling; exercised with nested panel menus. |
| Marco window cycling | `script_manager.py`, `scripts/switcher/script.py`, `scripts/switcher/script_utilities.py` | Already implemented; see [window switcher checks](window-switcher.md). |
| MATE notification daemon | `script_manager.py`, `scripts/apps/notification-daemon/script.py` | Already routed through notification capture, speech, Braille and history; added an explicit MATE daemon regression. |
| Unnamed panel icons | `generator.py:_generate_accessible_name` | Adapted the containing panel's name/description when the icon supplies neither. Own names and descriptions retain precedence. |
| Embedded panel applets | `script_utilities.py:frame_and_dialog`, `script_utilities.py:top_level_object`, `scripts/default.py:_on_focused_changed` | Follow the accessible parent chain through a GTK plug/socket to its host window before normal foreground validation. |
Orca has no dedicated `mate-panel` script in this checkout. Its current app
script catalog also contains no Caja, Pluma, Atril, Engrampa or Eye of MATE
specialization. Those applications use shared toolkit/role behavior; this
comparison does not establish that every workflow in those applications works.
## Panel menu policy
The native adapter recognizes the `mate-panel` process, then freshly queries
the popup's state and menu structure on the GLib owner. It requires an active,
showing, non-iconified, non-defunct native menu window. The existing menu
structure check permits a window with one menu child, or an unnamed frame
with one menu-bar child. A panel application name alone grants no exception.
This check is used both before routine background content capture and during
foreground validation. It also works when X11 has no foreground client, as
when a panel menu opens over an empty desktop. Ordinary panel windows and
hidden menu items retain normal filtering. Native actions and review use the
same window validation. The correlated X11 application is preserved; no popup
cache, native references, timer or extra window owner is introduced.
## Embedded applet ownership
The newer `kendell/mate.log`, recorded with revision `702894ee`, shows a
different failure: Bottom Panel controls are accepted, but focused icons from
other provider buses are rejected as outside the X11 foreground. The reader
announces the host's generic "panel" while discarding the embedded icon.
A real GTK socket/plug reproduction exposes the same structure. The applet
publishes its own frame, whose accessible parent chain crosses the socket's
provider and reaches the panel frame. Window resolution now follows that chain
to the host instead of stopping at the plug frame. The background filter also
resolves this window before rejecting a different provider bus. The source
object retains its own bus, path and process identity for focus and actions.
This is shared window ancestry handling: it requires no MATE process-name
exception. Normal X11 process, state and geometry checks still apply to the
host. Same-provider nested frames retain their existing nearest-window
behavior. An unembedded or detached applet cannot borrow the host's identity,
and a background host cannot admit applet focus. Parent links beyond the plug
frame are refreshed on the GLib owner; no embedding cache is retained.
## Automated checks
```sh
python3 tests/native_test_session.py env CTHULHU_NATIVE_PANEL_MENU=1 CTHULHU_NATIVE_WINDOW_SWITCHER=1 CTHULHU_NATIVE_BACKGROUND_EVENTS=1 go test -race ./internal/atspi ./internal/app -run '^TestNative(MatePanelMenu|MateWindowSwitcherOutsideForeground|BackgroundEventFiltering)' -count=1 -p=1 -timeout=90s -v
python3 tests/native_test_session.py env CTHULHU_NATIVE_PANEL_APPLET=1 go test -race ./internal/atspi ./internal/app -run '^TestNativeEmbeddedPanelApplet' -count=1 -p=1 -timeout=90s -v
go test ./internal/app -run '^TestNotificationProvidersAndHistoryMatchReferenceBehavior$' -count=1
```
The private GTK fixture uses separate panel and editor providers. Native
checks cover menu activation over an editor and an empty desktop, forward and
reverse navigation, a submenu, Escape, editor restoration, rejection of an
ordinary panel window, a late focus signal from a hidden menu, and an unrelated
process claiming the panel's application name. Panel icon captures verify
inherited labels, own-name/description precedence and unrelated-container
rejection. The event-loop check verifies queued speech and Braille frames for
navigation, dismissal, editor return and reopening. It emits no audible speech.
The socket/plug fixture uses separate host, applet and editor processes. It
checks the shared containing-window identity, preserved applet identity, icon
label inheritance, Tab/Shift+Tab within the applet, host controls on either
side, and editor restoration. It also checks a non-MATE host, background applet
focus, an unrelated applet claiming the MATE application name, and stale focus
after socket destruction. The event-loop check verifies speech requests and
Braille frames through two panel/editor round trips.
The existing background flood regression checks that ordinary same-provider
and other-provider updates still cause zero content queries. The Marco
regression checks switcher insertions and showing events while an editor
retains foreground ownership.
Validation on 2026-10-27 passed the full Go suite, the combined native checks
above with the race detector, `go vet ./internal/atspi ./internal/app`, the
parity ledger validator and a candidate build. GTK/Qt traversal and menus,
same-process window recovery, Brave address focus, dialogs, empty workspaces
and shutdown also passed ownership verification using a temporary copy of
`tests/native_ownership.py` with current schema-2 settings and `--append` on
reader launches. The checked-in ownership script still uses legacy settings
and assumes logs survive reader restart. Its restart assertion fails on the
unchanged revision too, despite the expected activation appearing in the log.
That existing harness needs separate maintenance; it is not a product failure
or an unqualified passing check.
## Human review and live acceptance
Review the diff before submission, as required by the contribution policy.
The fixtures model the native contracts; they do not run the reporter's Fedora
MATE session. After starting the candidate through the normal launcher:
1. Open the Applications menu over a browser, a terminal and the desktop.
Navigate forward/backward, enter/leave submenus, and check spoken labels
and Braille if available. Repeat with Places/System menus and panel context
menus offered by the installed MATE configuration.
2. Press Escape and confirm reading resumes in the original application.
Reopen the menu and activate an application. Check its initial control,
typing and ordinary Tab navigation. Check terminal-reader handoff if used.
3. Use Control+Alt+Tab to reach the panel and navigate its applets. Confirm
applet icons use supplied labels without repeating unrelated container text.
Traverse both directions through launchers, clock, notification area and
configured external applets. Open and dismiss applet controls, then return
to the previous application. Background applet updates must stay silent.
4. Cycle windows with Alt+Tab and Shift+Alt+Tab, then cancel with Escape.
Check a MATE notification and its notification-history entry.
5. Return to browser heading navigation and address-bar suggestions, and open
ordinary GTK/Qt menus and dialogs. Background updates must not take over
speech. Panel menu events must remain silent while the screen is locked.
Audible speech, physical keyboard/Braille behavior, the exact Fedora panel
tree and real MATE application workflows remain live acceptance checks.