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
This commit is contained in:
@ -373,14 +373,62 @@ static void
|
|||||||
gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap,
|
gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap,
|
||||||
GdkModifierType *state)
|
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
|
static gboolean
|
||||||
gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap,
|
gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap,
|
||||||
GdkModifierType *state)
|
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
|
static void
|
||||||
|
Reference in New Issue
Block a user