[caribou] xadapter: get all group information from libxklavier



commit ea323335ac66a5633f00fd62c9284e6bff7bdeb5
Author: Dan Winship <danw gnome org>
Date:   Thu Jun 2 12:56:01 2011 -0400

    xadapter: get all group information from libxklavier
    
    The XkbStateNotifyEvent "group" field does not seem to correspond
    reliably to libxklavier group numbers, resulting in warnings and
    crashes when we try to look up the libxklavier group name
    corresponding to an apparently-bogus group number.
    
    Fix this by using Xkl.State's group rather than the Xkb event's.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=651724

 libcaribou/external-libs.vapi |    2 +-
 libcaribou/libxklavier.vapi   |    2 +-
 libcaribou/xadapter.vala      |   38 ++++++++++++++++++++++++--------------
 3 files changed, 26 insertions(+), 16 deletions(-)
---
diff --git a/libcaribou/external-libs.vapi b/libcaribou/external-libs.vapi
index 6a87d33..bab3978 100644
--- a/libcaribou/external-libs.vapi
+++ b/libcaribou/external-libs.vapi
@@ -48,7 +48,7 @@ namespace Xkb {
     [CCode (cname = "XkbStateNotifyEvent", free_function = "")]
     public struct StateNotifyEvent {
         uint changed;
-        int group;
+        int locked_group;
         uint mods;
     }
 
diff --git a/libcaribou/libxklavier.vapi b/libcaribou/libxklavier.vapi
index 7d31572..23c386e 100644
--- a/libcaribou/libxklavier.vapi
+++ b/libcaribou/libxklavier.vapi
@@ -65,7 +65,7 @@ namespace Xkl {
 		[NoWrapper]
 		public virtual void config_notify ();
 		public void delete_state (X.Window win);
-		public int filter_events (X.Event evt);
+		public int filter_events (X.Event* evt);
 		public unowned string get_backend_name ();
 		public unowned Xkl.State get_current_state ();
 		public X.Window get_current_window ();
diff --git a/libcaribou/xadapter.vala b/libcaribou/xadapter.vala
index cad827b..8b6b196 100644
--- a/libcaribou/xadapter.vala
+++ b/libcaribou/xadapter.vala
@@ -35,7 +35,8 @@ namespace Caribou {
         HashTable<uint, KeyButtonHandler> key_funcs;
 
         construct {
-            Xkb.State state;
+            Xkb.State xkb_state;
+            unowned Xkl.State xkl_state;
 
             Gdk.Window rootwin = Gdk.get_default_root_window();
             this.xdisplay = Gdk.X11Display.get_xdisplay (rootwin.get_display ());
@@ -44,11 +45,15 @@ namespace Caribou {
                                              Xkb.GBN_AllComponentsMask,
                                              Xkb.UseCoreKbd);
             this.xkl_engine = Xkl.Engine.get_instance (this.xdisplay);
+            xkl_engine.start_listen (Xkl.EngineListenModes.TRACK_KEYBOARD_STATE);
+            xkl_state = this.xkl_engine.get_current_state ();
+            this.group = (uchar) xkl_state.group;
+            Signal.connect_object (xkl_engine, "X-state-changed",
+                                   (Callback) xkl_state_changed,
+                                   this, ConnectFlags.AFTER);
 
-            Xkb.get_state (this.xdisplay, Xkb.UseCoreKbd, out state);
-
-            this.group = state.group;
-            this.modifiers = state.mods;
+            Xkb.get_state (this.xdisplay, Xkb.UseCoreKbd, out xkb_state);
+            this.modifiers = xkb_state.mods;
 
             this.reserved_keycode = 0;
 
@@ -78,8 +83,10 @@ namespace Caribou {
 
         private Gdk.FilterReturn x_event_filter (Gdk.XEvent xevent, Gdk.Event event) {
             void* pointer = &xevent;
-            Xkb.Event *xkbev = (Xkb.Event *) pointer;
-            X.Event *xev = (X.Event *) pointer;
+            Xkb.Event* xkbev = (Xkb.Event *) pointer;
+            X.Event* xev = (X.Event *) pointer;
+
+			this.xkl_engine.filter_events(xev);
 
             if (xev.type == X.EventType.ButtonPress ||
                 xev.type == X.EventType.ButtonRelease) {
@@ -98,13 +105,7 @@ namespace Caribou {
                                 xev.type == X.EventType.KeyPress);
             } else if (xkbev.any.xkb_type == Xkb.StateNotify) {
                 Xkb.StateNotifyEvent *sevent = &xkbev.state;
-                if ((sevent.changed & Xkb.GroupStateMask) != 0) {
-                    string group_name;
-                    string variant_name;
-                    this.group = (uchar) sevent.group;
-                    get_current_group (out group_name, out variant_name);
-                    group_changed (this.group, group_name, variant_name);
-                } else if ((sevent.changed & Xkb.ModifierStateMask) != 0) {
+				if ((sevent.changed & Xkb.ModifierStateMask) != 0) {
                     this.modifiers = (uchar) sevent.mods;
                 }
             }
@@ -112,6 +113,15 @@ namespace Caribou {
             return Gdk.FilterReturn.CONTINUE;
         }
 
+		private static void xkl_state_changed (Xkl.Engine xklengine, int type, int group, bool restore, XAdapter self) {
+			string group_name;
+			string variant_name;
+
+			self.group = (uchar) group;
+			self.get_current_group (out group_name, out variant_name);
+			self.group_changed (self.group, group_name, variant_name);
+		}
+
         private uchar get_reserved_keycode () {
             uchar i;
             unowned Xkb.Desc xkbdesc = this.xkbdesc;



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