+ (void)xkb_state_update_mask(
+ dummy_state_numlock,
+ (bind->event_state_mask & 0x1FFF) | xcb_numlock_mask /* xkb_mod_mask_t base_mods, */,
+ 0 /* xkb_mod_mask_t latched_mods, */,
+ 0 /* xkb_mod_mask_t locked_mods, */,
+ 0 /* xkb_layout_index_t base_group, */,
+ 0 /* xkb_layout_index_t latched_group, */,
+ group /* xkb_layout_index_t locked_group, */);
+
+ (void)xkb_state_update_mask(
+ dummy_state_numlock_no_shift,
+ ((bind->event_state_mask & 0x1FFF) | xcb_numlock_mask) ^ XCB_KEY_BUT_MASK_SHIFT /* xkb_mod_mask_t base_mods, */,
+ 0 /* xkb_mod_mask_t latched_mods, */,
+ 0 /* xkb_mod_mask_t locked_mods, */,
+ 0 /* xkb_layout_index_t base_group, */,
+ 0 /* xkb_layout_index_t latched_group, */,
+ group /* xkb_layout_index_t locked_group, */);
+
+ if (bind->keycode > 0) {
+ /* We need to specify modifiers for the keycode binding (numlock
+ * fallback). */
+ while (!TAILQ_EMPTY(&(bind->keycodes_head))) {
+ struct Binding_Keycode *first = TAILQ_FIRST(&(bind->keycodes_head));
+ TAILQ_REMOVE(&(bind->keycodes_head), first, keycodes);
+ FREE(first);
+ }
+
+ ADD_TRANSLATED_KEY(bind->keycode, bind->event_state_mask);
+
+ /* Also bind the key with active CapsLock */
+ ADD_TRANSLATED_KEY(bind->keycode, bind->event_state_mask | XCB_MOD_MASK_LOCK);
+
+ /* If this binding is not explicitly for NumLock, check whether we need to
+ * add a fallback. */
+ if ((bind->event_state_mask & xcb_numlock_mask) != xcb_numlock_mask) {
+ /* Check whether the keycode results in the same keysym when NumLock is
+ * active. If so, grab the key with NumLock as well, so that users don’t
+ * need to duplicate every key binding with an additional Mod2 specified.
+ */
+ xkb_keysym_t sym = xkb_state_key_get_one_sym(dummy_state, bind->keycode);
+ xkb_keysym_t sym_numlock = xkb_state_key_get_one_sym(dummy_state_numlock, bind->keycode);
+ if (sym == sym_numlock) {
+ /* Also bind the key with active NumLock */
+ ADD_TRANSLATED_KEY(bind->keycode, bind->event_state_mask | xcb_numlock_mask);
+
+ /* Also bind the key with active NumLock+CapsLock */
+ ADD_TRANSLATED_KEY(bind->keycode, bind->event_state_mask | xcb_numlock_mask | XCB_MOD_MASK_LOCK);
+ } else {
+ DLOG("Skipping automatic numlock fallback, key %d resolves to 0x%x with numlock\n",
+ bind->keycode, sym_numlock);
+ }
+ }
+
+ continue;
+ }
+
+ /* We need to translate the symbol to a keycode */
+ const xkb_keysym_t 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;
+ }
+