Selections are one of the most powerful IPC mechanisms provided by the X server, allowing complex features not seen in other systems such as content negotiation and lazy generation of content only when it is created. However, several issues with their design make common idioms impossible to implement and their full power is as yet unrealized. Perhaps the main problem is the inability of applications to 'copy' the contents of a selection in a non-destructive fashion, by choosing to receive the data, they must decide on a format and the alternate formats are lost.
This should be unsurprising, as the generation of alternate formats and/or lazy generation of content might require arbitrary computations by the publisher of the data which the X server or other clients cannot be expected to replicate. although some problems may be addressed by X Server extensions such as XFIXES, the fundamental problem of copying selections cannot be without client participation.
examples of several things which are currently impossible, unacceptably lossy or inefficient are:
- having an app which provides multiple clipboards, or a place to temporarily place multiple selections for later use.
- have an app which is able to accept drag-n-drop's and place them in the clipboard (or other holding area), and vice versa, taking the contents of the clipboard and publishing them via drag-n-drop.
- a proxy for allowing drag-n-drops between screens on a single X server
- saving the contents of the CLIPBOARD in an alternate location
- saving the contents of a selection after an app owning it exits
- assigning a global hot-key which swaps CLIPBOARD and SECONDARY
- assign a global hot-key which copies PRIMARY to CLIPBOARD
the fundamental difficulty is that we would like the ability to work with and manipulate selections as separate entities, but in fact the app which holds the selection has complete control over it, so all interactions with the selection must go through it's owner.
the two parts of this proposal are relatively independent and may be considered separately or as a unit.
Part 1: copying selections
An owner of a selection (call it 'SEL_A') may advertise a conversion type of 'CAN_CLONE_SELECTION' if it wishes to participate. any client may send such a selection owner a 'CLONE_SELECTION' message with an atom representing a new selection name (call it 'SEL_B') and a timestamp. the owner of SEL_A then calls
XSetSelectionOwner(disp, SEL_B, owner's window, timestamp from message);
and publishes the exact same data on SEL_B as SEL_A. from now on, the selections are treated independently, losing one does not imply losing the other and SEL_B may be the source of more clones.
this protocol would allow many of the type of apps discussed above to be written, not only could selections be cloned, it is done without sending any data through the X server, effectively making it 'free' to manipulate selections.
An interesting utility that this would allow is a generic 'palette' or dock app could be implemented which would accept many drops of arbitrary, even unknown types and keep them as icons in a window to be used as the source of drags in the future. if you are commonly working on several directories ,with certain colors or with chunks of text or an arbitrary mix you could create a custom toolbox just by dragging and dropping them and without lossy conversions or inefficient sending of data through the X server. AFAIK this sort of app is impossible to write on windows or macs without actually copying the selection data around.
Part 2: Persistence of selection data
In general, since converting data between types and/or generating them dynamically or lazily could require arbitrary code, the only truly general way for selections to stick around is for their owner to not exit, but rather, keep a stub around to hold the selections after the app quits. However, this is overkill for most types of apps which use selections for simple blocks of text.
to solve this selections may advertise either of these conversion targets:
- This means the client handles persistence after its exit itself such as by wine or xclip. persistence daemons need do nothing. the reason for it's inclusion is to keep clipboard type apps from harvesting it's selections prematurely thinking the data would be lost on exit.
- this target means that it is okay for a persistence daemon to copy this data out of the selection. A client wishing to copy the raw data would do a ConvertSelection to this type, what is returned is a list of atoms representing the types which should be copied. the persistence daemon should copy the data from all types listed and advertise the same set of types when it grabs the selection returning the same raw data.
if neither of these are listed the owner is not participating in this protocol and the proper behavior of a persistence daemon will have to be decided by heuristic or user preference.
A notification ClientMessage could be sent to the persistance manager on exit, the app would wait for a SelectionClearEvent to be sure the manager got the data out okay.