You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(whisper): add dropdown preset keybinding selector for speech-to-text (#447)
* feat(whisper): add dropdown preset keybinding selector for speech-to-text
Replace the single HotkeyRecorder + 'Set to Fn' button in Whisper hotkey
settings with a dropdown offering preset keybinding options. This solves
the problem where standalone modifier keys (Option, Command, etc.) could
not be captured by the recorder since browser keydown events treat them
as modifiers rather than keys.
Preset options include: Fn (hold-to-talk), Option (hold-to-talk), F5,
F6, Option+Space, Option+., Command+., Control+Space, Shift+Space.
A 'Custom…' option in the dropdown reveals the HotkeyRecorder for
advanced key combos.
Backend changes generalize the native CGEventTap-based Fn speak-toggle
watcher to support any standalone modifier key as a hold-to-talk trigger
(Option/Alt keyCode 58, Command keyCode 55, etc.). The
hotkey-hold-monitor.swift binary already handles flagsChanged events for
modifier keys, so no native code changes were needed.
All 9 locale files updated with new i18n keys (custom, holdToTalkHint)
replacing the removed keys (setToFn, fnHint, fnHintBefore, fnHintAfter).
* fix(whisper): trim dropdown to Fn/Option/Command with L/R variants, fix Custom auto-record
- Replace the 9 preset list (F5, F6, combos) with the 3 hold-to-talk
modifier families: Fn, Left/Right Option, Left/Right Command
- Add right-side modifier key codes (61=RightOption, 54=RightCommand) to
STANDALONE_MODIFIER_KEYCODES and parseHoldShortcutConfig key map
- Update normalizeAccelerator to recognize left/right modifier tokens as
modifiers when used in combos (e.g. LeftOption+Space → Alt+Space)
- Update isStandaloneAlt/isStandaloneCmd detection for left/right variants
- Format display: ⌥←/⌥→/⌘←/⌘→ with directional arrows for side info
- Fix Custom option: blur the <select> when Custom is chosen so it stops
intercepting keyboard events, and add autoRecord prop to HotkeyRecorder
so it auto-starts recording and grabs focus on mount
* fix(whisper): move whisperCustomMode useState above early return to fix hooks order
The useState for whisperCustomMode was placed after the early return
(!settings), causing React to throw 'Rendered more hooks than during the
previous render' when settings loaded asynchronously.
* fix(whisper): show HotkeyRecorder when Custom is selected from dropdown
The recorder visibility was gated on whisperPresetValue which only
reflects the stored hotkey — but selecting 'Custom…' doesn't change the
stored value, so the recorder never appeared. Use whisperSelectValue
instead, which accounts for the user's explicit Custom selection.
* fix(whisper): eliminate dropdown flash when recording custom keybinding
Keep whisperCustomMode=true until the stored hotkey actually updates
via IPC instead of clearing it in the recorder's onChange (which fires
before the async settings save completes). A 150ms timeout fallback
handles the edge case where the recorded value equals the current
stored value.
* fix(whisper): move whisperCustomMode useEffect above early return
The useEffect for clearing whisperCustomMode was placed after the
component-level early return guard, causing the hooks order mismatch
again. Derive whisperSpeakToggleHotkey from settings? before the guard
and move the effect up with the other hooks.
* fix(whisper): keep custom mode active until recorder saves, not on timer
The previous 150ms timeout-based useEffect fired immediately when
custom mode was entered, snapping the dropdown back before the user
could record anything. Now custom mode only clears when the
HotkeyRecorder's onChange resolves (i.e. after IPC save completes).
Copy file name to clipboardExpand all lines: src/renderer/src/i18n/locales/de.json
+2-4Lines changed: 2 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -384,10 +384,8 @@
384
384
"hotkeys": {
385
385
"title": "Whisper-Tastenkombinationen",
386
386
"startStop": "Sprechen starten/stoppen",
387
-
"setToFn": "Auf Fn setzen",
388
-
"fnHint": "Verwende Auf Fn setzen, um die standardmaessige Push-to-Talk-Taste wiederherzustellen.",
389
-
"fnHintBefore": "Use",
390
-
"fnHintAfter": "to restore the default hold-to-talk key."
387
+
"custom": "Benutzerdefiniert…",
388
+
"holdToTalkHint": "Waehlen Sie eine Push-to-Talk-Taste. Halten zum Aufnehmen, loslassen zum Eingeben. Benutzen Sie Benutzerdefiniert fuer jede Tastenkombination."
Copy file name to clipboardExpand all lines: src/renderer/src/i18n/locales/es.json
+2-4Lines changed: 2 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -384,10 +384,8 @@
384
384
"hotkeys": {
385
385
"title": "Atajos de Whisper",
386
386
"startStop": "Iniciar/detener dictado",
387
-
"setToFn": "Asignar a Fn",
388
-
"fnHint": "Usa Asignar a Fn para restaurar la tecla predeterminada de pulsar para hablar.",
389
-
"fnHintBefore": "Use",
390
-
"fnHintAfter": "to restore the default hold-to-talk key."
387
+
"custom": "Personalizado…",
388
+
"holdToTalkHint": "Seleccione una tecla push-to-talk. Mantenga para grabar, suelte para escribir. Use Personalizado para grabar cualquier combinacion."
Copy file name to clipboardExpand all lines: src/renderer/src/i18n/locales/fr.json
+2-4Lines changed: 2 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -384,10 +384,8 @@
384
384
"hotkeys": {
385
385
"title": "Raccourcis Whisper",
386
386
"startStop": "Demarrer/arreter la dictee",
387
-
"setToFn": "Definir sur Fn",
388
-
"fnHint": "Utilisez Definir sur Fn pour restaurer la touche push-to-talk par defaut.",
389
-
"fnHintBefore": "Use",
390
-
"fnHintAfter": "to restore the default hold-to-talk key."
387
+
"custom": "Personnalise…",
388
+
"holdToTalkHint": "Selectionnez une touche push-to-talk. Maintenez pour enregistrer, relachez pour saisir. Utilisez Personnalise pour enregistrer toute combinaison."
Copy file name to clipboardExpand all lines: src/renderer/src/i18n/locales/it.json
+2-4Lines changed: 2 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -384,10 +384,8 @@
384
384
"hotkeys": {
385
385
"title": "Scorciatoie di Whisper",
386
386
"startStop": "Avvia/Ferma la dettatura",
387
-
"setToFn": "Imposta su Fn",
388
-
"fnHint": "Usa Imposta su Fn per ripristinare il tasto predefinito di registrazione.",
389
-
"fnHintBefore": "Usa",
390
-
"fnHintAfter": "per ripristinare il tasto predefinito di registrazione."
387
+
"custom": "Personalizzato…",
388
+
"holdToTalkHint": "Seleziona un tasto push-to-talk. Tieni premuto per registrare, rilascia per digitare. Usa Personalizzato per registrare qualsiasi combinazione."
0 commit comments