From f688a559953de2d64055f0bf86e6d6a17e43fd61 Mon Sep 17 00:00:00 2001 From: flamboh Date: Mon, 2 Nov 2026 08:02:34 +0000 Subject: [PATCH] fix(web): keybinding settings list only this platform's variants --- .../KeybindingsSettings.logic.test.ts | 21 +++++++++++++++ .../settings/KeybindingsSettings.logic.ts | 26 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/apps/web/src/components/settings/KeybindingsSettings.logic.test.ts b/apps/web/src/components/settings/KeybindingsSettings.logic.test.ts index d8af8376daf21..9abcb133ce983 100644 --- a/apps/web/src/components/settings/KeybindingsSettings.logic.test.ts +++ b/apps/web/src/components/settings/KeybindingsSettings.logic.test.ts @@ -298,6 +298,27 @@ describe("KeybindingsSettings.logic", () => { ).toEqual(["New local thread", ...expected.ctrl].toSorted()); }); + it.each([ + { + platform: "MacIntel", + visible: ["", "!isMac || terminalFocus", "isMac", "isMac && isDesktop"], + }, + { platform: "Linux x86_64", visible: ["", "!isMac", "!isMac || terminalFocus"] }, + ])("lists only the $platform platform variants", ({ platform, visible }) => { + const rows = buildKeybindingRows( + compileResolvedKeybindingsConfig([ + { command: "layout.focusDown", key: "mod+alt+arrowdown", when: "isMac" }, + { command: "layout.focusDown", key: "alt+shift+arrowdown", when: "!isMac" }, + { command: "layout.focusDown", key: "mod+alt+j", when: "isMac && isDesktop" }, + { command: "layout.focusDown", key: "ctrl+j", when: "!isMac || terminalFocus" }, + { command: "layout.focusDown", key: "f9" }, + ]), + platform, + ); + + expect(rows.map((row) => row.when).toSorted()).toEqual(visible); + }); + it("keeps mod and ctrl shortcuts apart when their when contexts differ", () => { const rows = buildKeybindingRows( compileResolvedKeybindingsConfig([ diff --git a/apps/web/src/components/settings/KeybindingsSettings.logic.ts b/apps/web/src/components/settings/KeybindingsSettings.logic.ts index f36d1cea94b02..c77cc0304187c 100644 --- a/apps/web/src/components/settings/KeybindingsSettings.logic.ts +++ b/apps/web/src/components/settings/KeybindingsSettings.logic.ts @@ -171,6 +171,30 @@ function defaultBindingForBinding( ); } +function platformAllowsWhen(node: KeybindingWhenNode | undefined, isMac: boolean): boolean | null { + if (!node) return null; + switch (node.type) { + case "identifier": + return node.name === "isMac" ? isMac : null; + case "not": { + const value = platformAllowsWhen(node.node, isMac); + return value === null ? null : !value; + } + case "and": { + const left = platformAllowsWhen(node.left, isMac); + const right = platformAllowsWhen(node.right, isMac); + if (left === false || right === false) return false; + return left === true && right === true ? true : null; + } + case "or": { + const left = platformAllowsWhen(node.left, isMac); + const right = platformAllowsWhen(node.right, isMac); + if (left === true || right === true) return true; + return left === false && right === false ? false : null; + } + } +} + function keybindingRowId(command: KeybindingCommand, key: string, when: string): string { return `${command}\u0000${key}\u0000${when}`; } @@ -207,7 +231,9 @@ export function buildKeybindingRows( platform = navigator.platform, ): ReadonlyArray { const rowsById = new Map(); + const isMac = isMacPlatform(platform); for (const binding of keybindings) { + if (platformAllowsWhen(binding.whenAst, isMac) === false) continue; const defaultBinding = defaultBindingForBinding(binding); const key = shortcutToKeybindingInput(binding.shortcut); const when = whenAstToExpression(binding.whenAst);