xclipglue
xclipglue
– unify a set of X11 selections between two X displays
xclipglue [options] display
xclipglue [options] -remote command [argument...]
xclipglue [options] -stdio
xclipglue
connects to two X displays, and propagates X selection operations between them in both directions. In normal use, it tries to give the illusion that there is a single PRIMARY
selection common to both displays, and a single common CLIPBOARD
as well – it ‘glues together’ the selections on the two displays.
In other words, once you have xclipglue
running, you can drag to select in one window and then middle-click to paste in another, without having had to worry about whether the two windows were on the same X display or on different ones. Similarly, you can copy to the XDG clipboard (e.g. via a keystroke like Ctrl-C in many applications) in one X display, and paste (e.g. Ctrl-V) in the other.
If the two X displays are both accessible to the same user account on the same machine, you can run xclipglue
in the simplest possible way. For example, if you've started an auxiliary X display like Xephyr
(1) as the display :1
, then you could run this command (on your normal display, typically :0
):
xclipglue :1
and as long as xclipglue
stays running, you should be able to copy and paste between the inside and outside of your Xephyr
without having to keep thinking about the fact that it's a separate X display.
The way xclipglue
really works is that it's two processes. Each one talks to an X display at one end, and speaks a bidirectional text protocol at the other end. So the above command really runs two xclipglue
processes, one connected to each X display, and connects them with a pair of pipes that send selection requests back and forth encoded in the xclipglue
protocol (documented below).
So another thing you can use it for is to glue together the selections of two X displays that are not running on the same machine. For example, if you're accessing a remote X display using VNC, and you're unsatisfied with VNC's own less featureful clipboard propagation (not supporting multiple selections or variable data types), you could dispense with the vncconfig
program that does the default propagation, and set up a remote xclipglue
between the two displays instead.
For this, you'd typically start xclipglue
on one machine with the -remote
option, and provide it with a command line it can run to set up another xclipglue
running on the other machine. That second xclipglue
should be launched with the -stdio
option, which will make it speak the xclipglue
protocol on its standard input and output. For example, if you can connect from one machine to the other using SSH, you might run a command like this:
xclipglue -remote ssh otherhost xclipglue -display :1 -stdio
in which everything after remote
is the command that runs a remote xclipglue
on the other machine.
xclipglue
can run in one of three main modes. You must specify exactly one of them.
xclipglue
forks into two processes. One connects to the X display specified in $DISPLAY
(overridden by the -display
option if you gave it). The other connects to the X display given as a command-line argument. The two processes talk to each other by pipes. The effect is to unify the selections between your default X display and the one you specified on the command line. For example, ‘xclipglue :1
’ unifies $DISPLAY
(typically :0
) with :1
). Or ‘xclipglue -display :10 :11
’ unifies :10
with :11
.
-remote
followed by a command
xclipglue
starts a child process running the command you specified, and expects the child process to speak the xclipglue
protocol on its standard input and output. It's up to you to specify a command which will have that effect. A typical one would be to make an SSH connection to another machine and run xclipglue -stdio
at the far end, but other possibilities exist.
-stdio
xclipglue
will simply speak its textual protocol on its own standard input and output channels. Usually you'd run xclipglue
in this mode as part of the remote command given to a parent instance of xclipglue
in remote mode. But other possibilities exist. For example, you could simply use an xclipglue
in stdio mode as a convenient server to access a single X selection programmatically, by speaking its protocol directly (which is at least somewhat less complicated than the full X11 protocol).
-display
x-display
xclipglue
will connect to. By default this is given by the $DISPLAY
environment variable.
In remote mode and stdio mode, this will be the only display that this instance of xclipglue
connects to. In double-display mode, this is the display that the parent process connects to; the child process will connect to the one given as a bare command-line argument (see above).
-s
selection [-s
selection...]
If you do not specify this option at all, the default behaviour is to unify the PRIMARY
and CLIPBOARD
selections.
-active
, -passive
xclipglue
unifies a pair of selections on two X displays, the effect is that on one of the displays the previous contents of the selection is destroyed, and replaced with the contents of that selection on the other display. The xclipglue
that imposes its current selection contents on the far end at startup is said to be in ‘active mode’, and the xclipglue
that lets its initial selection contents be superseded by the remote end is in ‘passive mode’.
So, when you start up a pair of xclipglue
processes, it's important to arrange that one of them is in active mode and the other is in passive mode. If both are passive, the selections will never get unified in the first place; if both are active, the two processes will fight, and whatever happens after that, it won't be useful.
In normal usage, the defaults are set up so that you don't need to worry about this:
xclipglue
process (talking to the default X display) runs in active mode, and the child process (talking to the secondary X display) runs in passive mode. So xclipglue -display :1 :2
, for example, starts by replacing the previous selection contents on :2
with the contents on :1
.
xclipglue
s with something like SSH between them, with one in each of those modes, then you get one active and one passive.
However, in more unusual cases, you might need to manually specify which xclipglue
is active and which one is passive. For example, if you're manually running two instances of xclipglue -stdio
and connecting them together by some ad-hoc system of sockets or pipes, then you'll need to force one of them into active mode.
The -active
and -passive
options force xclipglue
into active and passive mode respectively.
In double-display mode, -active
and -passive
control the mode in which the parent xclipglue
process runs; the child process will still automatically run in the other mode.
-v
xclipglue
will log the traffic in its wire protocol on standard error. You can use this for debugging, or just to learn about the protocol for the purpose of implementing a compatible client.
This section documents the textual protocol spoken between two xclipglue
instances. You might need this for debugging, or in order to implement compatible clients.
Every command in the xclipglue
protocol occupies a single line of text, terminated with the \n
character only (line feed / Ctrl-J / 0x0A
). A line consists of one or more words, separated by spaces. Within a word, no space character or \n
may appear.
Many words in the protocol are encoded using the %
hex system used in URL encoding. That is, a %
character followed by two hex digits is taken to mean the byte whose value is given by those hex digits. The space character, \n
and the literal %
sign MUST be so encoded (as %20
, %0A
and %25
respectively), and in the context of encoded X properties (see below), so must the colon character, which is used as a second-level separator in that context.
Other byte values MAY be %
-encoded, at the encoder's option. Byte values that are not printable ASCII characters SHOULD be %
-encoded, so that diagnostic dumps of the protocol are easy to read, but it won't break protocol correctness if they're not.
The protocol is symmetric: roles interchange between the two ends constantly. At any given time, for a particular X selection, one end of the protocol will be operating in a ‘sender’ role (meaning that another client on its X display owns that selection, and it expects to receive selection requests in the xclipglue
protocol and satisfy them by asking the real selection owner for some data to send back); the other will be in the ‘receiver’ role (meaning that xclipglue
itself owns the physical X selection on that display, and responds to X11 selection requests by translating them into the xclipglue
protocol and sending them to the other xclipglue
). But it's possible (indeed, common) for an xclipglue
to be in sender role with respect to one selection and in receiver role with respect to another. And the roles switch back and forth whenever another X client on the receiver side declares itself the new owner of that selection.
The protocol commands are as follows:
acq
selection-name
xclipglue
sending this command assumes the sender role for that selection; the one receiving it assumes the receiver role.
At startup, this command is sent from the active xclipglue
to the passive one for each selection that xclipglue
is configured to handle. (In fact this is the only effect of the active / passive setting.)
During run time, when the xclipglue
in receiver role is notified by the X display that another client has taken a selection away from it (i.e. receives the SelectionClear X event), it sends ‘acq
’ to the other xclipglue
and the roles interchange.
The selection-name is %
-encoded.
req
selection-name request-id target [target...]
xclipglue
in receiver role to one in sender role, requesting the contents of the named X selection. The xclipglue
receiving this is expected to make an X selection request, and send back the results via the ‘rsp
’ command (see below).
The selection-name is %
-encoded.
The request-id is an opaque string which will be repeated in the ‘rsp
’ command, to allow multiple concurrent selection requests to be distinguished in the protocol. Its encoding is therefore not specified: it just needs to avoid containing spaces or \n
.
Each target is %
-encoded, and represents the X atom name of a type of selection data being requested. More than one target can be requested at a time, which corresponds to the special ICCCM MULTIPLE
mechanism.
rsp
request-id property [property...]
xclipglue
in sender role to one in receiver role, returning the selection data requested by a previous ‘req
’ command.
The request-id is the same one that was in the ‘req
’ command to which this is a response.
Each property encodes the returned selection data for one of the target atoms specified in the request, in the same order.
If a property word is the string ‘none
’, it indicates that the retrieval of that selection target failed, or was refused by the selection owner.
Otherwise, a property is encoded as a colon-separated list of at least two substrings, none of which may contain a colon in turn. (So when they are %
-encoded, ‘:
’ is added to the list of characters that MUST be escaped.)
The first substring is a %
-encoded X atom name specifying the type of the data. The second substring is an encoding type, specifying how to interpret the remaining substrings (if any) and what the element size of the data is (required by the X protocol, for variable-endianness support). The encoding type must be one of the following values.
Encoding type ‘8p
’ indicates that the element size is 8 bits. It expects exactly one further substring, which contains the %
-encoded text of the property, except that an unescaped underscore character is taken to mean a space rather than a literal underscore (and therefore a literal underscore must be encoded as %5F
).
Encoding type ‘8b
’ indicates that the element size is 8 bits. It expects exactly one further substring, which contains the base64-encoded text of the property.
(When xclipglue
itself encodes selection data with 8-bit element size, it will choose between ‘8p
’ and ‘8b
’ based on space efficiency, which keeps textual selections legible in the protocol diagnostics. Other implementations of this protocol need not follow that policy. The receiver of an encoded property must be able to handle both formats.)
Encoding types ‘16i
’ and ‘32i
’ indicate that the element size is 16 or 32 bits respectively. The remaining substrings (if any) are interpreted as decimal integers and give the integer values of the data elements.
Encoding type ‘32a
’ indicates that the element size is 32 bits, and that the data consists of a list of X11 atom names (which were converted from numeric values on the source X display, and must be converted back into numbers on the target X display). The remaining substrings (if any) are interpreted as %
-encoded atom names, except that a substring consisting of the ASCII minus sign ‘-
’ is interpreted as the null atom value None. An atom consisting of the literal text ‘-
’ must therefore be represented as the substring ‘%2D
’.
ICCCM permits selection requests to be parametric, in principle. Before sending the ConvertSelection
request, the requesting client may preload the destination property on its window with information intended to be read by the selection owner, in the expectation that this will inform the selection owner's choice of data to deliver (or action to take). If anyone uses this protocol option, then it won't work between X displays connected by xclipglue
, because the xclipglue
protocol has no way to specify the initial contents of the destination window property.
Also, it's possible in principle for selection data to refer to other entities specific to an X display, such as window ids. If someone does that, then xclipglue
won't notice, and will propagate the selection data completely literally – so that when it arrives in the receiving X client, it will refer to a window id that doesn't exist on that client's X display (or, worse still, one that does!).
As of 2020-04-17 I've never heard of anyone actually using either of these protocol options.