diff --git a/i3-input/i3-input.h b/i3-input/i3-input.h index 6c982bc5..8d8b467f 100644 --- a/i3-input/i3-input.h +++ b/i3-input/i3-input.h @@ -8,7 +8,7 @@ char *convert_ucs_to_utf8(char *input); char *convert_utf8_to_ucs2(char *input, int *real_strlen); uint32_t get_colorpixel(xcb_connection_t *conn, char *hex); -uint32_t get_mode_switch_mask(xcb_connection_t *conn); +uint32_t get_mod_mask(xcb_connection_t *conn, uint32_t keycode); int connect_ipc(char *socket_path); void ipc_send_message(int sockfd, uint32_t message_size, uint32_t message_type, uint8_t *payload); diff --git a/i3-input/main.c b/i3-input/main.c index 97976396..f5229c08 100644 --- a/i3-input/main.c +++ b/i3-input/main.c @@ -37,6 +37,7 @@ static int sockfd; static xcb_key_symbols_t *symbols; static int modeswitchmask; +static int numlockmask; static bool modeswitch_active = false; static xcb_window_t win; static xcb_pixmap_t pixmap; @@ -119,6 +120,9 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t static int handle_key_release(void *ignored, xcb_connection_t *conn, xcb_key_release_event_t *event) { printf("releasing %d, state raw = %d\n", event->detail, event->state); + /* fix state */ + event->state &= ~numlockmask; + xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, event->state); if (sym == XK_Mode_switch) { printf("Mode switch disabled\n"); @@ -163,6 +167,11 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press if (modeswitch_active) event->state |= modeswitchmask; + /* Apparantly, after activating numlock once, the numlock modifier + * stays turned on (use xev(1) to verify). So, to resolve useful + * keysyms, we remove the numlock flag from the event state */ + event->state &= ~numlockmask; + xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, event->state); if (sym == XK_Mode_switch) { printf("Mode switch enabled\n"); @@ -290,7 +299,8 @@ int main(int argc, char *argv[]) { xcb_event_set_key_release_handler(&evenths, handle_key_release, NULL); xcb_event_set_expose_handler(&evenths, handle_expose, NULL); - modeswitchmask = get_mode_switch_mask(conn); + modeswitchmask = get_mod_mask(conn, XK_Mode_switch); + numlockmask = get_mod_mask(conn, XK_Num_Lock); symbols = xcb_key_symbols_alloc(conn); uint32_t font_id = get_font_id(conn, pattern, &font_height); diff --git a/i3-input/xcb.c b/i3-input/xcb.c index 71189a97..661d4863 100644 --- a/i3-input/xcb.c +++ b/i3-input/xcb.c @@ -53,12 +53,12 @@ uint32_t get_colorpixel(xcb_connection_t *conn, char *hex) { * keycode). * */ -uint32_t get_mode_switch_mask(xcb_connection_t *conn) { +uint32_t get_mod_mask(xcb_connection_t *conn, uint32_t keycode) { xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(conn); xcb_get_modifier_mapping_reply_t *modmap_r; xcb_keycode_t *modmap, kc; - xcb_keycode_t *modeswitchcodes = xcb_key_symbols_get_keycode(symbols, XK_Mode_switch); + xcb_keycode_t *modeswitchcodes = xcb_key_symbols_get_keycode(symbols, keycode); if (modeswitchcodes == NULL) return 0; @@ -66,7 +66,7 @@ uint32_t get_mode_switch_mask(xcb_connection_t *conn) { modmap = xcb_get_modifier_mapping_keycodes(modmap_r); for (int i = 0; i < 8; i++) - for(int j = 0; j < modmap_r->keycodes_per_modifier; j++) { + for (int j = 0; j < modmap_r->keycodes_per_modifier; j++) { kc = modmap[i * modmap_r->keycodes_per_modifier + j]; for (xcb_keycode_t *ktest = modeswitchcodes; *ktest; ktest++) { if (*ktest != kc)