summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2008-04-29 08:41:52 +0000
committerBastien Nocera <hadess@src.gnome.org>2008-04-29 08:41:52 +0000
commit061b9187dda39297078c3e8137bfe59a125e23dd (patch)
tree20cee30d73e94279b90f6ed49b5ab751ba80a4c6
parent656f45516ec1b9d6cf947f7f0213eca44a0af11d (diff)
downloadgnome-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--ChangeLog9
-rw-r--r--plugins/common/gsd-keygrab.c56
2 files changed, 65 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 80302ea0..717e6931 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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));