Low-brow clipboard integration with remote X

Sunday, 11 Feb 2024

This is another one of those small-lightbulb moments like this one was. The setup for this one is that I run some X programs on my home server for remote use from the machine I actually work on – but via VNC, where I never got clipboard integration working.1 I only rarely need to paste in X, so I’ve just been living with this… until the obvious recently occcured to me:

The low-brow but perfectly serviceable solution is to just use the clipboard commands of both systems, strung together with a pipe over a SSH connection. Of course this needs to be done manually to transfer the clipboard every single time I copy something on one side and want to paste it on the other – the low-brow bit. But it is far more convenient than pasting into terminals like I was doing before, to the point I won’t feel the lack any more.

Only… it didn’t quite work right.

I searched the web for a fix and unsurprisingly found that plenty of people have had the same idea:

# copy in X, run this, then paste locally
ssh server.home xclip -selection clipboard -out | pbcopy

(If you’re not using a Mac locally, just replace pbcopy (and pbpaste) with your system’s equivalent.)

The trouble is, I was looking for the other direction – and far from novel though the idea may be, I didn’t find a command written up anywhere. There turns out to be a minor trick to it (and maybe that’s why), which I ultimately had to figure out for myself:

# copy locally, run this, then paste in X
pbpaste | exec ssh server.home 'exec xclip -selection clipboard &> /dev/null'

Namely, this won’t work as desired without the “&> /dev/null” bit.

It will work, except without returning to the prompt. It just hangs. This comes down to the way that selections work in X: the program the selected content came from must grab that selection and then answer requests to paste it – no program, no paste. So the only way xclip can work is to stick around as a background process after putting something on the clipboard – until something else is copied, then it can exit. And because xclip doesn’t close stdout and stderr, ssh won’t know to quit any sooner than that, so it sits there waiting. To create a compound command that immediately returns to the prompt after shipping over the local clipboard contents, it is therefore necessary to close stdout and stderr on xclip explicitly.

With that, I have a solution I can happily live with.2


  1. This is after trying all the usual suggestions (like running vncconfig on the server). Presumably they didn’t work because I am using the Screen Sharing app that comes with MacOS, which apparently is not actually a VNC client but just uses that protocol for most of its functionality.

    The backstory to that is that I used to use Xpra for remote X because it makes that rather neat: individual windows on the server are displayed remotely as individual windows on the client, complete with native local windowing UI, so there is none of the ungainly window-in-window hassle and no need for an X window manager. The catch is that Xpra requires reasonably matching versions on server and client, and I have at times fallen well behind running the latest OS version on either side, which on a few occasions has made them tricky to align. A while ago I failed to find any working constellation at all, at which point I decided I was tired of doing that and would switch to something less bespoke. Now I no longer need to install anything on the Mac and have multiple highly compatible options on the server.

  2. Or maybe I’ll go back to Xpra, who knows…