Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Ctrl+Shift+C (and Ctrl+C with a selection) send ^C instead of copying on Linux/Windows

Open Beginner friendly
#204 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
frontend

Research direction

The key handling lives in handleKeyDown in lib/input-handler.ts, which currently special-cases only metaKey plus KeyC and reaches the existing onCopyCallback. Run the reproduction snippet from the issue and confirm that a keydown with ctrlKey and shiftKey still reaches onData as "\u0003". Done means Ctrl+Shift+C invokes the copy callback and sends nothing to the PTY, and Ctrl+C copies only when a selection exists, otherwise it still sends ^C. Check the Cmd+C path still behaves the same.

Written by the indexing model from the issue text.

Description

Summary

On Linux and Windows there is no keyboard way to copy the terminal selection: Ctrl+Shift+C (the terminal copy chord everywhere on those platforms) is passed to the key encoder and sent to the PTY as ^C (0x03), and plain Ctrl+C with text selected also sends ^C. Only Cmd+C (macOS, event.metaKey && event.code === 'KeyC') triggers the copy path. In a shell this means the user selects text, presses the copy shortcut, and interrupts their running program.

Seen on [email protected]; main (lib/input-handler.ts) still only special-cases metaKey + KeyC.

Minimal reproduction

<div id="t"></div>
<script type="module">
  import { init, Terminal } from 'ghostty-web';
  await init();
  const term = new Terminal();
  term.open(document.getElementById('t'));
  term.onData((d) => console.log(JSON.stringify(d)));
  term.write('hello world');
  term.select(0, 0, 5);            // "hello"
  console.log(term.getSelection()); // "hello"
  term.focus();
  term.element.dispatchEvent(new KeyboardEvent('keydown', { key: 'C', code: 'KeyC', ctrlKey: true, shiftKey: true, bubbles: true, cancelable: true }));
</script>

Actual: onData receives "\u0003"; the clipboard is untouched. Expected: the selection is copied and nothing is sent to the PTY (Ctrl+Shift+C), and ideally Ctrl+C copies instead of interrupting when a selection exists (xterm.js users get this from attachCustomKeyEventHandler; Windows Terminal and GNOME Terminal behave this way).

Suggested fix

In handleKeyDown, treat (ctrlKey && shiftKey && code === 'KeyC') as copy using the existing onCopyCallback (always swallow it, never forward ^C), and ctrlKey && !shiftKey && code === 'KeyC' as copy when onCopyCallback() reports a selection.

Found while evaluating ghostty-web as a PTY renderer for https://github.com/erisera-code/clawser; the host currently works around it with attachCustomKeyEventHandler.

Dominant language
TypeScript
Stars
2.9k
Forks
182
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from coder/ghostty-web

All issues in coder/ghostty-web

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.