From 100ac159397ba2dd1f30dc8dc5d0b1ced64fd68e Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Sun, 22 Mar 2026 23:55:59 +0100 Subject: [PATCH] fix: deduplicate keybind actions when native hook and web fallback both fire When the app is focused and the native uiohook hook is active, both the IPC bridge and the web fallback capture the same keypress, dispatching the toggle action twice (~0-20ms apart). This double-toggles mute/deafen back to the original state. Add a 100ms dedup window in dispatchKeybindAction to suppress the second dispatch. Safe for human input (key repeat starts at ~500ms). --- packages/web/src/hooks/useKeybinds.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/web/src/hooks/useKeybinds.ts b/packages/web/src/hooks/useKeybinds.ts index 40b818a0..8412f152 100644 --- a/packages/web/src/hooks/useKeybinds.ts +++ b/packages/web/src/hooks/useKeybinds.ts @@ -27,8 +27,16 @@ function getSpaceEnforcementState(): { isSpaceMuted: boolean; isSpaceDeafened: b }; } +/** Dedup rapid duplicate dispatches (native hook + web fallback both fire when focused) */ +const lastDispatch: Record = {}; + /** Dispatch a keybind action to the appropriate voice handler */ function dispatchKeybindAction(actionId: string, pressed: boolean): void { + const now = Date.now(); + const key = `${actionId}:${pressed}`; + if (now - (lastDispatch[key] || 0) < 100) return; + lastDispatch[key] = now; + const voice = useVoiceStore.getState(); if (!voice.currentVoiceChannelId) return;