Reset master to testing content

This commit is contained in:
Storm Dragon committed 2026-10-25 01:57:54 -04:00
1 parent 0f2587b719
commit 42afa2a56c
1483 files changed
+145308 -938069

No files matched your search

+109
View File
@@ -0,0 +1,109 @@
# Qt control state reporting
Cthulhu preserves AT-SPI checkability independently of the native role.
An ordinary menu-item role with CHECKABLE, CHECKED or INDETERMINATE is
presented as a check menu item for speech, state sounds and Braille. A checked
state-change event also establishes checkability when its new value is false.
When a provider omits CHECKABLE, Cthulhu remembers that evidence on the native
accessible object, so a subsequent unchecked value still has check-menu
semantics. This applies to all applications without matching names or labels.
An ordinary menu command without that evidence keeps its existing presentation.
Qt menu actions can change state without sending a checked-state event.
Cthulhu refreshes their native cache on focus so reopening a menu reads the
current state instead of a previously cached value.
Actions shared between a menu bar and a context menu can keep their original
AT-SPI parent. Qt can emit focus-gained for the shared accessible while a state
query reports it unfocused because its original menu is hidden. Cthulhu uses
that explicit focus event for menu items, including check and radio menu
items, before applying the existing foreground checks. The event must name
the captured accessible itself; redirected descendants and defunct items do
not inherit this evidence. No focus evidence is retained beyond the event.
Checkability evidence belongs to the AT-SPI accessible on the GLib owner
thread. No extra accessible references are retained. It ends with that object's
native lifetime, is cleared on defunct/name-change events or a changed role,
and respects withdrawal of an explicitly exported CHECKABLE state. Replacement
actions, including ones with the same label, do not inherit the evidence.
## Automated checks
Run the generic Qt 5 (PyQt5) and Qt 6 (PySide6) fixture with:
```sh
/usr/bin/python3 tests/native_qt_controls.py
```
This uses private Xvfb, D-Bus and temporary configuration directories. It checks
queued speech and Braille frames through Cthulhu's event loop for menu-bar and
context-menu actions, checking and unchecking ordinary checkboxes and checkable
buttons, an ordinary menu command, same-label action replacement, and explicit
capability removal. It also traverses shared and context-only actions in both
directions and after reopening the context menu. It requires both Python Qt bindings,
xdotool and the native build dependencies. It does not replace the active
reader or establish audible speech or physical Braille acceptance.
Existing package checks cover mixed states, state sounds, speech-only and
sound-only modes, and repeated focus after checking and unchecking. The
existing browser menu test checks ordinary and compound menu navigation:
```sh
go test ./internal/atspi ./internal/presentation ./internal/app -count=1
CTHULHU_NATIVE_BROWSER_TESTS=menu /usr/bin/python3 tests/native_browser.py
```
## Providers which omit checkability
The tested Mumble 1.5.939 / Qt 5 installation exports Mute Self and Deafen Self
as ordinary menu items, with CHECKED only while checked and no CHECKABLE state.
Its toolbar equivalents use the check-box role. Qt 5's upstream
[AT-SPI state mapping](https://github.com/qt/qtbase/blob/5.15/src/platformsupport/linuxaccessibility/constant_mappings.cpp)
omits `state.checkable`, although
[menu accessibility](https://github.com/qt/qtbase/blob/5.15/src/widgets/accessible/qaccessiblemenu.cpp)
sets that field internally. Qt 6's
[mapping](https://github.com/qt/qtbase/blob/6.12/src/gui/accessible/linux/qspi_constant_mappings.cpp)
exports it.
No toolkit patch is required for Cthulhu to retain observed checkability.
The Qt 5 native fixture verifies the sequence unchecked, checked, unchecked
for both menu-bar and context-menu actions. After checking establishes the
capability, unchecking and reopening announces `not checked`, with the
corresponding Braille indicator. Native checked-state events establish the same
capability even when the first observed transition is to false.
The Python reference's `generator._generateCheckedStateIfCheckable` and Orca's
`generator._generate_state_checked_if_checkable` also treat CHECKED as sufficient
evidence even without CHECKABLE. Their menu generators do not assign an
unchecked state to an ordinary menu action without evidence.
On first encountering an unchecked menu action with neither the correct role
nor CHECKABLE nor a checked-state event, its semantics are unknown. Cthulhu
keeps ordinary menu presentation until evidence arrives, rather than
announcing every menu command as unchecked. Retained evidence cannot detect
an unreported capability removal by a provider that never exports CHECKABLE;
object destruction, role changes and name changes still retire it.
## Live acceptance
After reviewing the diff, rebuild and restart the intended Cthulhu binary:
1. In Mumble's Self menu, navigate to Mute Self and Deafen Self. Toggle each,
reopen the menu, and confirm both checked and not-checked states once the
capability is established. Restore the original settings.
2. On a server authorized for testing, open another user's context menu and
exercise Local Mute in both states. Reopen the menu after each change.
Restore the original local mute setting; do not change server mute.
3. Test the toolbar mute/deafen controls and ordinary settings checkboxes in
both states. Confirm Tab and Shift+Tab still reach adjacent controls.
4. Navigate ordinary Mumble and browser menu commands. Confirm no invented
checked state, duplicate announcements, or lost keyboard focus.
5. Listen to actual speech and check a physical Braille display when available.
6. Open your own user context menu. Arrow through every enabled item in both
directions, including ordinary commands and checkable items, then close and
reopen it and repeat. Confirm every stop reads once. Also test the menu-bar
equivalents, Escape back to the user list, and switching away from Mumble
while the popup is open; background menu events must remain silent.
Do not submit before human review and live testing, as required by
[the contribution policy](../../CONTRIBUTING.md#ai-assisted-contributions).