Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions apps/web/src/terminal/ghostty/surface.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down
12 changes: 8 additions & 4 deletions apps/web/src/terminal/ghostty/surface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,11 @@ export function isTerminalCopyShortcut(
event: Pick<KeyboardEvent, "ctrlKey" | "key" | "metaKey" | "shiftKey">,
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;
}

Expand Down Expand Up @@ -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 {
Expand Down
Loading