442 lines
14 KiB
XML
442 lines
14 KiB
XML
|
<chapter id='Keyboard_State'>
|
||
|
<title>Keyboard State</title>
|
||
|
<para>
|
||
|
The core protocol description of
|
||
|
keyboard state consists of eight <emphasis>
|
||
|
modifiers</emphasis>
|
||
|
(<emphasis>
|
||
|
Shift</emphasis>
|
||
|
, <emphasis>
|
||
|
Lock</emphasis>
|
||
|
, <emphasis>
|
||
|
Control</emphasis>
|
||
|
, and <emphasis>
|
||
|
Mod1</emphasis>
|
||
|
-<emphasis>
|
||
|
Mod5</emphasis>
|
||
|
). A modifier reports the state of one or modifier keys, which are similar to
|
||
|
qualifier keys as defined by the ISO9995 standard:
|
||
|
</para>
|
||
|
|
||
|
<variablelist>
|
||
|
<varlistentry>
|
||
|
<term>Qualifier key</term>
|
||
|
<listitem>
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
</varlistentry>
|
||
|
</variablelist>
|
||
|
|
||
|
<para>
|
||
|
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 <emphasis>
|
||
|
QueryPointer</emphasis>
|
||
|
request.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The XKB extension retains the eight "real" modifiers defined by the core
|
||
|
protocol but extends the core protocol notion of <emphasis>
|
||
|
keyboard state</emphasis>
|
||
|
to include up to four <emphasis>
|
||
|
keysym groups</emphasis>
|
||
|
, as defined by the ISO9995 standard:
|
||
|
</para>
|
||
|
|
||
|
|
||
|
<variablelist>
|
||
|
<varlistentry>
|
||
|
<term>Group:</term>
|
||
|
<listitem>
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
</varlistentry>
|
||
|
</variablelist>
|
||
|
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
|
||
|
<sect1 id='Locking_and_Latching_Modifiers_and_Groups'>
|
||
|
<title>Locking and Latching Modifiers and Groups</title>
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
|
||
|
</sect1>
|
||
|
<sect1 id='Fundamental_Components_of_XKB_Keyboard_State'>
|
||
|
<title>Fundamental Components of XKB Keyboard State</title>
|
||
|
<para>
|
||
|
The fundamental components of XKB keyboard state include:
|
||
|
</para>
|
||
|
|
||
|
<itemizedlist>
|
||
|
<listitem>
|
||
|
<para>The locked modifiers and group</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>The latched modifiers and group</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>The base modifiers and group (for which keys are physically or
|
||
|
logically down)
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>The effective modifiers and group (the cumulative effect of the base,
|
||
|
locked and latched modifier and group states).
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>State of the core pointer buttons.</para>
|
||
|
</listitem>
|
||
|
</itemizedlist>
|
||
|
|
||
|
<para>
|
||
|
The latched and locked state of modifiers and groups can be changed in response
|
||
|
to keyboard activity or under application control using the <emphasis>
|
||
|
XkbLatchLockState</emphasis>
|
||
|
request. The base modifier, base group
|
||
|
and pointer button states always reflect the logical state of the keyboard and
|
||
|
pointer and change <emphasis>
|
||
|
only</emphasis>
|
||
|
in response to keyboard or pointer activity.
|
||
|
</para>
|
||
|
|
||
|
<sect2 id='Computing_Effective_Modifier_and_Group'>
|
||
|
<title>Computing Effective Modifier and Group</title>
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The effective modifiers are simply the bitwise union of the base, latched and
|
||
|
locked modifiers.
|
||
|
</para>
|
||
|
|
||
|
|
||
|
<para>
|
||
|
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
|
||
|
<emphasis>
|
||
|
Group1</emphasis>
|
||
|
-<emphasis>
|
||
|
Group4</emphasis>
|
||
|
, so they are adjusted into range as specified by the global <emphasis>
|
||
|
GroupsWrap </emphasis>
|
||
|
control as follows:
|
||
|
</para>
|
||
|
|
||
|
<itemizedlist>
|
||
|
<listitem>
|
||
|
<para>
|
||
|
If the <emphasis>
|
||
|
RedirectIntoRange</emphasis>
|
||
|
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 <emphasis>
|
||
|
Group1</emphasis>.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>
|
||
|
If the <emphasis>
|
||
|
ClampIntoRange</emphasis>
|
||
|
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 <emphasis>
|
||
|
Group1</emphasis>
|
||
|
are mapped to <emphasis>
|
||
|
Group1</emphasis>
|
||
|
. For example, a key with two groups of symbols uses <emphasis>
|
||
|
Group2</emphasis>
|
||
|
type and symbols if the global effective group is either <emphasis>
|
||
|
Group3</emphasis>
|
||
|
or <emphasis>
|
||
|
Group4</emphasis>.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>
|
||
|
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 <emphasis>
|
||
|
Group1</emphasis>
|
||
|
symbols if the global effective group is <emphasis>
|
||
|
Group3</emphasis>
|
||
|
or <emphasis>
|
||
|
Group2</emphasis>
|
||
|
symbols if the global effective group is <emphasis>
|
||
|
Group4</emphasis>.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
</itemizedlist>
|
||
|
|
||
|
<para>
|
||
|
The base and latched keyboard groups are unrestricted eight-bit integer values
|
||
|
and are not affected by the <emphasis>
|
||
|
GroupsWrap</emphasis>
|
||
|
control.
|
||
|
</para>
|
||
|
|
||
|
</sect2>
|
||
|
|
||
|
<sect2 id='Computing_A_State_Field_from_an_XKB_State'>
|
||
|
<title>Computing A State Field from an XKB State</title>
|
||
|
<para>
|
||
|
Many events report the keyboard state
|
||
|
in a single <emphasis>
|
||
|
state</emphasis>
|
||
|
field. Using XKB, a state field combines modifiers, group and the pointer
|
||
|
button state into a single sixteen bit value as follows:
|
||
|
</para>
|
||
|
|
||
|
<itemizedlist>
|
||
|
<listitem>
|
||
|
<para>Bits 0 through 7 (the least significant eight bits) of the effective
|
||
|
state comprise a mask of type KEYMASK which reports the state modifiers.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>Bits 8 through 12 comprise a mask of type BUTMASK which reports pointer
|
||
|
button state.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>Bits 13 and 14 are interpreted as a two-bit unsigned numeric value and
|
||
|
report the state keyboard group.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>Bit 15 (the most significant bit) is reserved and must be zero.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
</itemizedlist>
|
||
|
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
|
||
|
</sect2>
|
||
|
</sect1>
|
||
|
|
||
|
<sect1 id='Derived_Components_of_XKB_Keyboard_State'>
|
||
|
<title>Derived Components of XKB Keyboard State</title>
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
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 <emphasis>
|
||
|
ServerInternalModifiers</emphasis>
|
||
|
, <emphasis>
|
||
|
IgnoreLocksModifiers</emphasis>
|
||
|
and <emphasis>
|
||
|
IgnoreGroupLock</emphasis>
|
||
|
controls, described in <link linkend='Server_Internal_Modifiers_and_Ignore_Locks_Behavior'>Server
|
||
|
Internal Modifiers and Ignore Locks Behavior</link>, to derive these two
|
||
|
states as follows:
|
||
|
</para>
|
||
|
|
||
|
<itemizedlist>
|
||
|
<listitem>
|
||
|
<para>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.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>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.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
</itemizedlist>
|
||
|
|
||
|
<sect2 id='Server_Internal_Modifiers_and_Ignore_Locks_Behavior'>
|
||
|
<title>Server Internal Modifiers and Ignore Locks Behavior</title>
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
The modifiers specified in the mask of the <emphasis>
|
||
|
InternalMods</emphasis>
|
||
|
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.
|
||
|
</para>
|
||
|
|
||
|
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
|
||
|
|
||
|
<para>
|
||
|
The locked state of the modifiers specified in mask of the <emphasis>
|
||
|
IgnoreLockMods</emphasis>
|
||
|
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 <emphasis>
|
||
|
IgnoreGroupLock</emphasis>
|
||
|
control is set, the locked state of the
|
||
|
keyboard group is not considered when activating passive grabs.
|
||
|
</para>
|
||
|
|
||
|
|
||
|
<para>
|
||
|
Without XKB, the passive grab set by a translation (e.g. <emphasis>
|
||
|
Alt<KeyPress>space</emphasis>
|
||
|
) 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.
|
||
|
</para>
|
||
|
|
||
|
|
||
|
</sect2>
|
||
|
</sect1>
|
||
|
<sect1 id='Compatibility_Components_of_Keyboard_State'>
|
||
|
<title>Compatibility Components of Keyboard State</title>
|
||
|
<para>
|
||
|
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
|
||
|
<link linkend='Computing_A_State_Field_from_an_XKB_State'>Computing A State Field from an
|
||
|
XKB State</link>.
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
This modified state field would not be interpreted correctly by XKB-unaware
|
||
|
clients, so XKB provides a <emphasis>
|
||
|
group compatibility mapping</emphasis>
|
||
|
(see <link linkend='Group_Compatibility_Map'>Group Compatibility Map</link>) 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:
|
||
|
</para>
|
||
|
|
||
|
<itemizedlist>
|
||
|
<listitem>
|
||
|
<para>
|
||
|
The <emphasis>
|
||
|
compatibility state</emphasis>
|
||
|
corresponds to the effective modifier
|
||
|
and effective group state.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>
|
||
|
The <emphasis>
|
||
|
compatibility lookup state</emphasis>
|
||
|
is the core-protocol equivalent of the
|
||
|
lookup state.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
<listitem>
|
||
|
<para>
|
||
|
The <emphasis>
|
||
|
compatibility grab state</emphasis>
|
||
|
is the nearest core-protocol equivalent
|
||
|
of the grab state.
|
||
|
</para>
|
||
|
</listitem>
|
||
|
</itemizedlist>
|
||
|
|
||
|
<para>
|
||
|
Compatibility states are essentially the corresponding XKB state, but with
|
||
|
keyboard group possibly encoded as one or more modifiers; <link linkend='Group_Compatibility_Map'>Group Compatibility Map</link> describes
|
||
|
the group compatibility map, which specifies the modifier(s) that correspond to
|
||
|
each keyboard group.
|
||
|
</para>
|
||
|
|
||
|
|
||
|
<para>
|
||
|
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 <emphasis>
|
||
|
Mode_switch</emphasis>
|
||
|
is not reported in any event except (Device)KeyPress and (Device)KeyRelease
|
||
|
events that do not trigger a passive grab.
|
||
|
</para>
|
||
|
|
||
|
<note>
|
||
|
<para>
|
||
|
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 <emphasis>
|
||
|
directly</emphasis>
|
||
|
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.
|
||
|
</para>
|
||
|
</note>
|
||
|
|
||
|
<para>
|
||
|
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.
|
||
|
</para>
|
||
|
</sect1>
|
||
|
</chapter>
|