Bugfix: Correctly filter out the numlock state bit (doesn’t get cleared for some reason)

This fixes ticket 
This commit is contained in:
Michael Stapelberg
2009-03-27 15:24:52 +01:00
parent 9077831ed3
commit a8478efa34
5 changed files with 65 additions and 3 deletions

@@ -107,7 +107,7 @@ int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_
LOG("state %d\n", event->state);
/* Remove the numlock bit, all other bits are modifiers we can bind to */
uint16_t state_filtered = event->state & ~XCB_MOD_MASK_LOCK;
uint16_t state_filtered = event->state & ~(xcb_numlock_mask | XCB_MOD_MASK_LOCK);
/* Find the binding */
Binding *bind;

@@ -503,13 +503,22 @@ int main(int argc, char *argv[], char *env[]) {
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, atoms[_NET_SUPPORTING_WM_CHECK], WINDOW, 32, 1, &root);
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, atoms[_NET_WM_NAME], atoms[UTF8_STRING], 8, strlen("i3"), "i3");
xcb_get_numlock_mask(conn);
/* Grab the bound keys */
Binding *bind;
TAILQ_FOREACH(bind, &bindings, bindings) {
LOG("Grabbing %d\n", bind->keycode);
if (bind->mods & BIND_MODE_SWITCH)
xcb_grab_key(conn, 0, root, 0, bind->keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_SYNC);
else xcb_grab_key(conn, 0, root, bind->mods, bind->keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
else {
/* Grab the key in all combinations */
#define GRAB_KEY(modifier) xcb_grab_key(conn, 0, root, modifier, bind->keycode, \
XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC)
GRAB_KEY(bind->mods);
GRAB_KEY(bind->mods | xcb_numlock_mask);
GRAB_KEY(bind->mods | xcb_numlock_mask | XCB_MOD_MASK_LOCK);
}
}
/* check for Xinerama */

@@ -16,12 +16,14 @@
#include <string.h>
#include <xcb/xcb.h>
#include <xcb/xcb_keysyms.h>
#include "util.h"
#include "xcb.h"
TAILQ_HEAD(cached_fonts_head, Font) cached_fonts = TAILQ_HEAD_INITIALIZER(cached_fonts);
SLIST_HEAD(colorpixel_head, Colorpixel) colorpixels;
unsigned int xcb_numlock_mask;
/*
* Loads a font for usage, getting its height. This function is used very often, so it
@@ -209,3 +211,48 @@ void fake_configure_notify(xcb_connection_t *conn, Rect r, xcb_window_t window)
LOG("Told the client it is at %dx%d with %dx%d\n", r.x, r.y, r.width, r.height);
}
/*
* 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, numlock;
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 */
numlock = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK);
/* Check all modifiers (Mod1-Mod5, Shift, Control, Lock) */
for (mask = 0; mask < sizeof(masks); 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);
}