Skip to content

fix(web): Ctrl+C and terminal links work on Windows - #7698

Closed
ArjandenHartog wants to merge 3 commits into
pingdotgg:mainfrom
ArjandenHartog:fix/windows-terminal-copy-and-links
Closed

ArjandenHartog wants to merge 3 commits into
pingdotgg:mainfrom
ArjandenHartog:fix/windows-terminal-copy-and-links

Conversation

@ArjandenHartog

@ArjandenHartog ArjandenHartog commented Aug 20, 2026 •

Copy link
Copy Markdown

What Changed

  • Terminal copy now parks the Ghostty selection in the hidden IME textarea and only claims the native copy event when clipboardData is actually writable, so Ctrl+C/Cmd+C copies the selected text instead of a blank clipboard.
  • Electron Edit → Copy can fire without a prior keydown. The deferred copy path now primes the textarea with the current selection before the default action runs.
  • The desktop Edit menu no longer registers Cut/Copy/Paste/Select All accelerators. Those chords reach the renderer, so Ctrl+C can SIGINT in a WSL terminal when nothing is selected, and Ctrl+A is beginning-of-line again.
  • Ctrl/Cmd-click on a public http(s) terminal link opens immediately in the browser that already has T3 Code open, via a same-tick <a target="_blank"> click. Desktop still intercepts _blank through openExternal.
  • Loopback URLs (localhost, 127.0.0.1, ::1, 0.0.0.0) open the in-app preview panel again, without an async preview-vs-browser menu.

Why

On Windows (including a WSL terminal) Ctrl+C was eaten by native copy of the empty textarea, so people had to use Ctrl+Shift+C. That chord is also Chrome/Electron Inspect, so it does not work well.

Clicking a printed URL waited on an async preview-vs-browser menu. window.open after that menu is popup-blocked, and openExternal leaves the current browser for the OS default. Opening public URLs during the click keeps the tab in the browser you already have open. Preview does not need that user gesture, so loopback links can still land in the right panel.

Fixes #7677. Also addresses the Windows symptoms in #6173, #5917, and #5702.

UI Changes

No visual chrome change. Keyboard copy/interrupt and modifier-click link opening are interaction-only.

Terminal with a public URL and a loopback URL recognized as links:

Terminal URLs

Selection plus Copy in the terminal context menu. Ctrl+C on that selection copied the highlighted echo line in a web session:

Terminal selection and Copy

Headless Chrome could not capture a new host-browser tab or the in-app preview panel after Ctrl+click. Those paths are covered by unit tests.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Fix terminal Ctrl+C copy and link opening on Windows by letting renderer own clipboard accelerators

  • Replaces Electron's default { role: "editMenu" } with a custom desktopEditMenu(platform) that sets registerAccelerator=false on all Edit roles, so the renderer handles clipboard shortcuts instead of Electron. Adds a Speech submenu on macOS.
  • Adds clipboard priming in GhosttyTerminalSurface: primeTerminalCopyInput writes the terminal selection into the hidden textarea so native copy (keyboard or Edit menu) produces non-empty text. applyTerminalCopyEvent claims copy events via clipboardData and falls back to document.execCommand("copy"). Primed content is cleared before key encoding (except during IME composition) to avoid leaking to the PTY.
  • Adds openUrlInHostBrowser to open http(s) links via a synchronous _blank anchor click (rejecting non-http schemes), and canOpenTerminalLinkInPreview to restrict in-app preview to loopback URLs. Refactors openTerminalLinkInPreview to skip the context-menu prompt and deterministically preview or fall back to the browser.
  • Behavioral Change: shell.openExternal in createBrowserLocalApi now rejects non-http(s) URLs with an error instead of passing them to window.open; terminal http(s) links no longer show a context-menu choice.

Macroscope summarized f10b1ea.

The Ghostty IME textarea is empty, so native copy wrote a blank clipboard
and Electron's Edit menu stole Ctrl+C before SIGINT could reach the PTY.
Ctrl+click also waited on a preview menu, so window.open was popup-blocked
and left the current browser. Prime the selection, let the renderer own
Edit accelerators, and open http links with a same-tick _blank click.

Made with Cursor Grok 4.6
@coderabbitai

coderabbitai Bot commented Aug 20, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 50609b97-7281-45a1-b909-eacf584dc5de

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 20, 2026
Comment thread apps/web/src/terminal/ghostty/surface.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the terminal link path now bypasses the in-app preview panel for loopback URLs. Everything else in the changed web files (the new openUrlInHostBrowser helper, localApi browser branch, and the Ghostty copy priming) stays inside the existing owners and introduces no shared-primitive, Tailwind-ownership, or theming problems.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/ThreadTerminalDrawer.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 20, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR makes significant behavioral changes to terminal clipboard handling and link opening: removes the context menu for terminal links, introduces new clipboard 'priming' for copy operations, and changes how Edit menu accelerators are processed. These runtime behavior changes warrant human review.

You can add or adjust custom eligibility rules. Learn more.

Electron Edit Copy can fire without a prior keydown, so the deferred copy path now primes the Ghostty selection. Loopback links open the in-app preview again without an async menu; public URLs still open in the current browser on the same click.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ArjandenHartog

Copy link
Copy Markdown
Author

Follow-up for the Macroscope notes is in 074db33.

Screenshots from a web session (WSL). Ctrl+C on a Ghostty selection copied the highlighted echo line into the clipboard. Headless Chrome could not show a new host-browser tab or the in-app preview panel after Ctrl+click (no new window event, and localhost:5173 was not a live preview target).

Terminal with public and loopback links:

Terminal URLs

Selection plus the Copy context menu:

Terminal selection and Copy

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding in the terminal surface keyboard path: the new unconditional textarea clear on keydown runs before the IME/composition early-return, so it can wipe an in-progress composition preedit. Inline comment with a suggested guard below. Nothing else in the changed web UI scope (no styling, primitive, or theme changes) raised a consistency concern; the link routing now keeps loopback URLs in the in-app preview, and the preview address bar still exposes "Open in system browser".

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/terminal/ghostty/surface.ts Outdated
Copy priming parks selection text in the Ghostty textarea. Clearing that field on every later keydown also wiped an in-progress composition, so skip the clear while IME is active.

Co-authored-by: Cursor <cursoragent@cursor.com>
@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of the open-PR backlog sweep (wave 1).

Reason: Windows Ctrl+C/blank clipboard already fixed on main
Related: #7678

Reopen if this is still wanted and you’re willing to rebase onto current main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: terminal Cmd+C copies blankness from an empty IME textarea

2 participants