# Virtual Modifiers

The core protocol specifies that certain keysyms, when bound to modifiers, affect the rules of keycode to keysym interpretation for all keys; for example, when Num_Lock is bound to some modifier, that modifier is used to choose shifted or unshifted state for the numeric keypad keys. The core protocol does not provide a convenient way to determine the mapping of modifier bits, in particular Mod1 through Mod5 , to keysyms such as Num_Lock and Mode_switch . Clients must retrieve and search the modifier map to determine the keycodes bound to each modifier, and then retrieve and search the keyboard mapping to determine the keysyms bound to the keycodes. They must repeat this process for all modifiers whenever any part of the modifier mapping is changed.

XKB provides a set of sixteen named virtual modifiers, each of which can be bound to any set of the eight "real" modifiers ( Shift , Lock , Control and Mod1 - Mod5 as reported in the keyboard state). This makes it easier for applications and keyboard layout designers to specify to the function a modifier key or data structure should fulfill without having to worry about which modifier is bound to a particular keysym.

The use of a single, server-driven mechanism for reporting changes to all data structures makes it easier for clients to stay synchronized. For example, the core protocol specifies a special interpretation for the modifier bound to the Num_Lock key. Whenever any keys or modifiers are rebound, every application has to check the keyboard mapping to make sure that the binding for Num_Lock has not changed. If Num_Lock is remapped when XKB is in use, the keyboard description is automatically updated to reflect the new binding, and clients are notified immediately and explicitly if there is a change they need to consider.

The separation of function from physical modifier bindings also makes it easier to specify more clearly the intent of a binding. X servers do not all assign modifiers the same way — for example, Num_Lock might be bound to Mod2 for one vendor and to Mod4 for another. This makes it cumbersome to automatically remap the keyboard to a desired configuration without some kind of prior knowledge about the keyboard layout and bindings. With XKB, applications simply use virtual modifiers to specify the behavior they want, without regard for the actual physical bindings in effect.

XKB puts most aspects of the keyboard under user or program control, so it is even more important to clearly and uniformly refer to modifiers by function.

## Modifier Definitions

Use an XKB modifier definition to specify the modifiers affected by any XKB control or data structure. An XKB modifier definition consists of a set of real modifiers, a set of virtual modifiers, and an effective mask. The mask is derived from the real and virtual modifiers and cannot be explicitly changed — it contains all of the real modifiers specified in the definition plus any real modifiers that are bound to the virtual modifiers specified in the definition. For example, this modifier definition specifies the numeric lock modifier if the Num_Lock keysym is not bound to any real modifier:

    { real_mods= None, virtual_mods= NumLock, mask= None }

If we assign Mod2 to the Num_Lock key, the definition changes to:

    { real_mods= None, virtual_mods= NumLock, mask= Mod2 }

Using this kind of modifier definition makes it easy to specify the desired behavior in such a way that XKB can automatically update all of the data structures that make up a keymap to reflect user or application specified changes in any one aspect of the keymap.

The use of modifier definitions also makes it possible to unambiguously specify the reason that a modifier is of interest. On a system for which the Alt and Meta keysyms are bound to the same modifier, the following definitions behave identically:

    { real_mods= None, virtual_mods= Alt, mask= Mod1 }
    { real_mods= None, virtual_mods= Meta, mask= Mod1 }

If we rebind one of the modifiers, the modifier definitions automatically reflect the change:

    { real_mods= None, virtual_mods= Alt, mask= Mod1 }
    { real_mods= None, virtual_mods= Meta, mask= Mod4 }

Without the level of indirection provided by virtual modifier maps and modifier definitions, we would have no way to tell which of the two definitions is concerned with Alt and which is concerned with Meta.

### Inactive Modifier Definitions

Some XKB structures ignore modifier definitions in which the virtual modifiers are unbound. Consider this example:

    if ( state matches { Shift } ) Do OneThing;
    if ( state matches { Shift+NumLock } ) Do Another;

If the NumLock virtual modifier is not bound to any real modifiers, these effective masks for these two cases are identical (i.e. they contain only Shift ). When it is essential to distinguish between OneThing and Another, XKB considers only those modifier definitions for which all virtual modifiers are bound.

## Virtual Modifier Mapping

XKB maintains a virtual modifier mapping , which lists the virtual modifiers associated with each key. The real modifiers bound to a virtual modifier always include all of the modifiers bound to any of the keys that specify that virtual modifier in their virtual modifier mapping.

For example, if Mod3 is bound to the Num_Lock key by the core protocol modifier mapping, and the NumLock virtual modifier is bound to they Num_Lock key by the virtual modifier mapping, Mod3 is added to the set of modifiers associated with the NumLock virtual modifier.

The virtual modifier mapping is normally updated automatically whenever actions are assigned to keys (see Changing the Keyboard Mapping Using the Core Protocol for details) and few applications should need to change the virtual modifier mapping explicitly.