Skip to content

fix(tui): clipboard copy on Linux without external binaries - #44394

Closed
fQwQf wants to merge 5 commits into
anomalyco:devfrom
fQwQf:fix/tui-linux-clipboard
Closed

fix(tui): clipboard copy on Linux without external binaries#44394
fQwQf wants to merge 5 commits into
anomalyco:devfrom
fQwQf:fix/tui-linux-clipboard

Conversation

@fQwQf

@fQwQf fQwQf commented Aug 23, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #29834
Closes #24713
Closes #41470

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

On Linux, copy silently fails when no external tool (wl-copy/xclip/xsel) is installed and the terminal ignores OSC 52 (e.g. GNOME Terminal/VTE). The toast says "Copied to clipboard" but nothing is copied, because clipboardy's bundled xsel fallback doesn't exist inside the compiled binary and every failure is swallowed by .catch(() => undefined).

Changes:

  • New pure-JS X11 selection owner (src/clipboard/x11.ts, via the x11 package, no native code). It claims the CLIPBOARD selection and serves paste requests for the TUI's lifetime. On Wayland this works through XWayland, and the compositor keeps the content after exit.
  • write() now picks backends by environment instead of trying everything: SSH sessions only use tmux/OSC 52 (native clipboard on the remote host is useless); local Linux tries the X11 owner, then any installed tools, then OSC 52. If every backend fails, the error is thrown so the UI shows a real error instead of a false success.
  • OSC 52 now writes to /dev/tty when stdout isn't a TTY and caps payloads at 100 KB.
  • read() gets the same pure-JS X11 fallback for text.

How did you verify your code works?

  • bun test packages/tui/test/clipboard.test.ts (6 backend-routing cases) and the full tui suite pass; monorepo typecheck passes (pre-push hook).
  • Manually on Debian 13, GNOME Terminal , Wayland, with no clipboard tools installed: copied text pastes into other apps. Verified with a standalone bun --compile binary, the setup where it previously failed.
  • Reviewer repro: on a similar machine, build with ./packages/opencode/script/build.ts --single, copy a message in the TUI, paste elsewhere.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

fQwQf added 5 commits August 19, 2026 10:24
Implements an ICCCM selection owner over the X11 protocol using the
pure-JS x11 package, requiring no external binaries (wl-copy/xclip/xsel)
and surviving bundling into the compiled binary. Works on native X11 and
on Wayland via XWayland, where the compositor bridges the CLIPBOARD
selection to the Wayland clipboard and persists it after process exit.

The connection is kept alive for the TUI lifetime (same ownership
semantics as codex's ClipboardLease) so paste requests can be served.
Large payloads are written with chunked ChangeProperty appends.
Model the copy path after codex's clipboard_copy.rs:

- SSH sessions only use terminal-mediated copy (tmux load-buffer -w, or
  OSC 52), since a native clipboard on the remote host is unreachable.
- Local Linux sessions prefer the pure-JS X11 selection owner, then any
  installed external tools, then OSC 52.
- Backend failures are collected and thrown instead of being swallowed,
  so the UI shows an error instead of a false 'Copied to clipboard'
  toast (fixes silent failures like anomalyco#29834, anomalyco#24713, anomalyco#41470).
- OSC 52 writes to /dev/tty when stdout is not a TTY and caps payloads
  at 100KB, matching codex.
- read() gains a pure-JS X11 text fallback instead of relying on
  clipboardy's bundled xsel binary, which is absent from the compiled
  binary.
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Based on my search, I found several related PRs that address clipboard functionality on Linux:

Related PRs:

  1. fix(tui): surface clipboard write failures instead of false success #41924 - fix(tui): surface clipboard write failures instead of false success

  2. fix: enable primary clipboard copy for Wayland/X11 to fix Linux middle-click paste #6370 - fix: enable primary clipboard copy for Wayland/X11 to fix Linux middle-click paste

    • Related to X11/Wayland clipboard handling on Linux
  3. feat(tui): add linux_clipboard_selection config for primary buffer support #32370 - feat(tui): add linux_clipboard_selection config for primary buffer support

    • Related to Linux clipboard selection configuration
  4. fix(clipboard): write OSC52 to /dev/tty instead of stdout #12129 - fix(clipboard): write OSC52 to /dev/tty instead of stdout

The most relevant is #41924 which appears to address the same issue of surfacing clipboard failures. You should verify if #44394 builds on or replaces that work, or if they address different aspects of the same problem.

@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference, author can ignore or act on any point.

Diff too large for automated batch review (6 changed files, +3591/-3276) — recommending manual human review.

@simonklee

Copy link
Copy Markdown
Member

This has been fixed in the next version of OpenCode.

@simonklee simonklee closed this Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants