Bugfix: Correctly filter out the numlock state bit (doesn’t get cleared for some reason)
This fixes ticket #14
This commit is contained in:
parent
9077831ed3
commit
a8478efa34
2
Makefile
2
Makefile
|
@ -15,7 +15,7 @@ CFLAGS += -DI3_VERSION=\"${GIT_VERSION}\"
|
||||||
|
|
||||||
LDFLAGS += -lm
|
LDFLAGS += -lm
|
||||||
LDFLAGS += -lxcb-wm
|
LDFLAGS += -lxcb-wm
|
||||||
#LDFLAGS += -lxcb-keysyms
|
LDFLAGS += -lxcb-keysyms
|
||||||
LDFLAGS += -lxcb-xinerama
|
LDFLAGS += -lxcb-xinerama
|
||||||
LDFLAGS += -lX11
|
LDFLAGS += -lX11
|
||||||
LDFLAGS += -L/usr/local/lib -L/usr/pkg/lib
|
LDFLAGS += -L/usr/local/lib -L/usr/pkg/lib
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#define XCB_CURSOR_SB_H_DOUBLE_ARROW 108
|
#define XCB_CURSOR_SB_H_DOUBLE_ARROW 108
|
||||||
#define XCB_CURSOR_SB_V_DOUBLE_ARROW 116
|
#define XCB_CURSOR_SB_V_DOUBLE_ARROW 116
|
||||||
|
|
||||||
|
/* from X11/keysymdef.h */
|
||||||
|
#define XCB_NUM_LOCK 0xff7f
|
||||||
|
|
||||||
/* The event masks are defined here because we don’t only set them once but we need to set slight
|
/* The event masks are defined here because we don’t only set them once but we need to set slight
|
||||||
variations of them (without XCB_EVENT_MASK_ENTER_WINDOW while rendering the layout) */
|
variations of them (without XCB_EVENT_MASK_ENTER_WINDOW while rendering the layout) */
|
||||||
/* The XCB_CW_EVENT_MASK for the child (= real window) */
|
/* The XCB_CW_EVENT_MASK for the child (= real window) */
|
||||||
|
@ -51,6 +54,8 @@ enum { _NET_SUPPORTED = 0,
|
||||||
UTF8_STRING
|
UTF8_STRING
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern unsigned int xcb_numlock_mask;
|
||||||
|
|
||||||
i3Font *load_font(xcb_connection_t *conn, const char *pattern);
|
i3Font *load_font(xcb_connection_t *conn, const char *pattern);
|
||||||
uint32_t get_colorpixel(xcb_connection_t *conn, char *hex);
|
uint32_t get_colorpixel(xcb_connection_t *conn, char *hex);
|
||||||
xcb_window_t create_window(xcb_connection_t *conn, Rect r, uint16_t window_class, int cursor,
|
xcb_window_t create_window(xcb_connection_t *conn, Rect r, uint16_t window_class, int cursor,
|
||||||
|
@ -61,5 +66,6 @@ void xcb_draw_line(xcb_connection_t *conn, xcb_drawable_t drawable, xcb_gcontext
|
||||||
void xcb_draw_rect(xcb_connection_t *conn, xcb_drawable_t drawable, xcb_gcontext_t gc,
|
void xcb_draw_rect(xcb_connection_t *conn, xcb_drawable_t drawable, xcb_gcontext_t gc,
|
||||||
uint32_t colorpixel, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
uint32_t colorpixel, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||||
void fake_configure_notify(xcb_connection_t *conn, Rect r, xcb_window_t window);
|
void fake_configure_notify(xcb_connection_t *conn, Rect r, xcb_window_t window);
|
||||||
|
void xcb_get_numlock_mask(xcb_connection_t *conn);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -107,7 +107,7 @@ int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_
|
||||||
LOG("state %d\n", event->state);
|
LOG("state %d\n", event->state);
|
||||||
|
|
||||||
/* Remove the numlock bit, all other bits are modifiers we can bind to */
|
/* 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 */
|
/* Find the binding */
|
||||||
Binding *bind;
|
Binding *bind;
|
||||||
|
|
11
src/mainx.c
11
src/mainx.c
|
@ -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_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_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 */
|
/* Grab the bound keys */
|
||||||
Binding *bind;
|
Binding *bind;
|
||||||
TAILQ_FOREACH(bind, &bindings, bindings) {
|
TAILQ_FOREACH(bind, &bindings, bindings) {
|
||||||
LOG("Grabbing %d\n", bind->keycode);
|
LOG("Grabbing %d\n", bind->keycode);
|
||||||
if (bind->mods & BIND_MODE_SWITCH)
|
if (bind->mods & BIND_MODE_SWITCH)
|
||||||
xcb_grab_key(conn, 0, root, 0, bind->keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_SYNC);
|
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 */
|
/* check for Xinerama */
|
||||||
|
|
47
src/xcb.c
47
src/xcb.c
|
@ -16,12 +16,14 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "xcb.h"
|
#include "xcb.h"
|
||||||
|
|
||||||
TAILQ_HEAD(cached_fonts_head, Font) cached_fonts = TAILQ_HEAD_INITIALIZER(cached_fonts);
|
TAILQ_HEAD(cached_fonts_head, Font) cached_fonts = TAILQ_HEAD_INITIALIZER(cached_fonts);
|
||||||
SLIST_HEAD(colorpixel_head, Colorpixel) colorpixels;
|
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
|
* 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);
|
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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue