From 13d69e552dffe681ee80c0600366a8c04fc205c6 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 12 Feb 2010 15:45:16 -0500 Subject: [PATCH] Fix a compatibility problem It turns out that my attempt at handling Super, Hyper and Meta better is causing problems, mostly because Alt and Meta are commonly colocated in the modmap, and apps do a check for the Alt modifier regularly. See e.g bug 607697. --- docs/reference/gdk/gdk-sections.txt | 1 + gdk/gdk.symbols | 1 + gdk/gdkkeys.h | 2 ++ gdk/quartz/gdkkeys-quartz.c | 7 +++++ gdk/win32/gdkkeys-win32.c | 6 ++++ gdk/x11/gdkevents-x11.c | 2 +- gdk/x11/gdkkeys-x11.c | 49 +++++++++++++++++++++++++++-- gtk/gtkkeyhash.c | 1 + 8 files changed, 66 insertions(+), 3 deletions(-) diff --git a/docs/reference/gdk/gdk-sections.txt b/docs/reference/gdk/gdk-sections.txt index 90ae3b20f6..5d05c993c8 100644 --- a/docs/reference/gdk/gdk-sections.txt +++ b/docs/reference/gdk/gdk-sections.txt @@ -1006,6 +1006,7 @@ gdk_keymap_get_entries_for_keycode gdk_keymap_get_direction gdk_keymap_have_bidi_layouts gdk_keymap_get_caps_lock_state +gdk_keymap_add_virtual_modifiers gdk_keymap_map_virtual_modifiers diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index 12967c425f..67ffb0a84e 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -852,6 +852,7 @@ gdk_keymap_have_bidi_layouts gdk_keymap_get_caps_lock_state gdk_keymap_lookup_key gdk_keymap_translate_keyboard_state +gdk_keymap_add_virtual_modifiers gdk_keymap_map_virtual_modifiers gdk_keyval_convert_case gdk_keyval_from_name diff --git a/gdk/gdkkeys.h b/gdk/gdkkeys.h index 6fe55f7bb2..a6750ce439 100644 --- a/gdk/gdkkeys.h +++ b/gdk/gdkkeys.h @@ -108,6 +108,8 @@ gboolean gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap, PangoDirection gdk_keymap_get_direction (GdkKeymap *keymap); gboolean gdk_keymap_have_bidi_layouts (GdkKeymap *keymap); gboolean gdk_keymap_get_caps_lock_state (GdkKeymap *keymap); +void gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap, + GdkModifierType *state); gboolean gdk_keymap_map_virtual_modifiers (GdkKeymap *keymap, GdkModifierType *state); diff --git a/gdk/quartz/gdkkeys-quartz.c b/gdk/quartz/gdkkeys-quartz.c index a277af35d1..52b08677a5 100644 --- a/gdk/quartz/gdkkeys-quartz.c +++ b/gdk/quartz/gdkkeys-quartz.c @@ -652,6 +652,13 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap, return TRUE; } +void +gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap, + GdkModifierType *state) +{ + /* FIXME: For now, we've mimiced the Windows backend. */ +} + gboolean gdk_keymap_map_virtual_modifiers (GdkKeymap *keymap, GdkModifierType *state) diff --git a/gdk/win32/gdkkeys-win32.c b/gdk/win32/gdkkeys-win32.c index 52858d1d04..eff2ebec80 100644 --- a/gdk/win32/gdkkeys-win32.c +++ b/gdk/win32/gdkkeys-win32.c @@ -872,6 +872,12 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap, return tmp_keyval != GDK_VoidSymbol; } +void +gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap, + GdkModifierType *state) +{ +} + gboolean gdk_keymap_map_virtual_modifiers (GdkKeymap *keymap, GdkModifierType *state) diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index a9efe76af1..1f27497f3f 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -636,7 +636,7 @@ translate_key_event (GdkDisplay *display, &event->key.keyval, NULL, NULL, &consumed); state = event->key.state & ~consumed; - _gdk_keymap_add_virtual_modifiers (keymap, &state); + _gdk_keymap_add_virtual_modifiers_compat (keymap, &state); event->key.state |= state; event->key.is_modifier = _gdk_keymap_key_is_modifier (keymap, event->key.hardware_keycode); diff --git a/gdk/x11/gdkkeys-x11.c b/gdk/x11/gdkkeys-x11.c index f7d7a9099d..3863f4abe5 100644 --- a/gdk/x11/gdkkeys-x11.c +++ b/gdk/x11/gdkkeys-x11.c @@ -1657,8 +1657,8 @@ _gdk_x11_get_group_for_state (GdkDisplay *display, } void -_gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap, - GdkModifierType *modifiers) +_gdk_keymap_add_virtual_modifiers_compat (GdkKeymap *keymap, + GdkModifierType *modifiers) { GdkKeymapX11 *keymap_x11; int i; @@ -1666,6 +1666,51 @@ _gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap, keymap = GET_EFFECTIVE_KEYMAP (keymap); keymap_x11 = GDK_KEYMAP_X11 (keymap); + for (i = 3; i < 8; i++) + { + if ((1 << i) & *modifiers) + { + if (keymap_x11->modmap[i] & GDK_MOD1_MASK) + *modifiers |= GDK_MOD1_MASK; + else if (keymap_x11->modmap[i] & GDK_SUPER_MASK) + *modifiers |= GDK_SUPER_MASK; + else if (keymap_x11->modmap[i] & GDK_HYPER_MASK) + *modifiers |= GDK_HYPER_MASK; + else if (keymap_x11->modmap[i] & GDK_META_MASK) + *modifiers |= GDK_META_MASK; + } + } +} + +/** + * gdk_keymap_add_virtual_modifiers: + * @keymap: a #GdkKeymap + * @modifiers: pointer to the modifier mask to change + * + * Adds virtual modifiers (i.e. Super, Hyper and Meta) which correspond + * to the real modifiers (i.e Mod2, Mod3, ...) in @modifiers. + * are set in @state to their non-virtual counterparts (i.e. Mod2, + * Mod3,...) and set the corresponding bits in @modifiers. + * + * GDK already does this before delivering key events, but for + * compatibility reasons, it only sets the first virtual modifier + * it finds, whereas this function sets all matching virtual modifiers. + * + * This function is useful when matching key events against + * accelerators. + * + * Since: 2.20 + */ +void +gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap, + GdkModifierType *modifiers) +{ + GdkKeymapX11 *keymap_x11; + int i; + + keymap = GET_EFFECTIVE_KEYMAP (keymap); + keymap_x11 = GDK_KEYMAP_X11 (keymap); + for (i = 3; i < 8; i++) { if ((1 << i) & *modifiers) diff --git a/gtk/gtkkeyhash.c b/gtk/gtkkeyhash.c index 368699cc18..cbe0b7747c 100644 --- a/gtk/gtkkeyhash.c +++ b/gtk/gtkkeyhash.c @@ -404,6 +404,7 @@ _gtk_key_hash_lookup (GtkKeyHash *key_hash, gdk_keymap_translate_keyboard_state (key_hash->keymap, hardware_keycode, state, group, &keyval, &effective_group, &level, &consumed_modifiers); + gdk_keymap_add_virtual_modifiers (key_hash->keymap, &state); GTK_NOTE (KEYBINDINGS, g_message ("Looking up keycode = %u, modifiers = 0x%04x,\n"