fix(tui): clipboard copy on Linux without external binaries - #44394
fix(tui): clipboard copy on Linux without external binaries#44394fQwQf wants to merge 5 commits into
Conversation
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.
|
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:
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. |
Diff too large for automated batch review (6 changed files, +3591/-3276) — recommending manual human review. |
|
This has been fixed in the next version of OpenCode. |
Issue for this PR
Closes #29834
Closes #24713
Closes #41470
Type of change
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:
src/clipboard/x11.ts, via thex11package, 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./dev/ttywhen 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).bun --compilebinary, the setup where it previously failed../packages/opencode/script/build.ts --single, copy a message in the TUI, paste elsewhere.Screenshots / recordings
N/A
Checklist