Table of Contents
This section describes the steps involved in processing a key event within the server when XKB is present. Key events can be generated due to keyboard activity and passed to XKB by the DDX layer, or they can be synthesized by another extension, such as XTEST.
When the X Keyboard Extension receives a key event, it first checks the global key controls to decide whether to process the event immediately or at all. The global key controls which might affect the event, in descending order of priority, are:
If a key is pressed while the BounceKeys control is enabled, the extension generates the event only if the key is active. When a key is released, the server deactivates the key and starts a bounce keys timer with an interval specified by the debounce delay.
If the bounce keys timer expires or if some other key is pressed before the timer expires, the server reactivates the corresponding key and deactivates the timer. Neither expiration nor deactivation of a bounce keys timer causes an event.
If the SlowKeys control is enabled, the extension sets a slow keys timer with an interval specified by the slow keys delay, but does not process the key event immediately. The corresponding key release deactivates this timer.
If the slow keys timer expires, the server generates a key press for the corresponding key, sends an XkbAccessXNotify and deactivates the timer.
The extension processes key press events normally whether or not the RepeatKeys control is active, but if RepeatKeys are enabled and per-key autorepeat is enabled for the event key, the extension processes key press events normally, but it also initiates an autorepeat timer with an interval specified by the autorepeat delay. The corresponding key release deactivates the timer.
If the autorepeat timer expires, the server generates a key release and a key press for the corresponding key and reschedules the timer according to the autorepeat interval.
Key events are processed by each global control in turn: if the BounceKeys control accepts a key event, SlowKeys considers it. Once SlowKeys allows or synthesizes an event, the RepeatKeys control acts on it.
Once an event is accepted by all of the controls or generated by a timer, the server checks the per-key behavior of the corresponding key. This extension currently defines the following key behaviors:
Behavior | Effect |
---|---|
KB_Default | Press and release events are processed normally. |
KB_Lock | If a key is logically up (i.e. the corresponding bit of the core key map is cleared) when it is pressed, the key press is processed normally and the corresponding release is ignored. If the key is logically down when pressed, the key press is ignored but the corresponding release is processed normally. |
KB_RadioGroup flags: CARD8 index: CARD8 | If another member of the radio group specified by index is logically down when a key is pressed, the server synthesizes a key release for the member that is logically down and then processes the new key press event normally. If the key itself is logically down when pressed, the key press event is ignored, but the processing of the corresponding key release depends on the value of the RGAllowNone bit in flags . If it is set, the key release is processed normally; otherwise the key release is also ignored. All other key release events are ignored. |
KB_Overlay1 key: KEYCODE | If the Overlay1 control is enabled, events from this key are reported as if they came from the key specified in key . Otherwise, press and release events are processed normally. |
KB_Overlay2 key: KEYCODE | If the Overlay2 control is enabled, events from this key are reported as if they came from the key specified in key . Otherwise, press and release events are processed normally. |
The X server uses key behavior to determine whether to process or filter out any given key event; key behavior is independent of keyboard modifier or group state (each key has exactly one behavior.
Key behaviors can be used to simulate any of these types of keys or to indicate an unmodifiable physical, electrical or software driver characteristic of a key. An optional permanent flag can modify any of the supported behaviors and indicates that behavior describes an unalterable physical, electrical or software aspect of the keyboard. Permanent behaviors cannot be changed or set by the XkbSetMap request. The permanent flag indicates a characteristic of the underlying system that XKB cannot affect, so XKB treats all permanent behaviors as if they were KB_Default and does not filter key events described in the table above.
Once the server has applied the global controls and per-key behavior and has decided to process a key event, it applies key actions to determine the effects of the key on the internal state of the server. A key action consists of an operator and some optional data. XKB supports actions which:
change base, latched or locked modifiers or group
move the core pointer or simulate core pointer button events
change most aspects of keyboard behavior
terminate or suspend the server
send a message to interested clients
simulate events on other keys
Each key has an optional list of actions. If present, this list parallels the list of symbols associated with the key (i.e. it has one action per symbol associated with the key). For key press events, the server looks up the action to be applied from this list using the key symbol mapping associated with the event key, just as a client looks up symbols as described in Determining the KeySym Associated with a Key Event; if the event key does not have any actions, the server uses the SA_NoAction event for that key regardless of modifier or group state.
Key actions have essentially two halves; the effects on the server when the key is pressed and the effects when the key is released. The action applied for a key press event determines the further actions, if any, that are applied to the corresponding release event or to events that occur while the key is held down. Clients can change the actions associated with a key while the key is down without changing the action applied next time the key is released; subsequent press-release pairs will use the newly bound key action.
Most actions directly change the state of the keyboard or server; some actions also modify other actions that occur simultaneously with them. Two actions occur simultaneously if the keys which invoke the actions are both logically down at the same time, regardless of the order in which they are pressed or delay between the activation of one and the other.
Most actions which affect keyboard modifier state accept a modifier definition (see Virtual Modifiers) named mods and a boolean flag name useModMap among their arguments. These two fields combine to specify the modifiers affected by the action as follows: If useModMap is True , the action sets any modifiers bound by the modifier mapping to the key that initiated the action; otherwise, the action sets the modifiers specified by mods . For brevity in the text of the following definitions, we refer to this combination of useModMap and mods as the "action modifiers."
The X Keyboard Extension supports the following actions:
Action | Effect |
---|---|
SA_NoAction |
|
SA_SetMods mods: MOD_DEF useModMap: BOOL clearLocks: BOOL |
|
SA_LatchMods mods: MOD_DEF useModMap: BOOL clearLocks: BOOL latchToLock: BOOL |
|
SA_LockMods mods: MOD_DEF useModMap: BOOL noLock: BOOL noUnlock: BOOL |
|
SA_SetGroup group: INT8 groupAbsolute: BOOL clearLocks: BOOL |
|
SA_LatchGroup group: INT8 groupAbsolute: BOOL clearLocks: BOOL latchToLock: BOOL |
|
SA_LockGroup group: INT8 groupAbsolute: BOOL |
|
SA_MovePtr x, y: INT16 noAccel: BOOL absoluteX: BOOL absoluteY: BOOL |
|
SA_PtrBtn button: CARD8 count: CARD8 useDfltBtn: BOOL |
|
SA_LockPtrBtn button: BUTTON noLock: BOOL noUnlock: BOOL useDfltBtn: BOOL |
|
SA_SetPtrDflt affect: CARD8 value: CARD8 dfltBtnAbs: BOOL |
|
SA_ISOLock dfltIsGroup: False mods: MOD_DEF useModMap: BOOL noLock: BOOL noUnlock: BOOL noAffectMods: BOOL noAffectGrp: BOOL noAffectPtr: BOOL noAffectCtrls: BOOL or dfltIsGroup: True group: INT8 groupAbsolute: BOOL noAffectMods: BOOL noAffectGrp: BOOL noAffectPtr: BOOL noAffectCtrls: BOOL |
|
SA_TerminateServer |
|
SA_SwitchScreen num: INT8 switchApp: BOOL screenAbs: BOOL |
|
SA_SetControls controls: KB_BOOLCTRLMASK |
|
SA_LockControls controls: KB_BOOLCTRLMASK noLock: BOOL noUnlock: BOOL |
|
SA_ActionMessage : pressMsg: BOOL releaseMsg: BOOL genEvent: BOOL message: STRING |
|
SA_RedirectKey newKey: KEYCODE modsMask: KEYMASK mods: KEYMASK vmodsMask: CARD16 vmods: CARD16 |
|
SA_DeviceBtn count: CARD8 button: BUTTON device: CARD8 |
|
SA_LockDeviceBtn button: BUTTON device: CARD8 noLock: BOOL noUnlock: BOOL |
|
SA_DeviceValuator device : CARD8 val1What : SA_DVOP val1 : CARD8 val1Value : INT8 val1Scale : 0...7 val2What : BOOL val2 : CARD8 val2Value : INT8 val2Scale : 0...7 |
|
If StickyKeys are enabled, all SA_SetMods and SA_SetGroup actions act like SA_LatchMods and SA_LatchGroup respectively. If the LatchToLock AccessX option is set, either action behaves as if both the SA_ClearLocks and SA_LatchToLock flags are set.
Actions which cause an event from another key or from a button on another device immediately generate the specified event. These actions do not consider the behavior or actions (if any) that are bound to the key or button to which the event is redirected.
Core events generated by server actions contain the keyboard state that was in effect at the time the key event occurred; the reported state does not reflect any changes in state that occur as a result of the actions bound to the key event that caused them.
Events sent to clients that have not issued an XkbUseExtension request contain a compatibility state in place of the actual XKB keyboard state. See Effects of XKB on Core Protocol Events for a description of this compatibility mapping.
The window and client that receive core protocol and input extension key or button events are determined using the focus policy, window hierarchy and passive grabs as specified by the core protocol and the input extension, with the following changes:
A passive grab triggers if the modifier state specified in the grab matches the grab compatibility state (described in Compatibility Components of Keyboard State). Clients can choose to use the XKB grab state instead by setting the GrabsUseXKBState per-client flag. This flag affects all passive grabs that are requested by the client which sets it but does not affect passive grabs that are set by any other client.
The state field of events which trigger a passive grab reports the XKB or compatibility grab state in effect at the time the grab is triggered; the state field of the corresponding release event reports the corresponding grab state in effect when the key or button is released.
If the LookupStateWhenGrabbed per-client flag is set, all key or button events that occur while a keyboard or pointer grab is active contain the XKB or compatibility lookup state, depending on the value of the GrabsUseXKBState per-client flag. If LookupStateWhenGrabbed is not set, they include the XKB or compatibility grab state, instead.
Otherwise, the state field of events that do not trigger a passive grab report is derived from the XKB effective modifiers and group, as described in Computing A State Field from an XKB State.
If a key release event is the result of an autorepeating key that is being held down, and the client to which the event is reported has requested detectable autorepeat (see Detectable Autorepeat), the event is not delivered to the client.
The following section explains the intent of the XKB interactions with core protocol grabs and the reason that the per-client flags are needed.
XKB provides the separate lookup and grab states to help work around some difficulties with the way the core protocol specifies passive grabs. Unfortunately, many clients work around those problems differently, and the way that XKB handles grabs and reports keyboard state can sometimes interact with those client workarounds in unexpected and unpleasant ways.
To provide more reasonable behavior for clients that are aware of XKB without causing problems for clients that are unaware of XKB, this extension provides two per-client flags that specify the way that XKB and the core protocol should interact.
The largest problems arise from the fact that an XKB state field encodes an explicit keyboard group in bits 13-14 (as described in Computing A State Field from an XKB State), while pre-XKB clients use one of the eight keyboard modifiers to select an alternate keyboard group. To make existing clients behave reasonably, XKB normally uses the compatibility grab state instead of the XKB grab state to determine whether or not a passive grab is triggered. XKB-aware clients can set the GrabsUseXKBState per-client flag to indicate that they are specifying passive grabs using an XKB state.
Some toolkits start an active grab when a passive grab is triggered, in order to have more control over the conditions under which the grab is terminated. Unfortunately, the fact that XKB reports a different state in events that trigger or terminate grabs means that this grab simulation can fail to terminate the grab under some conditions. To work around this problem, XKB normally reports the grab state in all events whenever a grab is active. Clients which do not use active grabs like this can set the LookupStateWhenGrabbed per-client flag in order to receive the same state component whether or not a grab is active.
The GrabsUseXKBState per-client flag also applies to the state of events sent while a grab is active. If it is set, events during a grab contain the XKB lookup or grab state; by default, events during a grab contain the compatibility lookup or grab state.
The state used to trigger a passive grab is controlled by the setting of the GrabsUseXKBState per-client flag at the time the grab is registered. Changing this flag does not affect existing passive grabs.