diff --git a/i3-config-wizard/main.c b/i3-config-wizard/main.c index db4b623e..d66eda08 100644 --- a/i3-config-wizard/main.c +++ b/i3-config-wizard/main.c @@ -246,11 +246,17 @@ static int handle_expose() { static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) { printf("Keypress %d, state raw = %d\n", event->detail, event->state); - xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, event->state); + /* Remove the numlock bit, all other bits are modifiers we can bind to */ + uint16_t state_filtered = event->state & ~(xcb_numlock_mask | XCB_MOD_MASK_LOCK); + /* Only use the lower 8 bits of the state (modifier masks) so that mouse + * button masks are filtered out */ + state_filtered &= 0xFF; + + xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, state_filtered); printf("sym = %c (%d)\n", sym, sym); - if (sym == XK_Return) { + if (sym == XK_Return || sym == XK_KP_Enter) { if (current_step == STEP_WELCOME) current_step = STEP_GENERATE; else finish(); @@ -428,6 +434,8 @@ int main(int argc, char *argv[]) { xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screens); root = root_screen->root; + xcb_get_numlock_mask(conn); + symbols = xcb_key_symbols_alloc(conn); font_id = get_font_id(conn, pattern, &font_height); diff --git a/i3-config-wizard/xcb.c b/i3-config-wizard/xcb.c index 9a9bf615..2c2e5614 100644 --- a/i3-config-wizard/xcb.c +++ b/i3-config-wizard/xcb.c @@ -19,7 +19,10 @@ #include +#include "xcb.h" + extern xcb_window_t root; +unsigned int xcb_numlock_mask; /* * Convenience-wrapper around xcb_change_gc which saves us declaring a variable @@ -164,3 +167,58 @@ int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height) { return result; } + +/* + * Finds out which modifier mask is the one for numlock, as the user may change this. + * + */ +void xcb_get_numlock_mask(xcb_connection_t *conn) { + xcb_key_symbols_t *keysyms; + xcb_get_modifier_mapping_cookie_t cookie; + xcb_get_modifier_mapping_reply_t *reply; + xcb_keycode_t *modmap; + int mask, i; + const int masks[8] = { XCB_MOD_MASK_SHIFT, + XCB_MOD_MASK_LOCK, + XCB_MOD_MASK_CONTROL, + XCB_MOD_MASK_1, + XCB_MOD_MASK_2, + XCB_MOD_MASK_3, + XCB_MOD_MASK_4, + XCB_MOD_MASK_5 }; + + /* Request the modifier map */ + cookie = xcb_get_modifier_mapping_unchecked(conn); + + /* Get the keysymbols */ + keysyms = xcb_key_symbols_alloc(conn); + + if ((reply = xcb_get_modifier_mapping_reply(conn, cookie, NULL)) == NULL) { + xcb_key_symbols_free(keysyms); + return; + } + + modmap = xcb_get_modifier_mapping_keycodes(reply); + + /* Get the keycode for numlock */ +#ifdef OLD_XCB_KEYSYMS_API + xcb_keycode_t numlock = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK); +#else + /* For now, we only use the first keysymbol. */ + xcb_keycode_t *numlock_syms = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK); + if (numlock_syms == NULL) + return; + xcb_keycode_t numlock = *numlock_syms; + free(numlock_syms); +#endif + + /* Check all modifiers (Mod1-Mod5, Shift, Control, Lock) */ + for (mask = 0; mask < 8; mask++) + for (i = 0; i < reply->keycodes_per_modifier; i++) + if (modmap[(mask * reply->keycodes_per_modifier) + i] == numlock) + xcb_numlock_mask = masks[mask]; + + xcb_key_symbols_free(keysyms); + free(reply); +} + diff --git a/i3-config-wizard/xcb.h b/i3-config-wizard/xcb.h index 71280e1c..e66d3fa9 100644 --- a/i3-config-wizard/xcb.h +++ b/i3-config-wizard/xcb.h @@ -1,6 +1,15 @@ +#ifndef _XCB_H +#define _XCB_H + +/* from X11/keysymdef.h */ +#define XCB_NUM_LOCK 0xff7f + +extern unsigned int xcb_numlock_mask; void xcb_change_gc_single(xcb_connection_t *conn, xcb_gcontext_t gc, uint32_t mask, uint32_t value); uint32_t get_colorpixel(xcb_connection_t *conn, char *hex); uint32_t get_mod_mask(xcb_connection_t *conn, uint32_t keycode); xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t height); int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height); + +#endif