Many programs allow the user to search through text, be it a text file, a collection of email messages, or a web page. Sometimes one has the text for which to search in one program (e.g. in a mail message) while the text in which to search is in a different program (e.g. a text editor or a web browser). While one can usually copy the search string from the source program and paste it into the destination program, it is even more convenient if the programs can share this text directly. The Search Parameter Sharing Protocol (XSearch) provides a simple way to share both the search string and the replace string, thereby replacing the sequence:
with the must shorter sequence:
Many text editors already provide this convenience between windows within the application. The XSearch protocol can be viewed as an extension of this ability to work with all windows on the desktop.
Note that Mac OS X also provides this feature for all native applications.
Current version: 1
Last updated on May 1, 2000
Supporters of the XSearch protocol
The search string is the text for which to search.
The replace string is the text to be substituted in place of the search string, once it is found.
An entire word match is one where the match starts and ends at a word boundary. As an example, searching for "and" would not match "band."
An entire partial word match uses a more restrictive definition of a word boundary which is particularly useful for source code. In addition to the ends of a word, a partial word boundary also occurs within a word when one encounters a change in case or a non-alphabetic character. As an example, "call_me_ishmael" contains three partial words, and so does "GetDNDAction."
The version window is the X window on which the XsearchVersion property is set.
The data window is the X window on which the XsearchDataV* properties are set.
Initialization
When a program starts, it must initialize itself so that it can use the XSearch protocol. Define D1 to be the display that is already open.
Setting the search parameters
The search parameters must be updated when:
Retrieving the search parameters
The search parameters must be retrieved when the program receives a PropertyNotify event from the version window for the XsearchVersion property and the program does not currently own XsearchSelection.
The XSearch protocol provides the most efficient method for the current owner of the search parameters to broadcast changes in these parameters to all other programs that support the protocol.
All properties are stored on two persistent windows: the version window and the data window. The ID's of these windows are stored in the XSearchWindows property on the root window so all programs can find the windows once they have been created. Storing XsearchVersion on its own window minimizes the number of PropertyNotify events received because each program only needs to listen to the version window. Storing XsearchDataV* on a separate window avoids sending unnecessary PropertyNotify events to programs that are forced to listen to other properties on the root window.
Storing XsearchVersion separately from the data also allows each receiver to retrieve only two window properties: XsearchVersion and then a single XsearchDataVN, as explained in the Procedures section.
XsearchSelection is used to reduce the network traffic and improve performance. Since the server is grabbed when the search parameters are updated, each program is guaranteed to receive a SelectionClear message for XsearchSelection before it receives any PropertyNotify events that were generated by other programs. Thus, if a program thinks that it currently owns the selection, then that program can ignore PropertyNotify events because they must result either from the program's own changes or from changes made by other programs before this program last took ownership of the selection (i.e. events still in transit from the server or in the Xlib queue when the server was grabbed). The latter reason obviously reduces network traffic. The former reason eliminates the four packets required to retrieve XsearchVersion and XsearchDataVN, at a cost of three packets to obtain ownership of XsearchSelection and one packet to notify the previous owner. Even though there is no net change in traffic in this case, it does reduce the delay required to set the data because retrieving the two window properties requires two blocking round trips to the X server and redrawing of the screen to display the new values, while obtaining ownership of XsearchSelection only requires one blocking round trip (the mandatory check of XGetSelectionOwner()).
Since the version property is modified separately, programs may not manage to retrieve the data before somebody else modifies the data in preparation for sending a new PropertyNotify event. This is not dangerous, however, because XChangeProperty() is atomic, so the receivers will simply get data that is closer to being current. If the new owner doesn't support the previous owner's version, the receiver will get the "correct," outdated data. Either way, another PropertyNotify event will already be in the queue, and this will force the receiver to update to the correct data. Note that such rapid changes are very unlikely since they are triggered by user actions which are orders of magnitude slower than the typical network. Repeated, redundant updating will therefore happen very rarely, if at all.
An alternate protocol would be to modify only a version property and have each receiver request the contents of the XsearchSelection. In an environment with many programs that support the XSearch protocol, this puts an unnecessarily large load on the network. Define NV to be the number of XSearch protocol versions and NR to be the number of receivers. Retrieving a selection requires seven packets per receiver, while the current method requires only NV packets to set XsearchDataV*, and two packets per receiver. (This ignores the packet to set XsearchVersion, the packet to each receiver containing the PropertyNotify event, and the two packets per receiver to retrieve XsearchVersion. These packets are required by both protocols.) As long as NV+2*NR<7*NR, the protocol that is used by XSearch requires significantly less network traffic. It also puts far less load on the source program since the source does not have to respond to SelectionRequest events.
Regular expression searching is provided by many programs. Unfortunately, since there are so many dialects, it is not possible to make this part of the official protocol. Instead, specification of the dialect is covered by the provision for extended data, as described in the Technical Details section. This allows programs that use the same dialect to share the parameters. For other programs that do not understand the dialect, the user must translate the regular expression manually. (The regular expression should always be treated as any other search string, because this saves the user the trouble of copying it from one program to another.)
All constants mentioned below are the string names of X atoms, capitalized as shown. This avoids the need for hard-coded values, which would require a global registry.
XsearchSelection
This is the name of the X Selection that is used to avoid retrieving ones own data.
XSearchWindows
This window property must be set on the root window and must be of type XA_WINDOW. It contains the ID's of the version and data windows, in that order.
XsearchVersion
This window property is set on the version window and must be of type XA_ATOM. It contains the maximum XSearch protocol version supported by the program that last set the contents of XsearchDataV*.
XsearchDataV*
These window properties are set on the data window and must be of type text/plain, including the charset attribute, if it is not ISO-8859-1. This allows the search and replace strings to be in any language. Programs that cannot handle the character set can ignore the data.
The version number is encoded in the property name so programs that do not support the latest version can still easily retrieve data that they can interpret.
XsearchDataV1
Version 1 of the XSearch protocol contains the following data:
Providing additional search parameters
Most programs provide many features beyond simply searching for a literal string. Regular expression searching is the most common (see Notes section). In order to allow programs to share such additional information, one can append additional data to the XsearchDataV* properties after appending 0x00, followed by a unique tag to identify the data format, followed by 0x00. To allow for new formats of this data in later releases, the data itself should have the format: first version id, data, second version id, data, etc. This allows each program to retrieve the newest version that it can handle by skipping over the older versions. As an example, the JX Application Framework appends the following data
If you are interested in supporting this protocol, but daunted by having to start from scratch, you can obtain sample C++ code via anonymous ftp. This code may be used under any license.
If you use a different language, please consider donating your code for others to look at.
We also have a binary that you can use to test interoperability between a correct implementation and your implementation.
While implementing this protocol, you may find it very useful to use the programs xlsatoms to list all the atoms that the server knows about, xprop to list all the properties on a particular window, and xscope to study the timing of events.
Even if you implement XSearch from scratch, we would appreciate it if your distribution included some sort of documentation that states clearly that you are supporting this protocol and provides a reference to this web page. This will help get the snowball rolling. The more programs that support the same protocol, the more useful XSearch will be for the users. If you tell us that you support the protocol, we will also add you to the list of supporters.
May 1, 2000:
Initial publication.
This protocol was developed by John Lindal at New Planet Software. The original inspiration for XSearch came from NeXT which provided the capability as part of the operating system.