diff --git a/apps/web/src/terminal/ghostty/surface.test.ts b/apps/web/src/terminal/ghostty/surface.test.ts index ee3240b41b08..2ef7fe26a115 100644 --- a/apps/web/src/terminal/ghostty/surface.test.ts +++ b/apps/web/src/terminal/ghostty/surface.test.ts @@ -556,6 +556,20 @@ describe("isTerminalCopyShortcut", () => { expect(isTerminalCopyShortcut(event({ key: "C", metaKey: true }), "MacIntel")).toBe(true); expect(isTerminalCopyShortcut(event({ key: "j", metaKey: true }), "MacIntel")).toBe(false); }); + + it("supports the conventional Ctrl+Insert copy shortcut", () => { + expect(isTerminalCopyShortcut(event({ key: "Insert", ctrlKey: true }), "Linux x86_64")).toBe( + true, + ); + expect(isTerminalCopyShortcut(event({ key: "Insert" }), "Linux x86_64")).toBe(false); + expect( + isTerminalCopyShortcut( + event({ key: "Insert", ctrlKey: true, shiftKey: true }), + "Linux x86_64", + ), + ).toBe(false); + expect(isTerminalCopyShortcut(event({ key: "Insert", ctrlKey: true }), "MacIntel")).toBe(false); + }); }); describe("applyTerminalCopyEvent", () => { diff --git a/apps/web/src/terminal/ghostty/surface.ts b/apps/web/src/terminal/ghostty/surface.ts index 29aaac6f6abd..ca1cd5a18eb2 100644 --- a/apps/web/src/terminal/ghostty/surface.ts +++ b/apps/web/src/terminal/ghostty/surface.ts @@ -321,7 +321,11 @@ export function isTerminalCopyShortcut( event: Pick, platform = navigator.platform, ) { - if (event.key.toLowerCase() !== "c") return false; + const key = event.key.toLowerCase(); + if (key === "insert" && !isMacPlatform(platform)) { + return event.ctrlKey && !event.shiftKey && !event.metaKey; + } + if (key !== "c") return false; return isMacPlatform(platform) ? event.metaKey : event.ctrlKey; } @@ -1027,12 +1031,12 @@ export class GhosttyTerminalSurface { // A plain Ctrl+C/Cmd+C fires the browser's native copy event, caught in // onCopyEvent; not preventing the default keeps that path alive. WebKit // omits the keyboard copy event without a DOM selection, so race the - // clipboard write against it the same way paste races its read. The - // Shift variant has no native event (Chrome binds Ctrl+Shift+C to + // clipboard write against it the same way paste races its read. Ctrl+Shift+C + // and Ctrl+Insert have no native copy event (Chrome binds the former to // inspect), so synthesize one with execCommand("copy"). const selection = this.getSelection(); this.primeCopy(selection); - if (event.shiftKey) { + if (event.shiftKey || event.key.toLowerCase() === "insert") { event.preventDefault(); document.execCommand("copy"); } else {