XCB_CFLAGS += $(call cflags_for_lib, xcb-util)
XCB_LIBS += $(call ldflags_for_lib, xcb-util)
endif
+XCB_XKB_LIBS := $(call ldflags_for_lib, xcb-xkb,xcb-xkb)
# XCB keyboard stuff
XCB_KBD_CFLAGS := $(call cflags_for_lib, xcb-keysyms)
XCB_WM_LIBS += $(call ldflags_for_lib, xcb-xinerama,xcb-xinerama)
XCB_WM_LIBS += $(call ldflags_for_lib, xcb-randr,xcb-randr)
-# Xlib
-X11_CFLAGS := $(call cflags_for_lib, x11)
-X11_LIBS := $(call ldflags_for_lib, x11,X11)
+XKB_COMMON_CFLAGS := $(call cflags_for_lib, xkbcommon,xkbcommon)
+XKB_COMMON_LIBS := $(call ldflags_for_lib, xkbcommon,xkbcommon)
+XKB_COMMON_X11_CFLAGS := $(call cflags_for_lib, xkbcommon-x11,xkbcommon-x11)
+XKB_COMMON_X11_LIBS := $(call ldflags_for_lib, xkbcommon-x11,xkbcommon-x11)
# Xcursor
XCURSOR_CFLAGS := $(call cflags_for_lib, xcb-cursor)
libxcb-randr0-dev,
libxcb-icccm4-dev,
libxcb-cursor-dev,
+ libxcb-xkb-dev,
+ libxkbcommon-dev,
+ libxkbcommon-x11-dev,
asciidoc (>= 8.4.4),
xmlto,
docbook-xml,
i3_config_wizard_SOURCES := $(wildcard i3-config-wizard/*.c)
i3_config_wizard_HEADERS := $(wildcard i3-config-wizard/*.h)
-i3_config_wizard_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(X11_CFLAGS) $(PANGO_CFLAGS)
-i3_config_wizard_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(X11_LIBS) $(PANGO_LIBS)
+i3_config_wizard_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS) $(XKB_COMMON_CFLAGS) $(XKB_COMMON_X11_CFLAGS)
+i3_config_wizard_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) $(XKB_COMMON_LIBS) $(XKB_COMMON_X11_LIBS)
i3_config_wizard_OBJECTS := $(i3_config_wizard_SOURCES:.c=.o)
#include <xcb/xcb_event.h>
#include <xcb/xcb_keysyms.h>
+#include <xkbcommon/xkbcommon.h>
+#include <xkbcommon/xkbcommon-x11.h>
+
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
static xcb_gcontext_t pixmap_gc;
static xcb_key_symbols_t *symbols;
xcb_window_t root;
-Display *dpy;
+static struct xkb_keymap *xkb_keymap;
+static uint8_t xkb_base_event;
+static uint8_t xkb_base_error;
static void finish();
* This reduces a lot of confusion for users who switch keyboard
* layouts from qwerty to qwertz or other slight variations of
* qwerty (yes, that happens quite often). */
- KeySym sym = XkbKeycodeToKeysym(dpy, keycode, 0, 0);
- if (!keysym_used_on_other_key(sym, keycode))
+ const xkb_keysym_t *syms;
+ int num = xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, 0, 0, &syms);
+ if (num == 0)
+ errx(1, "xkb_keymap_key_get_syms_by_level returned no symbols for keycode %d", keycode);
+ if (!keysym_used_on_other_key(syms[0], keycode))
level = 0;
}
- KeySym sym = XkbKeycodeToKeysym(dpy, keycode, 0, level);
- char *str = XKeysymToString(sym);
+
+ const xkb_keysym_t *syms;
+ int num = xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, 0, level, &syms);
+ if (num == 0)
+ errx(1, "xkb_keymap_key_get_syms_by_level returned no symbols for keycode %d", keycode);
+ if (num > 1)
+ printf("xkb_keymap_key_get_syms_by_level (keycode = %d) returned %d symbolsinstead of 1, using only the first one.\n", keycode, num);
+
+ char str[4096];
+ if (xkb_keysym_get_name(syms[0], str, sizeof(str)) == -1)
+ errx(EXIT_FAILURE, "xkb_keysym_get_name(%u) failed", syms[0]);
const char *release = get_string("release");
char *res;
char *modrep = (modifiers == NULL ? sstrdup("") : sstrdup(modifiers));
static void finish() {
printf("creating \"%s\"...\n", config_path);
- if (!(dpy = XOpenDisplay(NULL)))
- errx(1, "Could not connect to X11");
+ struct xkb_context *xkb_context;
+
+ if ((xkb_context = xkb_context_new(0)) == NULL)
+ errx(1, "could not create xkbcommon context");
+
+ int32_t device_id = xkb_x11_get_core_keyboard_device_id(conn);
+ if ((xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, conn, device_id, 0)) == NULL)
+ errx(1, "xkb_x11_keymap_new_from_device failed");
FILE *kc_config = fopen(SYSCONFDIR "/i3/config.keycodes", "r");
if (kc_config == NULL)
xcb_connection_has_error(conn))
errx(1, "Cannot open display\n");
+ if (xkb_x11_setup_xkb_extension(conn,
+ XKB_X11_MIN_MAJOR_XKB_VERSION,
+ XKB_X11_MIN_MINOR_XKB_VERSION,
+ 0,
+ NULL,
+ NULL,
+ &xkb_base_event,
+ &xkb_base_error) != 1)
+ errx(EXIT_FAILURE, "Could not setup XKB extension.");
+
if (socket_path == NULL)
socket_path = root_atom_contents("I3_SOCKET_PATH", conn, screen);
i3bar_SOURCES := $(wildcard i3bar/src/*.c)
i3bar_HEADERS := $(wildcard i3bar/include/*.h)
-i3bar_CFLAGS = $(XCB_CFLAGS) $(X11_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS)
-i3bar_LIBS = $(XCB_LIBS) $(X11_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS)
+i3bar_CFLAGS = $(XCB_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS)
+i3bar_LIBS = $(XCB_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) $(XCB_XKB_LIBS)
i3bar_OBJECTS := $(i3bar_SOURCES:.c=.o)
*
*/
#include <xcb/xcb.h>
+#include <xcb/xkb.h>
#include <xcb/xproto.h>
#include <xcb/xcb_aux.h>
int bar_height;
/* These are only relevant for XKB, which we only need for grabbing modifiers */
-Display *xkb_dpy;
-int xkb_event_base;
+int xkb_base;
int mod_pressed = 0;
/* Because the statusline is the same on all outputs, we have
}
while ((event = xcb_poll_for_event(xcb_connection)) != NULL) {
- switch (event->response_type & ~0x80) {
+ int type = (event->response_type & ~0x80);
+
+ if (type == xkb_base && xkb_base > -1) {
+ DLOG("received an xkb event\n");
+
+ xcb_xkb_state_notify_event_t *state = (xcb_xkb_state_notify_event_t *)event;
+ if (state->xkbType == XCB_XKB_STATE_NOTIFY) {
+ int modstate = state->mods & config.modifier;
+
+#define DLOGMOD(modmask, status) \
+ do { \
+ switch (modmask) { \
+ case ShiftMask: \
+ DLOG("ShiftMask got " #status "!\n"); \
+ break; \
+ case ControlMask: \
+ DLOG("ControlMask got " #status "!\n"); \
+ break; \
+ case Mod1Mask: \
+ DLOG("Mod1Mask got " #status "!\n"); \
+ break; \
+ case Mod2Mask: \
+ DLOG("Mod2Mask got " #status "!\n"); \
+ break; \
+ case Mod3Mask: \
+ DLOG("Mod3Mask got " #status "!\n"); \
+ break; \
+ case Mod4Mask: \
+ DLOG("Mod4Mask got " #status "!\n"); \
+ break; \
+ case Mod5Mask: \
+ DLOG("Mod5Mask got " #status "!\n"); \
+ break; \
+ } \
+ } while (0)
+
+ if (modstate != mod_pressed) {
+ if (modstate == 0) {
+ DLOGMOD(config.modifier, released);
+ if (!activated_mode)
+ hide_bars();
+ } else {
+ DLOGMOD(config.modifier, pressed);
+ activated_mode = false;
+ unhide_bars();
+ }
+ mod_pressed = modstate;
+ }
+#undef DLOGMOD
+ }
+
+ free(event);
+ continue;
+ }
+
+ switch (type) {
case XCB_EXPOSE:
/* Expose-events happen, when the window needs to be redrawn */
redraw_bars();
void xcb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
}
-/*
- * We need to bind to the modifier per XKB. Sadly, XCB does not implement this
- *
- */
-void xkb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
- XkbEvent ev;
- int modstate = 0;
-
- DLOG("Got XKB-Event!\n");
-
- while (XPending(xkb_dpy)) {
- XNextEvent(xkb_dpy, (XEvent *)&ev);
-
- if (ev.type != xkb_event_base) {
- ELOG("No Xkb-Event!\n");
- continue;
- }
-
- if (ev.any.xkb_type != XkbStateNotify) {
- ELOG("No State Notify!\n");
- continue;
- }
-
- unsigned int mods = ev.state.mods;
- modstate = mods & config.modifier;
- }
-
-#define DLOGMOD(modmask, status) \
- do { \
- switch (modmask) { \
- case ShiftMask: \
- DLOG("ShiftMask got " #status "!\n"); \
- break; \
- case ControlMask: \
- DLOG("ControlMask got " #status "!\n"); \
- break; \
- case Mod1Mask: \
- DLOG("Mod1Mask got " #status "!\n"); \
- break; \
- case Mod2Mask: \
- DLOG("Mod2Mask got " #status "!\n"); \
- break; \
- case Mod3Mask: \
- DLOG("Mod3Mask got " #status "!\n"); \
- break; \
- case Mod4Mask: \
- DLOG("Mod4Mask got " #status "!\n"); \
- break; \
- case Mod5Mask: \
- DLOG("Mod5Mask got " #status "!\n"); \
- break; \
- } \
- } while (0)
-
- if (modstate != mod_pressed) {
- if (modstate == 0) {
- DLOGMOD(config.modifier, released);
- if (!activated_mode)
- hide_bars();
- } else {
- DLOGMOD(config.modifier, pressed);
- activated_mode = false;
- unhide_bars();
- }
- mod_pressed = modstate;
- }
-
-#undef DLOGMOD
-}
-
/*
* Early initialization of the connection to X11: Everything which does not
* depend on 'config'.
*
*/
void register_xkb_keyevents() {
- if (xkb_dpy == NULL) {
- int xkb_major, xkb_minor, xkb_errbase, xkb_err;
- xkb_major = XkbMajorVersion;
- xkb_minor = XkbMinorVersion;
-
- xkb_dpy = XkbOpenDisplay(NULL,
- &xkb_event_base,
- &xkb_errbase,
- &xkb_major,
- &xkb_minor,
- &xkb_err);
-
- if (xkb_dpy == NULL) {
- ELOG("No XKB!\n");
- exit(EXIT_FAILURE);
- }
-
- if (fcntl(ConnectionNumber(xkb_dpy), F_SETFD, FD_CLOEXEC) == -1) {
- ELOG("Could not set FD_CLOEXEC on xkbdpy: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- int i1;
- if (!XkbQueryExtension(xkb_dpy, &i1, &xkb_event_base, &xkb_errbase, &xkb_major, &xkb_minor)) {
- ELOG("XKB not supported by X-server!\n");
- exit(EXIT_FAILURE);
- }
-
- if (!XkbSelectEvents(xkb_dpy, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask)) {
- ELOG("Could not grab Key!\n");
- exit(EXIT_FAILURE);
- }
-
- xkb_io = smalloc(sizeof(ev_io));
- ev_io_init(xkb_io, &xkb_io_cb, ConnectionNumber(xkb_dpy), EV_READ);
- ev_io_start(main_loop, xkb_io);
- XFlush(xkb_dpy);
+ const xcb_query_extension_reply_t *extreply;
+ extreply = xcb_get_extension_data(conn, &xcb_xkb_id);
+ if (!extreply->present) {
+ ELOG("xkb is not present on this server\n");
+ exit(EXIT_FAILURE);
}
+ DLOG("initializing xcb-xkb\n");
+ xcb_xkb_use_extension(conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
+ xcb_xkb_select_events(conn,
+ XCB_XKB_ID_USE_CORE_KBD,
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
+ 0,
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
+ 0xff,
+ 0xff,
+ NULL);
+ xkb_base = extreply->first_event;
}
/*
*
*/
void deregister_xkb_keyevents() {
- if (xkb_dpy != NULL) {
- ev_io_stop(main_loop, xkb_io);
- XCloseDisplay(xkb_dpy);
- close(xkb_io->fd);
- FREE(xkb_io);
- xkb_dpy = NULL;
- }
+ xcb_xkb_select_events(conn,
+ XCB_XKB_ID_USE_CORE_KBD,
+ 0,
+ 0,
+ 0,
+ 0xff,
+ 0xff,
+ NULL);
}
/*
#include <xcb/randr.h>
extern int randr_base;
+extern int xkb_base;
/**
* Adds the given sequence to the list of events which are ignored.
#include <sys/resource.h>
#include <xcb/xcb_keysyms.h>
+#include <xcb/xkb.h>
#include <X11/XKBlib.h>
*/
#include "all.h"
+#include <xkbcommon/xkbcommon.h>
+
pid_t command_error_nagbar_pid = -1;
/*
continue;
/* We need to translate the symbol to a keycode */
- keysym = XStringToKeysym(bind->symbol);
- if (keysym == NoSymbol) {
+ keysym = xkb_keysym_from_name(bind->symbol, XKB_KEYSYM_NO_FLAGS);
+ if (keysym == XKB_KEY_NoSymbol) {
ELOG("Could not translate string to key symbol: \"%s\"\n",
bind->symbol);
continue;
*
*/
#include "all.h"
-
-/* We need Xlib for XStringToKeysym */
-#include <X11/Xlib.h>
+#include <xkbcommon/xkbcommon.h>
char *current_configpath = NULL;
Config config;
#include <libsn/sn-monitor.h>
int randr_base = -1;
+int xkb_base = -1;
+int xkb_current_group;
/* After mapping/unmapping windows, a notify event is generated. However, we don’t want it,
since it’d trigger an infinite loop of switching between the different windows when
*
*/
void handle_event(int type, xcb_generic_event_t *event) {
+ DLOG("event type %d, xkb_base %d\n", type, xkb_base);
if (randr_base > -1 &&
type == randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
handle_screen_change(event);
return;
}
+ if (xkb_base > -1 && type == xkb_base) {
+ DLOG("xkb event, need to handle it.\n");
+
+ xcb_xkb_state_notify_event_t *state = (xcb_xkb_state_notify_event_t *)event;
+ if (state->xkbType == XCB_XKB_MAP_NOTIFY) {
+ if (event_is_ignored(event->sequence, type)) {
+ DLOG("Ignoring map notify event for sequence %d.\n", state->sequence);
+ } else {
+ DLOG("xkb map notify, sequence %d, time %d\n", state->sequence, state->time);
+ add_ignore_event(event->sequence, type);
+ ungrab_all_keys(conn);
+ translate_keysyms();
+ grab_all_keys(conn, false);
+ }
+ } else if (state->xkbType == XCB_XKB_STATE_NOTIFY) {
+ DLOG("xkb state group = %d\n", state->group);
+
+ /* See The XKB Extension: Library Specification, section 14.1 */
+ /* We check if the current group (each group contains
+ * two levels) has been changed. Mode_switch activates
+ * group XkbGroup2Index */
+ if (xkb_current_group == state->group)
+ return;
+ xkb_current_group = state->group;
+ if (state->group == XCB_XKB_GROUP_1) {
+ DLOG("Mode_switch disabled\n");
+ ungrab_all_keys(conn);
+ grab_all_keys(conn, false);
+ } else {
+ DLOG("Mode_switch enabled\n");
+ grab_all_keys(conn, false);
+ }
+ }
+
+ return;
+ }
+
switch (type) {
case XCB_KEY_PRESS:
case XCB_KEY_RELEASE:
i3_SOURCES := $(filter-out $(i3_SOURCES_GENERATED),$(wildcard src/*.c))
i3_HEADERS_CMDPARSER := $(wildcard include/GENERATED_*.h)
i3_HEADERS := $(filter-out $(i3_HEADERS_CMDPARSER),$(wildcard include/*.h))
-i3_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(XCB_WM_CFLAGS) $(X11_CFLAGS) $(XCURSOR_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS) $(PCRE_CFLAGS) $(LIBSN_CFLAGS)
-i3_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(XCB_WM_LIBS) $(X11_LIBS) $(XCURSOR_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) $(PCRE_LIBS) $(LIBSN_LIBS) -lm -lpthread
+i3_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(XCB_WM_CFLAGS) $(XCURSOR_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS) $(PCRE_CFLAGS) $(LIBSN_CFLAGS)
+i3_LIBS = $(XKB_COMMON_LIBS) $(XCB_LIBS) $(XCB_XKB_LIBS) $(XCB_KBD_LIBS) $(XCB_WM_LIBS) $(XCURSOR_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) $(PCRE_LIBS) $(LIBSN_LIBS) -lm -lpthread
# When using clang, we use pre-compiled headers to speed up the build. With
# gcc, this actually makes the build slower.
* temporarily for drag_pointer(). */
static struct ev_check *xcb_check;
-static int xkb_event_base;
-
-int xkb_current_group;
-
extern Con *focused;
char **start_argv;
xcb_key_symbols_t *keysyms;
-/* Those are our connections to X11 for use with libXcursor and XKB */
-Display *xlibdpy, *xkbdpy;
-
/* Default shmlog size if not set by user. */
const int default_shmlog_size = 25 * 1024 * 1024;
/* We hope that those are supported and set them to true */
bool xcursor_supported = true;
-bool xkb_supported = true;
/* This will be set to true when -C is used so that functions can behave
* slightly differently. We don’t want i3-nagbar to be started when validating
}
}
-/*
- * When using xmodmap to change the keyboard mapping, this event
- * is only sent via XKB. Therefore, we need this special handler.
- *
- */
-static void xkb_got_event(EV_P_ struct ev_io *w, int revents) {
- DLOG("Handling XKB event\n");
- XkbEvent ev;
-
- /* When using xmodmap, every change (!) gets an own event.
- * Therefore, we just read all events and only handle the
- * mapping_notify once. */
- bool mapping_changed = false;
- while (XPending(xkbdpy)) {
- XNextEvent(xkbdpy, (XEvent *)&ev);
- /* While we should never receive a non-XKB event,
- * better do sanity checking */
- if (ev.type != xkb_event_base)
- continue;
-
- if (ev.any.xkb_type == XkbMapNotify) {
- mapping_changed = true;
- continue;
- }
-
- if (ev.any.xkb_type != XkbStateNotify) {
- ELOG("Unknown XKB event received (type %d)\n", ev.any.xkb_type);
- continue;
- }
-
- /* See The XKB Extension: Library Specification, section 14.1 */
- /* We check if the current group (each group contains
- * two levels) has been changed. Mode_switch activates
- * group XkbGroup2Index */
- if (xkb_current_group == ev.state.group)
- continue;
-
- xkb_current_group = ev.state.group;
-
- if (ev.state.group == XkbGroup2Index) {
- DLOG("Mode_switch enabled\n");
- grab_all_keys(conn, true);
- }
-
- if (ev.state.group == XkbGroup1Index) {
- DLOG("Mode_switch disabled\n");
- ungrab_all_keys(conn);
- grab_all_keys(conn, false);
- }
- }
-
- if (!mapping_changed)
- return;
-
- DLOG("Keyboard mapping changed, updating keybindings\n");
- xcb_key_symbols_free(keysyms);
- keysyms = xcb_key_symbols_alloc(conn);
-
- xcb_numlock_mask = aio_get_mod_mask_for(XCB_NUM_LOCK, keysyms);
-
- ungrab_all_keys(conn);
- DLOG("Re-grabbing...\n");
- translate_keysyms();
- grab_all_keys(conn, (xkb_current_group == XkbGroup2Index));
- DLOG("Done\n");
-}
-
/*
* Exit handler which destroys the main_loop. Will trigger cleanup handlers.
*
#include "atoms.xmacro"
#undef xmacro
- /* Initialize the Xlib connection */
- xlibdpy = xkbdpy = XOpenDisplay(NULL);
-
- /* Try to load the X cursors and initialize the XKB extension */
- if (xlibdpy == NULL) {
- ELOG("ERROR: XOpenDisplay() failed, disabling libXcursor/XKB support\n");
- xcursor_supported = false;
- xkb_supported = false;
- } else if (fcntl(ConnectionNumber(xlibdpy), F_SETFD, FD_CLOEXEC) == -1) {
- ELOG("Could not set FD_CLOEXEC on xkbdpy\n");
- return 1;
- } else {
- xcursor_load_cursors();
- /*init_xkb();*/
- }
+ xcursor_load_cursors();
/* Set a cursor for the root window (otherwise the root window will show no
cursor until the first client is launched). */
else
xcb_set_root_cursor(XCURSOR_CURSOR_POINTER);
- if (xkb_supported) {
- int errBase,
- major = XkbMajorVersion,
- minor = XkbMinorVersion;
-
- if (fcntl(ConnectionNumber(xkbdpy), F_SETFD, FD_CLOEXEC) == -1) {
- fprintf(stderr, "Could not set FD_CLOEXEC on xkbdpy\n");
- return 1;
- }
-
- int i1;
- if (!XkbQueryExtension(xkbdpy, &i1, &xkb_event_base, &errBase, &major, &minor)) {
- fprintf(stderr, "XKB not supported by X-server\n");
- xkb_supported = false;
- }
- /* end of ugliness */
-
- if (xkb_supported && !XkbSelectEvents(xkbdpy, XkbUseCoreKbd, XkbMapNotifyMask | XkbStateNotifyMask, XkbMapNotifyMask | XkbStateNotifyMask)) {
- fprintf(stderr, "Could not set XKB event mask\n");
- return 1;
- }
+ const xcb_query_extension_reply_t *extreply;
+ extreply = xcb_get_extension_data(conn, &xcb_xkb_id);
+ if (!extreply->present) {
+ DLOG("xkb is not present on this server\n");
+ } else {
+ DLOG("initializing xcb-xkb\n");
+ xcb_xkb_use_extension(conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
+ xcb_xkb_select_events(conn,
+ XCB_XKB_ID_USE_CORE_KBD,
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY,
+ 0,
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY,
+ 0xff,
+ 0xff,
+ NULL);
+ xkb_base = extreply->first_event;
}
restore_connect();
ewmh_update_number_of_desktops();
struct ev_io *xcb_watcher = scalloc(sizeof(struct ev_io));
- struct ev_io *xkb = scalloc(sizeof(struct ev_io));
xcb_check = scalloc(sizeof(struct ev_check));
struct ev_prepare *xcb_prepare = scalloc(sizeof(struct ev_prepare));
ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ);
ev_io_start(main_loop, xcb_watcher);
- if (xkb_supported) {
- ev_io_init(xkb, xkb_got_event, ConnectionNumber(xkbdpy), EV_READ);
- ev_io_start(main_loop, xkb);
-
- /* Flush the buffer so that libev can properly get new events */
- XFlush(xkbdpy);
- }
-
ev_check_init(xcb_check, xcb_check_cb);
ev_check_start(main_loop, xcb_check);