A selection is an atom used to identify data that can be shared among all client programs connected to an X server. Unlike properties, the data represented by a selection is stored by some client program, not by the server.
The data named by a selection is associated with a client window, which is referred to as the selection owner. The server always knows which window is the owner of a selection. Selections can be created freely by clients using intern-atom to create an atom. CLX provides functions to inquire or change the owner of a selection and to convert a selection.
Conversion is the key to the use of selections for inter-client communication. Suppose Client A wants to paste the contents of the data named by selection S into his window WA. Client A calls convert-selection on selection atom S, sending a conversion request to the server. The server, in turn, sends a :selection-request event to the current owner of S, which is window WB belonging to Client B. The :selection-request event contains the requestor window (WA), the selection atom (S), an atom identifying a requested data type, and the name of a property of WA into which the value of S will be stored.
Since WB is the owner of S, it must be associated with the data defined by Client B as the value of S. When WB gets the :selection-request event, Client B is expected to convert the value of S to the requested data type (if possible) and store the converted value in the given requestor property. Client B is then expected to send a :selection-notify event to the requestor window WA, informing the requestor that the converted value for S is ready. Upon receiving the :selection-notify event, Client A can call get-property to retrieve the converted value and to paste it into WA.
NOTE: Clients using selections must always be prepared to handle :selection-request events and/or :selection-notify events. There is no way for a client to ask not to receive these types of events.
Type atoms used in selection conversion can represent arbitrary client-defined interpretations of the selection data. For example, if the value of selection S is a text string, Client A might request its typeface by requesting conversion to the :font type. A type atom can also represent a request to the selection owner to perform some action as a side-effect of conversion (for example, :delete). Some of the predefined atoms of an X server are intended to be used as selection types (for example, :colormap, :bitmap, :string, and so forth) However, X does not impose any requirements on the interpretation of type atoms.
When multiple clients negotiate for ownership of a selection, certain race conditions might be possible. For example, two clients might each receive a user command to assert ownership of the :primary selection, but the order in which the server processes these client requests is unpredictable. As a result, the ownership request initiated most recently by the user might be incorrectly overridden by the other earlier ownership request. To prevent such anomalies, the server records a last-changed timestamp for each change of selection ownership.
Although inter-client communication via selections is rather complex, it offers important benefits. Since selection communication is mediated by an X server, clients can share data even though they are running on different hosts and using different networking protocols. Data storage and conversion is distributed among clients so that the server is not required to provide all possible data types or to store multiple forms of selection data.
Certain predefined atoms are used as standard selections, as described in the X11 Inter-client Communications Conventions Manual. Some of the standard selections covered by these conventions are:
|convert-selection||selection type requestor &optional property time||Function|
Requests that the value of the selection be converted to the specified type and stored in the given property of the requestor window.
If the selection has an owner, the X server sends a :selection-request event to the owner window. Otherwise, if no owner exists, the server generates on the requestor a :selection-notify event containing a nil property atom.
The given property specifies the requestor property that will receive the converted value. If the property is omitted, the selection owner will define a property to use. The time furnishes a timestamp representing the time of the conversion request; by default, the current server time is used.
NOTE: Standard conventions for inter-client communication require that both the requestor property and the time must be specified. If possible, the time should be the time of a user event which initiated the conversion. Alternatively, a timestamp can be obtained by calling change-property to append zero-length data to some property; the timestamp in the resulting :property-notify event can then be used.
|selection-owner||display selection &optional time||Function|
Returns and (with setf) changes the owner and the last-changed time for the selection. If the owner is nil, no owner for the selection exists. When the owner window for a selection is destroyed, the selection owner is set to nil without affecting the last-changed time.
The time argument is used only when changing the selection owner. If the time is nil, the current server time is used. If the time is earlier than the current last-changed time of the selection or if the time is later than the current server time, the owner is not changed. Therefore, a client should always confirm successful change of ownership by immediately calling selection-owner. If the change in ownership is successful, the last-changed time of the selection is set to the specified time.
If the change in ownership is successful and the new owner is different from the previous owner, and if the previous owner is not nil, a :selection-clear event is generated for the previous owner window.
NOTE: Standard conventions for inter-client communication require that a non-nil time must be specified. If possible, the time should be the time of a user event which initiated the change of ownership. Alternatively, a timestamp can be obtained by calling change-property to append zero-length data to some property; the timestamp in the resulting :property-notify event can then be used.