starting to try figure out xkb and how to use it for better international/multilayout...
authorDana Jansens <danakj@orodu.net>
Tue, 9 Feb 2010 14:59:43 +0000 (09:59 -0500)
committerDana Jansens <danakj@orodu.net>
Wed, 10 Feb 2010 15:04:29 +0000 (10:04 -0500)
obt/display.c
obt/keyboard.c
openbox/event.c
openbox/menu.c
openbox/openbox.c
openbox/openbox.h

index f34fc574056915dc5151d4ea538ac12b7d4ddf48..37b1215737bf1117e3dc95dcd7839a65d76bcb01 100644 (file)
@@ -58,8 +58,8 @@ gboolean obt_display_open(const char *display_name)
     n = display_name ? g_strdup(display_name) : NULL;
     obt_display = d = XOpenDisplay(n);
     if (d) {
-        gint junk;
-        (void)junk;
+        gint junk, major, minor;
+        (void)junk, (void)major, (void)minor;
 
         if (fcntl(ConnectionNumber(d), F_SETFD, 1) == -1)
             g_message("Failed to set display as close-on-exec");
@@ -67,12 +67,14 @@ gboolean obt_display_open(const char *display_name)
 
         /* read what extensions are present */
 #ifdef XKB
+        major = XkbMajorVersion;
+        minor = XkbMinorVersion;
         obt_display_extension_xkb =
             XkbQueryExtension(d, &junk,
                               &obt_display_extension_xkb_basep, &junk,
-                              NULL, NULL);
+                              &major, &minor);
         if (!obt_display_extension_xkb)
-            g_message("XKB extension is not present on the server");
+            g_message("XKB extension is not present on the server or too old");
 #endif
 
 #ifdef SHAPE
index 6bb1386151ae619f735ff5e46b04fd8681619c35..a1d182834c0c57289dc30a3ae21890df25435c00 100644 (file)
@@ -64,6 +64,7 @@ void obt_keyboard_reload(void)
     /* note: modmap->max_keypermod can be 0 when there is no valid key layout
        available */
 
+
     XDisplayKeycodes(obt_display, &min_keycode, &max_keycode);
     keymap = XGetKeyboardMapping(obt_display, min_keycode,
                                  max_keycode - min_keycode + 1,
@@ -228,6 +229,9 @@ gunichar obt_keyboard_keycode_to_unichar(guint keycode)
         if (unikey == (gunichar)-1 || unikey == (gunichar)-2 || unikey == 0)
             unikey = 0;
     }
+    if (key) {
+        g_print("key %s\n", key);
+    }
     g_free(key);
     return unikey;
 }
index 1e6df48d487cc86eea08792f0d322969bace9228..b2f9be4eca9d34e2863ef83a933f92e8fa7768f0 100644 (file)
@@ -56,9 +56,6 @@
 #ifdef HAVE_UNISTD_H
 #  include <unistd.h> /* for usleep() */
 #endif
-#ifdef XKB
-#  include <X11/XKBlib.h>
-#endif
 
 #ifdef USE_SM
 #include <X11/ICE/ICElib.h>
@@ -141,6 +138,13 @@ void event_startup(gboolean reconfig)
     IceAddConnectionWatch(ice_watch, NULL);
 #endif
 
+#ifdef XKB
+    /* ask to be notified when the keyboard group changes */
+    if (obt_display_extension_xkb)
+        XkbSelectEventDetails(obt_display, XkbUseCoreKbd, XkbStateNotify,
+                              XkbGroupStateMask, XkbGroupStateMask);
+#endif
+
     client_add_destroy_notify(focus_delay_client_dest, NULL);
 }
 
@@ -650,14 +654,40 @@ static void event_process(const XEvent *ec, gpointer data)
         event_handle_root(e);
     else if (e->type == MapRequest)
         window_manage(window);
+#ifdef XKB
+    else if (obt_display_extension_xkb &&
+             e->type == obt_display_extension_xkb_basep)
+    {
+        switch (((XkbAnyEvent*)e)->xkb_type) {
+        case XkbStateNotify:
+            /* the effective xkb group changed, so they keyboard layout is now
+               different */
+            if (((XkbStateNotifyEvent*)e)->changed & XkbGroupStateMask)
+                ob_reconfigure_keyboard();
+
+            break;
+        default:
+            break;
+        }
+    }
+#endif
     else if (e->type == MappingNotify) {
-        /* keyboard layout changes for modifier mapping changes. reload the
-           modifier map, and rebind all the key bindings as appropriate */
-        ob_debug("Keyboard map changed. Reloading keyboard bindings.");
-        ob_set_state(OB_STATE_RECONFIGURING);
-        obt_keyboard_reload();
-        keyboard_rebind();
-        ob_set_state(OB_STATE_RUNNING);
+        ob_debug("MappingNotify");
+
+#ifdef XKB
+        /* the keyboard map changed, so we might need to listen on a new
+           device */
+        if (obt_display_extension_xkb) {
+            XkbSelectEvents(obt_display, XkbUseCoreKbd, XkbStateNotifyMask, 0);
+            XRefreshKeyboardMapping(&e->xmapping);
+            XkbSelectEventDetails(obt_display, XkbUseCoreKbd, XkbStateNotify,
+                                  XkbGroupStateMask, XkbGroupStateMask);
+        }
+#else
+        XRefreshKeyboardMapping(&e->xmapping);
+#endif
+
+        ob_reconfigure_keyboard();
     }
     else if (e->type == ClientMessage) {
         /* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for
index ac28ade967aef2c45dfe64332c5897d64d35ebee..812f124afa49015b2389d26f21ca83a302da87ca 100644 (file)
@@ -236,7 +236,7 @@ static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut,
             /* you have to use a printable ascii character for shortcuts
                don't allow space either, so you can have like "a _ b"
             */
-            if (VALID_SHORTCUT(*(i+1))) {
+            if (*(i+1)) {
                 shortcut = g_unichar_tolower(g_utf8_get_char(i+1));
                 *position = i - *strippedlabel;
                 *always_show = TRUE;
index d2b66b5b08516e62d41608d42df4443ec16d8b56..72a013f6a14e4b33e05d4a3a620c99535eb420f0 100644 (file)
@@ -718,6 +718,17 @@ void ob_reconfigure(void)
     ob_exit(0);
 }
 
+void ob_reconfigure_keyboard(void)
+{
+    /* keyboard mapping or group changed, so reload the keyboard map
+       and rebind all the key bindings */
+    ob_debug("Keyboard map changed. Reloading keyboard bindings.");
+    ob_set_state(OB_STATE_RECONFIGURING);
+    obt_keyboard_reload();
+    keyboard_rebind();
+    ob_set_state(OB_STATE_RUNNING);
+}
+
 void ob_exit(gint code)
 {
     exitcode = code;
index c43f0a61b53e50635584058fce5755f6178b9abf..be0c1f307a64422202f749e854bfc15adc9629af 100644 (file)
@@ -57,6 +57,7 @@ void ob_exit(gint code);
 void ob_exit_replace(void);
 
 void ob_reconfigure(void);
+void ob_reconfigure_keyboard(void);
 
 void ob_exit_with_error(const gchar *msg) G_GNUC_NORETURN;