Fix numlock state

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. What
currently does not work is actually using your keypad.
This commit is contained in:
Michael Stapelberg 2010-03-24 03:28:38 +01:00
parent 56139f3656
commit 85730d6892
3 changed files with 15 additions and 5 deletions

View File

@ -8,7 +8,7 @@
char *convert_ucs_to_utf8(char *input); char *convert_ucs_to_utf8(char *input);
char *convert_utf8_to_ucs2(char *input, int *real_strlen); char *convert_utf8_to_ucs2(char *input, int *real_strlen);
uint32_t get_colorpixel(xcb_connection_t *conn, char *hex); 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); int connect_ipc(char *socket_path);
void ipc_send_message(int sockfd, uint32_t message_size, void ipc_send_message(int sockfd, uint32_t message_size,
uint32_t message_type, uint8_t *payload); uint32_t message_type, uint8_t *payload);

View File

@ -37,6 +37,7 @@
static int sockfd; static int sockfd;
static xcb_key_symbols_t *symbols; static xcb_key_symbols_t *symbols;
static int modeswitchmask; static int modeswitchmask;
static int numlockmask;
static bool modeswitch_active = false; static bool modeswitch_active = false;
static xcb_window_t win; static xcb_window_t win;
static xcb_pixmap_t pixmap; 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) { 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); 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); xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, event->state);
if (sym == XK_Mode_switch) { if (sym == XK_Mode_switch) {
printf("Mode switch disabled\n"); 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) if (modeswitch_active)
event->state |= modeswitchmask; 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); xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, event->state);
if (sym == XK_Mode_switch) { if (sym == XK_Mode_switch) {
printf("Mode switch enabled\n"); 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_key_release_handler(&evenths, handle_key_release, NULL);
xcb_event_set_expose_handler(&evenths, handle_expose, 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); symbols = xcb_key_symbols_alloc(conn);
uint32_t font_id = get_font_id(conn, pattern, &font_height); uint32_t font_id = get_font_id(conn, pattern, &font_height);

View File

@ -53,12 +53,12 @@ uint32_t get_colorpixel(xcb_connection_t *conn, char *hex) {
* keycode). * 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_key_symbols_t *symbols = xcb_key_symbols_alloc(conn);
xcb_get_modifier_mapping_reply_t *modmap_r; xcb_get_modifier_mapping_reply_t *modmap_r;
xcb_keycode_t *modmap, kc; 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) if (modeswitchcodes == NULL)
return 0; return 0;
@ -66,7 +66,7 @@ uint32_t get_mode_switch_mask(xcb_connection_t *conn) {
modmap = xcb_get_modifier_mapping_keycodes(modmap_r); modmap = xcb_get_modifier_mapping_keycodes(modmap_r);
for (int i = 0; i < 8; i++) 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]; kc = modmap[i * modmap_r->keycodes_per_modifier + j];
for (xcb_keycode_t *ktest = modeswitchcodes; *ktest; ktest++) { for (xcb_keycode_t *ktest = modeswitchcodes; *ktest; ktest++) {
if (*ktest != kc) if (*ktest != kc)