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");
/* 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
/* 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,
if (unikey == (gunichar)-1 || unikey == (gunichar)-2 || unikey == 0)
unikey = 0;
}
+ if (key) {
+ g_print("key %s\n", key);
+ }
g_free(key);
return unikey;
}
#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>
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);
}
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
/* 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;
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;
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;