Files
voculinux/tests
dbe0215aad feat(shortcuts): add language switching shortcuts, fix PTT races, and add dictation history (#880)
* feat(shortcuts): per-language dictation shortcuts (#805)

Bind extra keys that start dictation in a specific catalog language for
one utterance, then restore the configured language. Bindings live in
shortcuts.language_shortcuts as [{shortcut, language}], normalized
against the language catalog and the backend's shortcut parser.

The tray spawns one KeyboardShortcutManager per binding in the active
mode; toggle presses route through start_recognition_with_language, and
push-to-talk arms press/release the same way. The manager keeps the
override one-shot: it applies before the utterance starts (outranking
follow-keyboard-layout) and unwinds on the next IDLE/ERROR transition
or when a mid-dictation reconfigure picks a new language. Engines that
cannot re-language without a reload (VOSK, Parakeet, English-only
whisper.cpp) refuse with the error cue and a notification instead of
dictating in the wrong language.

Settings gains a Language Shortcuts group under Shortcuts: each row is
a language picker, an editable key entry, a Record button that retargets
the shared key-capture, and a remove button; edits persist immediately
and rebuild the live listeners. A non-dict shortcuts section now rebuilds
instead of crashing config load.

* fix(shortcuts): class-level default for language shortcut listeners

TrayIndicator stubs built with __new__ (e.g. test_suspend_handler)
skip __init__ but still run _quit(); give _language_shortcut_managers
a class-level default so teardown iterates an empty list.

* Fix Greptile review findings on per-language shortcuts (#805)

- Bind each dictation session's language for transcription workers so the
  one-shot restore cannot rewrite a queued segment's language
- Judge a shortcut's capability against the model the layout refresh will
  serve (whisper.cpp sibling swap) and refuse requests the engine drops
- Add _oneshot_language_restore to the reconfigure snapshot and settle a
  revived pending restore on failure
- Dedupe language bindings by gesture (modifier reordering, enter/return
  alias, pure-modifier side sets) instead of by string
- Stop per-language listeners under external activation and never re-arm
- Gate push-to-talk release on the binding that started the session, and
  stop a held hold before rebuilding listeners
- Keep a row's last valid binding during partial edits, report rejected
  duplicates, cancel a capture aimed at a removed row, disarm the previous
  Record target, persist a recorded key once, and add the missing type
  hints

* fix(shortcuts): resolve remaining Greptile race findings on PR #880

- Stamp each queued audio segment with the session language it was
  recorded under, so a worker that outlives stop_recognition's joins
  transcribes each utterance in its own language rather than whatever a
  newer session stored in _session_language.
- Serialize push-to-talk press/release behind _ptt_lock: a release
  landing while start_recognition runs now waits for the owner claim
  instead of being dropped, so a quick key tap cannot leave the
  microphone running.
- Add the missing return type hint on _stop_language_shortcut_managers.

* test(shortcuts): stub _segment_started_at on bare manager stubs

* fix(shortcuts): carry segment language as attribute, default language on bare managers

* fix(shortcuts): keep (segment, language) queue tuples, stamp segment.language too

* fix(settings): apply history toggle and limit to the live store

---------

Co-authored-by: Jatin K Malik <jatinkrmalik@gmail.com>
2026-09-30 01:05:18 -07:00
..