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"