🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

fix(site): add a custom copy/paste menu to the web terminal - #26015

Merged
jaaydenh merged 8 commits into
mainfrom
codagt-415/windows-terminal-context-menu
Jun 11, 2026
Merged

fix(site): add a custom copy/paste menu to the web terminal#26015
jaaydenh merged 8 commits into
mainfrom
codagt-415/windows-terminal-context-menu

Conversation

@jaaydenh

@jaaydenh jaaydenh commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes CODAGT-415.

Right-clicking selected text in the web terminal on Windows (and Linux) showed
the browser's image actions ("Copy image", "Save image as") instead of
copy/paste. The terminal uses xterm.js with the canvas/WebGL renderer, so the
underlying element is a <canvas>, which Chromium and Firefox treat as an
image. xterm.js tries to retarget the menu by moving a hidden textarea under
the cursor, but on Windows and Linux the browser's own non-native context menu
locks onto the canvas before that workaround lands.

Change

Wrap the terminal in the shared Radix ContextMenu so right-click shows a
custom Copy / Paste menu instead of the browser default:

  • Copy reuses the existing copy-on-select clipboard path (getSelection()
    • copyToClipboard). It is disabled when there is no selection.
  • Paste reads the clipboard and uses xterm's paste(), which respects
    bracketed-paste mode.
  • The menu is gated to non-macOS (disabled={isMac()} on the trigger). macOS
    renders native context menus that already expose working copy/paste across
    Chrome, Firefox, and Safari, so its default is left untouched.

Platform scope

Platform Behavior
Windows (Chromium / Firefox) Custom Copy/Paste menu (fixes the bug)
Linux (Chromium / Firefox) Custom Copy/Paste menu
macOS (Chrome / Firefox / Safari) Native menu preserved (already works)

Testing

  • TerminalPage.test.tsx: on non-macOS, right-click suppresses the native menu
    and shows the Copy/Paste menu; on macOS the native menu is preserved.
  • TerminalPage.stories.tsx: new RightClickMenu story opens the menu via a
    play function for real-browser and visual coverage.
  • tsc, biome, and make pre-commit (gen/fmt/lint/build) pass locally.
Decision log
  • The issue was originally reported as Windows-only. Hands-on testing confirmed
    macOS is not affected: Chrome, Firefox, and Safari on macOS all show a working
    copy/paste menu. The difference is the menu implementation: macOS uses native
    OS context menus (which pick up xterm's repositioned textarea), while
    Chromium/Firefox on Windows and Linux draw their own menu that targets the
    <canvas> directly.
  • Root cause is the canvas/WebGL renderer plus the unreliability of xterm's
    textarea-repositioning workaround on non-native menus, not the operating
    system itself.
  • A custom menu (rather than just preventDefault) was chosen so users keep an
    explicit copy/paste affordance on the affected platforms. A bare
    preventDefault removes the menu entirely.
  • Scope is gated to non-macOS to avoid regressing the working native menu on
    macOS. Rejected alternatives: suppressing/replacing on all platforms (regresses
    macOS), and Windows-only (misses Linux, which shares the same non-native menu).

Generated by Coder Agents on behalf of @jaaydenh.

Chromium-based browsers on Windows show image actions like "Copy
image" or "Save image as" when right-clicking on the xterm.js
canvas/WebGL renderer, because the underlying <canvas> is treated as
an image. xterm.js mitigates this by repositioning its hidden helper
textarea under the cursor on contextmenu, but the workaround does not
reliably retarget the menu on Windows.

Intercept contextmenu on Windows and call preventDefault so the
misleading menu never appears. Copy still works via selection (which
writes to the clipboard automatically) and Ctrl+Shift+C; paste still
works via Ctrl+V.

Fixes CODAGT-415.
Right-clicking the canvas/WebGL terminal renderer on Windows and Linux
showed the browser's image actions ("Copy image", "Save image as")
because the underlying element is a <canvas>. xterm.js tries to retarget
the menu by moving a hidden textarea under the cursor, but Chromium and
Firefox on Windows and Linux render their own non-native menu that locks
onto the canvas before that workaround lands.

Wrap the terminal in the shared Radix ContextMenu so right-click shows a
custom Copy/Paste menu instead. macOS renders native context menus that
already expose working copy/paste, so the custom menu is disabled there
(isMac) and the browser default is preserved.

Copy reuses the existing copy-on-select clipboard path; Paste reads the
clipboard and uses xterm's bracketed-paste-safe paste().
@jaaydenh jaaydenh changed the title fix(site): suppress browser context menu on Windows web terminal fix(site): add a custom copy/paste menu to the web terminal Jun 9, 2026
…rminal-context-menu

# Conflicts:
#	site/src/modules/terminal/WorkspaceTerminal.tsx
@jaaydenh

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 526d72f6c6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/TerminalPage/TerminalPage.test.tsx Outdated
jaaydenh added 2 commits June 10, 2026 07:35
…orybook

site/AGENTS.md reserves plain vitest files for pure logic and requires
page/component UI behavior to be covered by Storybook stories. The
right-click copy/paste menu behavior is already exercised by the
RightClickMenu play function, so remove the duplicated vitest coverage
from TerminalPage.test.tsx.

Copy link
Copy Markdown
Contributor Author

@codex review

Requested by Coder Agents on behalf of @jaaydenh.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b8ffc65092

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/modules/terminal/WorkspaceTerminal.tsx Outdated
…ads are unavailable

On insecure contexts such as plain HTTP deployments, navigator.clipboard
is undefined, so the custom right-click Paste could only fail into the
catch/toast. Only render the Paste item when navigator.clipboard.readText
is available. Keyboard paste (Ctrl+V) still works via xterm's own paste
handling in those deployments.

Copy link
Copy Markdown
Contributor Author

@codex review

Requested by Coder Agents on behalf of @jaaydenh.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@jaaydenh
jaaydenh marked this pull request as ready for review June 10, 2026 08:39
@jaaydenh
jaaydenh requested a review from DanielleMaywood June 10, 2026 08:39
return;
}
try {
const text = await navigator.clipboard.readText();

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.

We have useClipboard which returns { copyToClipboard }. Could we extend that to { copyToClipboard, readFromClipboard }?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added readFromClipboard

@jaaydenh

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e16b4e13de

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/hooks/useClipboard.ts Outdated
readFromClipboard previously caught every navigator.clipboard.readText
rejection and returned the cached copy, so a denied permission in a
secure context could silently paste a stale selection. Only fall back to
the cached value when the clipboard cannot be read (insecure context or
unsupported browser) and let secure-context read failures reject so the
caller can surface them.

Copy link
Copy Markdown
Contributor Author

@codex review

Generated by Coder Agents on behalf of @jaaydenh.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@jaaydenh
jaaydenh merged commit 5ab25b3 into main Jun 11, 2026
29 checks passed
@jaaydenh
jaaydenh deleted the codagt-415/windows-terminal-context-menu branch June 11, 2026 08:12
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 11, 2026
@Shelnutt2 Shelnutt2 added cherry-pick cherry-pick/v2.34 Cherry-pick PR targeting release/2.34 labels Jun 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

backport cherry-pick/v2.34 Cherry-pick PR targeting release/2.34 cherry-pick

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants