diff options
author | Bastien Nocera <hadess@hadess.net> | 2008-04-29 08:41:52 +0000 |
---|---|---|
committer | Bastien Nocera <hadess@src.gnome.org> | 2008-04-29 08:41:52 +0000 |
commit | 061b9187dda39297078c3e8137bfe59a125e23dd (patch) | |
tree | 20cee30d73e94279b90f6ed49b5ab751ba80a4c6 | |
parent | 656f45516ec1b9d6cf947f7f0213eca44a0af11d (diff) | |
download | gnome-settings-daemon-061b9187dda39297078c3e8137bfe59a125e23dd.tar.gz |
When checking whether a key matches our key event, check the keysym from
2008-04-29 Bastien Nocera <hadess@hadess.net>
* plugins/common/gsd-keygrab.c (have_xkb), (match_key):
When checking whether a key matches our key event, check
the keysym from the key event, to avoid triggering another
keybindings with the same keycode, but different keysym,
Fixes Eject being triggered when pressing the Stop key with the
default inet keymap (Closes: #530356)
svn path=/trunk/; revision=326
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | plugins/common/gsd-keygrab.c | 56 |
2 files changed, 65 insertions, 0 deletions
@@ -1,3 +1,12 @@ +2008-04-29 Bastien Nocera <hadess@hadess.net> + + * plugins/common/gsd-keygrab.c (have_xkb), (match_key): + When checking whether a key matches our key event, check + the keysym from the key event, to avoid triggering another + keybindings with the same keycode, but different keysym, + Fixes Eject being triggered when pressing the Stop key with the + default inet keymap (Closes: #530356) + 2008-04-23 Vincent Untz <vuntz@gnome.org> * configure.ac: post release version bump. diff --git a/plugins/common/gsd-keygrab.c b/plugins/common/gsd-keygrab.c index 165f7038..6c7375bb 100644 --- a/plugins/common/gsd-keygrab.c +++ b/plugins/common/gsd-keygrab.c @@ -24,6 +24,11 @@ #include <gdk/gdk.h> #include <gdk/gdkx.h> +#ifdef HAVE_X11_EXTENSIONS_XKB_H +#include <X11/XKBlib.h> +#include <X11/extensions/XKB.h> +#include <gdk/gdkkeysyms.h> +#endif #include "gsd-keygrab.h" @@ -119,9 +124,60 @@ grab_key (Key *key, } } +static gboolean +have_xkb (Display *dpy) +{ + static int have_xkb = -1; + + if (have_xkb == -1) { +#ifdef HAVE_X11_EXTENSIONS_XKB_H + int opcode, error_base, major, minor, xkb_event_base; + + gdk_error_trap_push (); + have_xkb = XkbQueryExtension (dpy, + &opcode, + &xkb_event_base, + &error_base, + &major, + &minor) + && XkbUseExtension (dpy, &major, &minor); + gdk_error_trap_pop (); +#else + have_xkb = 0; +#endif + } + + return have_xkb; +} + gboolean match_key (Key *key, XEvent *event) { + GdkKeymap *keymap; + guint keyval; + GdkModifierType consumed; + gint group; + + if (key == NULL) + return FALSE; + + keymap = gdk_keymap_get_default (); + if (have_xkb (event->xkey.display)) + group = XkbGroupForCoreState (event->xkey.state); + else + group = (event->xkey.state & GDK_Mode_switch) ? 1 : 0; + /* Check if we find a keysym that matches our current state */ + if (gdk_keymap_translate_keyboard_state (keymap, event->xkey.keycode, + event->xkey.state, group, + &keyval, NULL, NULL, &consumed)) { + guint lower, upper; + + gdk_keyval_convert_case (keyval, &lower, &upper); + return ((lower == key->keysym || upper == key->keysym) + && (key->state & ~consumed & GSD_USED_MODS) == key->state); + } + + /* The key we passed doesn't have a keysym, so try with just the keycode */ return (key != NULL && key->keycode == event->xkey.keycode && key->state == (event->xkey.state & GSD_USED_MODS)); |