Clipboard¶
Status: xterm.
OSC 52 lets an application write to, and in principle read from, the system clipboard or selection through the PTY. It is the only clipboard mechanism that works over SSH without a forwarded display, which makes it both widely used and widely restricted.
Window Ops: xterm gates OSC 52 reads with GetSelection and writes
(including clears) with SetSelection. Both are denied by default. See the
Window Ops policy for the permission rules.
Syntax¶
OSC 52 ; Pc ; Pd ST
Pc names one or more targets; Pd is base64-encoded data, or ? to query.
Pc |
Target |
|---|---|
c |
Clipboard |
p |
Primary selection (X11, Wayland) |
q |
Secondary selection |
s |
Select (xterm's configurable selection, usually primary) |
0–7 |
Cut buffers 0–7 (X11 only) |
Several letters may be combined: cp writes both clipboard and primary. An
empty Pc means s0 in xterm. Non-X11 emulators treat everything except
c (and often p) as the clipboard.
printf '\033]52;c;%s\033\\' "$(printf 'hello' | base64)"
An empty Pd clears the selection. Invalid base64 is ignored.
Behavior¶
Writes¶
The write is applied by the emulator, not the application, so it works through SSH and inside containers as long as every hop forwards the OSC. Payload limits differ: xterm truncates at its OSC buffer, tmux at 100 KiB unless raised, kitty and foot accept several megabytes. Emulators that reject an oversized write generally do so silently.
Reads¶
OSC 52 ; c ; ? ST asks the emulator to reply with
OSC 52 ; c ; base64 ST. The reply arrives as input, so any program that
can write to the terminal can read the user's clipboard, including passwords
in a password manager's clipboard. Most emulators therefore refuse reads by
default, and many refuse them without any configuration to enable them.
Applications should treat a read as best-effort with a timeout, and should never depend on it for correctness.
Multiplexers¶
tmux intercepts OSC 52 and, with set-clipboard on, both updates its own
paste buffer and forwards the write to the outer terminal using the
Ms terminfo capability. With set-clipboard external it forwards only;
with off it drops the sequence. A read query is answered by tmux from its
own buffer only when set-clipboard on. screen does not implement OSC 52;
use DCS passthrough.
Probe¶
tools/sendosc copy 'TDN clipboard probe'
printf '\033]52;c;%s\033\\' "$(printf 'TDN clipboard probe' | base64)"
printf '\033]52;c;?\033\\' # read; expect a reply, a prompt, or silence
Paste into another application after the first command. Use
tools/query to capture any reply to the third.
Sources¶
- XTerm Control Sequences, OSC 52
- kitty: clipboard_control
- Ghostty: clipboard-read, clipboard-write
- foot.ini(5)
- WezTerm escape sequences, OSC 52
- Windows Terminal 1.16 release notes
- iTerm2 preferences, clipboard
- @xterm/addon-clipboard
- mintty control sequences
- tmux(1), set-clipboard
Separately tracked behavior¶
OSC 52 multiple targets¶
Feature ID: osc-52-multiple-targets. Accept a list of selection letters rather than only one target.
OSC 52 default targets¶
Feature ID: osc-52-default-targets. Apply xterm selection defaults when the target field is empty.
OSC 52 cut-buffer targets¶
Feature ID: osc-52-cut-buffers. Honor the cut-buffer digits and target letters without folding them into CLIPBOARD.
OSC 52 invalid-data handling¶
Feature ID: osc-52-invalid-base64-clear. Match xterm selection clearing for invalid base64 rather than silently ignoring it.
OSC 52 reply target encoding¶
Feature ID: osc-52-reply-target. Match the requested target spelling in selection replies.
Kitty clipboard protocol¶
Feature ID: osc-5522-clipboard. Separate clipboard extension, outside the current dispatch queue.
Compatibility¶
Choose terminals
| Feature / stable ID | Alacritty | Apple Terminal | ConPTY (conhost) | Contour | DomTerm | foot | Ghostty | iTerm2 | kitty | Konsole | mintty | mlterm | PuTTY | Revenant | RLogin | st | tmux | rxvt-unicode | VTE | wayst | WezTerm | Windows Terminal | xterm | xterm.js |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
OSC 52 writeosc-52-write |
SupportedImported · unverified | UnknownImported · unverified | Unknown | SupportedImported · unverified | Unknown | SupportedImported · unverified | SupportedImported · unverified | SupportedImported · unverified | SupportedImported · unverified | SupportedImported · unverified | SupportedImported · unverified | Unknown | UnknownImported · unverified | Partial | Unknown | Unknown | SupportedImported · unverified | Unknown | SupportedImported · unverified | Unknown | SupportedImported · unverified | SupportedImported · unverified | SupportedImported · unverified | PartialImported · unverified |
OSC 52 readosc-52-read |
UnknownImported · unverified | UnknownImported · unverified | Unknown | UnknownImported · unverified | Unknown | SupportedImported · unverified | SupportedImported · unverified | UnknownImported · unverified | SupportedImported · unverified | UnknownImported · unverified | SupportedImported · unverified | Unknown | UnknownImported · unverified | Partial | Unknown | Unknown | PartialImported · unverified | Unknown | UnknownImported · unverified | Unknown | UnknownImported · unverified | UnknownImported · unverified | SupportedImported · unverified | PartialImported · unverified |
Clipboard and selection accessosc-52-selection-access |
Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
OSC 52 multiple targetsosc-52-multiple-targets |
Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
OSC 52 default targetsosc-52-default-targets |
Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
OSC 52 cut-buffer targetsosc-52-cut-buffers |
Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
OSC 52 invalid-data handlingosc-52-invalid-base64-clear |
Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
OSC 52 reply target encodingosc-52-reply-target |
Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
Kitty clipboard protocolosc-5522-clipboard |
Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |