From 010d0155608af27414a1c5c750fa15b0673c9a79 Mon Sep 17 00:00:00 2001 From: MarcoDotIO Date: Wed, 21 Oct 2026 10:15:07 -0400 Subject: [PATCH] fix(desktop): SnapShot shortcuts with arrow keys register on macOS and Windows Recorded shortcuts store lowercase keys ("arrowup"), but the Electron accelerator map was keyed by "ArrowUp", so the lookup missed and the accelerator became "ARROWUP", a token Electron does not accept. Key the map by the stored lowercase tokens. Co-Authored-By: Claude Opus 5.5 --- apps/desktop/src/snapShot/snapShot.test.ts | 17 +++++++++++++++++ apps/desktop/src/snapShot/snapShot.ts | 11 ++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/snapShot/snapShot.test.ts b/apps/desktop/src/snapShot/snapShot.test.ts index 26ae8fbf9ebe9..0c1ebec70a826 100644 --- a/apps/desktop/src/snapShot/snapShot.test.ts +++ b/apps/desktop/src/snapShot/snapShot.test.ts @@ -1,5 +1,6 @@ import { it as effectIt } from "@effect/vitest"; import * as HostProcess from "@t3tools/shared/HostProcess"; +import { parseKeybindingShortcut } from "@t3tools/shared/keybindings"; import * as Effect from "effect/Effect"; import { describe, expect, it } from "vite-plus/test"; @@ -11,6 +12,7 @@ import { findCaptureSource, hideAndWaitForBlur, isWaylandSession, + toElectronAccelerator, } from "./snapShot.ts"; describe("accessibleWindowText", () => { @@ -512,6 +514,21 @@ describe("findCaptureSource", () => { }); }); +describe("toElectronAccelerator", () => { + // The settings recorder stores shortcuts through parseKeybindingShortcut, which lowercases keys. + it.each([ + ["mod+shift+arrowup", "CommandOrControl+Shift+Up"], + ["mod+shift+arrowdown", "CommandOrControl+Shift+Down"], + ["ctrl+alt+arrowleft", "Control+Alt+Left"], + ["ctrl+alt+arrowright", "Control+Alt+Right"], + ["mod+shift+esc", "CommandOrControl+Shift+Esc"], + ["mod+shift+space", "CommandOrControl+Shift+Space"], + ["mod+shift+2", "CommandOrControl+Shift+2"], + ])("maps a recorded %s to an Electron accelerator", (recorded, accelerator) => { + expect(toElectronAccelerator(parseKeybindingShortcut(recorded)!)).toBe(accelerator); + }); +}); + describe("isWaylandSession", () => { effectIt.effect( "falls back to a live runtime directory socket when session variables are stripped", diff --git a/apps/desktop/src/snapShot/snapShot.ts b/apps/desktop/src/snapShot/snapShot.ts index 958e017299e0e..16811786a00c4 100644 --- a/apps/desktop/src/snapShot/snapShot.ts +++ b/apps/desktop/src/snapShot/snapShot.ts @@ -560,14 +560,15 @@ function findBrowserTitleMatch( return browserMatches.length === 1 ? browserMatches[0] : undefined; } +// Keyed by the lowercase tokens parseKeybindingShortcut stores; Electron has no `ArrowUp` token. const ELECTRON_KEY_NAMES: Readonly> = { " ": "Space", "+": "Plus", - ArrowDown: "Down", - ArrowLeft: "Left", - ArrowRight: "Right", - ArrowUp: "Up", - Escape: "Esc", + arrowdown: "Down", + arrowleft: "Left", + arrowright: "Right", + arrowup: "Up", + escape: "Esc", }; export function sameSnapShotShortcut(left: SnapShotShortcut, right: SnapShotShortcut): boolean {