# Keyboard State

The core protocol description of keyboard state consists of eight modifiers ( Shift , Lock , Control , and Mod1 - Mod5 ). A modifier reports the state of one or modifier keys, which are similar to qualifier keys as defined by the ISO9995 standard:

Qualifier key

  A key whose operation has no immediate effect, but which, for as long as it is held down, modifies the effect of other keys. A qualifier key may be, for example, a shift key or a control key.

Whenever a modifier key is physically or logically depressed, the modifier it controls is set in the keyboard state. The protocol implies that certain modifier keys lock (i.e. affect modifier state after they have been physically released) but does not explicitly discuss locking keys or their behavior. The current modifier state is reported to clients in a number of core protocol events and can be determined using the QueryPointer request.

The XKB extension retains the eight "real" modifiers defined by the core protocol but extends the core protocol notion of keyboard state to include up to four keysym groups , as defined by the ISO9995 standard:

Group:

  A logical state of a keyboard providing access to a collection of characters. A group usually contains a set of characters which logically belong together and which may be arranged on several shift levels within that group.

For example, keyboard group can be used to select between multiple alphabets on a single keyboard, or to access less-commonly used symbols within a character set.

## Locking and Latching Modifiers and Groups

With the core protocol, there is no way to tell whether a modifier is set due to a lock or because the user is actually holding down a key; this can make for a clumsy user-interface as locked modifiers or group state interfere with accelerators and translations.

XKB adds explicit support for locking and latching modifiers and groups. Locked modifiers or groups apply to all future key events until they are explicitly changed. Latched modifiers or groups apply only to the next key event that does not change keyboard state.

## Fundamental Components of XKB Keyboard State

The fundamental components of XKB keyboard state include:

- The locked modifiers and group

- The latched modifiers and group

- The base modifiers and group (for which keys are physically or logically down)

- The effective modifiers and group (the cumulative effect of the base, locked and latched modifier and group states).

- State of the core pointer buttons.

The latched and locked state of modifiers and groups can be changed in response to keyboard activity or under application control using the XkbLatchLockState request. The base modifier, base group and pointer button states always reflect the logical state of the keyboard and pointer and change only in response to keyboard or pointer activity.

### Computing Effective Modifier and Group

The effective modifiers and group report the cumulative effects of the base, latched and locked modifiers and group respectively, and cannot be directly changed. Note that the effective modifiers and effective group are computed differently.

The effective modifiers are simply the bitwise union of the base, latched and locked modifiers.

The effective group is the arithmetic sum of the base, latched and locked groups. The locked and effective keyboard group must fall in the range Group1 - Group4 , so they are adjusted into range as specified by the global GroupsWrap control as follows:

- If the RedirectIntoRange flag is set, the four least significant bits of the groups wrap control specify the index of a group to which all illegal groups correspond. If the specified group is also out of range, all illegal groups map to Group1.

- If the ClampIntoRange flag is set, out-of-range groups correspond to the nearest legal group. Effective groups larger than the highest supported group are mapped to the highest supported group; effective groups less than Group1 are mapped to Group1 . For example, a key with two groups of symbols uses Group2 type and symbols if the global effective group is either Group3 or Group4.

- If neither flag is set, group is wrapped into range using integer modulus. For example, a key with two groups of symbols for which groups wrap uses Group1 symbols if the global effective group is Group3 or Group2 symbols if the global effective group is Group4.

The base and latched keyboard groups are unrestricted eight-bit integer values and are not affected by the GroupsWrap control.

### Computing A State Field from an XKB State

Many events report the keyboard state in a single state field. Using XKB, a state field combines modifiers, group and the pointer button state into a single sixteen bit value as follows:

- Bits 0 through 7 (the least significant eight bits) of the effective state comprise a mask of type KEYMASK which reports the state modifiers.

- Bits 8 through 12 comprise a mask of type BUTMASK which reports pointer button state.

- Bits 13 and 14 are interpreted as a two-bit unsigned numeric value and report the state keyboard group.

- Bit 15 (the most significant bit) is reserved and must be zero.

It is possible to assemble a state field from any of the components of the XKB keyboard state. For example, the effective keyboard state would be assembled as described above using the effective keyboard group, the effective keyboard modifiers and the pointer button state.

