Store widgets references as wibox items
This will store the widgets references that the wibox have inside their environment table, and not in the global registry, avoiding memory leaks. This should fix FS#771. Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
b473a6fe66
commit
6a1ce5ce05
70
event.c
70
event.c
|
@ -159,7 +159,11 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
|
||||||
ev->event_y -= wibox->geometry.y;
|
ev->event_y -= wibox->geometry.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Push the wibox */
|
||||||
luaA_object_push(globalconf.L, wibox);
|
luaA_object_push(globalconf.L, wibox);
|
||||||
|
/* Duplicate the wibox */
|
||||||
|
lua_pushvalue(globalconf.L, -1);
|
||||||
|
/* Handle the button event on it */
|
||||||
event_button_callback(ev, &wibox->buttons, -1, 1, NULL);
|
event_button_callback(ev, &wibox->buttons, -1, 1, NULL);
|
||||||
|
|
||||||
/* then try to match a widget binding */
|
/* then try to match a widget binding */
|
||||||
|
@ -169,10 +173,16 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
|
||||||
&ev->event_x, &ev->event_y);
|
&ev->event_x, &ev->event_y);
|
||||||
if(w)
|
if(w)
|
||||||
{
|
{
|
||||||
luaA_object_push(globalconf.L, w);
|
/* Push widget (the wibox is already on stack) */
|
||||||
luaA_object_push(globalconf.L, wibox);
|
luaA_object_push_item(globalconf.L, -1, w);
|
||||||
|
/* Move widget before wibox */
|
||||||
|
lua_insert(globalconf.L, -2);
|
||||||
event_button_callback(ev, &w->buttons, -2, 2, NULL);
|
event_button_callback(ev, &w->buttons, -2, 2, NULL);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
/* Remove the wibox, we did not use it */
|
||||||
|
lua_pop(globalconf.L, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if((c = client_getbywin(ev->event)))
|
else if((c = client_getbywin(ev->event)))
|
||||||
{
|
{
|
||||||
|
@ -341,12 +351,12 @@ event_handle_destroynotify(void *data __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Handle a motion notify over widgets.
|
/** Handle a motion notify over widgets.
|
||||||
* \param object The object.
|
* \param wibox The wibox.
|
||||||
* \param mouse_over The pointer to the registered mouse over widget.
|
* \param mouse_over The pointer to the registered mouse over widget.
|
||||||
* \param widget The new widget the mouse is over.
|
* \param widget The new widget the mouse is over.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
event_handle_widget_motionnotify(void *object,
|
event_handle_widget_motionnotify(wibox_t *wibox,
|
||||||
widget_t **mouse_over,
|
widget_t **mouse_over,
|
||||||
widget_t *widget)
|
widget_t *widget)
|
||||||
{
|
{
|
||||||
|
@ -354,25 +364,46 @@ event_handle_widget_motionnotify(void *object,
|
||||||
{
|
{
|
||||||
if(*mouse_over)
|
if(*mouse_over)
|
||||||
{
|
{
|
||||||
/* call mouse leave function on old widget */
|
/* Emit mouse leave signal on old widget:
|
||||||
luaA_object_push(globalconf.L, *mouse_over);
|
* - Push wibox.*/
|
||||||
luaA_object_emit_signal(globalconf.L, -1, "mouse::leave", 0);
|
luaA_object_push(globalconf.L, wibox);
|
||||||
|
/* - Push the widget the mouse was on */
|
||||||
|
luaA_object_push_item(globalconf.L, -1, *mouse_over);
|
||||||
|
/* - Emit the signal mouse::leave with the wibox as argument */
|
||||||
|
luaA_object_emit_signal(globalconf.L, -2, "mouse::leave", 1);
|
||||||
|
/* - Remove the widget */
|
||||||
lua_pop(globalconf.L, 1);
|
lua_pop(globalconf.L, 1);
|
||||||
|
|
||||||
luaA_object_unref(globalconf.L, *mouse_over);
|
/* Re-push wibox */
|
||||||
|
luaA_object_push(globalconf.L, wibox);
|
||||||
|
luaA_object_unref_item(globalconf.L, -1, *mouse_over);
|
||||||
*mouse_over = NULL;
|
*mouse_over = NULL;
|
||||||
|
/* Remove the wibox */
|
||||||
|
lua_pop(globalconf.L, 1);
|
||||||
}
|
}
|
||||||
if(widget)
|
if(widget)
|
||||||
{
|
{
|
||||||
/* Get a ref on this widget so that it can't be unref'd from
|
/* Get a ref on this widget so that it can't be unref'd from
|
||||||
* underneath us (-> invalid pointer dereference). */
|
* underneath us (-> invalid pointer dereference):
|
||||||
luaA_object_push(globalconf.L, widget);
|
* - Push the wibox */
|
||||||
luaA_object_ref(globalconf.L, -1);
|
luaA_object_push(globalconf.L, wibox);
|
||||||
|
/* - Push the widget */
|
||||||
|
luaA_object_push_item(globalconf.L, -1, widget);
|
||||||
|
/* - Reference the widget into the wibox */
|
||||||
|
luaA_object_ref_item(globalconf.L, -2, -1);
|
||||||
|
|
||||||
|
/* Store that this widget was the one with the mouse over */
|
||||||
*mouse_over = widget;
|
*mouse_over = widget;
|
||||||
|
|
||||||
/* emit mouse::enter signal on new widget */
|
/* Emit mouse::enter signal on new widget:
|
||||||
luaA_object_push(globalconf.L, widget);
|
* - Push the widget */
|
||||||
luaA_object_emit_signal(globalconf.L, -1, "mouse::enter", 0);
|
luaA_object_push_item(globalconf.L, -1, widget);
|
||||||
|
/* - Move the widget before the wibox we pushed just above */
|
||||||
|
lua_insert(globalconf.L, -2);
|
||||||
|
/* - Emit the signal with the wibox as argument */
|
||||||
|
|
||||||
|
luaA_object_emit_signal(globalconf.L, -2, "mouse::enter", 1);
|
||||||
|
/* - Remove the widget from the stack */
|
||||||
lua_pop(globalconf.L, 1);
|
lua_pop(globalconf.L, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,9 +464,14 @@ event_handle_leavenotify(void *data __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
if(wibox->mouse_over)
|
if(wibox->mouse_over)
|
||||||
{
|
{
|
||||||
luaA_object_push(globalconf.L, wibox->mouse_over);
|
/* Push the wibox */
|
||||||
/* emit mouse::leave signal on widget the mouse was over */
|
luaA_object_push(globalconf.L, wibox);
|
||||||
luaA_object_emit_signal(globalconf.L, -1, "mouse::leave", 0);
|
/* Push the widget the mouse is over in this wibox */
|
||||||
|
luaA_object_push_item(globalconf.L, -1, wibox->mouse_over);
|
||||||
|
/* Emit mouse::leave signal on widget the mouse was over with
|
||||||
|
* its wibox as argument */
|
||||||
|
luaA_object_emit_signal(globalconf.L, -2, "mouse::leave", 1);
|
||||||
|
/* Remove the widget from the stack */
|
||||||
lua_pop(globalconf.L, 1);
|
lua_pop(globalconf.L, 1);
|
||||||
wibox_clear_mouse_over(wibox);
|
wibox_clear_mouse_over(wibox);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,20 @@ luaA_wibox_gc(lua_State *L)
|
||||||
return luaA_object_gc(L);
|
return luaA_object_gc(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Wipe an array of widget_node. Release references to widgets.
|
||||||
|
* \param L The Lua VM state.
|
||||||
|
* \param idx The index of the wibox on the stack.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
wibox_widget_node_array_wipe(lua_State *L, int idx)
|
||||||
|
{
|
||||||
|
wibox_t *wibox = luaA_checkudata(L, idx, &wibox_class);
|
||||||
|
foreach(widget_node, wibox->widgets)
|
||||||
|
luaA_object_unref_item(globalconf.L, idx, widget_node);
|
||||||
|
widget_node_array_wipe(&wibox->widgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
wibox_unref_simplified(wibox_t **item)
|
wibox_unref_simplified(wibox_t **item)
|
||||||
{
|
{
|
||||||
|
|
|
@ -84,6 +84,7 @@ struct wibox_t
|
||||||
void wibox_unref_simplified(wibox_t **);
|
void wibox_unref_simplified(wibox_t **);
|
||||||
|
|
||||||
ARRAY_FUNCS(wibox_t *, wibox, wibox_unref_simplified)
|
ARRAY_FUNCS(wibox_t *, wibox, wibox_unref_simplified)
|
||||||
|
void wibox_widget_node_array_wipe(lua_State *, int);
|
||||||
|
|
||||||
void wibox_refresh(void);
|
void wibox_refresh(void);
|
||||||
|
|
||||||
|
|
|
@ -49,15 +49,6 @@ luaA_widget_gc(lua_State *L)
|
||||||
return luaA_object_gc(L);
|
return luaA_object_gc(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Delete a widget node structure.
|
|
||||||
* \param node The node to destroy.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
widget_node_delete(widget_node_t *node)
|
|
||||||
{
|
|
||||||
luaA_object_unref(globalconf.L, node->widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get a widget node from a wibox by coords.
|
/** Get a widget node from a wibox by coords.
|
||||||
* \param orientation Wibox orientation.
|
* \param orientation Wibox orientation.
|
||||||
* \param widgets The widget list.
|
* \param widgets The widget list.
|
||||||
|
@ -100,19 +91,21 @@ widget_getbycoords(orientation_t orientation, widget_node_array_t *widgets,
|
||||||
|
|
||||||
/** Convert a Lua table to a list of widget nodes.
|
/** Convert a Lua table to a list of widget nodes.
|
||||||
* \param L The Lua VM state.
|
* \param L The Lua VM state.
|
||||||
|
* \param idx Index of the table where to store the widgets references.
|
||||||
* \param widgets The linked list of widget node.
|
* \param widgets The linked list of widget node.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
luaA_table2widgets(lua_State *L, widget_node_array_t *widgets)
|
luaA_table2widgets(lua_State *L, int idx, widget_node_array_t *widgets)
|
||||||
{
|
{
|
||||||
if(lua_istable(L, -1))
|
if(lua_istable(L, -1))
|
||||||
{
|
{
|
||||||
|
int table_idx = luaA_absindex(L, idx);
|
||||||
int i = 1;
|
int i = 1;
|
||||||
lua_pushnumber(L, i++);
|
lua_pushnumber(L, i++);
|
||||||
lua_gettable(L, -2);
|
lua_gettable(L, -2);
|
||||||
while(!lua_isnil(L, -1))
|
while(!lua_isnil(L, -1))
|
||||||
{
|
{
|
||||||
luaA_table2widgets(L, widgets);
|
luaA_table2widgets(L, table_idx, widgets);
|
||||||
lua_pushnumber(L, i++);
|
lua_pushnumber(L, i++);
|
||||||
lua_gettable(L, -2);
|
lua_gettable(L, -2);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +120,7 @@ luaA_table2widgets(lua_State *L, widget_node_array_t *widgets)
|
||||||
{
|
{
|
||||||
widget_node_t w;
|
widget_node_t w;
|
||||||
p_clear(&w, 1);
|
p_clear(&w, 1);
|
||||||
w.widget = luaA_object_ref(L, -1);
|
w.widget = luaA_object_ref_item(L, idx, -1);
|
||||||
widget_node_array_append(widgets, w);
|
widget_node_array_append(widgets, w);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -204,17 +197,19 @@ widget_geometries(wibox_t *wibox)
|
||||||
* or the wibox size, depending on which is less.
|
* or the wibox size, depending on which is less.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
widget_node_array_t *widgets = &wibox->widgets;
|
|
||||||
widget_node_array_wipe(widgets);
|
|
||||||
widget_node_array_init(widgets);
|
|
||||||
|
|
||||||
/* push wibox */
|
/* push wibox */
|
||||||
luaA_object_push(globalconf.L, wibox);
|
luaA_object_push(globalconf.L, wibox);
|
||||||
|
|
||||||
|
widget_node_array_t *widgets = &wibox->widgets;
|
||||||
|
wibox_widget_node_array_wipe(globalconf.L, -1);
|
||||||
|
widget_node_array_init(widgets);
|
||||||
|
|
||||||
/* push widgets table */
|
/* push widgets table */
|
||||||
luaA_object_push_item(globalconf.L, -1, wibox->widgets_table);
|
luaA_object_push_item(globalconf.L, -1, wibox->widgets_table);
|
||||||
|
/* Convert widgets table */
|
||||||
|
luaA_table2widgets(globalconf.L, -2, widgets);
|
||||||
/* remove wibox */
|
/* remove wibox */
|
||||||
lua_remove(globalconf.L, -2);
|
lua_remove(globalconf.L, -1);
|
||||||
luaA_table2widgets(globalconf.L, widgets);
|
|
||||||
|
|
||||||
lua_newtable(globalconf.L);
|
lua_newtable(globalconf.L);
|
||||||
for(int i = 0; i < widgets->len; i++)
|
for(int i = 0; i < widgets->len; i++)
|
||||||
|
@ -304,15 +299,17 @@ widget_render(wibox_t *wibox)
|
||||||
|
|
||||||
widget_node_array_t *widgets = &wibox->widgets;
|
widget_node_array_t *widgets = &wibox->widgets;
|
||||||
|
|
||||||
widget_node_array_wipe(widgets);
|
|
||||||
widget_node_array_init(widgets);
|
|
||||||
/* push wibox */
|
/* push wibox */
|
||||||
luaA_object_push(globalconf.L, wibox);
|
luaA_object_push(globalconf.L, wibox);
|
||||||
|
|
||||||
|
wibox_widget_node_array_wipe(globalconf.L, -1);
|
||||||
|
widget_node_array_init(widgets);
|
||||||
|
|
||||||
/* push widgets table */
|
/* push widgets table */
|
||||||
luaA_object_push_item(globalconf.L, -1, wibox->widgets_table);
|
luaA_object_push_item(globalconf.L, -1, wibox->widgets_table);
|
||||||
|
luaA_table2widgets(L, -2, widgets);
|
||||||
/* remove wibox */
|
/* remove wibox */
|
||||||
lua_remove(globalconf.L, -2);
|
lua_remove(globalconf.L, -1);
|
||||||
luaA_table2widgets(L, widgets);
|
|
||||||
|
|
||||||
/* get computed geometries */
|
/* get computed geometries */
|
||||||
for(unsigned int i = 0; i < lua_objlen(L, -1); i++)
|
for(unsigned int i = 0; i < lua_objlen(L, -1); i++)
|
||||||
|
|
|
@ -54,8 +54,6 @@ struct widget_t
|
||||||
bool isvisible;
|
bool isvisible;
|
||||||
};
|
};
|
||||||
|
|
||||||
void widget_node_delete(widget_node_t *);
|
|
||||||
|
|
||||||
struct widget_node
|
struct widget_node
|
||||||
{
|
{
|
||||||
/** The widget object */
|
/** The widget object */
|
||||||
|
@ -63,7 +61,7 @@ struct widget_node
|
||||||
/** The geometry where the widget was drawn */
|
/** The geometry where the widget was drawn */
|
||||||
area_t geometry;
|
area_t geometry;
|
||||||
};
|
};
|
||||||
DO_ARRAY(widget_node_t, widget_node, widget_node_delete)
|
DO_ARRAY(widget_node_t, widget_node, DO_NOTHING)
|
||||||
|
|
||||||
widget_t *widget_getbycoords(orientation_t, widget_node_array_t *, int, int, int16_t *, int16_t *);
|
widget_t *widget_getbycoords(orientation_t, widget_node_array_t *, int, int, int16_t *, int16_t *);
|
||||||
void widget_render(wibox_t *);
|
void widget_render(wibox_t *);
|
||||||
|
|
Loading…
Reference in New Issue