diff --git a/awesome-menu.c b/awesome-menu.c index 25f75280..79c39276 100644 --- a/awesome-menu.c +++ b/awesome-menu.c @@ -103,10 +103,6 @@ typedef struct xcb_connection_t *connection; /** Default screen number */ int default_screen; - /** Is the caps lock enabled? */ - bool caps_lock; - /** Is the shift lock enabled? */ - bool shift_lock; /** The window */ SimpleWindow *sw; /** The draw contet */ @@ -117,8 +113,14 @@ typedef struct style_t normal; style_t focus; } styles; + /** Key symbols */ + xcb_key_symbols_t *keysyms; /** Numlock mask */ unsigned int numlockmask; + /** Shiftlock mask */ + unsigned int shiftlockmask; + /** Capslock mask */ + unsigned int capslockmask; /** The text */ char *text; /** The text when we asked to complete */ @@ -510,29 +512,17 @@ redraw(void) * \todo use XKB! */ static void -x_lookup_string(xcb_key_press_event_t *e, char **buf, size_t *buf_len, xcb_keysym_t *ksym) +key_press_lookup_string(xcb_key_press_event_t *e, + char **buf, size_t *buf_len, + xcb_keysym_t *ksym) { - xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(globalconf.connection); xcb_keysym_t k0, k1; /* 'col' (third parameter) is used to get the proper KeySym * according to modifier (XCB doesn't provide an equivalent to * XLookupString()) */ - k0 = xcb_key_press_lookup_keysym(keysyms, e, 0); - k1 = xcb_key_press_lookup_keysym(keysyms, e, 1); - - xcb_key_symbols_free(keysyms); - - if(xcb_is_modifier_key(k0) && !k1) - { - /* The Caps_Lock is now enabled */ - if(k0 == XK_Caps_Lock) - globalconf.caps_lock = true; - - /* The Shift lock is now enabled */ - if(k0 == XK_Shift_Lock) - globalconf.shift_lock = true; - } + k0 = xcb_key_press_lookup_keysym(globalconf.keysyms, e, 0); + k1 = xcb_key_press_lookup_keysym(globalconf.keysyms, e, 1); /* The numlock modifier is on and the second KeySym is a keypad * KeySym */ @@ -541,7 +531,7 @@ x_lookup_string(xcb_key_press_event_t *e, char **buf, size_t *buf_len, xcb_keysy /* The Shift modifier is on, or if the Lock modifier is on and * is interpreted as ShiftLock, use the first KeySym */ if((e->state & XCB_MOD_MASK_SHIFT) || - (e->state & XCB_MOD_MASK_LOCK && globalconf.shift_lock)) + (e->state & XCB_MOD_MASK_LOCK && (e->state & globalconf.shiftlockmask))) *ksym = k0; else *ksym = k1; @@ -555,25 +545,25 @@ x_lookup_string(xcb_key_press_event_t *e, char **buf, size_t *buf_len, xcb_keysy /* The Shift modifier is off and the Lock modifier is on and is * interpreted as CapsLock */ else if(!(e->state & XCB_MOD_MASK_SHIFT) && - (e->state & XCB_MOD_MASK_LOCK && globalconf.caps_lock)) - /* TODO: The first Keysym is used but if that KeySym is - * lowercase alphabetic, then the corresponding uppercase - * KeySym is used instead */ - *ksym = k0; + (e->state & XCB_MOD_MASK_LOCK && (e->state & globalconf.capslockmask))) + /* The first Keysym is used but if that KeySym is lowercase + * alphabetic, then the corresponding uppercase KeySym is used + * instead */ + *ksym = k1; /* The Shift modifier is on, and the Lock modifier is on and is * interpreted as CapsLock */ else if((e->state & XCB_MOD_MASK_SHIFT) && - (e->state & XCB_MOD_MASK_LOCK && globalconf.caps_lock)) - /* TODO: The second Keysym is used but if that KeySym is - * lowercase alphabetic, then the corresponding uppercase - * KeySym is used instead */ + (e->state & XCB_MOD_MASK_LOCK && (e->state & globalconf.capslockmask))) + /* The second Keysym is used but if that KeySym is lowercase + * alphabetic, then the corresponding uppercase KeySym is used + * instead */ *ksym = k1; /* The Shift modifer is on, or the Lock modifier is on and is * interpreted as ShiftLock, or both */ else if((e->state & XCB_MOD_MASK_SHIFT) || - (e->state & XCB_MOD_MASK_LOCK && globalconf.shift_lock)) + (e->state & XCB_MOD_MASK_LOCK && (e->state & globalconf.shiftlockmask))) *ksym = k1; if(xcb_is_modifier_key(*ksym) || xcb_is_function_key(*ksym) || @@ -607,7 +597,7 @@ handle_kpress(xcb_key_press_event_t *e) len = a_strlen(globalconf.text); - x_lookup_string(e, &buf, &num, &ksym); + key_press_lookup_string(e, &buf, &num, &ksym); /* Got a special key, see x_lookup_string() */ if(!num) return; @@ -931,10 +921,11 @@ main(int argc, char **argv) redraw(); - /* TODO: do we need to check at startup that the Caps_Lock and - * Shift_Lock keys are pressed? */ - globalconf.caps_lock = false; - globalconf.shift_lock = false; + globalconf.keysyms = xcb_key_symbols_alloc(globalconf.connection); + + /* Get the numlock, capslock and shiftlock mask */ + xutil_get_lock_mask(conn, globalconf.keysyms, &globalconf.numlockmask, + &globalconf.shiftlockmask, &globalconf.capslockmask); xutil_map_raised(globalconf.connection, globalconf.sw->window); @@ -982,6 +973,7 @@ main(int argc, char **argv) } } + xcb_key_symbols_free(globalconf.keysyms); p_delete(&globalconf.text); draw_context_delete(&globalconf.ctx); simplewindow_delete(&globalconf.sw); diff --git a/awesome.c b/awesome.c index 5f8273c0..0193cd2b 100644 --- a/awesome.c +++ b/awesome.c @@ -411,7 +411,14 @@ main(int argc, char *argv[]) XSynchronize(dpy, true); */ - /* store display */ + /* Allocate the key symbols */ + globalconf.keysyms = xcb_key_symbols_alloc(conn); + + /* Get the NumLock, ShiftLock and CapsLock masks */ + xutil_get_lock_mask(conn, globalconf.keysyms, &globalconf.numlockmask, + &globalconf.shiftlockmask, &globalconf.capslockmask); + + /* store connection */ globalconf.connection = conn; /* init EWMH atoms */ diff --git a/common/xutil.c b/common/xutil.c index 426b003b..a670dfb3 100644 --- a/common/xutil.c +++ b/common/xutil.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "common/util.h" #include "common/xutil.h" @@ -67,13 +66,14 @@ xgettextprop(xcb_connection_t *conn, xcb_window_t w, xcb_atom_t atom, return true; } -unsigned int -xgetnumlockmask(xcb_connection_t *conn) +void +xutil_get_lock_mask(xcb_connection_t *conn, xcb_key_symbols_t *keysyms, + unsigned int *numlockmask, unsigned int *shiftlockmask, + unsigned int *capslockmask) { xcb_get_modifier_mapping_reply_t *modmap_r; - xcb_keycode_t *modmap; - xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(conn); - unsigned int mask = 0; + xcb_keycode_t *modmap, kc; + unsigned int mask; int i, j; modmap_r = xcb_get_modifier_mapping_reply(conn, @@ -84,14 +84,22 @@ xgetnumlockmask(xcb_connection_t *conn) for(i = 0; i < 8; i++) for(j = 0; j < modmap_r->keycodes_per_modifier; j++) - if(modmap[i * modmap_r->keycodes_per_modifier + j] - == xcb_key_symbols_get_keycode(keysyms, XK_Num_Lock)) - mask = (1 << i); + { + kc = modmap[i * modmap_r->keycodes_per_modifier + j]; + mask = (1 << i); + + if(numlockmask != NULL && + kc == xcb_key_symbols_get_keycode(keysyms, XK_Num_Lock)) + *numlockmask = mask; + else if(shiftlockmask != NULL && + kc == xcb_key_symbols_get_keycode(keysyms, XK_Shift_Lock)) + *shiftlockmask = mask; + else if(capslockmask != NULL && + kc == xcb_key_symbols_get_keycode(keysyms, XK_Caps_Lock)) + *capslockmask = mask; + } p_delete(&modmap_r); - xcb_key_symbols_free(keysyms); - - return mask; } /** Equivalent to 'XGetTransientForHint' which is actually a diff --git a/common/xutil.h b/common/xutil.h index bd6e28d3..e9fc2436 100644 --- a/common/xutil.h +++ b/common/xutil.h @@ -25,12 +25,14 @@ #include #include +#include /* XCB doesn't provide keysyms definition */ #include bool xgettextprop(xcb_connection_t *, xcb_window_t, xcb_atom_t, char *, ssize_t); -unsigned int xgetnumlockmask(xcb_connection_t *); +void xutil_get_lock_mask(xcb_connection_t *, xcb_key_symbols_t *, + unsigned int *, unsigned int *, unsigned int *); /* See http://tronche.com/gui/x/xlib/appendix/b/ for values */ #define CURSOR_FLEUR 52 diff --git a/config.c b/config.c index 0c22eff6..803f4da1 100644 --- a/config.c +++ b/config.c @@ -22,7 +22,6 @@ /* XStringToKeysym() */ #include -#include #include #include "config.h" @@ -561,9 +560,6 @@ config_parse(const char *confpatharg) /* Mouse: titlebar windows click bindings */ globalconf.buttons.titlebar = parse_mouse_bindings(cfg_mouse, "titlebar", true); - /* Keys */ - globalconf.numlockmask = xgetnumlockmask(globalconf.connection); - globalconf.keys = section_keys(cfg_keys); if(defconfig) diff --git a/event.c b/event.c index ab22d445..2801882d 100644 --- a/event.c +++ b/event.c @@ -388,7 +388,6 @@ event_handle_keypress(void *data __attribute__ ((unused)), { int screen; xcb_query_pointer_reply_t *qpr = NULL; - xcb_key_symbols_t *keysyms; xcb_keysym_t keysym; Key *k; @@ -407,16 +406,13 @@ event_handle_keypress(void *data __attribute__ ((unused)), break; } - keysyms = xcb_key_symbols_alloc(globalconf.connection); - keysym = xcb_key_symbols_get_keysym(keysyms, ev->detail, 0); + keysym = xcb_key_symbols_get_keysym(globalconf.keysyms, ev->detail, 0); for(k = globalconf.keys; k; k = k->next) if(((k->keycode && ev->detail == k->keycode) || (k->keysym && keysym == k->keysym)) && k->func && CLEANMASK(k->mod) == CLEANMASK(ev->state)) k->func(screen, k->arg); - xcb_key_symbols_free(keysyms); - return 0; } @@ -429,11 +425,8 @@ event_handle_mappingnotify(void *data __attribute__ ((unused)), xcb_connection_t *connection, xcb_mapping_notify_event_t *ev) { int screen; - xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(connection); - - xcb_refresh_keyboard_mapping(keysyms, ev); - xcb_key_symbols_free(keysyms); + xcb_refresh_keyboard_mapping(globalconf.keysyms, ev); if(ev->request == XCB_MAPPING_KEYBOARD) for(screen = 0; screen < xcb_setup_roots_length(xcb_get_setup(connection)); screen++) window_root_grabkeys(screen); diff --git a/structs.h b/structs.h index 44552526..c3df4c3b 100644 --- a/structs.h +++ b/structs.h @@ -348,6 +348,8 @@ struct AwesomeConf xcb_event_handlers_t *evenths; /** Default screen number */ int default_screen; + /** Keys symbol table */ + xcb_key_symbols_t *keysyms; /** Logical screens */ VirtScreen *screens; /** Screens info */ @@ -365,6 +367,10 @@ struct AwesomeConf } buttons; /** Numlock mask */ unsigned int numlockmask; + /** Numlock mask */ + unsigned int shiftlockmask; + /** Numlock mask */ + unsigned int capslockmask; /** Check for XShape extension */ bool have_shape; /** Check for XRandR extension */ diff --git a/window.c b/window.c index 3131ce4b..83a67365 100644 --- a/window.c +++ b/window.c @@ -180,15 +180,12 @@ window_root_grabkeys(int phys_screen) { Key *k; xcb_keycode_t kc; - xcb_key_symbols_t *keysyms; xcb_ungrab_key(globalconf.connection, ANY_KEY, root_window(globalconf.connection, phys_screen), ANY_MODIFIER); - keysyms = xcb_key_symbols_alloc(globalconf.connection); - for(k = globalconf.keys; k; k = k->next) - if((kc = k->keycode) || (k->keysym && (kc = xcb_key_symbols_get_keycode(keysyms, k->keysym)))) + if((kc = k->keycode) || (k->keysym && (kc = xcb_key_symbols_get_keycode(globalconf.keysyms, k->keysym)))) { xcb_grab_key(globalconf.connection, true, root_window(globalconf.connection, phys_screen), k->mod, kc, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); @@ -200,8 +197,6 @@ window_root_grabkeys(int phys_screen) k->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK, kc, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); } - - xcb_key_symbols_free(keysyms); } void