diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-04-06 01:39:17 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-04-06 16:32:03 -0400 |
commit | 93a1b3027d00e6efc0038195fcf1a8edaf88a165 (patch) | |
tree | 01f72371d0b92da5ce659e5ea0fc72a335ad532c /gdk/gdkkeys.c | |
parent | 1de7719e342b9e6e6341d17293b3e921c11e282a (diff) | |
download | gtk+-93a1b3027d00e6efc0038195fcf1a8edaf88a165.tar.gz |
Reshuffle keymap docs
Since GdkKeymap api is on longer public, move relevant
documentation to the long description.
Diffstat (limited to 'gdk/gdkkeys.c')
-rw-r--r-- | gdk/gdkkeys.c | 123 |
1 files changed, 84 insertions, 39 deletions
diff --git a/gdk/gdkkeys.c b/gdk/gdkkeys.c index 1fed1045ea..469d204e0b 100644 --- a/gdk/gdkkeys.c +++ b/gdk/gdkkeys.c @@ -36,8 +36,9 @@ * @Title: Key Values * * Key values are the codes which are sent whenever a key is pressed or released. - * They appear in the #GdkEventKey.keyval field of the #GdkEventKey structure. - * The complete list of key values can be found in the `gdk/gdkkeysyms.h` header file. + * 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 @@ -56,43 +57,87 @@ * * # Groups # {#key-group-explanation} * - * One #GdkKeymap object exists for each user display. To obtain keymaps for - * a display, use gdk_display_get_keymap(). A keymap is a mapping from - * #GdkKeymapKey to key values. You can think of a #GdkKeymapKey as a - * representation of a symbol printed on a physical keyboard key. That is, it - * contains three pieces of information. First, it contains the hardware keycode; - * this is an identifying number for a physical key. 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 only the uppercase letter is printed. Third, the - * #GdkKeymapKey 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. - * - * In order to use a keymap to interpret a key event, it’s necessary to first - * convert the 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 function gdk_keymap_translate_keyboard_state() accepts a - * keyboard state -- consisting of hardware keycode pressed, active modifiers, and - * active group -- 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 keymap lookups because some keys don't - * have multiple groups - e.g. the Enter key is always in group 0 regardless of - * keyboard state. - * - * Note that gdk_keymap_translate_keyboard_state() also returns the keyval, i.e. it - * goes ahead and performs the keymap lookup in addition to telling you which - * effective group/level values were used for the lookup. #GdkEventKey already - * contains this keyval, however, so you don’t normally need to call - * gdk_keymap_translate_keyboard_state() just to get the keyval. + * 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 gdk_display_map_keycode(), and the reverse mapping + * is available via gdk_display_map_keyval(). The results of these functions + * are returned in #GdkKeymapKey structs. + * + * You can think of a #GdkKeymapKey as a representation of a symbol printed on + * a physical keyboard key. That is, it contains three pieces of information. + * First, it contains the hardware keycode; this is an identifying number for + * a physical key. 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. Third, the #GdkKeymapKey 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 Enter + * 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 #GdkEvent 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. + * + * |[<!-- language="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 @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: + * |[<!-- language="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`. */ enum { |