fix(tui-v2): copy via native clipboard, OSC 52 only over SSH (#581)

Ctrl+C / selection copy fell back to Textual's OSC 52 escape on Windows/Linux.
Some terminals (notably VSCode's integrated terminal) decode the OSC 52 base64
payload as latin-1 instead of UTF-8, so non-ASCII copied text lands in the
clipboard as mojibake (e.g. 需要 -> éè¦). Classic Windows conhost ignores
OSC 52 clipboard writes entirely, so copy was a silent no-op there (incl.
Windows Server).

Prefer the OS-native clipboard (_copy_to_clipboard: win32 CF_UNICODETEXT /
pbcopy / wl-copy / xclip), which writes real Unicode and bypasses the terminal.
Keep OSC 52 only as a fallback, and force it under SSH (SSH_CONNECTION /
SSH_TTY) where the native call would write the remote host's clipboard instead
of the user's local one.
This commit is contained in:
nianyucatfish authored and GitHub committed 2026-06-08 10:47:29 +08:00
1 parent 8ec764a87e
commit da6a4ba558
1 file changed
+4 -11
+4 -11
View File
@@ -3025,17 +3025,10 @@ class GenericAgentTUI(App[None]):
self._refresh_all()
def copy_to_clipboard(self, text: str) -> None:
"""Override Textual's OSC 52 clipboard (broken on macOS Terminal.app).
Use pbcopy on macOS, fall back to OSC 52 on other platforms."""
import sys, subprocess as _sp
if sys.platform == "darwin":
try:
_sp.Popen(["pbcopy"], stdin=_sp.PIPE, stdout=_sp.DEVNULL, stderr=_sp.DEVNULL).communicate(text.encode("utf-8"))
self._clipboard = text
return
except Exception:
pass
# Non-macOS or pbcopy failed: fall back to Textual default (OSC 52)
self._clipboard = text
_ssh = os.environ.get("SSH_CONNECTION") or os.environ.get("SSH_TTY")
if not _ssh and _copy_to_clipboard(text):
return
super().copy_to_clipboard(text)
def action_handle_ctrl_c(self) -> None: