Add native i3 desktop announcements

This commit is contained in:
ak47 committed 2026-11-07 14:46:46 -05:00
1 parent 49eeae89f4
commit bf1f155018
22 files changed
+1835 -1

No files matched your search

+132
View File
@@ -0,0 +1,132 @@
# Native i3 announcements
Cthulhu observes the active i3 X11 session directly over its Unix IPC socket,
using the [i3 IPC specification](https://i3wm.org/docs/ipc.html).
There is no Python runtime helper, new binding, sound, or window-management
command. Other desktops keep their existing support. The installed i3 executable
and an inherited `I3SOCK` variable do not enable support: the active window
manager must identify itself as i3, and its root window must advertise its socket.
The Reading settings table provides six choices, all enabled by default:
- Announce i3 binding modes: the configured name followed by “mode”; returning
to the default binding mode says “Default mode”. Pango markup is converted
to text when i3 flags it as markup.
- Announce i3 workspaces: “Workspace {name}” on focus, including empty workspaces
and focused-workspace renames.
- Announce i3 window states: fullscreen on/off, global fullscreen on, and
floating on/off. Background changes include the window title or class.
- Announce i3 urgent windows: the window and workspace when available. Aggregate
workspace urgency does not produce a second message.
- Announce i3 marks: additions and removals compared with the previously
reported mark set.
- Announce i3 window workspace moves: the destination, only when previous and
current workspace identities are known. Rearrangement within a workspace stays
silent. Rapid events may be consolidated to the confirmed destination.
These choices persist in the versioned TOML profile under
`presentation.reading` as `i3-modes`, `i3-workspaces`, `i3-window-states`,
`i3-urgency`, `i3-marks`, and `i3-workspace-moves`. Apply/reload and application
profiles use the existing settings path. Global preferences are usually the most
convenient place to set desktop announcement choices.
Announcements queue with other incoming speech; normal user-input interruption
still applies. They can speak during Fenrir terminal handoff. Screen lock,
internal reader UI, speech disable, speech mode, and braille flash preferences
retain their existing policies. Suppressed events are discarded. Braille uses
the existing flash duration and restores the current application frame without
moving focus. Existing persistent-flash settings still apply.
I38 may announce some of the same actions independently. Cthulhu does not edit
I38 configuration. If both announce a workspace or mode, choose which source you
want to hear and disable the corresponding announcements in that source.
Scratchpad visibility/cycling, automatic layout changes, window creation and
closure, and extra window introductions are excluded. Sending a tiled window to
the scratchpad implicitly enables floating; that scratchpad state change is
suppressed too. Binding commands are never used to guess state. Startup and
reconnection establish silent baselines. Missing context skips comparisons;
malformed messages, timeouts, or excessive pending events discard the connection
and retry discovery with bounded backoff.
## Automated verification
Run from the repository root:
```sh
GOCACHE=/tmp/cthulhu-go-cache GOPROXY=off go test -race ./internal/i3ipc ./internal/config ./internal/preferences -count=1
GOCACHE=/tmp/cthulhu-go-cache GOPROXY=off go test -race ./internal/app -run 'TestI3|TestAnnouncement|TestBrailleFlash|TestProcessInputEventsUsesLiveInterruption|TestTitlePreference' -count=1 -timeout=60s
python3 tests/native_i3.py
GOCACHE=/tmp/cthulhu-go-cache GOPROXY=off go build -o /tmp/cthulhu-i3-reader ./cmd/cthulhu
CTHULHU_BINARY=/tmp/cthulhu-i3-reader CTHULHU_PREFS_READING_ONLY=1 python3 tests/native_preferences.py
python3 tests/check_speech.py
```
The native harness uses a private 24-bit Xvfb display and the shared disposable
D-Bus session launcher. It checks actual mode, markup, empty workspace, rename,
fullscreen, floating, mark, same-workspace move, cross-workspace move, and urgency
events, plus background window identity and scratchpad silence. It also verifies
that a private X display without i3 does not activate support. Tests do not
replace or control the running reader or desktop WM.
## Live speech, keyboard, and braille acceptance
Human diff review and live acceptance are required before submission. Automated
checks establish queue requests and braille frames, not audible output or a
physical braille display. Preserve diagnostic logs if investigating a failure.
Use an expendable window and named workspaces for move and mark checks.
1. Quit the current reader with Cthulhu+Q. Press Ctrl+Escape to enter i3 personal
mode, release those keys, then press Shift+G. Ctrl+Escape and Shift+G are
separate key presses. This runs `~/devel/cthulhu-go.sh`, rebuilding the reader
and braille helper, starting the debug log, and opening the test terminal.
Expect no announcement of the existing mode/workspace merely from startup.
2. In global Preferences, find the six “Announce i3” rows in Reading. Check
their setting names, descriptions, and checked states. Use arrows between
columns and rows, Space to toggle, and Tab/Shift+Tab into and out of the
table. Apply, close, and reopen. Expect saved values and usable keyboard
focus. Restore all six to enabled for the following checks. For braille
restoration checks, enable flash messages with a finite duration and turn
persistent flashes off.
3. Enter each configured personal, ratpoison, and panel mode using your existing
bindings, returning to default between them. Expect the reported name plus
“mode”, and “Default mode” on return. A configured markup mode should read
its text without tags. Expect the same text briefly on braille, followed by
current application content. Focus and ordinary typing must remain usable.
4. Focus an empty named workspace, for example using
`i3-msg 'workspace "cthulhu test empty"'`. Expect “Workspace cthulhu test
empty”. Rename it with `i3-msg 'rename workspace to "cthulhu test renamed"'`;
expect “Workspace cthulhu test renamed”. Switching back should announce the
destination workspace. Existing application-focus and title speech should
still occur normally, with no new i3 window introduction.
5. In the expendable window, use existing bindings to enable/disable fullscreen
and floating. Expect “Fullscreen on/off” and “Floating on/off”, with braille
flashes and no extra focus change. Add and remove a temporary mark with
`i3-msg 'mark "cthulhu test"'` and `i3-msg 'unmark "cthulhu test"'`.
Expect “Mark added: cthulhu test” and “Mark removed: cthulhu test”.
6. Move the expendable window to a different workspace using your usual binding.
Expect “Moved to workspace {destination}”, with a title prefix if the event
reports a background window. Rearrange it within that workspace; expect no
workspace-move announcement. An actual urgent background window should
produce one “Urgent: {window}, workspace {name}” announcement. Record any
unavailable urgency case as untested. Scratchpad show/hide/cycling should
add no scratchpad announcement.
7. Return to the Fenrir test terminal. Enter and leave an i3 mode and switch
workspaces. Expect Cthulhu's desktop announcements while Fenrir continues
handling terminal content and keys. Leave the terminal for an accessible
application; expect normal Cthulhu application focus, reading keys, title
changes, and braille to resume.
8. Disable one i3 Reading choice, Apply, and exercise its action. Expect that
category silent in Cthulhu; re-enable it and verify new events speak without
replaying the suppressed events. Check speech disable/mode behavior using
existing reader settings. While the screen is locked or internal reader UI
is active, background i3 changes should not speak or flash, and should not
replay after leaving that state. Use only transitions reachable in those
states; do not bypass the lock to create a test event.
9. Trigger several desktop changes while other speech is queued. Expect incoming
messages to queue without cutting off incoming speech. Fresh user input
should still interrupt according to your configured interruption keys.
Distinguish a key's normal interruption from a new announcement arriving.
10. Report the exact speech, braille text and restoration, focused control/window,
keys used, and any independent I38 duplicate. If anything differs, inspect
`~/devel/cthulhu-go.log` before restarting again.