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, to transfer the clipboard contents. Of course this needs to be invoked manually every single time I want to copy something on one side and paste it on the other – the low-brow bit. But that still is far more convenient than pasting into terminals (like I was doing before), to the point that 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:

# perform a copy in X, then 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 my searches were coming up empty), which ultimately I had to figure out for myself:

# perform a copy locally, then 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 in which content was selected registers itself to answer requests to paste that selection and must then answer them – so no running program, no paste. So the only way xclip can work is to stick around as a background process after taking control the clipboard – until something else is copied, at which point it can exit. And because xclip doesn’t close stdout and stderr, ssh won’t know to quit any sooner than that, and so it sits there waiting. To create a compound command that immediately returns to the prompt after shipping the local clipboard contents over, 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…