In conformance with the principle that clients should behave, as far as possible, when a window manager is running as they would when it is not, a client that has the input focus may assume that it can receive all the available keys and buttons.
Window managers should ensure that they provide some mechanism for their clients to receive events from all keys and all buttons, except for events involving keys whose KeySyms are registered as being for window management functions (for example, a hypothetical WINDOW KeySym).
In other words, window managers must provide some mechanism by which a client can receive events from every key and button (regardless of modifiers) unless and until the X Consortium registers some KeySyms as being reserved for window management functions. Currently, no KeySyms are registered for window management functions.
Even so, clients are advised to allow the key and button combinations used to elicit program actions to be modified, because some window managers may choose not to observe this convention or may not provide a convenient method for the user to transmit events from some keys.
Clients should establish button and key grabs only on windows that they own.
In particular, this convention means that a window manager that wishes to establish a grab over the client's top-level window should either establish the grab on the root, or reparent the window and establish the grab on a proper ancestor. In some cases, a window manager may want to consume the event received, placing the window in a state where a subsequent such event will go to the client. Examples are:
pointer/keyboard-mode == Synchronous
Then, the window manager should release the grab by using an AllowEvents request with the following specified:
mode == ReplayPointer/Keyboard
In this way, the client will receive the events as if they had not been intercepted.
Obviously, these conventions place some constraints on possible user interface policies. There is a trade-off here between freedom for window managers to implement their user interface policies and freedom for clients to implement theirs. The dilemma is resolved by:
The contents of the RGB_COLOR_MAP type property are as follows:
|ID of the colormap described
|Values for pixel calculations
|Visual to which colormap belongs
|ID for destroying the resources
When deleting or replacing an RGB_COLOR_MAP, it is not sufficient to delete the property; it is important to free the associated colormap resources as well. If kill_id is greater than one, the resources should be freed by issuing a KillClient request with kill_id as the argument. If kill_id is one, the resources should be freed by issuing a FreeColormap request with colormap as the colormap argument. If kill_id is zero, no attempt should be made to free the resources. A client that creates an RGB_COLOR_MAP for which the colormap resource is created specifically for this purpose should set kill_id to one (and can create more than one such standard colormap using a single connection). A client that creates an RGB_COLOR_MAP for which the colormap resource is shared in some way (for example, is the default colormap for the root window) should create an arbitrary resource and use its resource ID for kill_id (and should create no other standard colormaps on the connection).
If an RGB_COLOR_MAP property is too short to contain the visual_id field, it can be assumed that the visual_id is the root visual of the appropriate screen. If an RGB_COLOR_MAP property is too short to contain the kill_id field, a value of zero can be assumed.
During the connection handshake, the server informs the client of the default colormap for each screen. This is a colormap for the root visual, and clients can use it to improve the extent of colormap sharing if they use the root visual.
It is possible for clients to modify this table by using a ChangeKeyboardMapping request. In general, clients should not do this. In particular, this is not the way in which clients should implement key bindings or key remapping. The conversion between a sequence of keycodes received from the server and a string in a particular encoding is a private matter for each client (as it must be in a world where applications may be using different encodings to support different languages and fonts). See the Xlib reference manual for converting keyboard events to text.
The only valid reason for using a ChangeKeyboardMapping request is when the symbols written on the keys have changed as, for example, when a Dvorak key conversion kit or a set of APL keycaps has been installed. Of course, a client may have to take the change to the keycap on trust.
The following illustrates a permissible interaction between a client and a user:
Clients should not use ChangeKeyboardMapping requests.
If a client succeeds in changing the keyboard mapping table, all clients will receive MappingNotify (request==Keyboard) events. There is no mechanism to avoid receiving these events.
Clients receiving MappingNotify (request==Keyboard) events should update any internal keycode translation tables they are using.
A client that needs to use one of the preassigned modifiers should assume that the modifier table has been set up correctly to control these modifiers. The Lock modifier should be interpreted as Caps Lock or Shift Lock according as the keycodes in its controlling set include XK_Caps_Lock or XK_Shift_Lock.
Clients should determine the meaning of a modifier bit from the KeySyms being used to control it.
A client that needs to use an extra modifier (for example, META) should do the following:
There is no good solution to the problem of reclaiming assignments to the five nonpreassigned modifiers when they are no longer being used.
The user must use xmodmap or some other utility to deassign obsolete modifier mappings by hand.
When a client succeeds in performing a SetModifierMapping request, all clients will receive MappingNotify (request==Modifier) events. There is no mechanism for preventing these events from being received. A client that uses one of the nonpreassigned modifiers that receives one of these events should do a GetModifierMapping request to discover the new mapping, and if the modifier it is using has been cleared, it should reinstall the modifier.
Note that a GrabServer request must be used to make the GetModifierMapping and SetModifierMapping pair in these transactions atomic.