[gtk+/gtk-3-20] wayland: Implement virtual modifiers



commit 4018a32e0b15047032e54d9a911bd9856b89ab34
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Apr 15 22:20:25 2016 -0400

    wayland: Implement virtual modifiers
    
    Since Wayland is using libxkbcommon, it inherits X unfortunate
    real/virtual modifier distinction, so we have to do the same
    gymnastics we do for X to map between the two.
    
    This should fix matching of accelerators using virtual modifiers
    (modulo gnome-shell bugs regarding the handling of Super).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=764424

 gdk/wayland/gdkkeys-wayland.c |   52 +++++++++++++++++++++++++++++++++++++++-
 1 files changed, 50 insertions(+), 2 deletions(-)
---
diff --git a/gdk/wayland/gdkkeys-wayland.c b/gdk/wayland/gdkkeys-wayland.c
index 4819ab6..c8190c4 100644
--- a/gdk/wayland/gdkkeys-wayland.c
+++ b/gdk/wayland/gdkkeys-wayland.c
@@ -370,14 +370,62 @@ static void
 gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap       *keymap,
                                          GdkModifierType *state)
 {
-  return;
+  struct xkb_keymap *xkb_keymap;
+  struct xkb_state *xkb_state;
+  xkb_mod_index_t idx;
+  uint32_t mods, real;
+  struct { const char *name; GdkModifierType mask; } vmods[] = {
+    { "Super", GDK_SUPER_MASK },
+    { "Hyper", GDK_HYPER_MASK },
+    { "Meta", GDK_META_MASK },
+    { NULL, 0 }
+  };
+  int i;
+
+  xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
+  mods = get_xkb_modifiers (xkb_keymap, *state);
+
+  xkb_state = xkb_state_new (xkb_keymap);
+
+  for (i = 0; vmods[i].name; i++)
+    {
+      idx = xkb_keymap_mod_get_index (xkb_keymap, vmods[i].name);
+      if (idx == XKB_MOD_INVALID)
+        continue;
+
+      xkb_state_update_mask (xkb_state, 1 << idx, 0, 0, 0, 0, 0);
+      real = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
+      real &= 0xff;
+      if (mods & real)
+        *state |= vmods[i].mask;
+      xkb_state_update_mask (xkb_state, 0, 0, 0, 0, 0, 0);
+    }
+
+  xkb_state_unref (xkb_state);
 }
 
 static gboolean
 gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap       *keymap,
                                          GdkModifierType *state)
 {
-  return TRUE;
+  struct xkb_keymap *xkb_keymap;
+  struct xkb_state *xkb_state;
+  uint32_t mods, mapped;
+  gboolean ret = TRUE;
+
+  xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
+  mods = get_xkb_modifiers (xkb_keymap, *state);
+
+  xkb_state = xkb_state_new (xkb_keymap);
+  xkb_state_update_mask (xkb_state, mods, 0, 0, 0, 0, 0);
+  mapped = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
+  if ((mapped & mods & 0xff) != 0)
+    ret = FALSE;
+  *state = get_gdk_modifiers (xkb_keymap, mapped);
+
+  xkb_state_unref (xkb_state);
+
+  return ret;
 }
 
 static void


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