diff --git a/packages/web/src/components/modals/settingsPanels/KeybindsPanel.tsx b/packages/web/src/components/modals/settingsPanels/KeybindsPanel.tsx index 6492a17a..56837a93 100644 --- a/packages/web/src/components/modals/settingsPanels/KeybindsPanel.tsx +++ b/packages/web/src/components/modals/settingsPanels/KeybindsPanel.tsx @@ -26,7 +26,12 @@ function keyDisplayName(code: string, key: string): string { } function codeToNumeric(code: string): number { - return code.charCodeAt(0) * 256 + (code.charCodeAt(1) || 0); + // djb2 hash — produces unique numeric IDs for all KeyboardEvent.code values + let hash = 5381; + for (let i = 0; i < code.length; i++) { + hash = ((hash << 5) + hash + code.charCodeAt(i)) | 0; + } + return hash >>> 0; // ensure unsigned } // --------------------------------------------------------------------------- diff --git a/packages/web/src/hooks/useKeybinds.ts b/packages/web/src/hooks/useKeybinds.ts index f834802c..2f5a2663 100644 --- a/packages/web/src/hooks/useKeybinds.ts +++ b/packages/web/src/hooks/useKeybinds.ts @@ -83,9 +83,12 @@ function setupWebFallback(keybindsRef: React.MutableRefObject): WebCl const activeActions = new Set(); function browserCodeToUiohook(code: string): number { - // Stable numeric ID from KeyboardEvent.code — consistent within web context - // because the recorder captures using the same mapping - return code.charCodeAt(0) * 256 + (code.charCodeAt(1) || 0); + // djb2 hash — must match codeToNumeric() in KeybindsPanel.tsx + let hash = 5381; + for (let i = 0; i < code.length; i++) { + hash = ((hash << 5) + hash + code.charCodeAt(i)) | 0; + } + return hash >>> 0; } function checkKeybinds(isDown: boolean): void {