forked from AuroraMiddleware/gtk
71aac48042
[`func@Foo`] is not the right link syntax either.
114 lines
5.6 KiB
Markdown
114 lines
5.6 KiB
Markdown
Title: Key Values
|
||
|
||
## Functions for manipulating keyboard codes
|
||
|
||
Key values are the codes which are sent whenever a key is pressed or released.
|
||
They are included in the data contained in a key press or release `GdkEvent`.
|
||
The complete list of key values can be found in the `gdk/gdkkeysyms.h` header
|
||
file.
|
||
|
||
Key values are regularly updated from the upstream X.org X11 implementation,
|
||
so new values are added regularly. They will be prefixed with GDK_KEY_ rather
|
||
than XF86XK_ or XK_ (for older symbols).
|
||
|
||
Key values can be converted into a string representation using
|
||
gdk_keyval_name(). The reverse function, converting a string to a key value,
|
||
is provided by gdk_keyval_from_name().
|
||
|
||
The case of key values can be determined using gdk_keyval_is_upper() and
|
||
gdk_keyval_is_lower(). Key values can be converted to upper or lower case
|
||
using gdk_keyval_to_upper() and gdk_keyval_to_lower().
|
||
|
||
When it makes sense, key values can be converted to and from
|
||
Unicode characters with gdk_keyval_to_unicode() and gdk_unicode_to_keyval().
|
||
|
||
## Key groups
|
||
|
||
At the lowest level, physical keys on the keyboard are represented by
|
||
numeric keycodes, and GDK knows how to translate these keycodes into
|
||
key values according to the configured keyboard layout and the current
|
||
state of the keyboard. In the GDK api, the mapping from keycodes to key
|
||
values is available via [method@Gdk.Display.map_keycode], and the reverse
|
||
mapping is available via [method@Gdk.Display.map_keyval]. The results of
|
||
these functions are returned in [struct@Gdk.KeymapKey] structures.
|
||
|
||
You can think of a [struct@Gdk.KeymapKey] as a representation of a symbol
|
||
printed on a physical keyboard key. That is, it contains three pieces of
|
||
information:
|
||
|
||
1. first, it contains the hardware keycode; this is an identifying number
|
||
for a physical key
|
||
1. second, it contains the “level” of the key. The level indicates which
|
||
symbol on the key will be used, in a vertical direction. So on a standard
|
||
US keyboard, the key with the number “1“ on it also has the exclamation
|
||
point (”!”) character on it. The level indicates whether to use the “1”
|
||
or the “!” symbol. The letter keys are considered to have a lowercase
|
||
letter at level 0, and an uppercase letter at level 1, though normally
|
||
only the uppercase letter is printed on the key
|
||
1. third, the [struct@Gdk.KeymapKey] contains a group; groups are not used on
|
||
standard US keyboards, but are used in many other countries. On a
|
||
keyboard with groups, there can be 3 or 4 symbols printed on a single
|
||
key. The group indicates movement in a horizontal direction. Usually
|
||
groups are used for two different languages. In group 0, a key might
|
||
have two English characters, and in group 1 it might have two Hebrew
|
||
characters. The Hebrew characters will be printed on the key next to
|
||
the English characters.
|
||
|
||
When GDK creates a key event in order to deliver a key press or release,
|
||
it first converts the current keyboard state into an effective group and
|
||
level. This is done via a set of rules that varies widely according to
|
||
type of keyboard and user configuration. The input to this translation
|
||
consists of the hardware keycode pressed, the active modifiers, and the
|
||
active group. It then applies the appropriate rules, and returns the
|
||
group/level to be used to index the keymap, along with the modifiers
|
||
which did not affect the group and level. i.e. it returns “unconsumed
|
||
modifiers.” The keyboard group may differ from the effective group used
|
||
for lookups because some keys don't have multiple groups - e.g. the
|
||
<kbd>Enter</kbd> key is always in group 0 regardless of keyboard state.
|
||
|
||
The results of the translation, including the keyval, are all included
|
||
in the key event and can be obtained via [class@Gdk.KeyEvent] getters.
|
||
|
||
### Consumed modifiers
|
||
|
||
The `consumed_modifiers` in a key event are modifiers that should be masked
|
||
out from @state when comparing this key press to a hot key. For instance,
|
||
on a US keyboard, the `plus` symbol is shifted, so when comparing a key
|
||
press to a `<Control>plus` accelerator `<Shift>` should be masked out.
|
||
|
||
```c
|
||
// We want to ignore irrelevant modifiers like ScrollLock
|
||
#define ALL_ACCELS_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_ALT_MASK)
|
||
state = gdk_event_get_modifier_state (event);
|
||
gdk_keymap_translate_keyboard_state (keymap,
|
||
gdk_key_event_get_keycode (event),
|
||
state,
|
||
gdk_key_event_get_group (event),
|
||
&keyval, NULL, NULL, &consumed);
|
||
if (keyval == GDK_PLUS &&
|
||
(state & ~consumed & ALL_ACCELS_MASK) == GDK_CONTROL_MASK)
|
||
// Control was pressed
|
||
```
|
||
|
||
An older interpretation of `consumed_modifiers` was that it contained
|
||
all modifiers that might affect the translation of the key;
|
||
this allowed accelerators to be stored with irrelevant consumed
|
||
modifiers, by doing:
|
||
|
||
```c
|
||
// XXX Don’t do this XXX
|
||
if (keyval == accel_keyval &&
|
||
(state & ~consumed & ALL_ACCELS_MASK) == (accel_mods & ~consumed))
|
||
// Accelerator was pressed
|
||
```
|
||
|
||
However, this did not work if multi-modifier combinations were
|
||
used in the keymap, since, for instance, `<Control>` would be
|
||
masked out even if only `<Control><Alt>` was used in
|
||
the keymap. To support this usage as well as well as possible, all single
|
||
modifier combinations that could affect the key for any combination
|
||
of modifiers will be returned in `consumed_modifiers`; multi-modifier
|
||
combinations are returned only when actually found in `state`. When
|
||
you store accelerators, you should always store them with consumed
|
||
modifiers removed. Store `<Control>plus`, not `<Control><Shift>plus`.
|