diff options
author | Owen Taylor <otaylor@redhat.com> | 2003-08-21 19:23:39 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2003-08-21 19:23:39 +0000 |
commit | c7c5a7ddaa55e9a9d6f4ee2a2ee11d045f97ff6c (patch) | |
tree | 77a201c7a8fc1d8c1c7ffd68a4d091c842be1b16 /gdk/x11 | |
parent | 28a466a69cfcfcdadc70e0ecb7cfafec0d7a51a5 (diff) | |
download | gtk+-c7c5a7ddaa55e9a9d6f4ee2a2ee11d045f97ff6c.tar.gz |
Change the interpretation of consumed_modifiers so that it contains: -
Thu Aug 21 15:17:42 2003 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkkeys-x11.c: Change the interpretation
of consumed_modifiers so that it contains:
- Modifiers combinations actually found in
state.
- Single modifier modifier combinations.
But not multi-modifier combinations that aren't
in event->state. Document. (#100439)
Diffstat (limited to 'gdk/x11')
-rw-r--r-- | gdk/x11/gdkkeys-x11.c | 87 |
1 files changed, 76 insertions, 11 deletions
diff --git a/gdk/x11/gdkkeys-x11.c b/gdk/x11/gdkkeys-x11.c index cec1f10d20..d4e2f51c6b 100644 --- a/gdk/x11/gdkkeys-x11.c +++ b/gdk/x11/gdkkeys-x11.c @@ -841,9 +841,12 @@ gdk_keymap_lookup_key (GdkKeymap *keymap, } #ifdef HAVE_XKB -/* This is copied straight from XFree86 Xlib, because I needed to - * add the group and level return. It's unchanged for ease of - * diff against the Xlib sources; don't reformat it. +/* This is copied straight from XFree86 Xlib, to: + * - add the group and level return. + * - change the interpretation of mods_rtrn as described + * in the docs for gdk_keymap_translate_keyboard_state() + * It's unchanged for ease of diff against the Xlib sources; don't + * reformat it. */ static Bool MyEnhancedXkbTranslateKeyCode(register XkbDescPtr xkb, @@ -897,29 +900,48 @@ MyEnhancedXkbTranslateKeyCode(register XkbDescPtr xkb, if (type->map) { /* find the column (shift level) within the group */ register int i; register XkbKTMapEntryPtr entry; + /* ---- Begin section modified for GDK ---- */ + int found = 0; + for (i=0,entry=type->map;i<type->map_count;i++,entry++) { - if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) { + if (mods_rtrn) { + int bits = 0; + unsigned long tmp = entry->mods.mask; + while (tmp) { + if ((tmp & 1) == 1) + bits++; + tmp >>= 1; + } + /* We always add one-modifiers levels to mods_rtrn since + * they can't wipe out bits in the state unless the + * level would be triggered. But return other modifiers + * + */ + if (bits == 1 || (mods&type->mods.mask)==entry->mods.mask) + *mods_rtrn |= entry->mods.mask; + } + + if (!found&&entry->active&&((mods&type->mods.mask)==entry->mods.mask)) { col+= entry->level; if (type->preserve) preserve= type->preserve[i].mask; - /* ---- Begin stuff GDK adds to the original Xlib version ---- */ - if (level_rtrn) *level_rtrn = entry->level; - /* ---- End stuff GDK adds to the original Xlib version ---- */ - - break; + found = 1; } } + /* ---- End section modified for GDK ---- */ } if (keysym_rtrn!=NULL) *keysym_rtrn= syms[col]; if (mods_rtrn) { - *mods_rtrn= type->mods.mask&(~preserve); - + /* ---- Begin section modified for GDK ---- */ + *mods_rtrn &= ~preserve; + /* ---- End section modified for GDK ---- */ + /* ---- Begin stuff GDK comments out of the original Xlib version ---- */ /* This is commented out because xkb_info is a private struct */ @@ -1040,6 +1062,49 @@ translate_keysym (GdkKeymapX11 *keymap_x11, * affected by the active keyboard group. The @level is derived from * @state. For convenience, #GdkEventKey already contains the translated * keyval, so this function isn't as useful as you might think. + * + * <note><para> + * @consumed_modifiers gives modifiers that should be masked out + * from @state when comparing this key press to a hot key. For + * instance, on a US keyboard, the <literal>plus</literal> + * symbol is shifted, so when comparing a key press to a + * <literal><Control>plus</literal> accelerator <Shift> should + * be masked out. + * </para> + * <informalexample><programlisting> + * /* We want to ignore irrelevant modifiers like ScrollLock */ + * #define ALL_ACCELS_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK) + * gdk_keymap_translate_keyboard_state (keymap, event->hardware_keycode, + * event->state, event->group, + * &keyval, NULL, NULL, &consumed); + * if (keyval == GDK_PLUS && + * (event->state & ~consumed & ALL_ACCELS_MASK) == GDK_CONTROL_MASK) + * /* Control was pressed */ + * </programlisting></informalexample> + * <para> + * 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:</para> + * <informalexample><programlisting> + * /* XXX Don't do this XXX */ + * if (keyval == accel_keyval && + * (event->state & ~consumed & ALL_ACCELS_MASK) == (accel_mods & ~consumed)) + * /* Accelerator was pressed */ + * </programlisting></informalexample> + * <para> + * However, this did not work if multi-modifier combinations were + * used in the keymap, since, for instance, <literal><Control></literal> + * would be masked out even if only <literal><Control><Alt></literal> + * was used in the keymap. To support this usage as well as well as + * possible, all <emphasis>single modifier</emphasis> 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 <literal><Control>plus</literal>, + * not <literal><Control><Shift>plus</literal>, + * </para></note> * * Return value: %TRUE if there was a keyval bound to the keycode/state/group **/ |