diff --git a/Makefile b/Makefile index 63ea71c..fc4a521 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ CFLAGS ?= -O2 -g WARN_CFLAGS = -Wall -Wextra IBUS_CFLAGS = $(shell $(PKG_CONFIG) --cflags dbus-1 xkbcommon) IBUS_LIBS = $(shell $(PKG_CONFIG) --libs dbus-1 xkbcommon) -XIM_CFLAGS = $(shell $(PKG_CONFIG) --cflags xcb-imdkit xkbcommon-x11) -XIM_LIBS = $(shell $(PKG_CONFIG) --libs xcb-imdkit xkbcommon-x11) +XIM_CFLAGS = $(shell $(PKG_CONFIG) --cflags xcb-imdkit xcb-xkb xkbcommon-x11) +XIM_LIBS = $(shell $(PKG_CONFIG) --libs xcb-imdkit xcb-xkb xkbcommon-x11) TEXT_CFLAGS = $(shell $(PKG_CONFIG) --cflags pangocairo cairo) TEXT_LIBS = $(shell $(PKG_CONFIG) --libs pangocairo cairo) POPUP_CFLAGS = $(shell $(PKG_CONFIG) --cflags xcb-randr) diff --git a/tests/Makefile b/tests/Makefile index aa4b8be..53a1c13 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -18,8 +18,8 @@ IBUS_CLIENT_CFLAGS = $(shell $(PKG_CONFIG) --cflags ibus-1.0) IBUS_CLIENT_LIBS = $(shell $(PKG_CONFIG) --libs ibus-1.0) X11_CFLAGS = $(shell $(PKG_CONFIG) --cflags x11) X11_LIBS = $(shell $(PKG_CONFIG) --libs x11) -XIM_CFLAGS = $(shell $(PKG_CONFIG) --cflags xcb-imdkit xkbcommon-x11) -XIM_LIBS = $(shell $(PKG_CONFIG) --libs xcb-imdkit xkbcommon-x11) +XIM_CFLAGS = $(shell $(PKG_CONFIG) --cflags xcb-imdkit xcb-xkb xkbcommon-x11) +XIM_LIBS = $(shell $(PKG_CONFIG) --libs xcb-imdkit xcb-xkb xkbcommon-x11) UNIT_LDLIBS = -lthread -lbio $(TEXT_LIBS) $(IBUS_LIBS) $(XIM_LIBS) PROG = unit_test diff --git a/xim/xim.c b/xim/xim.c index 977da11..dc90091 100644 --- a/xim/xim.c +++ b/xim/xim.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ enum static xcb_connection_t *conn; static xcb_im_t *xim; static struct xkb_state *kstate; +static uint8_t xkbevent; static xcb_window_t rootwin; static Ic *ics; static Ic *preowner; @@ -55,6 +57,7 @@ ximlog(char *msg) fprint(2, "strans: xim: %s\n", msg); } +/* Reads the server's keymap; XKB-aware clients get XKB events, not MappingNotify. */ static int kinit(void) { @@ -70,7 +73,7 @@ kinit(void) context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if(context == nil || !xkb_x11_setup_xkb_extension(conn, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION, - XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, nil, nil, nil, nil)) + XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, nil, nil, &xkbevent, nil)) goto out; device = xkb_x11_get_core_keyboard_device_id(conn); if(device < 0) @@ -93,6 +96,22 @@ out: return ok; } +static void +kwatch(void) +{ + u16int events, parts; + + events = XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | + XCB_XKB_EVENT_TYPE_MAP_NOTIFY; + parts = XCB_XKB_MAP_PART_KEY_TYPES | XCB_XKB_MAP_PART_KEY_SYMS | + XCB_XKB_MAP_PART_MODIFIER_MAP | + XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | + XCB_XKB_MAP_PART_KEY_ACTIONS | XCB_XKB_MAP_PART_VIRTUAL_MODS | + XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP; + xcb_xkb_select_events(conn, XCB_XKB_ID_USE_CORE_KBD, events, 0, + events, parts, parts, nil); +} + static xcb_screen_t* getscreen(int scr) { @@ -472,6 +491,7 @@ ximinit(void) ximlog("cannot read keyboard mapping"); return -1; } + kwatch(); win = xcb_generate_id(conn); xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, screen->root, 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, @@ -511,7 +531,7 @@ ximthread(void *arg) break; while((ev = xcb_poll_for_event(conn)) != nil){ type = ev->response_type & ~0x80; - if(type == XCB_MAPPING_NOTIFY){ + if(type == xkbevent){ if(kinit() < 0) ximlog("cannot refresh keyboard mapping"); }else