Skip to content

Feature request: OSC 52 escape sequence support for remote/tmux clipboard #288

@bpiwowar

Description

@bpiwowar

Summary

It would be great if pyperclip could support OSC 52 escape sequences as a fallback clipboard mechanism. This would enable clipboard operations to work in remote terminal sessions (SSH, tmux, screen) where traditional clipboard mechanisms fail.

Problem

Currently, pyperclip doesn't work when running Python applications over SSH or inside tmux/screen, because:

  • X11 clipboard requires $DISPLAY or X forwarding
  • Wayland clipboard requires a local session
  • macOS pbcopy isn't available on remote Linux hosts

Many terminal-based applications (TUIs) need clipboard support that works in these remote scenarios.

Proposed Solution

OSC 52 is an escape sequence that tells the terminal emulator to copy text to the system clipboard. It works:

  • Through SSH connections
  • Inside tmux (with set -g set-clipboard on and set -g allow-passthrough on)
  • Inside screen
  • In most modern terminals: iTerm2, kitty, alacritty, Windows Terminal, WezTerm, foot, etc.

The escape sequence format is:

ESC ] 52 ; c ; <base64-encoded-text> ESC \

For tmux, it needs to be wrapped in a DCS passthrough:

ESC P tmux ; <escaped-osc52> ESC \

Example Implementation

Here's a minimal implementation that could be added as a fallback – I use it there in my project, and I confirm this worked when connected via SSH (with tmux or not) – I am using iterm (macOS):

import base64
import os
import sys

def _copy_osc52(text: str) -> bool:
    try:
        encoded = base64.b64encode(text.encode("utf-8")).decode("ascii")
        osc52 = f"\033]52;c;{encoded}\033\\"
        
        # Wrap for tmux passthrough
        if os.environ.get("TMUX"):
            escaped = osc52.replace("\033", "\033\033")
            sequence = f"\033Ptmux;{escaped}\033\\"
        else:
            sequence = osc52
        
        # Write to tty
        try:
            with open("/dev/tty", "w") as tty:
                tty.write(sequence)
                tty.flush()
        except OSError:
            sys.stdout.write(sequence)
            sys.stdout.flush()
        
        return True
    except Exception:
        return False

Suggested Behavior

OSC 52 could be used as a last-resort fallback when all other mechanisms fail, or optionally as a preferred mechanism when running in a terminal (detected via $TERM, $TMUX, etc.).

References

Thank you for maintaining pyperclip!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions