6. Manipulation of Shared Resources

X Version 11 permits clients to manipulate a number of shared resources, for example, the input focus, the pointer, and colormaps. Conventions are required so that clients share resources in an orderly fashion.

6.1. The Input Focus

Clients that explicitly set the input focus must observe one of two modes:

Conventions

  • Locally active clients should set the input focus to one of their windows only when it is already in one of their windows or when they receive a WM_TAKE_FOCUS message. They should set the input field of the WM_HINTS structure to True .
  • Globally active clients should set the input focus to one of their windows only when they receive a button event and a passive-grabbed key event, or when they receive a WM_TAKE_FOCUS message. They should set the input field of the WM_HINTS structure to False .
  • In addition, clients should use the timestamp of the event that caused them to attempt to set the input focus as the time field on the SetInputFocus request, not CurrentTime .

    6.2. The Pointer

    In general, clients should not warp the pointer. Window managers, however, may do so (for example, to maintain the invariant that the pointer is always in the window with the input focus). Other window managers may want to preserve the illusion that the user is in sole control of the pointer.

      Conventions

    1. Clients should not warp the pointer.
    2. Clients that insist on warping the pointer should do so only with the src-window argument of the WarpPointer request set to one of their windows.

    6.3. Grabs

    A client's attempt to establish a button or a key grab on a window will fail if some other client has already established a conflicting grab on the same window. The grabs, therefore, are shared resources, and their use requires conventions.

    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.

    Convention

    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.

    Convention

    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:

    More typically, a window manager should add to rather than replace the client's semantics for key+button combinations by allowing the event to be used by the client after the window manager is done with it. To ensure this, the window manager should establish the grab on the parent by using the following:

    
    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:

    6.4. Colormaps

    Section 4.1.8 prescribes conventions for clients to communicate with the window manager about their colormap needs. If your clients are DirectColor type applications, you should consult section 14.3 of Xlib - C Language X Interface for conventions connected with sharing standard colormaps. They should look for and create the properties described there on the root window of the appropriate screen.

    The contents of the RGB_COLOR_MAP type property are as follows:

    Field Type Comments

    colormap COLORMAP ID of the colormap described
    red_max CARD32 Values for pixel calculations
    red_mult CARD32
    blue_max CARD32
    blue_mult CARD32
    base_pixel CARD32
    visual_id VISUALID Visual to which colormap belongs
    kill_id CARD32 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).

    Convention

    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.

    6.5. The Keyboard Mapping

    The X server contains a table (which is read by GetKeyboardMapping requests) that describes the set of symbols appearing on the corresponding key for each keycode generated by the server. This table does not affect the server's operations in any way; it is simply a database used by clients that attempt to understand the keycodes they receive. Nevertheless, it is a shared resource and requires conventions.

    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:

    Client:
    "You just started me on a server without a Pause key. Please choose a key to be the Pause key and press it now."
    User:
    Presses the Scroll Lock key
    Client:
    "Adding Pause to the symbols on the Scroll Lock key: Confirm or Abort."
    User:
    Confirms
    Client:
    Uses a ChangeKeyboardMapping request to add Pause to the keycode that already contains Scroll Lock and issues this request, "Please paint Pause on the Scroll Lock key."

    Convention

    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.

    Convention

    Clients receiving MappingNotify (request==Keyboard) events should update any internal keycode translation tables they are using.

    6.6. The Modifier Mapping

    X Version 11 supports eight modifier bits of which three are preassigned to Shift, Lock, and Control. Each modifier bit is controlled by the state of a set of keys, and these sets are specified in a table accessed by GetModifierMapping and SetModifierMapping requests. This table is a shared resource and requires conventions.

    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.

    Convention

    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:

    Conventions

  • Clients needing a modifier not currently in use should assign keycodes carrying suitable KeySyms to an unused modifier bit.
  • Clients assigning their own modifier bits should ask the user politely to remove his or her hands from the key in question if their SetModifierMapping request returns a Busy status.

    There is no good solution to the problem of reclaiming assignments to the five nonpreassigned modifiers when they are no longer being used.

    Convention

    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.


    <^>


    Christophe Tronche, ch@tronche.com