diff --git a/packages/app/src/hooks/use-keyboard-shortcuts.ts b/packages/app/src/hooks/use-keyboard-shortcuts.ts index ae0671c25..eb58f3ba6 100644 --- a/packages/app/src/hooks/use-keyboard-shortcuts.ts +++ b/packages/app/src/hooks/use-keyboard-shortcuts.ts @@ -9,6 +9,7 @@ import { type ChordState, resolveKeyboardShortcut, buildEffectiveBindings, + getWorkspaceIndexJumpModifierKey, } from "@/keyboard/keyboard-shortcuts"; import { resolveKeyboardFocusScope } from "@/keyboard/focus-scope"; import { @@ -73,6 +74,20 @@ export function useKeyboardShortcuts({ const isDesktopApp = getIsElectronRuntime(); const isMac = getShortcutOs() === "mac"; + // Only the modifier that actually performs the workspace-index jump on this + // runtime should reveal the sidebar number badges (Alt on web, Cmd on + // desktop Mac, Ctrl on desktop non-Mac). The store ORs altDown/cmdOrCtrlDown + // to drive badge visibility, so we set the flag matching this runtime. + const badgeModifierKey = getWorkspaceIndexJumpModifierKey({ isMac, isDesktop: isDesktopApp }); + const setBadgeModifierDown = (down: boolean) => { + const state = useKeyboardShortcutsStore.getState(); + if (isDesktopApp) { + state.setCmdOrCtrlDown(down); + } else { + state.setAltDown(down); + } + }; + const shouldHandle = () => { if (typeof document === "undefined") return false; if (document.visibilityState !== "visible") return false; @@ -156,11 +171,8 @@ export function useKeyboardShortcuts({ } const key = event.key ?? ""; - if (key === "Alt" && !event.shiftKey) { - useKeyboardShortcutsStore.getState().setAltDown(true); - } - if (isDesktopApp && (key === "Meta" || key === "Control") && !event.shiftKey) { - useKeyboardShortcutsStore.getState().setCmdOrCtrlDown(true); + if (key === badgeModifierKey && !event.shiftKey) { + setBadgeModifierDown(true); } if (key === "Shift") { const state = useKeyboardShortcutsStore.getState(); @@ -231,11 +243,8 @@ export function useKeyboardShortcuts({ const handleKeyUp = (event: KeyboardEvent) => { const key = event.key ?? ""; - if (key === "Alt") { - useKeyboardShortcutsStore.getState().setAltDown(false); - } - if (isDesktopApp && (key === "Meta" || key === "Control")) { - useKeyboardShortcutsStore.getState().setCmdOrCtrlDown(false); + if (key === badgeModifierKey) { + setBadgeModifierDown(false); } }; diff --git a/packages/app/src/keyboard/keyboard-shortcuts.test.ts b/packages/app/src/keyboard/keyboard-shortcuts.test.ts index a797aea9b..bec812563 100644 --- a/packages/app/src/keyboard/keyboard-shortcuts.test.ts +++ b/packages/app/src/keyboard/keyboard-shortcuts.test.ts @@ -3,6 +3,7 @@ import { buildKeyboardShortcutHelpSections, buildEffectiveBindings, getBindingIdForAction, + getWorkspaceIndexJumpModifierKey, resolveKeyboardShortcut, type ChordState, type KeyboardShortcutContext, @@ -638,3 +639,18 @@ describe("keyboard-shortcut help sections", () => { ).toBeNull(); }); }); + +describe("getWorkspaceIndexJumpModifierKey", () => { + it("uses Alt on web, regardless of OS", () => { + expect(getWorkspaceIndexJumpModifierKey({ isMac: true, isDesktop: false })).toBe("Alt"); + expect(getWorkspaceIndexJumpModifierKey({ isMac: false, isDesktop: false })).toBe("Alt"); + }); + + it("uses Cmd (Meta) on desktop Mac, not Control or Alt", () => { + expect(getWorkspaceIndexJumpModifierKey({ isMac: true, isDesktop: true })).toBe("Meta"); + }); + + it("uses Ctrl on desktop non-Mac, not Meta or Alt", () => { + expect(getWorkspaceIndexJumpModifierKey({ isMac: false, isDesktop: true })).toBe("Control"); + }); +}); diff --git a/packages/app/src/keyboard/keyboard-shortcuts.ts b/packages/app/src/keyboard/keyboard-shortcuts.ts index d3fbbd088..40358977d 100644 --- a/packages/app/src/keyboard/keyboard-shortcuts.ts +++ b/packages/app/src/keyboard/keyboard-shortcuts.ts @@ -1344,6 +1344,21 @@ export function getDefaultKeysForAction( return null; } +/** + * The `KeyboardEvent.key` whose hold reveals the sidebar workspace-jump number + * badges. It must match the modifier of the active `workspace.navigate.index` + * binding for this runtime, otherwise the badges appear for a modifier that + * does not actually jump: Alt on web, Cmd (Meta) on desktop Mac, Ctrl on + * desktop non-Mac. + */ +export function getWorkspaceIndexJumpModifierKey(platform: { + isMac: boolean; + isDesktop: boolean; +}): "Alt" | "Meta" | "Control" { + if (!platform.isDesktop) return "Alt"; + return platform.isMac ? "Meta" : "Control"; +} + export function buildKeyboardShortcutHelpSections( input: KeyboardShortcutPlatformContext, bindings: readonly ParsedShortcutBinding[] = DEFAULT_BINDINGS,