From 2857fdbdb887fcaa2e2f25d268c34ae039646e78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberts=20Muktup=C4=81vels?= Date: Wed, 14 Oct 2015 03:14:14 +0300 Subject: [PATCH] backend-x11: Ensure the Xkb group index remains properly set Ubuntu ships a patch in the X server that makes the group switch keybindings only work on key release, i.e. the X server internal group locking happens on key release which means that mutter gets the XKB_KEY_ISO_Next_Group key press event, does its XLockGroup() call with a new index and then, on key release, the X server moves the index further again. We can work around this without affecting our behavior in unpatched X servers by doing a XLockGroup() every time we're notified of the locked group changing if it doesn't match what we requested. https://bugzilla.gnome.org/show_bug.cgi?id=756543 --- src/backends/x11/meta-backend-x11.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index dbcd13fd2..a645bbd08 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -82,6 +82,7 @@ struct _MetaBackendX11Private gchar *keymap_layouts; gchar *keymap_variants; gchar *keymap_options; + int locked_group; }; typedef struct _MetaBackendX11Private MetaBackendX11Private; @@ -297,15 +298,23 @@ handle_host_xevent (MetaBackend *backend, if (event->type == priv->xkb_event_base) { - XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event; + XkbEvent *xkb_ev = (XkbEvent *) event; - if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID) + if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID) { - switch (xkb_ev->xkb_type) + switch (xkb_ev->any.xkb_type) { case XkbNewKeyboardNotify: case XkbMapNotify: keymap_changed (backend); + break; + case XkbStateNotify: + if (xkb_ev->state.changed & XkbGroupLockMask) + { + if (priv->locked_group != xkb_ev->state.locked_group) + XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, priv->locked_group); + } + break; default: break; } @@ -776,6 +785,7 @@ meta_backend_x11_lock_layout_group (MetaBackend *backend, MetaBackendX11 *x11 = META_BACKEND_X11 (backend); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + priv->locked_group = idx; XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, idx); }