[gnome-settings-daemon] Use virtual modifier <Super> for the Windows key



commit 469145ff59fe2a65d603cfeb5011427dc0f7c36b
Author: Ray Strode <rstrode redhat com>
Date:   Fri Jul 23 11:41:16 2010 -0400

    Use virtual modifier <Super> for the Windows key
    
    By making sure that we convert virtual modifiers to real ones when
    capturing keys with XGrabKey, and vice-versa when checking for
    XEvents.
    
    This is based heavily on a patch from
    
    Bastien Nocera <hadess hadess net>
    
    with just minor fixes.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=623223

 plugins/common/gsd-keygrab.c |   47 +++++++++++++++++++++++++++++++++++++++--
 plugins/media-keys/acme.h    |    2 +-
 2 files changed, 45 insertions(+), 4 deletions(-)
---
diff --git a/plugins/common/gsd-keygrab.c b/plugins/common/gsd-keygrab.c
index f00fdf3..ab01ccd 100644
--- a/plugins/common/gsd-keygrab.c
+++ b/plugins/common/gsd-keygrab.c
@@ -41,6 +41,10 @@ static GdkModifierType gsd_ignored_mods = 0;
  * for these set */
 static GdkModifierType gsd_used_mods = 0;
 
+/* Taken from a comment in XF86keysym.h */
+static guint gsd_unmodified_keysym_min = 0x10080001;
+static guint gsd_unmodified_keysym_max = 0x1008FFFF;
+
 static void
 setup_modifiers (void)
 {
@@ -120,12 +124,43 @@ grab_key_unsafe (Key                 *key,
         int   bit;
         int   bits_set_cnt;
         int   uppervalue;
-        guint mask;
+        guint mask, modifiers;
 
         setup_modifiers ();
 
         mask = gsd_ignored_mods & ~key->state & GDK_MODIFIER_MASK;
 
+        /* XGrabKey requires real modifiers, not virtual ones */
+        egg_keymap_resolve_virtual_modifiers (gdk_keymap_get_default (),
+					      key->state, &modifiers);
+
+        /* If key doesn't have a usable modifier, we don't want
+         * to grab it, since the user might lose a useful key.
+         *
+         * The exception is the XFree86 keys (which are useful to grab without
+         * a modifier).
+         */
+        if ((modifiers & gsd_used_mods) == 0 &&
+            ((key->keysym < gsd_unmodified_keysym_min) ||
+             (key->keysym > gsd_unmodified_keysym_max))) {
+                GString *keycodes;
+
+                keycodes = g_string_new ("");
+                if (key->keycodes != NULL) {
+                        guint *c;
+
+                        for (c = key->keycodes; *c; ++c) {
+                                g_string_printf (keycodes, " %u", *c);
+                        }
+                }
+                g_warning ("Key 0x%x (keycodes: %s)  with state 0x%x (resolved to 0x%x) "
+                           " has no usable modifiers (usable modifiers are 0x%x)",
+                           key->keysym, keycodes->str, key->state, modifiers, gsd_used_mods);
+                g_string_free (keycodes, TRUE);
+
+                return;
+        }
+
         bit = 0;
         /* store the indexes of all set bits in mask in the array */
         for (i = 0; mask; ++i, mask >>= 1) {
@@ -158,7 +193,7 @@ grab_key_unsafe (Key                 *key,
                                 grab_key_real (*code,
                                                gdk_screen_get_root_window (screen),
                                                grab,
-                                               result | key->state);
+                                               result | modifiers);
                         }
                 }
         }
@@ -226,6 +261,12 @@ match_key (Key *key, XEvent *event)
 					     event->xkey.state, group,
 					     &keyval, NULL, NULL, &consumed)) {
 		guint lower, upper;
+		guint mask;
+
+		/* The Key structure contains virtual modifiers, whereas
+		 * the XEvent will be using the real modifier, so translate those */
+		egg_keymap_resolve_virtual_modifiers (gdk_keymap_get_default (),
+						      key->state, &mask);
 
 		gdk_keyval_convert_case (keyval, &lower, &upper);
 
@@ -236,7 +277,7 @@ match_key (Key *key, XEvent *event)
 			consumed &= ~GDK_SHIFT_MASK;
 
 		return ((lower == key->keysym || upper == key->keysym)
-			&& (event->xkey.state & ~consumed & gsd_used_mods) == key->state);
+			&& (event->xkey.state & ~consumed & gsd_used_mods) == mask);
 	}
 
 	/* The key we passed doesn't have a keysym, so try with just the keycode */
diff --git a/plugins/media-keys/acme.h b/plugins/media-keys/acme.h
index d52535f..287f662 100644
--- a/plugins/media-keys/acme.h
+++ b/plugins/media-keys/acme.h
@@ -84,7 +84,7 @@ static struct {
         { FORWARD_KEY, "forward", "XF86AudioForward", NULL },
         { REPEAT_KEY, "repeat", "XF86AudioRepeat", NULL },
         { RANDOM_KEY, "random", "XF86AudioRandomPlay", NULL},
-        { VIDEO_OUT_KEY, NULL, "<Mod4>p", NULL },
+        { VIDEO_OUT_KEY, NULL, "<Super>p", NULL },
         /* Key code of the XF86Display key (Fn-F7 on Thinkpads, Fn-F4 on HP machines, etc.) */
         { VIDEO_OUT2_KEY, NULL, "XF86Display", NULL },
         /* Key code of the XF86RotateWindows key (present on some tablets) */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]