## Derived Components of XKB Keyboard State

In addition to the fundamental state components, XKB keeps track of and reports a number of state components which are derived from the fundamental components but stored and reported separately to make it easier to track changes in the keyboard state. These derived components are updated automatically whenever any of the fundamental components change but cannot be changed directly.

The first pair of derived state components control the way that passive grabs are activated and the way that modifiers are reported in core protocol events that report state. The server uses the ServerInternalModifiers , IgnoreLocksModifiers and IgnoreGroupLock controls, described in Server Internal Modifiers and Ignore Locks Behavior, to derive these two states as follows:

- The lookup state is the state used to determine the symbols associated with a key event and consists of the effective state minus any server internal modifiers.

- The grab state is the state used to decide whether a particular event triggers a passive grab and consists of the lookup state minus any members of the ignore locks modifiers that are not either latched or logically depressed. If the ignore group locks control is set, the grab state does not include the effects of any locked groups.

### Server Internal Modifiers and Ignore Locks Behavior

The core protocol does not provide any way to exclude certain modifiers from client events, so there is no way to set up a modifier which affects only the server.

The modifiers specified in the mask of the InternalMods control are not reported in any core protocol events, are not used to determine grabs and are not used to calculate compatibility state for XKB-unaware clients. Server internal modifiers affect only the action applied when a key is pressed.

The core protocol does not provide any way to exclude certain modifiers from grab calculations, so locking modifiers often have unanticipated and unfortunate side-effects. XKB provides another mask which can help avoid some of these problems.

The locked state of the modifiers specified in mask of the IgnoreLockMods control is not reported in most core protocol events and is not used to activate grabs. The only core events which include the locked state of the modifiers in the ignore locks mask are key press and release events that do not activate a passive grab and which do not occur while a grab is active. If the IgnoreGroupLock control is set, the locked state of the keyboard group is not considered when activating passive grabs.

Without XKB, the passive grab set by a translation (e.g. Alt<KeyPress>space ) does not trigger if any modifiers other than those specified by the translation are set, with the result that many user interface components do not react when either Num Lock or when the secondary keyboard group are active. The ignore locks mask and the ignore group locks control make it possible to avoid this behavior without exhaustively grabbing every possible modifier combination.

## Compatibility Components of Keyboard State

The core protocol interpretation of keyboard modifiers does not include direct support for multiple groups, so XKB reports the effective keyboard group to XKB-aware clients using some of the reserved bits in the state field of some core protocol events, as described in Computing A State Field from an XKB State.

This modified state field would not be interpreted correctly by XKB-unaware clients, so XKB provides a group compatibility mapping (see Group Compatibility Map) which remaps the keyboard group into a core modifier mask that has similar effects, when possible. XKB maintains three compatibility state components that are used to make non-XKB clients work as well as possible:

- The compatibility state corresponds to the effective modifier and effective group state.

- The compatibility lookup state is the core-protocol equivalent of the lookup state.

- The compatibility grab state is the nearest core-protocol equivalent of the grab state.

Compatibility states are essentially the corresponding XKB state, but with keyboard group possibly encoded as one or more modifiers; Group Compatibility Map describes the group compatibility map, which specifies the modifier(s) that correspond to each keyboard group.

The compatibility state reported to XKB-unaware clients for any given core protocol event is computed from the modifier state that XKB-capable clients would see for that same event. For example, if the ignore group locks control is set and group 2 is locked, the modifier bound to Mode_switch is not reported in any event except (Device)KeyPress and (Device)KeyRelease events that do not trigger a passive grab.

Referring to clients as "XKB-capable is somewhat misleading in this context. The sample implementation of XKB invisibly extends the X library to use the keyboard extension if it is present. This means that most clients can take advantage of all of XKB without modification, but it also means that the XKB state can be reported to clients that have not explicitly requested the keyboard extension. Clients that directly interpret the state field of core protocol events or that interpret the keymap directly may be affected by some of the XKB differences; clients that use library or toolkit routines to interpret keyboard events automatically use all of the XKB features.

XKB-aware clients can query the keyboard state at any time or request immediate notification of a change to any of the fundamental or derived components of the keyboard state.