diff --git a/awesome.c b/awesome.c index 2ce1bb514..156d61f4c 100644 --- a/awesome.c +++ b/awesome.c @@ -527,6 +527,8 @@ main(int argc, char **argv) | XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE + | XCB_EVENT_MASK_KEY_PRESS + | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_FOCUS_CHANGE }; diff --git a/client.c b/client.c index 988b25c5b..1e0b774f7 100644 --- a/client.c +++ b/client.c @@ -576,6 +576,17 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, */ window_state_set(c->win, XCB_WM_STATE_NORMAL); + /* Grab everything */ + xcb_grab_key(globalconf.connection, true, w, + XCB_MOD_MASK_ANY, XCB_GRAB_ANY, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_SYNC); + + xcb_grab_button(globalconf.connection, false, w, + XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, + XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, + XCB_GRAB_ANY, XCB_MOD_MASK_ANY); + + if(!startup) spawn_start_notify(c); @@ -1061,16 +1072,8 @@ client_unmanage(client_t *c) if(globalconf.hooks.clients != LUA_REFNIL) luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.clients, 0, 0); - /* The server grab construct avoids race conditions. */ - xcb_grab_server(globalconf.connection); - - xcb_ungrab_button(globalconf.connection, XCB_BUTTON_INDEX_ANY, c->win, - XCB_BUTTON_MASK_ANY); window_state_set(c->win, XCB_WM_STATE_WITHDRAWN); - xcb_flush(globalconf.connection); - xcb_ungrab_server(globalconf.connection); - titlebar_client_detach(c); ewmh_update_net_client_list(c->phys_screen); @@ -1914,8 +1917,6 @@ luaA_client_buttons(lua_State *L) if(lua_gettop(L) == 2) luaA_button_array_set(L, 1, 2, buttons); - window_buttons_grab(client->win, &client->buttons); - return luaA_button_array_get(L, 1, buttons); } @@ -1934,11 +1935,7 @@ luaA_client_keys(lua_State *L) key_array_t *keys = &c->keys; if(lua_gettop(L) == 2) - { luaA_key_array_set(L, 1, 2, keys); - xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, c->win, XCB_BUTTON_MASK_ANY); - window_grabkeys(c->win, keys); - } return luaA_key_array_get(L, 1, keys); } diff --git a/event.c b/event.c index 4a8cb606d..5a6545a88 100644 --- a/event.c +++ b/event.c @@ -43,7 +43,7 @@ #include "common/xutil.h" #define DO_EVENT_HOOK_CALLBACK(type, prefix, xcbtype, xcbeventprefix, arraytype, match) \ - static void \ + static int \ event_##xcbtype##_callback(xcb_##xcbtype##_press_event_t *ev, \ arraytype *arr, \ int oud, \ @@ -51,7 +51,7 @@ void *data) \ { \ int abs_oud = oud < 0 ? ((lua_gettop(globalconf.L) + 1) + oud) : oud; \ - int item_matching = 0; \ + int item_matching = 0, item_matched = 0; \ foreach(item, *arr) \ if(match(ev, *item, data)) \ { \ @@ -61,7 +61,7 @@ prefix##_push(globalconf.L, *item); \ item_matching++; \ } \ - for(; item_matching > 0; item_matching--) \ + for(item_matched = item_matching; item_matching > 0; item_matching--) \ { \ type *item = luaL_checkudata(globalconf.L, -1, #prefix); \ switch(ev->response_type) \ @@ -102,6 +102,7 @@ lua_pop(globalconf.L, 1); \ } \ lua_pop(globalconf.L, nargs); \ + return item_matched; \ } static bool @@ -602,10 +603,19 @@ event_handle_key(void *data __attribute__ ((unused)), if((c = client_getbywin(ev->event))) { client_push(globalconf.L, c); - event_key_callback(ev, &c->keys, -1, 1, &keysym); + if(!event_key_callback(ev, &c->keys, -1, 1, &keysym)) + if(!event_key_callback(ev, &globalconf.keys, 0, 0, &keysym)) + xcb_allow_events(globalconf.connection, + XCB_ALLOW_REPLAY_KEYBOARD, + XCB_CURRENT_TIME); + } else event_key_callback(ev, &globalconf.keys, 0, 0, &keysym); + + xcb_allow_events(globalconf.connection, + XCB_ALLOW_SYNC_KEYBOARD, + XCB_CURRENT_TIME); } return 0; @@ -787,24 +797,6 @@ event_handle_mappingnotify(void *data, globalconf.keysyms, &globalconf.numlockmask, &globalconf.shiftlockmask, &globalconf.capslockmask, &globalconf.modeswitchmask); - - int nscreen = xcb_setup_roots_length(xcb_get_setup(connection)); - - /* regrab everything */ - for(int phys_screen = 0; phys_screen < nscreen; phys_screen++) - { - xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); - /* yes XCB_BUTTON_MASK_ANY is also for grab_key even if it's look weird */ - xcb_ungrab_key(connection, XCB_GRAB_ANY, s->root, XCB_BUTTON_MASK_ANY); - window_grabkeys(s->root, &globalconf.keys); - } - - foreach(_c, globalconf.clients) - { - client_t *c = *_c; - xcb_ungrab_key(connection, XCB_GRAB_ANY, c->win, XCB_BUTTON_MASK_ANY); - window_grabkeys(c->win, &c->keys); - } } return 0; diff --git a/key.c b/key.c index 1f7418bcd..9e696c10e 100644 --- a/key.c +++ b/key.c @@ -33,36 +33,6 @@ DO_LUA_TOSTRING(keyb_t, key, "key") -/** Grab key on a window. - * \param win The window. - * \param k The key. - */ -static void -window_grabkey(xcb_window_t win, keyb_t *k) -{ - if(k->keycode) - xcb_grab_key(globalconf.connection, true, win, - k->mod, k->keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); - else if(k->keysym) - { - xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(globalconf.keysyms, k->keysym); - if(keycodes) - { - for(xcb_keycode_t *kc = keycodes; *kc; kc++) - xcb_grab_key(globalconf.connection, true, win, - k->mod, *kc, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); - p_delete(&keycodes); - } - } -} - -void -window_grabkeys(xcb_window_t win, key_array_t *keys) -{ - foreach(k, *keys) - window_grabkey(win, *k); -} - /** XCB equivalent of XLookupString which translate the keycode given * by PressEvent to a KeySym and a string * \todo use XKB! diff --git a/key.h b/key.h index fbbe591e3..b33f316d0 100644 --- a/key.h +++ b/key.h @@ -48,7 +48,6 @@ xcb_keysym_t key_getkeysym(xcb_keycode_t, uint16_t); void luaA_key_array_set(lua_State *, int, int, key_array_t *); int luaA_key_array_get(lua_State *, int, key_array_t *); -void window_grabkeys(xcb_window_t, key_array_t *); int luaA_pushmodifiers(lua_State *, uint16_t); uint16_t luaA_tomodifiers(lua_State *L, int ud); diff --git a/root.c b/root.c index cd0249b48..e3c79f38e 100644 --- a/root.c +++ b/root.c @@ -126,15 +126,6 @@ luaA_root_keys(lua_State *L) while(lua_next(L, 1)) key_array_append(&globalconf.keys, key_ref(L, -1)); - int nscreen = xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); - - for(int phys_screen = 0; phys_screen < nscreen; phys_screen++) - { - xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); - xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, s->root, XCB_BUTTON_MASK_ANY); - window_grabkeys(s->root, &globalconf.keys); - } - return 1; } diff --git a/window.c b/window.c index cad9c07d0..0c888f24c 100644 --- a/window.c +++ b/window.c @@ -23,12 +23,8 @@ #include #include "window.h" -#include "button.h" #include "common/atoms.h" -/** Mask shorthands */ -#define BUTTONMASK (XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE) - /** Set client state (WM_STATE) property. * \param win The window to set state. * \param state The state to set. @@ -96,19 +92,6 @@ window_configure(xcb_window_t win, area_t geometry, int border) xcb_send_event(globalconf.connection, false, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char *) &ce); } -/** Grab or ungrab buttons on a window. - * \param win The window. - * \param buttons The buttons to grab. - */ -void -window_buttons_grab(xcb_window_t win, button_array_t *buttons) -{ - foreach(b, *buttons) - xcb_grab_button(globalconf.connection, false, win, BUTTONMASK, - XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, - (*b)->button, (*b)->mod); -} - /** Get the opacity of a window. * \param win The window. * \return The opacity, between 0 and 1 or -1 or no opacity set. diff --git a/window.h b/window.h index 5d55a065d..47d680458 100644 --- a/window.h +++ b/window.h @@ -28,11 +28,9 @@ void window_state_set(xcb_window_t, long); xcb_get_property_cookie_t window_state_get_unchecked(xcb_window_t); uint32_t window_state_get_reply(xcb_get_property_cookie_t); void window_configure(xcb_window_t, area_t, int); -void window_buttons_grab(xcb_window_t, button_array_t *); double window_opacity_get(xcb_window_t); double window_opacity_get_from_reply(xcb_get_property_reply_t *); void window_opacity_set(xcb_window_t, double); -void window_grabbuttons(xcb_window_t, xcb_window_t, button_array_t *); void window_takefocus(xcb_window_t); #endif