[mutter] backend-x11: Ensure the Xkb group index remains properly set



commit 2857fdbdb887fcaa2e2f25d268c34ae039646e78
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Wed Oct 14 03:14:14 2015 +0300

    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 files changed, 13 insertions(+), 3 deletions(-)
---
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
index dbcd13f..a645bbd 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);
 }
 


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