event: push event/key objects and then call functions
This avoid the problem we can had while modifying globalconf.keys in a callback function from a key or button event. Now we push all matching objects on the stack, and call each callback function. If something modify globalconf.keys, we do not care. Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
339fb53d56
commit
fb3c5d90c7
44
event.c
44
event.c
|
@ -42,53 +42,65 @@
|
|||
#include "common/atoms.h"
|
||||
#include "common/xutil.h"
|
||||
|
||||
#define DO_EVENT_HOOK_CALLBACK(type, xcbeventprefix, arraytype, match) \
|
||||
#define DO_EVENT_HOOK_CALLBACK(type, prefix, xcbtype, xcbeventprefix, arraytype, match) \
|
||||
static void \
|
||||
event_##type##_callback(xcb_##type##_press_event_t *ev, \
|
||||
event_##xcbtype##_callback(xcb_##xcbtype##_press_event_t *ev, \
|
||||
arraytype *arr, \
|
||||
int oud, \
|
||||
int nargs, \
|
||||
void *data) \
|
||||
{ \
|
||||
int abs_oud = oud < 0 ? ((lua_gettop(globalconf.L) + 1) + oud) : oud; \
|
||||
int item_matching = 0; \
|
||||
foreach(item, *arr) \
|
||||
if(match(ev, *item, data)) \
|
||||
{ \
|
||||
if(oud) \
|
||||
luaA_object_push_item(globalconf.L, abs_oud, *item); \
|
||||
else \
|
||||
prefix##_push(globalconf.L, *item); \
|
||||
item_matching++; \
|
||||
} \
|
||||
for(; item_matching > 0; item_matching--) \
|
||||
{ \
|
||||
type *item = luaL_checkudata(globalconf.L, -1, #prefix); \
|
||||
switch(ev->response_type) \
|
||||
{ \
|
||||
case xcbeventprefix##_PRESS: \
|
||||
if((*item)->press) \
|
||||
if(item->press) \
|
||||
{ \
|
||||
for(int i = 0; i < nargs; i++) \
|
||||
lua_pushvalue(globalconf.L, - nargs); \
|
||||
lua_pushvalue(globalconf.L, - nargs - item_matching); \
|
||||
if(oud) \
|
||||
{ \
|
||||
luaA_object_push_item(globalconf.L, oud < 0 ? oud - nargs : oud, \
|
||||
(*item)); \
|
||||
luaA_object_push_item(globalconf.L, -1, (*item)->press); \
|
||||
luaA_object_push_item(globalconf.L, abs_oud, item); \
|
||||
luaA_object_push_item(globalconf.L, -1, item->press); \
|
||||
lua_remove(globalconf.L, -2); \
|
||||
} \
|
||||
else \
|
||||
type##_push_item(globalconf.L, *item, (*item)->press); \
|
||||
prefix##_push_item(globalconf.L, item, item->press); \
|
||||
luaA_dofunction(globalconf.L, nargs, 0); \
|
||||
} \
|
||||
break; \
|
||||
case xcbeventprefix##_RELEASE: \
|
||||
if((*item)->release) \
|
||||
if(item->release) \
|
||||
{ \
|
||||
for(int i = 0; i < nargs; i++) \
|
||||
lua_pushvalue(globalconf.L, - nargs); \
|
||||
lua_pushvalue(globalconf.L, - nargs - item_matching); \
|
||||
if(oud) \
|
||||
{ \
|
||||
luaA_object_push_item(globalconf.L, oud < 0 ? oud - nargs : oud, \
|
||||
(*item)); \
|
||||
luaA_object_push_item(globalconf.L, -1, (*item)->release); \
|
||||
luaA_object_push_item(globalconf.L, abs_oud, item); \
|
||||
luaA_object_push_item(globalconf.L, -1, item->release); \
|
||||
lua_remove(globalconf.L, -2); \
|
||||
} \
|
||||
else \
|
||||
type##_push_item(globalconf.L, *item, (*item)->release); \
|
||||
prefix##_push_item(globalconf.L, item, item->release); \
|
||||
luaA_dofunction(globalconf.L, nargs, 0); \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
lua_pop(globalconf.L, 1); \
|
||||
} \
|
||||
lua_pop(globalconf.L, nargs); \
|
||||
}
|
||||
|
||||
|
@ -109,8 +121,8 @@ event_key_match(xcb_key_press_event_t *ev, keyb_t *k, void *data)
|
|||
&& (k->mod == XCB_BUTTON_MASK_ANY || k->mod == ev->state));
|
||||
}
|
||||
|
||||
DO_EVENT_HOOK_CALLBACK(button, XCB_BUTTON, button_array_t, event_button_match)
|
||||
DO_EVENT_HOOK_CALLBACK(key, XCB_KEY, key_array_t, event_key_match)
|
||||
DO_EVENT_HOOK_CALLBACK(button_t, button, button, XCB_BUTTON, button_array_t, event_button_match)
|
||||
DO_EVENT_HOOK_CALLBACK(keyb_t, key, key, XCB_KEY, key_array_t, event_key_match)
|
||||
|
||||
/** Handle an event with mouse grabber if needed
|
||||
* \param x The x coordinate.
|
||||
|
|
Loading…
Reference in New Issue