luaobject: add and use item system
Now, each object can store items. Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
86cfe51540
commit
339fb53d56
|
@ -74,6 +74,7 @@ set(AWE_SRCS
|
|||
${SOURCE_DIR}/common/xutil.c
|
||||
${SOURCE_DIR}/common/xcursor.c
|
||||
${SOURCE_DIR}/common/backtrace.c
|
||||
${SOURCE_DIR}/common/luaobject.c
|
||||
${SOURCE_DIR}/widgets/graph.c
|
||||
${SOURCE_DIR}/widgets/progressbar.c
|
||||
${SOURCE_DIR}/widgets/textbox.c
|
||||
|
|
77
button.c
77
button.c
|
@ -24,26 +24,6 @@
|
|||
#include "common/tokenize.h"
|
||||
|
||||
DO_LUA_TOSTRING(button_t, button, "button")
|
||||
LUA_OBJECT_FUNCS(button_t, button, "button")
|
||||
|
||||
void
|
||||
button_unref_simplified(button_t **b)
|
||||
{
|
||||
button_unref(globalconf.L, *b);
|
||||
}
|
||||
|
||||
/** Collect a button.
|
||||
* \param L The Lua VM state.
|
||||
* \return 0.
|
||||
*/
|
||||
static int
|
||||
luaA_button_gc(lua_State *L)
|
||||
{
|
||||
button_t *button = luaL_checkudata(L, 1, "button");
|
||||
luaL_unref(globalconf.L, LUA_REGISTRYINDEX, button->press);
|
||||
luaL_unref(globalconf.L, LUA_REGISTRYINDEX, button->release);
|
||||
return luaA_object_gc(L);
|
||||
}
|
||||
|
||||
/** Create a new mouse button bindings.
|
||||
* \param L The Lua VM state.
|
||||
|
@ -60,7 +40,8 @@ luaA_button_new(lua_State *L)
|
|||
{
|
||||
xcb_button_t xbutton;
|
||||
button_t *button;
|
||||
luaA_ref press = LUA_REFNIL, release = LUA_REFNIL;
|
||||
|
||||
lua_settop(L, 5);
|
||||
|
||||
luaA_checktable(L, 2);
|
||||
/* arg 3 is mouse button */
|
||||
|
@ -69,19 +50,13 @@ luaA_button_new(lua_State *L)
|
|||
/* arg 4 and 5 are callback functions, check they are functions... */
|
||||
if(!lua_isnil(L, 4))
|
||||
luaA_checkfunction(L, 4);
|
||||
if(lua_gettop(L) == 5 && !lua_isnil(L, 5))
|
||||
if(!lua_isnil(L, 5))
|
||||
luaA_checkfunction(L, 5);
|
||||
|
||||
/* ... then register (can't register before since 5 maybe not nil but not a
|
||||
* function */
|
||||
if(!lua_isnil(L, 4))
|
||||
luaA_registerfct(L, 4, &press);
|
||||
if(lua_gettop(L) == 5 && !lua_isnil(L, 5))
|
||||
luaA_registerfct(L, 5, &release);
|
||||
|
||||
button = button_new(L);
|
||||
button->press = press;
|
||||
button->release = release;
|
||||
|
||||
button->press = luaA_object_ref_item(L, -1, 4);
|
||||
button->release = luaA_object_ref_item(L, -1, 4);
|
||||
button->button = xbutton;
|
||||
button->mod = luaA_tomodifiers(L, 2);
|
||||
|
||||
|
@ -90,32 +65,42 @@ luaA_button_new(lua_State *L)
|
|||
|
||||
/** Set a button array with a Lua table.
|
||||
* \param L The Lua VM state.
|
||||
* \param oidx The index of the object to store items into.
|
||||
* \param idx The index of the Lua table.
|
||||
* \param buttons The array button to fill.
|
||||
*/
|
||||
void
|
||||
luaA_button_array_set(lua_State *L, int idx, button_array_t *buttons)
|
||||
luaA_button_array_set(lua_State *L, int oidx, int idx, button_array_t *buttons)
|
||||
{
|
||||
luaA_checktable(L, idx);
|
||||
|
||||
foreach(button, *buttons)
|
||||
luaA_object_unref_item(L, oidx, *button);
|
||||
|
||||
button_array_wipe(buttons);
|
||||
button_array_init(buttons);
|
||||
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, idx))
|
||||
button_array_append(buttons, button_ref(L, -1));
|
||||
if(luaA_toudata(L, -1, "button"))
|
||||
button_array_append(buttons, luaA_object_ref_item(L, oidx, -1));
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
/** Push an array of button as an Lua table onto the stack.
|
||||
* \param L The Lua VM state.
|
||||
* \param oidx The index of the object to get items from.
|
||||
* \param buttons The button array to push.
|
||||
* \return The number of elements pushed on stack.
|
||||
*/
|
||||
int
|
||||
luaA_button_array_get(lua_State *L, button_array_t *buttons)
|
||||
luaA_button_array_get(lua_State *L, int oidx, button_array_t *buttons)
|
||||
{
|
||||
lua_createtable(L, buttons->len, 0);
|
||||
for(int i = 0; i < buttons->len; i++)
|
||||
{
|
||||
button_push(L, buttons->tab[i]);
|
||||
luaA_object_push_item(L, oidx, buttons->tab[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
return 1;
|
||||
|
@ -144,17 +129,9 @@ luaA_button_index(lua_State *L)
|
|||
switch(a_tokenize(attr, len))
|
||||
{
|
||||
case A_TK_PRESS:
|
||||
if(button->press != LUA_REFNIL)
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, button->press);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
return luaA_object_push_item(L, 1, button->press);
|
||||
case A_TK_RELEASE:
|
||||
if(button->release != LUA_REFNIL)
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, button->release);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
return luaA_object_push_item(L, 1, button->release);
|
||||
case A_TK_BUTTON:
|
||||
lua_pushnumber(L, button->button);
|
||||
break;
|
||||
|
@ -186,10 +163,14 @@ luaA_button_newindex(lua_State *L)
|
|||
switch(a_tokenize(attr, len))
|
||||
{
|
||||
case A_TK_PRESS:
|
||||
luaA_registerfct(L, 3, &button->press);
|
||||
luaA_checkfunction(L, 3);
|
||||
luaA_object_unref_item(L, 1, button->press);
|
||||
button->press = luaA_object_ref_item(L, 1, 3);
|
||||
break;
|
||||
case A_TK_RELEASE:
|
||||
luaA_registerfct(L, 3, &button->release);
|
||||
luaA_checkfunction(L, 3);
|
||||
luaA_object_unref_item(L, 1, button->release);
|
||||
button->release = luaA_object_ref_item(L, 1, 3);
|
||||
break;
|
||||
case A_TK_BUTTON:
|
||||
button->button = luaL_checknumber(L, 3);
|
||||
|
@ -213,7 +194,7 @@ const struct luaL_reg awesome_button_meta[] =
|
|||
{
|
||||
{ "__index", luaA_button_index },
|
||||
{ "__newindex", luaA_button_newindex },
|
||||
{ "__gc", luaA_button_gc },
|
||||
{ "__gc", luaA_object_gc },
|
||||
{ "__tostring", luaA_button_tostring },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
12
button.h
12
button.h
|
@ -33,16 +33,16 @@ struct button_t
|
|||
/** Mouse button number */
|
||||
xcb_button_t button;
|
||||
/** Lua function to execute on press. */
|
||||
luaA_ref press;
|
||||
void *press;
|
||||
/** Lua function to execute on release. */
|
||||
luaA_ref release;
|
||||
void *release;
|
||||
};
|
||||
|
||||
void button_unref_simplified(button_t **);
|
||||
ARRAY_FUNCS(button_t *, button, button_unref_simplified)
|
||||
ARRAY_FUNCS(button_t *, button, DO_NOTHING)
|
||||
LUA_OBJECT_FUNCS(button_t, button, "button")
|
||||
|
||||
int luaA_button_array_get(lua_State *, button_array_t *);
|
||||
void luaA_button_array_set(lua_State *, int idx, button_array_t *);
|
||||
int luaA_button_array_get(lua_State *, int, button_array_t *);
|
||||
void luaA_button_array_set(lua_State *, int, int, button_array_t *);
|
||||
|
||||
#endif
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||
|
|
21
client.c
21
client.c
|
@ -53,7 +53,6 @@ luaA_client_gc(lua_State *L)
|
|||
client_t *c = luaL_checkudata(L, 1, "client");
|
||||
button_array_wipe(&c->buttons);
|
||||
key_array_wipe(&c->keys);
|
||||
image_unref(L, c->icon);
|
||||
xcb_get_wm_protocols_reply_wipe(&c->protocols);
|
||||
p_delete(&c->class);
|
||||
p_delete(&c->startup_id);
|
||||
|
@ -517,7 +516,11 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen,
|
|||
client_setborder(c, wgeom->border_width);
|
||||
|
||||
if(ewmh_window_icon_get_reply(ewmh_icon_cookie))
|
||||
c->icon = image_ref(globalconf.L, -1);
|
||||
{
|
||||
client_push(globalconf.L, c);
|
||||
c->icon = luaA_object_ref_item(globalconf.L, -1, -2);
|
||||
lua_pop(globalconf.L, 1);
|
||||
}
|
||||
|
||||
/* we honor size hints by default */
|
||||
c->size_hints_honor = true;
|
||||
|
@ -1492,9 +1495,9 @@ luaA_client_newindex(lua_State *L)
|
|||
client_setmaxvert(c, luaA_checkboolean(L, 3));
|
||||
break;
|
||||
case A_TK_ICON:
|
||||
image_unref(L, c->icon);
|
||||
luaA_object_unref_item(L, 1, c->icon);
|
||||
c->icon = NULL;
|
||||
c->icon = image_ref(L, 3);
|
||||
c->icon = luaA_object_ref_item(L, 1, 3);
|
||||
/* execute hook */
|
||||
hook_property(client, c, "icon");
|
||||
break;
|
||||
|
@ -1733,7 +1736,7 @@ luaA_client_index(lua_State *L)
|
|||
lua_pushboolean(L, c->ismaxvert);
|
||||
break;
|
||||
case A_TK_ICON:
|
||||
image_push(L, c->icon);
|
||||
luaA_object_push_item(L, 1, c->icon);
|
||||
break;
|
||||
case A_TK_OPACITY:
|
||||
if((d = window_opacity_get(c->win)) >= 0)
|
||||
|
@ -1909,11 +1912,11 @@ luaA_client_buttons(lua_State *L)
|
|||
button_array_t *buttons = &client->buttons;
|
||||
|
||||
if(lua_gettop(L) == 2)
|
||||
luaA_button_array_set(L, 2, buttons);
|
||||
luaA_button_array_set(L, 1, 2, buttons);
|
||||
|
||||
window_buttons_grab(client->win, &client->buttons);
|
||||
|
||||
return luaA_button_array_get(L, buttons);
|
||||
return luaA_button_array_get(L, 1, buttons);
|
||||
}
|
||||
|
||||
/** Get or set keys bindings for a client.
|
||||
|
@ -1932,12 +1935,12 @@ luaA_client_keys(lua_State *L)
|
|||
|
||||
if(lua_gettop(L) == 2)
|
||||
{
|
||||
luaA_key_array_set(L, 2, keys);
|
||||
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, keys);
|
||||
return luaA_key_array_get(L, 1, keys);
|
||||
}
|
||||
|
||||
/* Client module.
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* luaobject.c - useful functions for handling Lua objects
|
||||
*
|
||||
* Copyright © 2009 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/luaobject.h"
|
||||
|
||||
/** Increment a object reference in its store table.
|
||||
* \param L The Lua VM state.
|
||||
* \param tud The table index on the stack.
|
||||
* \param oud The object index on the stack.
|
||||
* \return A pointer to the object.
|
||||
*/
|
||||
void *
|
||||
luaA_object_incref(lua_State *L, int tud, int oud)
|
||||
{
|
||||
/* Get pointer value of the item */
|
||||
void *pointer = (void *) lua_topointer(L, oud);
|
||||
|
||||
/* Not referencable. */
|
||||
if(!pointer)
|
||||
{
|
||||
lua_remove(L, oud);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Push the pointer (key) */
|
||||
lua_pushlightuserdata(L, pointer);
|
||||
/* Push the data (value) */
|
||||
lua_pushvalue(L, oud < 0 ? oud - 1 : oud);
|
||||
/* table.lightudata = data */
|
||||
lua_rawset(L, tud < 0 ? tud - 2 : tud);
|
||||
|
||||
/* refcount++ */
|
||||
|
||||
/* Get the metatable */
|
||||
lua_getmetatable(L, tud);
|
||||
/* Push the pointer (key) */
|
||||
lua_pushlightuserdata(L, pointer);
|
||||
/* Get the number of references */
|
||||
lua_rawget(L, -2);
|
||||
/* Get the number of references and increment it */
|
||||
int count = lua_tonumber(L, -1) + 1;
|
||||
lua_pop(L, 1);
|
||||
/* Push the pointer (key) */
|
||||
lua_pushlightuserdata(L, pointer);
|
||||
/* Push count (value) */
|
||||
lua_pushinteger(L, count);
|
||||
/* Set metatable[pointer] = count */
|
||||
lua_rawset(L, -3);
|
||||
/* Pop metatable */
|
||||
lua_pop(L, 1);
|
||||
|
||||
/* Remove referenced item */
|
||||
lua_remove(L, oud);
|
||||
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/** Decrement a object reference in its store table.
|
||||
* \param L The Lua VM state.
|
||||
* \param tud The table index on the stack.
|
||||
* \param oud The object index on the stack.
|
||||
* \return A pointer to the object.
|
||||
*/
|
||||
void
|
||||
luaA_object_decref(lua_State *L, int tud, void *pointer)
|
||||
{
|
||||
if(!pointer)
|
||||
return;
|
||||
|
||||
/* First, refcount-- */
|
||||
/* Get the metatable */
|
||||
lua_getmetatable(L, tud);
|
||||
/* Push the pointer (key) */
|
||||
lua_pushlightuserdata(L, pointer);
|
||||
/* Get the number of references */
|
||||
lua_rawget(L, -2);
|
||||
/* Get the number of references and decrement it */
|
||||
int count = lua_tonumber(L, -1) - 1;
|
||||
lua_pop(L, 1);
|
||||
/* Push the pointer (key) */
|
||||
lua_pushlightuserdata(L, pointer);
|
||||
/* Hasn't the ref reached 0? */
|
||||
if(count)
|
||||
lua_pushinteger(L, count);
|
||||
else
|
||||
/* Yup, delete it, set nil as value */
|
||||
lua_pushnil(L);
|
||||
/* Set meta[pointer] = count/nil */
|
||||
lua_rawset(L, -3);
|
||||
/* Pop metatable */
|
||||
lua_pop(L, 1);
|
||||
|
||||
/* Wait, no more ref? */
|
||||
if(!count)
|
||||
{
|
||||
/* Yes? So remove it from table */
|
||||
lua_pushlightuserdata(L, pointer);
|
||||
/* Push nil as value */
|
||||
lua_pushnil(L);
|
||||
/* table[pointer] = nil */
|
||||
lua_rawset(L, tud < 0 ? tud - 2 : tud);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
|
@ -25,9 +25,6 @@
|
|||
#include <lauxlib.h>
|
||||
#include "common/array.h"
|
||||
|
||||
/** Type for Lua references */
|
||||
typedef int luaA_ref;
|
||||
|
||||
static inline int
|
||||
luaA_settype(lua_State *L, const char *type)
|
||||
{
|
||||
|
@ -36,10 +33,66 @@ luaA_settype(lua_State *L, const char *type)
|
|||
return 1;
|
||||
}
|
||||
|
||||
DO_ARRAY(luaA_ref, luaA_ref, DO_NOTHING)
|
||||
void * luaA_object_incref(lua_State *, int, int);
|
||||
void luaA_object_decref(lua_State *, int, void *);
|
||||
|
||||
/** Store an item in the environment table of an object.
|
||||
* \param L The Lua VM state.
|
||||
* \param ud The index of the object on the stack.
|
||||
* \param iud The index of the item on the stack.
|
||||
* \return The item reference.
|
||||
*/
|
||||
static inline void *
|
||||
luaA_object_ref_item(lua_State *L, int ud, int iud)
|
||||
{
|
||||
/* Get the env table from the object */
|
||||
lua_getfenv(L, ud);
|
||||
void *pointer = luaA_object_incref(L, -1, iud < 0 ? iud - 1 : iud);
|
||||
/* Remove env table */
|
||||
lua_pop(L, 1);
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/** Unref an item from the environment table of an object.
|
||||
* \param L The Lua VM state.
|
||||
* \param ud The index of the object on the stack.
|
||||
* \param ref item.
|
||||
*/
|
||||
static inline void
|
||||
luaA_object_unref_item(lua_State *L, int ud, void *pointer)
|
||||
{
|
||||
/* Get the env table from the object */
|
||||
lua_getfenv(L, ud);
|
||||
/* Decrement */
|
||||
luaA_object_decref(L, -1, pointer);
|
||||
/* Remove env table */
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
/** Push an object item on the stack.
|
||||
* \param L The Lua VM state.
|
||||
* \param ud The object index on the stack.
|
||||
* \param pointer The item pointer.
|
||||
* \return The number of element pushed on stack.
|
||||
*/
|
||||
static inline int
|
||||
luaA_object_push_item(lua_State *L, int ud, void *pointer)
|
||||
{
|
||||
/* Get env table of the object */
|
||||
lua_getfenv(L, ud);
|
||||
/* Push key */
|
||||
lua_pushlightuserdata(L, pointer);
|
||||
/* Get env.pointer */
|
||||
lua_rawget(L, -2);
|
||||
/* Remove env table */
|
||||
lua_remove(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
DO_ARRAY(int, int, DO_NOTHING)
|
||||
|
||||
#define LUA_OBJECT_HEADER \
|
||||
luaA_ref_array_t refs;
|
||||
int_array_t refs;
|
||||
|
||||
/** Generic type for all objects.
|
||||
* All Lua objects can be casted to this type.
|
||||
|
@ -56,6 +109,10 @@ typedef struct
|
|||
type *p = lua_newuserdata(L, sizeof(type)); \
|
||||
p_clear(p, 1); \
|
||||
luaA_settype(L, lua_type); \
|
||||
lua_newtable(L); \
|
||||
lua_newtable(L); \
|
||||
lua_setmetatable(L, -2); \
|
||||
lua_setfenv(L, -2); \
|
||||
return p; \
|
||||
} \
|
||||
\
|
||||
|
@ -79,7 +136,7 @@ typedef struct
|
|||
return NULL; \
|
||||
type *item = luaL_checkudata(L, ud, lua_type); \
|
||||
lua_pushvalue(L, ud); \
|
||||
luaA_ref_array_append(&item->refs, luaL_ref(L, LUA_REGISTRYINDEX)); \
|
||||
int_array_append(&item->refs, luaL_ref(L, LUA_REGISTRYINDEX)); \
|
||||
lua_remove(L, ud); \
|
||||
return item; \
|
||||
} \
|
||||
|
@ -91,10 +148,20 @@ typedef struct
|
|||
{ \
|
||||
assert(item->refs.len); \
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, item->refs.tab[0]); \
|
||||
luaA_ref_array_take(&item->refs, 0); \
|
||||
int_array_take(&item->refs, 0); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static inline int \
|
||||
prefix##_push_item(lua_State *L, type *item, void *ref) \
|
||||
{ \
|
||||
prefix##_push(L, item); \
|
||||
luaA_object_push_item(L, -1, ref); \
|
||||
lua_remove(L, -2); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
|
||||
/** Garbage collect a Lua object.
|
||||
* \param L The Lua VM state.
|
||||
* \return The number of elements pushed on stack.
|
||||
|
@ -103,7 +170,7 @@ static inline int
|
|||
luaA_object_gc(lua_State *L)
|
||||
{
|
||||
lua_object_t *item = lua_touserdata(L, 1);
|
||||
luaA_ref_array_wipe(&item->refs);
|
||||
int_array_wipe(&item->refs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
76
event.c
76
event.c
|
@ -42,10 +42,11 @@
|
|||
#include "common/atoms.h"
|
||||
#include "common/xutil.h"
|
||||
|
||||
#define DO_EVENT_HOOK_CALLBACK(xcbtype, xcbeventprefix, type, arraytype, match) \
|
||||
#define DO_EVENT_HOOK_CALLBACK(type, xcbeventprefix, arraytype, match) \
|
||||
static void \
|
||||
event_##xcbtype##_callback(xcb_##xcbtype##_press_event_t *ev, \
|
||||
event_##type##_callback(xcb_##type##_press_event_t *ev, \
|
||||
arraytype *arr, \
|
||||
int oud, \
|
||||
int nargs, \
|
||||
void *data) \
|
||||
{ \
|
||||
|
@ -54,19 +55,37 @@
|
|||
switch(ev->response_type) \
|
||||
{ \
|
||||
case xcbeventprefix##_PRESS: \
|
||||
if((*item)->press != LUA_REFNIL) \
|
||||
if((*item)->press) \
|
||||
{ \
|
||||
for(int i = 0; i < nargs; i++) \
|
||||
lua_pushvalue(globalconf.L, - nargs); \
|
||||
luaA_dofunction_from_registry(globalconf.L, (*item)->press, nargs, 0); \
|
||||
if(oud) \
|
||||
{ \
|
||||
luaA_object_push_item(globalconf.L, oud < 0 ? oud - nargs : 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); \
|
||||
luaA_dofunction(globalconf.L, nargs, 0); \
|
||||
} \
|
||||
break; \
|
||||
case xcbeventprefix##_RELEASE: \
|
||||
if((*item)->release != LUA_REFNIL) \
|
||||
if((*item)->release) \
|
||||
{ \
|
||||
for(int i = 0; i < nargs; i++) \
|
||||
lua_pushvalue(globalconf.L, - nargs); \
|
||||
luaA_dofunction_from_registry(globalconf.L, (*item)->release, nargs, 0); \
|
||||
if(oud) \
|
||||
{ \
|
||||
luaA_object_push_item(globalconf.L, oud < 0 ? oud - nargs : 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); \
|
||||
luaA_dofunction(globalconf.L, nargs, 0); \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
|
@ -90,8 +109,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_t, button_array_t, event_button_match)
|
||||
DO_EVENT_HOOK_CALLBACK(key, XCB_KEY, keyb_t, key_array_t, event_key_match)
|
||||
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)
|
||||
|
||||
/** Handle an event with mouse grabber if needed
|
||||
* \param x The x coordinate.
|
||||
|
@ -153,7 +172,7 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
|
|||
}
|
||||
|
||||
wibox_push(globalconf.L, wibox);
|
||||
event_button_callback(ev, &wibox->buttons, 1, NULL);
|
||||
event_button_callback(ev, &wibox->buttons, -1, 1, NULL);
|
||||
|
||||
/* then try to match a widget binding */
|
||||
widget_t *w = widget_getbycoords(wibox->sw.orientation, &wibox->widgets,
|
||||
|
@ -164,13 +183,13 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
|
|||
{
|
||||
widget_push(globalconf.L, w);
|
||||
wibox_push(globalconf.L, wibox);
|
||||
event_button_callback(ev, &w->buttons, 2, NULL);
|
||||
event_button_callback(ev, &w->buttons, -2, 2, NULL);
|
||||
}
|
||||
}
|
||||
else if((c = client_getbywin(ev->event)))
|
||||
{
|
||||
client_push(globalconf.L, c);
|
||||
event_button_callback(ev, &c->buttons, 1, NULL);
|
||||
event_button_callback(ev, &c->buttons, -1, 1, NULL);
|
||||
xcb_allow_events(globalconf.connection,
|
||||
XCB_ALLOW_REPLAY_POINTER,
|
||||
XCB_CURRENT_TIME);
|
||||
|
@ -179,7 +198,7 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
|
|||
for(screen = 0; screen < nb_screen; screen++)
|
||||
if(xutil_screen_get(connection, screen)->root == ev->event)
|
||||
{
|
||||
event_button_callback(ev, &globalconf.buttons, 0, NULL);
|
||||
event_button_callback(ev, &globalconf.buttons, 0, 0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -343,21 +362,23 @@ event_handle_widget_motionnotify(void *object,
|
|||
{
|
||||
if(*mouse_over)
|
||||
{
|
||||
if((*mouse_over)->mouse_leave != LUA_REFNIL)
|
||||
if((*mouse_over)->mouse_leave)
|
||||
{
|
||||
/* call mouse leave function on old widget */
|
||||
widget_push(globalconf.L, *mouse_over);
|
||||
luaA_dofunction_from_registry(globalconf.L, (*mouse_over)->mouse_leave, 1, 0);
|
||||
widget_push_item(globalconf.L, *mouse_over, (*mouse_over)->mouse_leave);
|
||||
luaA_dofunction(globalconf.L, 1, 0);
|
||||
}
|
||||
}
|
||||
if(widget)
|
||||
{
|
||||
/* call mouse enter function on new widget and register it */
|
||||
*mouse_over = widget;
|
||||
if(widget->mouse_enter != LUA_REFNIL)
|
||||
if(widget->mouse_enter)
|
||||
{
|
||||
widget_push(globalconf.L, widget);
|
||||
luaA_dofunction_from_registry(globalconf.L, widget->mouse_enter, 1, 0);
|
||||
widget_push_item(globalconf.L, widget, widget->mouse_enter);
|
||||
luaA_dofunction(globalconf.L, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -418,17 +439,21 @@ event_handle_leavenotify(void *data __attribute__ ((unused)),
|
|||
{
|
||||
if(wibox->mouse_over)
|
||||
{
|
||||
if(wibox->mouse_over->mouse_leave != LUA_REFNIL)
|
||||
if(wibox->mouse_over->mouse_leave)
|
||||
{
|
||||
/* call mouse leave function on widget the mouse was over */
|
||||
wibox_push(globalconf.L, wibox);
|
||||
luaA_dofunction_from_registry(globalconf.L, wibox->mouse_over->mouse_leave, 1, 0);
|
||||
widget_push_item(globalconf.L, wibox->mouse_over, wibox->mouse_over->mouse_leave);
|
||||
luaA_dofunction(globalconf.L, 1, 0);
|
||||
}
|
||||
wibox->mouse_over = NULL;
|
||||
}
|
||||
|
||||
if(wibox->mouse_leave != LUA_REFNIL)
|
||||
luaA_dofunction_from_registry(globalconf.L, wibox->mouse_leave, 0, 0);
|
||||
if(wibox->mouse_leave)
|
||||
{
|
||||
wibox_push_item(globalconf.L, wibox, wibox->mouse_leave);
|
||||
luaA_dofunction(globalconf.L, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -459,8 +484,11 @@ event_handle_enternotify(void *data __attribute__ ((unused)),
|
|||
if(w)
|
||||
event_handle_widget_motionnotify(wibox, &wibox->mouse_over, w);
|
||||
|
||||
if(wibox->mouse_enter != LUA_REFNIL)
|
||||
luaA_dofunction_from_registry(globalconf.L, wibox->mouse_enter, 0, 0);
|
||||
if(wibox->mouse_enter)
|
||||
{
|
||||
wibox_push_item(globalconf.L, wibox, wibox->mouse_enter);
|
||||
luaA_dofunction(globalconf.L, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if((c = client_getbytitlebarwin(ev->event))
|
||||
|
@ -562,10 +590,10 @@ 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, &keysym);
|
||||
event_key_callback(ev, &c->keys, -1, 1, &keysym);
|
||||
}
|
||||
else
|
||||
event_key_callback(ev, &globalconf.keys, 0, &keysym);
|
||||
event_key_callback(ev, &globalconf.keys, 0, 0, &keysym);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
69
key.c
69
key.c
|
@ -31,29 +31,8 @@
|
|||
#include "common/xutil.h"
|
||||
#include "common/tokenize.h"
|
||||
|
||||
LUA_OBJECT_FUNCS(keyb_t, key, "key")
|
||||
|
||||
void
|
||||
key_unref_simplified(keyb_t **b)
|
||||
{
|
||||
key_unref(globalconf.L, *b);
|
||||
}
|
||||
|
||||
DO_LUA_TOSTRING(keyb_t, key, "key")
|
||||
|
||||
/** Garbage collect a key.
|
||||
* \param L The Lua VM state.
|
||||
* \return 0.
|
||||
*/
|
||||
static int
|
||||
luaA_key_gc(lua_State *L)
|
||||
{
|
||||
keyb_t *kbp = luaL_checkudata(L, 1, "key");
|
||||
luaL_unref(globalconf.L, LUA_REGISTRYINDEX, kbp->press);
|
||||
luaL_unref(globalconf.L, LUA_REGISTRYINDEX, kbp->release);
|
||||
return luaA_object_gc(L);
|
||||
}
|
||||
|
||||
/** Grab key on a window.
|
||||
* \param win The window.
|
||||
* \param k The key.
|
||||
|
@ -1026,7 +1005,9 @@ luaA_key_new(lua_State *L)
|
|||
size_t len;
|
||||
keyb_t *k;
|
||||
const char *key;
|
||||
luaA_ref press = LUA_REFNIL, release = LUA_REFNIL;
|
||||
|
||||
/* be sure there's 5 arguments */
|
||||
lua_settop(L, 5);
|
||||
|
||||
/* arg 2 is key mod table */
|
||||
luaA_checktable(L, 2);
|
||||
|
@ -1034,17 +1015,15 @@ luaA_key_new(lua_State *L)
|
|||
key = luaL_checklstring(L, 3, &len);
|
||||
|
||||
if(!lua_isnil(L, 4))
|
||||
luaA_registerfct(L, 4, &press);
|
||||
luaA_checkfunction(L, 4);
|
||||
|
||||
if(lua_gettop(L) == 5 && !lua_isnil(L, 5))
|
||||
luaA_registerfct(L, 5, &release);
|
||||
if(!lua_isnil(L, 5))
|
||||
luaA_checkfunction(L, 5);
|
||||
|
||||
k = key_new(L);
|
||||
k->press = luaA_object_ref_item(L, -1, 4);
|
||||
k->release = luaA_object_ref_item(L, -1, 4);
|
||||
luaA_keystore(k, key, len);
|
||||
|
||||
k->press = press;
|
||||
k->release = release;
|
||||
|
||||
k->mod = luaA_tomodifiers(L, 2);
|
||||
|
||||
return 1;
|
||||
|
@ -1052,34 +1031,42 @@ luaA_key_new(lua_State *L)
|
|||
|
||||
/** Set a key array with a Lua table.
|
||||
* \param L The Lua VM state.
|
||||
* \param oidx The index of the object to store items into.
|
||||
* \param idx The index of the Lua table.
|
||||
* \param keys The array key to fill.
|
||||
*/
|
||||
void
|
||||
luaA_key_array_set(lua_State *L, int idx, key_array_t *keys)
|
||||
luaA_key_array_set(lua_State *L, int oidx, int idx, key_array_t *keys)
|
||||
{
|
||||
luaA_checktable(L, idx);
|
||||
|
||||
foreach(key, *keys)
|
||||
luaA_object_unref_item(L, oidx, *key);
|
||||
|
||||
key_array_wipe(keys);
|
||||
key_array_init(keys);
|
||||
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, idx))
|
||||
key_array_append(keys, key_ref(L, -1));
|
||||
if(luaA_toudata(L, -1, "key"))
|
||||
key_array_append(keys, luaA_object_ref_item(L, oidx, -1));
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
/** Push an array of key as an Lua table onto the stack.
|
||||
* \param L The Lua VM state.
|
||||
* \param oidx The index of the object to get items from.
|
||||
* \param keys The key array to push.
|
||||
* \return The number of elements pushed on stack.
|
||||
*/
|
||||
int
|
||||
luaA_key_array_get(lua_State *L, key_array_t *keys)
|
||||
luaA_key_array_get(lua_State *L, int oidx, key_array_t *keys)
|
||||
{
|
||||
lua_createtable(L, keys->len, 0);
|
||||
for(int i = 0; i < keys->len; i++)
|
||||
{
|
||||
key_push(L, keys->tab[i]);
|
||||
luaA_object_push_item(L, oidx, keys->tab[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
return 1;
|
||||
|
@ -1182,11 +1169,9 @@ luaA_key_index(lua_State *L)
|
|||
luaA_pushmodifiers(L, k->mod);
|
||||
break;
|
||||
case A_TK_PRESS:
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, k->press);
|
||||
break;
|
||||
return luaA_object_push_item(L, 1, k->press);
|
||||
case A_TK_RELEASE:
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, k->release);
|
||||
break;
|
||||
return luaA_object_push_item(L, 1, k->release);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1217,10 +1202,14 @@ luaA_key_newindex(lua_State *L)
|
|||
k->mod = luaA_tomodifiers(L, 3);
|
||||
break;
|
||||
case A_TK_PRESS:
|
||||
luaA_registerfct(L, 3, &k->press);
|
||||
luaA_checkfunction(L, 3);
|
||||
luaA_object_unref_item(L, 1, k->press);
|
||||
k->press = luaA_object_ref_item(L, 1, 3);
|
||||
break;
|
||||
case A_TK_RELEASE:
|
||||
luaA_registerfct(L, 3, &k->release);
|
||||
luaA_checkfunction(L, 3);
|
||||
luaA_object_unref_item(L, 1, k->release);
|
||||
k->release = luaA_object_ref_item(L, 1, 3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1238,7 +1227,7 @@ const struct luaL_reg awesome_key_meta[] =
|
|||
{ "__tostring", luaA_key_tostring },
|
||||
{ "__index", luaA_key_index },
|
||||
{ "__newindex", luaA_key_newindex },
|
||||
{ "__gc", luaA_key_gc },
|
||||
{ "__gc", luaA_object_gc },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
|
13
key.h
13
key.h
|
@ -34,20 +34,19 @@ typedef struct keyb_t
|
|||
/** Keycode */
|
||||
xcb_keycode_t keycode;
|
||||
/** Lua function to execute on press */
|
||||
luaA_ref press;
|
||||
void *press;
|
||||
/** Lua function to execute on release */
|
||||
luaA_ref release;
|
||||
void *release;
|
||||
} keyb_t;
|
||||
|
||||
void key_unref_simplified(keyb_t **);
|
||||
|
||||
DO_ARRAY(keyb_t *, key, key_unref_simplified)
|
||||
DO_ARRAY(keyb_t *, key, DO_NOTHING)
|
||||
LUA_OBJECT_FUNCS(keyb_t, key, "key")
|
||||
|
||||
bool key_press_lookup_string(xcb_keysym_t, char *, ssize_t);
|
||||
xcb_keysym_t key_getkeysym(xcb_keycode_t, uint16_t);
|
||||
|
||||
void luaA_key_array_set(lua_State *, int, key_array_t *);
|
||||
int luaA_key_array_get(lua_State *, key_array_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);
|
||||
|
|
12
luaa.h
12
luaa.h
|
@ -198,13 +198,13 @@ luaA_usemetatable(lua_State *L, int idxobj, int idxfield)
|
|||
/** Register an Lua object.
|
||||
* \param L The Lua stack.
|
||||
* \param idx Index of the object in the stack.
|
||||
* \param ref A luaA_ref address: it will be filled with the luaA_ref
|
||||
* \param ref A int address: it will be filled with the int
|
||||
* registered. If the adresse point to an already registered object, it will
|
||||
* be unregistered.
|
||||
* \return Always 0.
|
||||
*/
|
||||
static inline int
|
||||
luaA_register(lua_State *L, int idx, luaA_ref *ref)
|
||||
luaA_register(lua_State *L, int idx, int *ref)
|
||||
{
|
||||
lua_pushvalue(L, idx);
|
||||
if(*ref != LUA_REFNIL)
|
||||
|
@ -218,7 +218,7 @@ luaA_register(lua_State *L, int idx, luaA_ref *ref)
|
|||
* \param ref A reference to an Lua object.
|
||||
*/
|
||||
static inline void
|
||||
luaA_unregister(lua_State *L, luaA_ref *ref)
|
||||
luaA_unregister(lua_State *L, int *ref)
|
||||
{
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, *ref);
|
||||
*ref = LUA_REFNIL;
|
||||
|
@ -227,13 +227,13 @@ luaA_unregister(lua_State *L, luaA_ref *ref)
|
|||
/** Register a function.
|
||||
* \param L The Lua stack.
|
||||
* \param idx Index of the function in the stack.
|
||||
* \param fct A luaA_ref address: it will be filled with the luaA_ref
|
||||
* \param fct A int address: it will be filled with the int
|
||||
* registered. If the adresse point to an already registered function, it will
|
||||
* be unregistered.
|
||||
* \return luaA_register value.
|
||||
*/
|
||||
static inline int
|
||||
luaA_registerfct(lua_State *L, int idx, luaA_ref *fct)
|
||||
luaA_registerfct(lua_State *L, int idx, int *fct)
|
||||
{
|
||||
luaA_checkfunction(L, idx);
|
||||
return luaA_register(L, idx, fct);
|
||||
|
@ -268,7 +268,7 @@ luaA_dofunction(lua_State *L, int nargs, int nret)
|
|||
* \return True on no error, false otherwise.
|
||||
*/
|
||||
static inline bool
|
||||
luaA_dofunction_from_registry(lua_State *L, luaA_ref ref, int nargs, int nret)
|
||||
luaA_dofunction_from_registry(lua_State *L, int ref, int nargs, int nret)
|
||||
{
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||
return luaA_dofunction(L, nargs, nret);
|
||||
|
|
|
@ -353,11 +353,14 @@ property_handle_net_wm_icon(void *data,
|
|||
|
||||
if(c)
|
||||
{
|
||||
image_unref(globalconf.L, c->icon);
|
||||
client_push(globalconf.L, c);
|
||||
luaA_object_unref_item(globalconf.L, 1, c->icon);
|
||||
if(ewmh_window_icon_from_reply(reply))
|
||||
c->icon = image_ref(globalconf.L, -1);
|
||||
c->icon = luaA_object_ref_item(globalconf.L, -2, -1);
|
||||
else
|
||||
c->icon = NULL;
|
||||
/* remove client */
|
||||
lua_pop(globalconf.L, 1);
|
||||
/* execute hook */
|
||||
hook_property(client, c, "icon");
|
||||
}
|
||||
|
|
48
root.c
48
root.c
|
@ -114,7 +114,17 @@ luaA_root_keys(lua_State *L)
|
|||
{
|
||||
if(lua_gettop(L) == 1)
|
||||
{
|
||||
luaA_key_array_set(L, 1, &globalconf.keys);
|
||||
luaA_checktable(L, 1);
|
||||
|
||||
foreach(key, globalconf.keys)
|
||||
key_unref(globalconf.L, *key);
|
||||
|
||||
key_array_wipe(&globalconf.keys);
|
||||
key_array_init(&globalconf.keys);
|
||||
|
||||
lua_pushnil(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));
|
||||
|
||||
|
@ -124,9 +134,18 @@ luaA_root_keys(lua_State *L)
|
|||
xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, s->root, XCB_BUTTON_MASK_ANY);
|
||||
window_grabkeys(s->root, &globalconf.keys);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return luaA_key_array_get(L, &globalconf.keys);
|
||||
lua_createtable(L, globalconf.keys.len, 0);
|
||||
for(int i = 0; i < globalconf.keys.len; i++)
|
||||
{
|
||||
key_push(L, globalconf.keys.tab[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Get or set global mouse bindings.
|
||||
|
@ -141,9 +160,30 @@ static int
|
|||
luaA_root_buttons(lua_State *L)
|
||||
{
|
||||
if(lua_gettop(L) == 1)
|
||||
luaA_button_array_set(L, 1, &globalconf.buttons);
|
||||
{
|
||||
luaA_checktable(L, 1);
|
||||
|
||||
return luaA_button_array_get(L, &globalconf.buttons);
|
||||
foreach(button, globalconf.buttons)
|
||||
button_unref(globalconf.L, *button);
|
||||
|
||||
button_array_wipe(&globalconf.buttons);
|
||||
button_array_init(&globalconf.buttons);
|
||||
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, 1))
|
||||
button_array_append(&globalconf.buttons, button_ref(L, -1));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_createtable(L, globalconf.buttons.len, 0);
|
||||
for(int i = 0; i < globalconf.buttons.len; i++)
|
||||
{
|
||||
button_push(L, globalconf.buttons.tab[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Set the root cursor.
|
||||
|
|
32
structs.h
32
structs.h
|
@ -97,34 +97,34 @@ struct awesome_t
|
|||
struct
|
||||
{
|
||||
/** Command to execute when spawning a new client */
|
||||
luaA_ref manage;
|
||||
int manage;
|
||||
/** Command to execute when unmanaging client */
|
||||
luaA_ref unmanage;
|
||||
int unmanage;
|
||||
/** Command to execute when giving focus to a client */
|
||||
luaA_ref focus;
|
||||
int focus;
|
||||
/** Command to execute when removing focus to a client */
|
||||
luaA_ref unfocus;
|
||||
int unfocus;
|
||||
/** Command to run when mouse enter a client */
|
||||
luaA_ref mouse_enter;
|
||||
int mouse_enter;
|
||||
/** Command to run when mouse leave a client */
|
||||
luaA_ref mouse_leave;
|
||||
int mouse_leave;
|
||||
/** Command to run when client list changes */
|
||||
luaA_ref clients;
|
||||
int clients;
|
||||
/** Command to run on numbers of tag changes */
|
||||
luaA_ref tags;
|
||||
int tags;
|
||||
/** Command to run when client gets (un)tagged */
|
||||
luaA_ref tagged;
|
||||
int tagged;
|
||||
/** Command to run on property change */
|
||||
luaA_ref property;
|
||||
int property;
|
||||
/** Command to run on time */
|
||||
luaA_ref timer;
|
||||
int timer;
|
||||
/** Command to run on awesome exit */
|
||||
luaA_ref exit;
|
||||
int exit;
|
||||
/** Startup notification hooks */
|
||||
luaA_ref startup_notification;
|
||||
int startup_notification;
|
||||
#ifdef WITH_DBUS
|
||||
/** Command to run on dbus events */
|
||||
luaA_ref dbus;
|
||||
int dbus;
|
||||
#endif
|
||||
} hooks;
|
||||
/** The event loop */
|
||||
|
@ -132,9 +132,9 @@ struct awesome_t
|
|||
/** The timeout after which we need to stop select() */
|
||||
struct ev_timer timer;
|
||||
/** The key grabber function */
|
||||
luaA_ref keygrabber;
|
||||
int keygrabber;
|
||||
/** The mouse pointer grabber function */
|
||||
luaA_ref mousegrabber;
|
||||
int mousegrabber;
|
||||
/** Focused screen */
|
||||
screen_t *screen_focus;
|
||||
/** Need to call client_stack_refresh() */
|
||||
|
|
69
wibox.c
69
wibox.c
|
@ -41,10 +41,6 @@ luaA_wibox_gc(lua_State *L)
|
|||
p_delete(&wibox->cursor);
|
||||
simplewindow_wipe(&wibox->sw);
|
||||
button_array_wipe(&wibox->buttons);
|
||||
image_unref(L, wibox->bg_image);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, wibox->widgets_table);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, wibox->mouse_enter);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, wibox->mouse_leave);
|
||||
widget_node_array_wipe(&wibox->widgets);
|
||||
return luaA_object_gc(L);
|
||||
}
|
||||
|
@ -472,7 +468,6 @@ luaA_wibox_new(lua_State *L)
|
|||
luaA_checktable(L, 2);
|
||||
|
||||
w = wibox_new(L);
|
||||
w->widgets_table = LUA_REFNIL;
|
||||
|
||||
w->sw.ctx.fg = globalconf.colors.fg;
|
||||
if((buf = luaA_getopt_lstring(L, 2, "fg", NULL, &len)))
|
||||
|
@ -498,8 +493,6 @@ luaA_wibox_new(lua_State *L)
|
|||
w->isvisible = true;
|
||||
w->cursor = a_strdup("left_ptr");
|
||||
|
||||
w->mouse_enter = w->mouse_leave = LUA_REFNIL;
|
||||
|
||||
for(i = 0; i <= reqs_nbr; i++)
|
||||
xcolor_init_reply(reqs[i]);
|
||||
|
||||
|
@ -514,9 +507,11 @@ luaA_wibox_new(lua_State *L)
|
|||
static bool
|
||||
luaA_wibox_hasitem(lua_State *L, wibox_t *wibox, const void *item)
|
||||
{
|
||||
if(wibox->widgets_table != LUA_REFNIL)
|
||||
if(wibox->widgets_table)
|
||||
{
|
||||
lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, wibox->widgets_table);
|
||||
wibox_push(L, wibox);
|
||||
luaA_object_push_item(L, -1, wibox->widgets_table);
|
||||
lua_remove(L, -2);
|
||||
if(lua_topointer(L, -1) == item || luaA_hasitem(L, item))
|
||||
return true;
|
||||
}
|
||||
|
@ -618,7 +613,7 @@ luaA_wibox_index(lua_State *L)
|
|||
luaA_pushxcolor(L, &wibox->sw.ctx.bg);
|
||||
break;
|
||||
case A_TK_BG_IMAGE:
|
||||
image_push(L, wibox->bg_image);
|
||||
luaA_object_push_item(L, 1, wibox->bg_image);
|
||||
break;
|
||||
case A_TK_POSITION:
|
||||
if(wibox->type == WIBOX_TYPE_NORMAL)
|
||||
|
@ -632,11 +627,7 @@ luaA_wibox_index(lua_State *L)
|
|||
lua_pushstring(L, orientation_tostr(wibox->sw.orientation));
|
||||
break;
|
||||
case A_TK_WIDGETS:
|
||||
if(wibox->widgets_table != LUA_REFNIL)
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, wibox->widgets_table);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
return luaA_object_push_item(L, 1, wibox->widgets_table);
|
||||
case A_TK_CURSOR:
|
||||
lua_pushstring(L, wibox->cursor);
|
||||
break;
|
||||
|
@ -650,23 +641,13 @@ luaA_wibox_index(lua_State *L)
|
|||
}
|
||||
break;
|
||||
case A_TK_MOUSE_ENTER:
|
||||
if(wibox->mouse_enter != LUA_REFNIL)
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, wibox->mouse_enter);
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
return luaA_object_push_item(L, 1, wibox->mouse_enter);
|
||||
case A_TK_MOUSE_LEAVE:
|
||||
if(wibox->mouse_leave != LUA_REFNIL)
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, wibox->mouse_leave);
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
return luaA_object_push_item(L, 1, wibox->mouse_leave);
|
||||
case A_TK_SHAPE_BOUNDING:
|
||||
image_push(L, wibox->sw.shape.bounding);
|
||||
break;
|
||||
return luaA_object_push_item(L, 1, wibox->sw.shape.bounding);
|
||||
case A_TK_SHAPE_CLIP:
|
||||
image_push(L, wibox->sw.shape.clip);
|
||||
break;
|
||||
return luaA_object_push_item(L, 1, wibox->sw.shape.clip);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -737,8 +718,8 @@ luaA_wibox_newindex(lua_State *L)
|
|||
wibox->need_update = true;
|
||||
break;
|
||||
case A_TK_BG_IMAGE:
|
||||
image_unref(L, wibox->bg_image);
|
||||
wibox->bg_image = image_ref(L, 3);
|
||||
luaA_object_unref_item(L, 1, wibox->bg_image);
|
||||
wibox->bg_image = luaA_object_ref_item(L, 1, 3);
|
||||
wibox->need_update = true;
|
||||
break;
|
||||
case A_TK_ALIGN:
|
||||
|
@ -850,7 +831,10 @@ luaA_wibox_newindex(lua_State *L)
|
|||
luaA_warn(L, "table is looping, cannot use this as widget table");
|
||||
return 0;
|
||||
}
|
||||
luaA_register(L, 3, &(wibox->widgets_table));
|
||||
/* duplicate table because next function will eat it */
|
||||
lua_pushvalue(L, 3);
|
||||
/* register object */
|
||||
wibox->widgets_table = luaA_object_ref_item(L, 1, -1);
|
||||
wibox_need_update(wibox);
|
||||
luaA_table2wtable(L);
|
||||
break;
|
||||
|
@ -865,19 +849,23 @@ luaA_wibox_newindex(lua_State *L)
|
|||
}
|
||||
break;
|
||||
case A_TK_MOUSE_ENTER:
|
||||
luaA_registerfct(L, 3, &wibox->mouse_enter);
|
||||
luaA_checkfunction(L, 3);
|
||||
luaA_object_unref_item(L, 1, wibox->mouse_enter);
|
||||
wibox->mouse_enter = luaA_object_ref_item(L, 1, 3);
|
||||
return 0;
|
||||
case A_TK_MOUSE_LEAVE:
|
||||
luaA_registerfct(L, 3, &wibox->mouse_leave);
|
||||
luaA_checkfunction(L, 3);
|
||||
luaA_object_unref_item(L, 1, wibox->mouse_leave);
|
||||
wibox->mouse_leave = luaA_object_ref_item(L, 1, 3);
|
||||
return 0;
|
||||
case A_TK_SHAPE_BOUNDING:
|
||||
image_unref(L, wibox->sw.shape.bounding);
|
||||
wibox->sw.shape.bounding = image_ref(L, 3);
|
||||
luaA_object_unref_item(L, 1, wibox->sw.shape.bounding);
|
||||
wibox->sw.shape.bounding = luaA_object_ref_item(L, 1, 3);
|
||||
wibox->need_shape_update = true;
|
||||
break;
|
||||
case A_TK_SHAPE_CLIP:
|
||||
image_unref(L, wibox->sw.shape.clip);
|
||||
wibox->sw.shape.clip = image_ref(L, 3);
|
||||
luaA_object_unref_item(L, 1, wibox->sw.shape.clip);
|
||||
wibox->sw.shape.clip = luaA_object_ref_item(L, 1, 3);
|
||||
wibox->need_shape_update = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -904,15 +892,14 @@ static int
|
|||
luaA_wibox_buttons(lua_State *L)
|
||||
{
|
||||
wibox_t *wibox = luaL_checkudata(L, 1, "wibox");
|
||||
button_array_t *buttons = &wibox->buttons;
|
||||
|
||||
if(lua_gettop(L) == 2)
|
||||
{
|
||||
luaA_button_array_set(L, 2, buttons);
|
||||
luaA_button_array_set(L, 1, 2, &wibox->buttons);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return luaA_button_array_get(L, buttons);
|
||||
return luaA_button_array_get(L, 1, &wibox->buttons);
|
||||
}
|
||||
|
||||
const struct luaL_reg awesome_wibox_methods[] =
|
||||
|
|
4
wibox.h
4
wibox.h
|
@ -52,11 +52,11 @@ struct wibox_t
|
|||
screen_t *screen;
|
||||
/** Widget list */
|
||||
widget_node_array_t widgets;
|
||||
luaA_ref widgets_table;
|
||||
void *widgets_table;
|
||||
/** Widget the mouse is over */
|
||||
widget_t *mouse_over;
|
||||
/** Mouse over event handler */
|
||||
luaA_ref mouse_enter, mouse_leave;
|
||||
void *mouse_enter, *mouse_leave;
|
||||
/** Need update */
|
||||
bool need_update;
|
||||
/** Need shape update */
|
||||
|
|
52
widget.c
52
widget.c
|
@ -45,8 +45,6 @@ luaA_widget_gc(lua_State *L)
|
|||
if(widget->destructor)
|
||||
widget->destructor(widget);
|
||||
button_array_wipe(&widget->buttons);
|
||||
luaL_unref(globalconf.L, LUA_REGISTRYINDEX, widget->mouse_enter);
|
||||
luaL_unref(globalconf.L, LUA_REGISTRYINDEX, widget->mouse_leave);
|
||||
return luaA_object_gc(L);
|
||||
}
|
||||
|
||||
|
@ -139,9 +137,14 @@ bool
|
|||
widget_geometries(wibox_t *wibox)
|
||||
{
|
||||
/* get the layout field of the widget table */
|
||||
if (wibox->widgets_table != LUA_REFNIL)
|
||||
if(wibox->widgets_table)
|
||||
{
|
||||
lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, wibox->widgets_table);
|
||||
/* push wibox */
|
||||
wibox_push(globalconf.L, wibox);
|
||||
/* push widgets table */
|
||||
luaA_object_push_item(globalconf.L, -1, wibox->widgets_table);
|
||||
/* remove wibox */
|
||||
lua_remove(globalconf.L, -2);
|
||||
lua_getfield(globalconf.L, -1, "layout");
|
||||
}
|
||||
else
|
||||
|
@ -192,7 +195,12 @@ widget_geometries(wibox_t *wibox)
|
|||
widget_node_array_wipe(widgets);
|
||||
widget_node_array_init(widgets);
|
||||
|
||||
lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, wibox->widgets_table);
|
||||
/* push wibox */
|
||||
wibox_push(globalconf.L, wibox);
|
||||
/* push widgets table */
|
||||
luaA_object_push_item(globalconf.L, -1, wibox->widgets_table);
|
||||
/* remove wibox */
|
||||
lua_remove(globalconf.L, -2);
|
||||
luaA_table2widgets(globalconf.L, widgets);
|
||||
lua_pop(globalconf.L, 2);
|
||||
|
||||
|
@ -285,7 +293,12 @@ widget_render(wibox_t *wibox)
|
|||
|
||||
widget_node_array_wipe(widgets);
|
||||
widget_node_array_init(widgets);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, wibox->widgets_table);
|
||||
/* push wibox */
|
||||
wibox_push(globalconf.L, wibox);
|
||||
/* push widgets table */
|
||||
luaA_object_push_item(globalconf.L, -1, wibox->widgets_table);
|
||||
/* remove wibox */
|
||||
lua_remove(globalconf.L, -2);
|
||||
luaA_table2widgets(L, widgets);
|
||||
|
||||
/* get computed geometries */
|
||||
|
@ -435,8 +448,6 @@ luaA_widget_new(lua_State *L)
|
|||
/* Set visible by default. */
|
||||
w->isvisible = true;
|
||||
|
||||
w->mouse_enter = w->mouse_leave = LUA_REFNIL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -452,15 +463,14 @@ static int
|
|||
luaA_widget_buttons(lua_State *L)
|
||||
{
|
||||
widget_t *widget = luaL_checkudata(L, 1, "widget");
|
||||
button_array_t *buttons = &widget->buttons;
|
||||
|
||||
if(lua_gettop(L) == 2)
|
||||
{
|
||||
luaA_button_array_set(L, 2, buttons);
|
||||
luaA_button_array_set(L, 1, 2, &widget->buttons);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return luaA_button_array_get(L, buttons);
|
||||
return luaA_button_array_get(L, 1, &widget->buttons);
|
||||
}
|
||||
|
||||
/** Generic widget.
|
||||
|
@ -488,17 +498,9 @@ luaA_widget_index(lua_State *L)
|
|||
lua_pushboolean(L, widget->isvisible);
|
||||
return 1;
|
||||
case A_TK_MOUSE_ENTER:
|
||||
if(widget->mouse_enter != LUA_REFNIL)
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, widget->mouse_enter);
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
return luaA_object_push_item(L, 1, widget->mouse_enter);
|
||||
case A_TK_MOUSE_LEAVE:
|
||||
if(widget->mouse_leave != LUA_REFNIL)
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, widget->mouse_leave);
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
return luaA_object_push_item(L, 1, widget->mouse_leave);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -524,10 +526,14 @@ luaA_widget_newindex(lua_State *L)
|
|||
widget->isvisible = luaA_checkboolean(L, 3);
|
||||
break;
|
||||
case A_TK_MOUSE_ENTER:
|
||||
luaA_registerfct(L, 3, &widget->mouse_enter);
|
||||
luaA_checkfunction(L, 3);
|
||||
luaA_object_unref_item(L, 1, widget->mouse_enter);
|
||||
widget->mouse_enter = luaA_object_ref_item(L, 1, 3);
|
||||
return 0;
|
||||
case A_TK_MOUSE_LEAVE:
|
||||
luaA_registerfct(L, 3, &widget->mouse_leave);
|
||||
luaA_checkfunction(L, 3);
|
||||
luaA_object_unref_item(L, 1, widget->mouse_leave);
|
||||
widget->mouse_leave = luaA_object_ref_item(L, 1, 3);
|
||||
return 0;
|
||||
default:
|
||||
return widget->newindex ? widget->newindex(L, token) : 0;
|
||||
|
|
2
widget.h
2
widget.h
|
@ -47,7 +47,7 @@ struct widget_t
|
|||
/** Newindex function */
|
||||
int (*newindex)(lua_State *, awesome_token_t);
|
||||
/** Mouse over event handler */
|
||||
luaA_ref mouse_enter, mouse_leave;
|
||||
void *mouse_enter, *mouse_leave;
|
||||
/** Misc private data */
|
||||
void *data;
|
||||
/** Button bindings */
|
||||
|
|
|
@ -88,7 +88,6 @@ static void
|
|||
imagebox_destructor(widget_t *w)
|
||||
{
|
||||
imagebox_data_t *d = w->data;
|
||||
image_unref(globalconf.L, d->image);
|
||||
p_delete(&d);
|
||||
}
|
||||
|
||||
|
@ -111,7 +110,7 @@ luaA_imagebox_index(lua_State *L, awesome_token_t token)
|
|||
switch(token)
|
||||
{
|
||||
case A_TK_IMAGE:
|
||||
image_push(L, d->image);
|
||||
luaA_object_push_item(L, 1, d->image);
|
||||
break;
|
||||
case A_TK_BG:
|
||||
luaA_pushcolor(L, &d->bg);
|
||||
|
@ -146,8 +145,8 @@ luaA_imagebox_newindex(lua_State *L, awesome_token_t token)
|
|||
size_t len;
|
||||
|
||||
case A_TK_IMAGE:
|
||||
image_unref(L, d->image);
|
||||
d->image = image_ref(L, 3);
|
||||
luaA_object_unref_item(L, 1, d->image);
|
||||
d->image = luaA_object_ref_item(L, 1, 3);
|
||||
break;
|
||||
case A_TK_BG:
|
||||
if(lua_isnil(L, 3))
|
||||
|
|
|
@ -138,7 +138,6 @@ static void
|
|||
textbox_destructor(widget_t *w)
|
||||
{
|
||||
textbox_data_t *d = w->data;
|
||||
image_unref(globalconf.L, d->bg_image);
|
||||
draw_text_context_wipe(&d->data);
|
||||
p_delete(&d);
|
||||
}
|
||||
|
@ -272,8 +271,8 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token)
|
|||
d->bg_resize = luaA_checkboolean(L, 3);
|
||||
break;
|
||||
case A_TK_BG_IMAGE:
|
||||
image_unref(L, d->bg_image);
|
||||
d->bg_image = image_ref(L, 3);
|
||||
luaA_object_unref_item(L, 1, d->bg_image);
|
||||
d->bg_image = luaA_object_ref_item(L, 1, 3);
|
||||
break;
|
||||
case A_TK_BG:
|
||||
if(lua_isnil(L, 3))
|
||||
|
|
Loading…
Reference in New Issue