diff --git a/event.c b/event.c index 809cbca9..c744360a 100644 --- a/event.c +++ b/event.c @@ -121,7 +121,6 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e int screen; const int nb_screen = xcb_setup_roots_length(xcb_get_setup(connection)); client_t *c; - widget_t *w; wibox_t *wibox; /* ev->state is @@ -168,10 +167,11 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e } /* then try to match a widget binding */ - if((w = widget_getbycoords(wibox->position, &wibox->widgets, - wibox->sw.geometry.width, - wibox->sw.geometry.height, - &ev->event_x, &ev->event_y))) + widget_t *w = widget_getbycoords(wibox->position, &wibox->widgets, + wibox->sw.geometry.width, + wibox->sw.geometry.height, + &ev->event_x, &ev->event_y); + if(w) { b = &w->buttons; @@ -427,16 +427,18 @@ event_handle_motionnotify(void *data __attribute__ ((unused)), xcb_motion_notify_event_t *ev) { wibox_t *wibox; - widget_t *w; event_handle_mousegrabber(ev->root_x, ev->root_y, ev->state); - if((wibox = wibox_getbywin(ev->event)) - && (w = widget_getbycoords(wibox->position, &wibox->widgets, - wibox->sw.geometry.width, - wibox->sw.geometry.height, - &ev->event_x, &ev->event_y))) - event_handle_widget_motionnotify(wibox, &wibox->mouse_over, w); + if((wibox = wibox_getbywin(ev->event))) + { + widget_t *w = widget_getbycoords(wibox->position, &wibox->widgets, + wibox->sw.geometry.width, + wibox->sw.geometry.height, + &ev->event_x, &ev->event_y); + if(w) + event_handle_widget_motionnotify(wibox, &wibox->mouse_over, w); + } return 0; } @@ -495,7 +497,6 @@ event_handle_enternotify(void *data __attribute__ ((unused)), xcb_enter_notify_event_t *ev) { client_t *c; - widget_t *w; wibox_t *wibox; if(ev->mode != XCB_NOTIFY_MODE_NORMAL) @@ -503,10 +504,11 @@ event_handle_enternotify(void *data __attribute__ ((unused)), if((wibox = wibox_getbywin(ev->event))) { - if((w = widget_getbycoords(wibox->position, &wibox->widgets, - wibox->sw.geometry.width, - wibox->sw.geometry.height, - &ev->event_x, &ev->event_y))) + widget_t *w = widget_getbycoords(wibox->position, &wibox->widgets, + wibox->sw.geometry.width, + wibox->sw.geometry.height, + &ev->event_x, &ev->event_y); + if(w) event_handle_widget_motionnotify(wibox, &wibox->mouse_over, w); if(wibox->mouse_enter != LUA_REFNIL) @@ -515,13 +517,11 @@ event_handle_enternotify(void *data __attribute__ ((unused)), if((c = client_getbytitlebarwin(ev->event)) || (c = client_getbywin(ev->event))) - { if(globalconf.hooks.mouse_enter != LUA_REFNIL) { luaA_client_userdata_new(globalconf.L, c); luaA_dofunction(globalconf.L, globalconf.hooks.mouse_enter, 1, 0); } - } return 0; } diff --git a/luaa.c b/luaa.c index 296e85c8..bd023a4f 100644 --- a/luaa.c +++ b/luaa.c @@ -534,7 +534,7 @@ luaA_wtable_newindex(lua_State *L) /* get current key value in content table */ lua_rawget(L, lua_upvalueindex(1)); /* if value is a widget, notify change */ - if(lua_istable(L, -1) || luaA_toudata(L, -1, "widget")) + if(lua_istable(L, -1) || luaA_toudata2(L, -1, "widget")) invalid = true; lua_pop(L, 1); /* remove value */ @@ -545,7 +545,7 @@ luaA_wtable_newindex(lua_State *L) luaA_table2wtable(L); invalid = true; } - else if(!invalid && luaA_toudata(L, 3, "widget")) + else if(!invalid && luaA_toudata2(L, 3, "widget")) invalid = true; /* upvalue 1 is content table */ diff --git a/mouse.c b/mouse.c index 56a7fd18..8935c4fb 100644 --- a/mouse.c +++ b/mouse.c @@ -482,7 +482,7 @@ luaA_mouse_object_under_pointer(lua_State *L) if(widget) { - luaA_widget_userdata_new(L, widget); + widget_push(L, widget); return 2; } return 1; diff --git a/structs.h b/structs.h index fc55ec12..378a5700 100644 --- a/structs.h +++ b/structs.h @@ -120,8 +120,8 @@ ARRAY_TYPE(wibox_t *, wibox) /** Widget */ struct widget_t { - /** Ref count */ - int refcount; + /** Lua references */ + luaA_ref_array_t refs; /** Widget type is constructor */ widget_constructor_t *type; /** Widget destructor */ diff --git a/wibox.c b/wibox.c index f4f2a990..fe01558b 100644 --- a/wibox.c +++ b/wibox.c @@ -1101,7 +1101,10 @@ luaA_wibox_newindex(lua_State *L) luaA_warn(L, "table is looping, cannot use this as widget table"); return 0; } + /* register object */ luaA_register(L, 3, &(*wibox)->widgets_table); + /* duplicate table because next function will eat it */ + lua_pushvalue(L, -1); /* recompute widget node list */ wibox_widgets_table_build(L, *wibox); luaA_table2wtable(L); diff --git a/widget.c b/widget.c index e49cde8f..5f2c1892 100644 --- a/widget.c +++ b/widget.c @@ -29,24 +29,33 @@ #include "wibox.h" #include "common/atoms.h" -DO_LUA_NEW(extern, widget_t, widget, "widget", widget_ref) -DO_LUA_GC(widget_t, widget, "widget", widget_unref) -DO_LUA_EQ(widget_t, widget, "widget") - #include "widgetgen.h" -/** Delete a widget structure. - * \param widget The widget to destroy. +DO_LUA_TOSTRING(widget_t, widget, "widget") + +/** Collect a widget structure. + * \param L The Lua VM state. + * \return 0 + */ +static int +luaA_widget_gc(lua_State *L) +{ + widget_t *widget = luaL_checkudata(L, 1, "widget"); + 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 0; +} + +/** Delete a widget node structure. + * \param node The node to destroy. */ void -widget_delete(widget_t **widget) +widget_node_delete(widget_node_t *node) { - 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); - p_delete(widget); + widget_unref(globalconf.L, node->widget); } /** Get a widget node from a wibox by coords. @@ -80,14 +89,11 @@ widget_getbycoords(position_t position, widget_node_array_t *widgets, default: break; } - for(int i = 0; i < widgets->len; i++) - { - widget_node_t *w = &widgets->tab[i]; - if(w->widget->isvisible && - *x >= w->geometry.x && *x < w->geometry.x + w->geometry.width + foreach(w, *widgets) + if(w->widget->isvisible + && *x >= w->geometry.x && *x < w->geometry.x + w->geometry.width && *y >= w->geometry.y && *y < w->geometry.y + w->geometry.height) return w->widget; - } return NULL; } @@ -103,21 +109,22 @@ luaA_table2widgets(lua_State *L, widget_node_array_t *widgets) { lua_pushnil(L); while(luaA_next(L, -2)) - { luaA_table2widgets(L, widgets); - lua_pop(L, 1); /* remove value */ - } + /* remove the table */ + lua_pop(L, 1); } else { - widget_t **widget = luaA_toudata(L, -1, "widget"); + widget_t *widget = luaA_toudata2(L, -1, "widget"); if(widget) { widget_node_t w; p_clear(&w, 1); - w.widget = widget_ref(widget); + w.widget = widget_ref(L); widget_node_array_append(widgets, w); } + else + lua_pop(L, 1); /* remove value */ } } @@ -186,7 +193,8 @@ widget_render(wibox_t *wibox) /* compute geometry */ for(int i = 0; i < widgets->len; i++) - if(widgets->tab[i].widget->align == AlignLeft && widgets->tab[i].widget->isvisible) + if(widgets->tab[i].widget->align == AlignLeft + && widgets->tab[i].widget->isvisible) { widgets->tab[i].geometry = widgets->tab[i].widget->geometry(widgets->tab[i].widget, wibox->screen, ctx->height, @@ -360,7 +368,7 @@ luaA_widget_new(lua_State *L) if((wc = name_func_lookup(type, len, WidgetList))) { - w = p_new(widget_t, 1); + w = widget_new(L); wc(w); } else @@ -380,7 +388,7 @@ luaA_widget_new(lua_State *L) w->mouse_enter = w->mouse_leave = LUA_REFNIL; - return luaA_widget_userdata_new(L, w); + return 1; } /** Get or set mouse buttons bindings to a widget. @@ -394,8 +402,8 @@ luaA_widget_new(lua_State *L) static int luaA_widget_buttons(lua_State *L) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - button_array_t *buttons = &(*widget)->buttons; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + button_array_t *buttons = &widget->buttons; if(lua_gettop(L) == 2) { @@ -419,7 +427,7 @@ static int luaA_widget_index(lua_State *L) { size_t len; - widget_t **widget = luaA_checkudata(L, 1, "widget"); + widget_t *widget = luaL_checkudata(L, 1, "widget"); const char *buf = luaL_checklstring(L, 2, &len); awesome_token_t token; @@ -429,20 +437,20 @@ luaA_widget_index(lua_State *L) switch((token = a_tokenize(buf, len))) { case A_TK_ALIGN: - lua_pushstring(L, draw_align_tostr((*widget)->align)); + lua_pushstring(L, draw_align_tostr(widget->align)); return 1; case A_TK_VISIBLE: - lua_pushboolean(L, (*widget)->isvisible); + 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); + if(widget->mouse_enter != LUA_REFNIL) + lua_rawgeti(L, LUA_REGISTRYINDEX, widget->mouse_enter); else return 0; return 1; case A_TK_MOUSE_LEAVE: - if((*widget)->mouse_leave != LUA_REFNIL) - lua_rawgeti(L, LUA_REGISTRYINDEX, (*widget)->mouse_leave); + if(widget->mouse_leave != LUA_REFNIL) + lua_rawgeti(L, LUA_REGISTRYINDEX, widget->mouse_leave); else return 0; return 1; @@ -450,7 +458,7 @@ luaA_widget_index(lua_State *L) break; } - return (*widget)->index ? (*widget)->index(L, token) : 0; + return widget->index ? widget->index(L, token) : 0; } /** Generic widget newindex. @@ -461,7 +469,7 @@ static int luaA_widget_newindex(lua_State *L) { size_t len; - widget_t **widget = luaA_checkudata(L, 1, "widget"); + widget_t *widget = luaL_checkudata(L, 1, "widget"); const char *buf = luaL_checklstring(L, 2, &len); awesome_token_t token; @@ -469,22 +477,22 @@ luaA_widget_newindex(lua_State *L) { case A_TK_ALIGN: buf = luaL_checklstring(L, 3, &len); - (*widget)->align = draw_align_fromstr(buf, len); + widget->align = draw_align_fromstr(buf, len); break; case A_TK_VISIBLE: - (*widget)->isvisible = luaA_checkboolean(L, 3); + widget->isvisible = luaA_checkboolean(L, 3); break; case A_TK_MOUSE_ENTER: - luaA_registerfct(L, 3, &(*widget)->mouse_enter); + luaA_registerfct(L, 3, &widget->mouse_enter); return 0; case A_TK_MOUSE_LEAVE: - luaA_registerfct(L, 3, &(*widget)->mouse_leave); + luaA_registerfct(L, 3, &widget->mouse_leave); return 0; default: - return (*widget)->newindex ? (*widget)->newindex(L, token) : 0; + return widget->newindex ? widget->newindex(L, token) : 0; } - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); return 0; } @@ -500,7 +508,6 @@ const struct luaL_reg awesome_widget_meta[] = { "__index", luaA_widget_index }, { "__newindex", luaA_widget_newindex }, { "__gc", luaA_widget_gc }, - { "__eq", luaA_widget_eq }, { "__tostring", luaA_widget_tostring }, { NULL, NULL } }; diff --git a/widget.h b/widget.h index 758337d2..be46f450 100644 --- a/widget.h +++ b/widget.h @@ -24,22 +24,19 @@ #include "mouse.h" +LUA_OBJECT_FUNCS(widget_t, widget, "widget"); + struct widget_node_t { - /** The widget */ + /** The widget object */ widget_t *widget; /** The geometry where the widget was drawn */ area_t geometry; }; -void widget_delete(widget_t **); - -DO_RCNT(widget_t, widget, widget_delete) - widget_t *widget_getbycoords(position_t, widget_node_array_t *, int, int, int16_t *, int16_t *); void widget_render(wibox_t *); -int luaA_widget_userdata_new(lua_State *, widget_t *); void luaA_table2widgets(lua_State *, widget_node_array_t *); void widget_invalidate_bywidget(widget_t *); @@ -51,15 +48,7 @@ widget_constructor_t widget_graph; widget_constructor_t widget_systray; widget_constructor_t widget_imagebox; -/** Delete a widget node structure. - * \param node The node to destroy. - */ -static inline void -widget_node_delete(widget_node_t *node) -{ - widget_unref(&node->widget); -} - +void widget_node_delete(widget_node_t *); ARRAY_FUNCS(widget_node_t, widget_node, widget_node_delete) #endif diff --git a/widgets/graph.c b/widgets/graph.c index df05051a..d8f1fa9f 100644 --- a/widgets/graph.c +++ b/widgets/graph.c @@ -298,8 +298,8 @@ graph_draw(widget_t *widget, draw_context_t *ctx, static int luaA_graph_plot_properties_set(lua_State *L) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - graph_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + graph_data_t *d = widget->data; float max_value; const char *title, *buf; size_t len; @@ -347,7 +347,7 @@ luaA_graph_plot_properties_set(lua_State *L) for(i = 0; i <= reqs_nbr; i++) xcolor_init_reply(reqs[i]); - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); return 0; } @@ -363,8 +363,8 @@ luaA_graph_plot_properties_set(lua_State *L) static int luaA_graph_plot_data_add(lua_State *L) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - graph_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + graph_data_t *d = widget->data; plot_t *plot = NULL; const char *title = luaL_checkstring(L, 2); float value; @@ -420,7 +420,7 @@ luaA_graph_plot_data_add(lua_State *L) plot->lines[plot->index] = d->box_height; } - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); return 0; } @@ -440,8 +440,8 @@ luaA_graph_plot_data_add(lua_State *L) static int luaA_graph_index(lua_State *L, awesome_token_t token) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - graph_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + graph_data_t *d = widget->data; switch(token) { @@ -492,8 +492,8 @@ static int luaA_graph_newindex(lua_State *L, awesome_token_t token) { size_t len; - widget_t **widget = luaA_checkudata(L, 1, "widget"); - graph_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + graph_data_t *d = widget->data; const char *buf; int width; position_t pos; @@ -559,7 +559,7 @@ luaA_graph_newindex(lua_State *L, awesome_token_t token) return 0; } - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); return 0; } diff --git a/widgets/imagebox.c b/widgets/imagebox.c index c88c9e29..5456db51 100644 --- a/widgets/imagebox.c +++ b/widgets/imagebox.c @@ -132,8 +132,8 @@ imagebox_destructor(widget_t *w) static int luaA_imagebox_index(lua_State *L, awesome_token_t token) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - imagebox_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + imagebox_data_t *d = widget->data; switch(token) { @@ -164,8 +164,8 @@ luaA_imagebox_index(lua_State *L, awesome_token_t token) static int luaA_imagebox_newindex(lua_State *L, awesome_token_t token) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - imagebox_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + imagebox_data_t *d = widget->data; switch(token) { @@ -193,7 +193,7 @@ luaA_imagebox_newindex(lua_State *L, awesome_token_t token) return 0; } - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); return 0; } diff --git a/widgets/progressbar.c b/widgets/progressbar.c index 13cb8106..cb6cca88 100644 --- a/widgets/progressbar.c +++ b/widgets/progressbar.c @@ -434,10 +434,10 @@ static int luaA_progressbar_bar_properties_set(lua_State *L) { size_t len; - widget_t **widget = luaA_checkudata(L, 1, "widget"); + widget_t *widget = luaL_checkudata(L, 1, "widget"); const char *buf, *title = luaL_checkstring(L, 2); bar_t *bar; - progressbar_data_t *d = (*widget)->data; + progressbar_data_t *d = widget->data; xcolor_init_request_t reqs[6]; int i, reqs_nbr = -1; @@ -483,7 +483,7 @@ luaA_progressbar_bar_properties_set(lua_State *L) for(i = 0; i <= reqs_nbr; i++) xcolor_init_reply(reqs[i]); - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); return 0; } @@ -499,9 +499,9 @@ luaA_progressbar_bar_properties_set(lua_State *L) static int luaA_progressbar_bar_data_add(lua_State *L) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); + widget_t *widget = luaL_checkudata(L, 1, "widget"); const char *title = luaL_checkstring(L, 2); - progressbar_data_t *d = (*widget)->data; + progressbar_data_t *d = widget->data; bar_t *bar; bar = progressbar_bar_get(&d->bars, title); @@ -509,7 +509,7 @@ luaA_progressbar_bar_data_add(lua_State *L) bar->value = luaL_checknumber(L, 3); bar->value = MAX(bar->min_value, MIN(bar->max_value, bar->value)); - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); return 0; } @@ -533,8 +533,8 @@ luaA_progressbar_bar_data_add(lua_State *L) static int luaA_progressbar_index(lua_State *L, awesome_token_t token) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - progressbar_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + progressbar_data_t *d = widget->data; switch(token) { @@ -583,8 +583,8 @@ luaA_progressbar_index(lua_State *L, awesome_token_t token) static int luaA_progressbar_newindex(lua_State *L, awesome_token_t token) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - progressbar_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + progressbar_data_t *d = widget->data; switch(token) { @@ -616,7 +616,7 @@ luaA_progressbar_newindex(lua_State *L, awesome_token_t token) return 0; } - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); return 0; } diff --git a/widgets/textbox.c b/widgets/textbox.c index ca10e61e..1d246479 100644 --- a/widgets/textbox.c +++ b/widgets/textbox.c @@ -139,13 +139,13 @@ textbox_destructor(widget_t *w) static int luaA_textbox_margin(lua_State *L) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - textbox_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + textbox_data_t *d = widget->data; if(lua_gettop(L) == 2) { d->margin = luaA_getopt_padding(L, 3, &d->margin); - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); } return luaA_pushpadding(L, &d->margin); @@ -172,8 +172,8 @@ luaA_textbox_margin(lua_State *L) static int luaA_textbox_index(lua_State *L, awesome_token_t token) { - widget_t **widget = luaA_checkudata(L, 1, "widget"); - textbox_data_t *d = (*widget)->data; + widget_t *widget = luaL_checkudata(L, 1, "widget"); + textbox_data_t *d = widget->data; switch(token) { @@ -251,9 +251,9 @@ static int luaA_textbox_newindex(lua_State *L, awesome_token_t token) { size_t len = 0; - widget_t **widget = luaA_checkudata(L, 1, "widget"); + widget_t *widget = luaL_checkudata(L, 1, "widget"); const char *buf = NULL; - textbox_data_t *d = (*widget)->data; + textbox_data_t *d = widget->data; switch(token) { @@ -353,7 +353,7 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token) return 0; } - widget_invalidate_bywidget(*widget); + widget_invalidate_bywidget(widget); return 0; }