diff --git a/src/components/dialog/content/setting/KeybindingPanel.vue b/src/components/dialog/content/setting/KeybindingPanel.vue index dbe61f089..a190328b5 100644 --- a/src/components/dialog/content/setting/KeybindingPanel.vue +++ b/src/components/dialog/content/setting/KeybindingPanel.vue @@ -237,7 +237,7 @@ async function removeKeybinding(commandData: ICommandData) { async function captureKeybinding(event: KeyboardEvent) { // Allow the use of keyboard shortcuts when adding keyboard shortcuts if (!event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey) { - switch (event.key) { + switch (event.code) { case 'Escape': cancelEdit() return diff --git a/src/constants/coreKeybindings.ts b/src/constants/coreKeybindings.ts index fe2bde835..f98c3ed46 100644 --- a/src/constants/coreKeybindings.ts +++ b/src/constants/coreKeybindings.ts @@ -26,58 +26,58 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ }, { combo: { - key: 'r' + key: 'KeyR' }, commandId: 'Comfy.RefreshNodeDefinitions' }, { combo: { - key: 'q' + key: 'KeyQ' }, commandId: 'Workspace.ToggleSidebarTab.queue' }, { combo: { - key: 'w' + key: 'KeyW' }, commandId: 'Workspace.ToggleSidebarTab.workflows' }, { combo: { - key: 'n' + key: 'KeyN' }, commandId: 'Workspace.ToggleSidebarTab.node-library' }, { combo: { - key: 'm' + key: 'KeyM' }, commandId: 'Workspace.ToggleSidebarTab.model-library' }, { combo: { - key: 's', + key: 'KeyS', ctrl: true }, commandId: 'Comfy.SaveWorkflow' }, { combo: { - key: 'o', + key: 'KeyO', ctrl: true }, commandId: 'Comfy.OpenWorkflow' }, { combo: { - key: 'g', + key: 'KeyG', ctrl: true }, commandId: 'Comfy.Graph.GroupSelectedNodes' }, { combo: { - key: ',', + key: 'Comma', ctrl: true }, commandId: 'Comfy.ShowSettingsDialog' @@ -85,7 +85,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ // For '=' both holding shift and not holding shift { combo: { - key: '=', + key: 'Equal', alt: true }, commandId: 'Comfy.Canvas.ZoomIn', @@ -93,7 +93,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ }, { combo: { - key: '+', + key: 'Equal', alt: true, shift: true }, @@ -103,7 +103,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ // For number pad '+' { combo: { - key: '+', + key: 'NumpadAdd', alt: true }, commandId: 'Comfy.Canvas.ZoomIn', @@ -111,7 +111,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ }, { combo: { - key: '-', + key: 'Minus', alt: true }, commandId: 'Comfy.Canvas.ZoomOut', @@ -119,21 +119,21 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ }, { combo: { - key: '.' + key: 'Period' }, commandId: 'Comfy.Canvas.FitView', targetElementId: 'graph-canvas-container' }, { combo: { - key: 'p' + key: 'KeyP' }, commandId: 'Comfy.Canvas.ToggleSelected.Pin', targetElementId: 'graph-canvas-container' }, { combo: { - key: 'c', + key: 'KeyC', alt: true }, commandId: 'Comfy.Canvas.ToggleSelectedNodes.Collapse', @@ -141,7 +141,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ }, { combo: { - key: 'b', + key: 'KeyB', ctrl: true }, commandId: 'Comfy.Canvas.ToggleSelectedNodes.Bypass', @@ -149,7 +149,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ }, { combo: { - key: 'm', + key: 'KeyM', ctrl: true }, commandId: 'Comfy.Canvas.ToggleSelectedNodes.Mute', @@ -157,20 +157,20 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ }, { combo: { - key: '`', + key: 'Backquote', ctrl: true }, commandId: 'Workspace.ToggleBottomPanelTab.logs-terminal' }, { combo: { - key: 'f' + key: 'KeyF' }, commandId: 'Workspace.ToggleFocusMode' }, { combo: { - key: 'e', + key: 'KeyE', ctrl: true, shift: true }, @@ -178,7 +178,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ }, { combo: { - key: 'm', + key: 'KeyM', alt: true }, commandId: 'Comfy.Canvas.ToggleMinimap' @@ -187,19 +187,19 @@ export const CORE_KEYBINDINGS: Keybinding[] = [ combo: { ctrl: true, shift: true, - key: 'k' + key: 'KeyK' }, commandId: 'Workspace.ToggleBottomPanel.Shortcuts' }, { combo: { - key: 'v' + key: 'KeyV' }, commandId: 'Comfy.Canvas.Unlock' }, { combo: { - key: 'h' + key: 'KeyH' }, commandId: 'Comfy.Canvas.Lock' }, diff --git a/src/services/keybindingService.ts b/src/services/keybindingService.ts index ed5049246..30617dfc9 100644 --- a/src/services/keybindingService.ts +++ b/src/services/keybindingService.ts @@ -51,7 +51,7 @@ export const useKeybindingService = () => { if (keybinding && keybinding.targetElementId !== 'graph-canvas') { // Special handling for Escape key - let dialogs handle it first if ( - event.key === 'Escape' && + event.code === 'Escape' && !event.ctrlKey && !event.altKey && !event.metaKey @@ -88,7 +88,7 @@ export const useKeybindingService = () => { } // Escape key: close the first open modal found, and all dialogs - if (event.key === 'Escape') { + if (event.code === 'Escape') { const modals = document.querySelectorAll('.comfy-modal') for (const modal of modals) { const modalDisplay = window diff --git a/src/stores/keybindingStore.ts b/src/stores/keybindingStore.ts index 76a21120c..d2f5adb58 100644 --- a/src/stores/keybindingStore.ts +++ b/src/stores/keybindingStore.ts @@ -44,7 +44,7 @@ export class KeyComboImpl implements KeyCombo { static fromEvent(event: KeyboardEvent) { return new KeyComboImpl({ - key: event.key, + key: event.code, ctrl: event.ctrlKey || event.metaKey, alt: event.altKey, shift: event.shiftKey @@ -75,7 +75,16 @@ export class KeyComboImpl implements KeyCombo { } get isModifier(): boolean { - return ['Control', 'Meta', 'Alt', 'Shift'].includes(this.key) + return [ + 'ControlLeft', + 'ControlRight', + 'MetaLeft', + 'MetaRight', + 'AltLeft', + 'AltRight', + 'ShiftLeft', + 'ShiftRight' + ].includes(this.key) } get modifierCount(): number { @@ -106,9 +115,95 @@ export class KeyComboImpl implements KeyCombo { if (this.shift) { sequences.push('Shift') } - sequences.push(this.key) + sequences.push(this.getDisplayKey()) return sequences } + + getDisplayKey(): string { + // Convert key codes to display names + const keyMap: Record = { + // Letters + KeyA: 'A', + KeyB: 'B', + KeyC: 'C', + KeyD: 'D', + KeyE: 'E', + KeyF: 'F', + KeyG: 'G', + KeyH: 'H', + KeyI: 'I', + KeyJ: 'J', + KeyK: 'K', + KeyL: 'L', + KeyM: 'M', + KeyN: 'N', + KeyO: 'O', + KeyP: 'P', + KeyQ: 'Q', + KeyR: 'R', + KeyS: 'S', + KeyT: 'T', + KeyU: 'U', + KeyV: 'V', + KeyW: 'W', + KeyX: 'X', + KeyY: 'Y', + KeyZ: 'Z', + // Numbers + Digit0: '0', + Digit1: '1', + Digit2: '2', + Digit3: '3', + Digit4: '4', + Digit5: '5', + Digit6: '6', + Digit7: '7', + Digit8: '8', + Digit9: '9', + // Function keys + F1: 'F1', + F2: 'F2', + F3: 'F3', + F4: 'F4', + F5: 'F5', + F6: 'F6', + F7: 'F7', + F8: 'F8', + F9: 'F9', + F10: 'F10', + F11: 'F11', + F12: 'F12', + // Special keys + Space: 'Space', + Enter: 'Enter', + Tab: 'Tab', + Escape: 'Escape', + Backspace: 'Backspace', + Delete: 'Delete', + ArrowUp: '↑', + ArrowDown: '↓', + ArrowLeft: '←', + ArrowRight: '→', + Home: 'Home', + End: 'End', + PageUp: 'PageUp', + PageDown: 'PageDown', + Insert: 'Insert', + // Punctuation + Minus: '-', + Equal: '=', + BracketLeft: '[', + BracketRight: ']', + Backslash: '\\', + Semicolon: ';', + Quote: "'", + Backquote: '`', + Comma: ',', + Period: '.', + Slash: '/' + } + return keyMap[this.key] || this.key + } } export const useKeybindingStore = defineStore('keybinding', () => { diff --git a/tests-ui/tests/services/keybindingService.escape.test.ts b/tests-ui/tests/services/keybindingService.escape.test.ts index 20b608e8d..e49eeaa9a 100644 --- a/tests-ui/tests/services/keybindingService.escape.test.ts +++ b/tests-ui/tests/services/keybindingService.escape.test.ts @@ -66,7 +66,7 @@ describe('keybindingService - Escape key handling', () => { it('should execute ExitSubgraph command when Escape is pressed', async () => { const event = new KeyboardEvent('keydown', { - key: 'Escape', + code: 'Escape', bubbles: true, cancelable: true }) @@ -83,7 +83,7 @@ describe('keybindingService - Escape key handling', () => { it('should not execute command when Escape is pressed with modifiers', async () => { const event = new KeyboardEvent('keydown', { - key: 'Escape', + code: 'Escape', ctrlKey: true, bubbles: true, cancelable: true @@ -100,7 +100,7 @@ describe('keybindingService - Escape key handling', () => { it('should not execute command when typing in input field', async () => { const inputElement = document.createElement('input') const event = new KeyboardEvent('keydown', { - key: 'Escape', + code: 'Escape', bubbles: true, cancelable: true }) @@ -130,7 +130,7 @@ describe('keybindingService - Escape key handling', () => { document.body.appendChild(dialog) const event = new KeyboardEvent('keydown', { - key: 'Escape', + code: 'Escape', bubbles: true, cancelable: true }) @@ -158,7 +158,7 @@ describe('keybindingService - Escape key handling', () => { ) const event = new KeyboardEvent('keydown', { - key: 'Escape', + code: 'Escape', bubbles: true, cancelable: true }) @@ -185,7 +185,7 @@ describe('keybindingService - Escape key handling', () => { keybindingService = useKeybindingService() const event = new KeyboardEvent('keydown', { - key: 'Escape', + code: 'Escape', bubbles: true, cancelable: true })