7

tmux can put text into the system clipboard using ANSI OSC (Operating System Control) 52 escape sequences, but the terminal emulator needs to recognize them. xfce4-terminal, out-of-the-box doesn't seem to recognize them. Would anybody know how to configure xfce4-terminal to recognize these OSC 52 sequences ?

I've read here that gnome-terminal can't recognize them, so I started to suspect that xfce4-terminal might not too, but couldn't find info anywhere about it.

I'm running Xubuntu 17.10 with xfce4-terminal 0.8.6.

1 Answers1

1

VTE does not support OSC52.

Work-around, make a wrapper that creates a terminal passthrough, detects osc52 and then uses Xorg clipboard. Example: save it as osc52detect.py

#!/usr/bin/env python

import os import pty import select import subprocess import sys import termios import tty import signal import struct import fcntl import re import base64

OSC52_PATTERN = re.compile(rb'\x1b]52;c;(.*?)\x07') log_file = open('osc52_log.txt', 'w')

def callback(plaintext): try: # Copy to X clipboard process = subprocess.Popen(['xclip', '-selection', 'clipboard'], stdin=subprocess.PIPE) process.communicate(plaintext.encode('utf-8'))

    # Also copy to primary selection
    process = subprocess.Popen(['xclip', '-selection', 'primary'], stdin=subprocess.PIPE)
    process.communicate(plaintext.encode('utf-8'))

    log_file.write(f"Copied to clipboard: {plaintext}\n")
except Exception as e:
    log_file.write(f"Failed to copy to clipboard: {e}\n")
log_file.flush()

def detect_osc52(data): matches = OSC52_PATTERN.findall(data) for match in matches: try: decoded = base64.b64decode(match).decode('utf-8') callback(decoded) except: log_file.write(f"Failed to decode OSC52 sequence: {match}\n") log_file.flush() return data

def set_winsize(fd, row, col, xpix=0, ypix=0): winsize = struct.pack("HHHH", row, col, xpix, ypix) fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize)

def get_terminal_size(): size = os.get_terminal_size() return size.lines, size.columns

def main(): old_tty = termios.tcgetattr(sys.stdin) try: tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno())

    master, slave = pty.openpty()

    rows, cols = get_terminal_size()
    set_winsize(slave, rows, cols)

    p = subprocess.Popen(["bash"], stdin=slave, stdout=slave, stderr=slave, preexec_fn=os.setsid)

    while p.poll() is None:
        rlist, _, _ = select.select([sys.stdin, master], [], [], 0.1)

        if sys.stdin in rlist:
            data = os.read(sys.stdin.fileno(), 1024)
            os.write(master, data)

        if master in rlist:
            data = os.read(master, 1024)
            data = detect_osc52(data)
            os.write(sys.stdout.fileno(), data)

except Exception as e:
    log_file.write(f"An error occurred: {e}\n")
finally:
    termios.tcsetattr(sys.stdin, termios.TCSAFLUSH, old_tty)
    log_file.close()

if name == "main": main()

then do

chmod +x osc52detect.py
./osc52detect.py

Assuming you use bash, now everytime we receive osc52 we call xclip manually, yay! this works assuming you use xorg, but if you dont just change the callback!

If you can't install xclip, you can use https://pkgs.pkgforge.dev/repo/bincache/x86_64-linux/xclip/xclip/ which is static xclip.

Or you could just use something like wezterm.

Rainb
  • 111