/** Retrieve a list of widget geometries using a Lua layout function. * a table which contains the geometries is then pushed onto the stack * \param wibox The wibox. * \return True is everything is ok, false otherwise. */ static bool widget_geometries(wibox_t *wibox) { /* get the layout field of the widget table */ if(wibox->widgets_table) { /* push wibox */ luaA_object_push(globalconf.L, wibox); /* push widgets table */ luaA_object_push_item(globalconf.L, -1, wibox->widgets_table); /* remove wibox */ lua_remove(globalconf.L, -2); /* get layout field from the table */ lua_getfield(globalconf.L, -1, "layout"); /* remove the widget table */ lua_remove(globalconf.L, -2); } else lua_pushnil(globalconf.L); /* if the layout field is a function */ if(lua_isfunction(globalconf.L, -1)) { /* Push 1st argument: wibox geometry */ area_t geometry = wibox->geometry; geometry.x = 0; geometry.y = 0; /* we need to exchange the width and height of the wibox window if it * it is rotated, so the layout function doesn't need to care about that */ if(wibox->orientation != East) { int i = geometry.height; geometry.height = geometry.width; geometry.width = i; } luaA_pusharea(globalconf.L, geometry); /* Push 2nd argument: widget table */ luaA_object_push(globalconf.L, wibox); luaA_object_push_item(globalconf.L, -1, wibox->widgets_table); lua_remove(globalconf.L, -2); /* Push 3rd argument: wibox screen */ lua_pushnumber(globalconf.L, screen_array_indexof(&globalconf.screens, wibox->screen)); /* Re-push the layout function */ lua_pushvalue(globalconf.L, -4); /* call the layout function with 3 arguments (wibox geometry, widget * table, screen) and wait for one result */ if(!luaA_dofunction(globalconf.L, 3, 1)) return false; /* Remove the left over layout function */ lua_remove(globalconf.L, -2); } else { /* Remove the "nil function" */ lua_pop(globalconf.L, 1); /* If no layout function has been specified, we just push a table with * geometries onto the stack. These geometries are nothing fancy, they * have x = y = 0 and their height and width set to the widgets demands * 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 */ luaA_object_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_newtable(globalconf.L); for(int i = 0; i < widgets->len; i++) { lua_pushnumber(globalconf.L, i + 1); widget_t *widget = widgets->tab[i].widget; lua_pushnumber(globalconf.L, screen_array_indexof(&globalconf.screens, wibox->screen)); area_t geometry = widget->extents(globalconf.L, widget); lua_pop(globalconf.L, 1); geometry.x = geometry.y = 0; geometry.width = MIN(wibox->geometry.width, geometry.width); geometry.height = MIN(wibox->geometry.height, geometry.height); luaA_pusharea(globalconf.L, geometry); lua_settable(globalconf.L, -3); } } return true; }
/** Get drawable geometry. The geometry consists of x, y, width and height. * * @return A table with drawable coordinates and geometry. * @function geometry */ static int luaA_drawable_geometry(lua_State *L) { drawable_t *d = luaA_checkudata(L, 1, &drawable_class); return luaA_pusharea(L, d->geometry); }