[gtk/keymap-rework-2: 9/12] Reshuffle keymap docs



commit 93a1b3027d00e6efc0038195fcf1a8edaf88a165
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Apr 6 01:39:17 2020 -0400

    Reshuffle keymap docs
    
    Since GdkKeymap api is on longer public, move relevant
    documentation to the long description.

 gdk/gdkkeys.c | 123 +++++++++++++++++++++++++++++++++++++++-------------------
 1 file 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 {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]