button, key: grab all keys by default, and check for match.
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
f4579d1dc1
commit
f6d2aa3064
|
@ -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
|
||||
};
|
||||
|
||||
|
|
25
client.c
25
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);
|
||||
}
|
||||
|
|
36
event.c
36
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;
|
||||
|
|
30
key.c
30
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!
|
||||
|
|
1
key.h
1
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);
|
||||
|
||||
|
|
9
root.c
9
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;
|
||||
}
|
||||
|
||||
|
|
17
window.c
17
window.c
|
@ -23,12 +23,8 @@
|
|||
#include <xcb/xcb_atom.h>
|
||||
|
||||
#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.
|
||||
|
|
2
window.h
2
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
|
||||
|
|
Loading…
Reference in New Issue