[gtk+] wayland: Implement virtual modifiers
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] wayland: Implement virtual modifiers
- Date: Sat, 16 Apr 2016 02:23:03 +0000 (UTC)
commit 64c2a65cc07e8beb11ada231a9f8e13b2e9abbb1
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 46d2631..d73199f 100644
--- a/gdk/wayland/gdkkeys-wayland.c
+++ b/gdk/wayland/gdkkeys-wayland.c
@@ -373,14 +373,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]