4.6 KiB
Direct speech preferences controls
Rate, pitch and volume are always editable. There are no separate server-default or inherited-voice checkboxes and no restore button. An untouched field preserves its existing explicit value or inheritance. Changing a field makes it explicit, even if it is subsequently moved back to its initial value. Uppercase retains automatic pitch until its pitch slider is changed.
The preferences worker queries Speech Dispatcher over a separate connection, with a 500 ms overall deadline. Unsupported, invalid or unavailable values use display defaults of rate 50, pitch 5 and volume 5. Server values are converted to the reader's existing scales, rounded to one decimal place and constrained by the sliders' existing ranges. Hardware speech uses the display defaults. Merely opening preferences or applying unrelated changes does not save these display values as speech overrides.
Build an isolated binary and run the focused checks:
go build -o /tmp/cthulhu-speech-preferences ./cmd/cthulhu
go test ./internal/preferences ./internal/speech ./internal/config ./internal/app -count=1
CTHULHU_BINARY=/tmp/cthulhu-speech-preferences CTHULHU_PREFS_NO_CONFIG_ONLY=1 /usr/bin/python3 tests/native_preferences.py
CTHULHU_BINARY=/tmp/cthulhu-speech-preferences CTHULHU_PREFS_NO_CONFIG_ONLY=1 CTHULHU_PREFS_DEFAULTS_UNSUPPORTED=1 /usr/bin/python3 tests/native_preferences.py
CTHULHU_BINARY=/tmp/cthulhu-speech-preferences CTHULHU_PREFS_VOICE_TYPES_ONLY=1 /usr/bin/python3 tests/native_preferences.py
CTHULHU_BINARY=/tmp/cthulhu-speech-preferences CTHULHU_PREFS_NUMBERS_ONLY=1 /usr/bin/python3 tests/native_preferences.py
CTHULHU_BINARY=/tmp/cthulhu-speech-preferences /usr/bin/python3 tests/native_preferences.py
The missing-file checks use the real reader, GTK preferences and a private SSIP server, isolated under Xvfb and D-Bus. They verify initial values with no settings file, direct keyboard edits, Tab and Shift+Tab, untouched inheritance, automatic Uppercase pitch, preview settings reaching SSIP, Apply creating the file, saved values after reopening, and Cancel discarding unsaved changes. Test logs, configuration and speech recordings remain in the reported temporary directory.
Human acceptance remains separate: with the rebuilt reader, use a temporary configuration and physically adjust all three sliders, listen to their previews, Apply and reopen, then change a value and Cancel. Check the Default, Uppercase, Hyperlink and System voices independently; confirm capital pitch still works, ordinary speech returns to its normal pitch, and Tab/Shift+Tab retain sensible labels and values. Check Braille if used. These checks also cover existing profiles with explicit values; the automated harness does not establish audible speech, physical input or physical Braille acceptance.
Speech numbers use at most one decimal place. After repeated slider changes, check pitch and volume with the quick speech keys, then save and reopen the settings. Values such as 4.5 must remain 4.5 in announcements and TOML rather than exposing floating-point tails. Check all voice types and custom key echo; untouched inherited values must remain unset.
Preferences focus with differing window bounds
On Slint/i3, GTK can report a frame at (0,0), sized 1916×994, while X11 reports its client at (2,18), sized 1912×974. Rejecting that frame by geometry silences control announcements even though Tab still moves focus. The reader registers the PID of its own preferences helper until the helper exits. That helper can bypass the geometry comparison when X11 identifies the same foreground process and GTK reports an active, showing, non-iconified window. Other applications retain the normal foreground correlation checks.
The adapter dropdown regression also checks that preferences activation and focused-control events are accepted:
go test ./internal/atspi ./internal/app -count=1
CTHULHU_BINARY=/tmp/cthulhu-speech-preferences CTHULHU_PREFS_ADAPTER_ONLY=1 python3 tests/native_preferences.py
On the affected Slint desktop, use the rebuilt reader to open preferences. Tab and Shift+Tab through controls, switch notebook pages with Ctrl+PageUp and Ctrl+PageDown, open a dropdown, change its selection, and close it with Escape. Confirm each control's name and value is announced. Apply a change, close and reopen preferences, and confirm it persists. Switch to another application while preferences remains open: speech and Braille must follow that application, then resume preferences announcements when returning. Repeat after closing and reopening preferences and after changing window size. Private X11 tests do not establish physical-key, audible-speech or Braille acceptance on Slint.