/** View or unview a tag. * \param L The Lua VM state. * \param udx The index of the tag on the stack. * \param view Set visible or not. */ static void tag_view(lua_State *L, int udx, bool view) { tag_t *tag = luaA_checkudata(L, udx, &tag_class); if(tag->selected != view) { tag->selected = view; if(tag->screen) { int screen_index = screen_array_indexof(&globalconf.screens, tag->screen); banning_need_update(tag->screen); ewmh_update_net_current_desktop(screen_virttophys(screen_index)); if(globalconf.hooks.tags != LUA_REFNIL) { lua_pushnumber(globalconf.L, screen_index + 1); luaA_object_push(globalconf.L, tag); if(view) lua_pushliteral(globalconf.L, "select"); else lua_pushliteral(globalconf.L, "unselect"); luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.tags, 3, 0); } } luaA_object_emit_signal(L, udx, "property::selected", 0); } }
/** Mouse library. * \param L The Lua VM state. * \return The number of elements pushed on stack. * \luastack * \lfield coords Mouse coordinates. * \lfield screen Mouse screen number. */ static int luaA_mouse_index(lua_State *L) { const char *attr = luaL_checkstring(L, 2); int16_t mouse_x, mouse_y; screen_t *screen; /* attr is not "screen"?! */ if (A_STRNEQ(attr, "screen")) return 0; if (!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, NULL)) return 0; screen = screen_getbycoord(mouse_x, mouse_y); lua_pushnumber(L, screen_array_indexof(&globalconf.screens, screen) + 1); return 1; }
static int property_handle_xrootpmap_id(uint8_t state, xcb_window_t window, xcb_atom_t name, xcb_get_property_reply_t *reply) { if(globalconf.xinerama_is_active) foreach(w, globalconf.wiboxes) (*w)->need_update = true; else { int screen = xutil_root2screen(globalconf.connection, window); foreach(w, globalconf.wiboxes) if(screen == screen_array_indexof(&globalconf.screens, (*w)->screen)) (*w)->need_update = true; } return 0; }
/** Remove a tag from screen. Tag must be on a screen and have no clients. * \param tag The tag to remove. */ void tag_remove_from_screen(tag_t *tag) { if(!tag->screen) return; int screen_index = screen_array_indexof(&globalconf.screens, tag->screen); int phys_screen = screen_virttophys(screen_index); tag_array_t *tags = &tag->screen->tags; for(int i = 0; i < tags->len; i++) if(tags->tab[i] == tag) { tag_array_take(tags, i); break; } /* tag was selected? If so, reban */ if(tag->selected) banning_need_update(tag->screen); ewmh_update_net_numbers_of_desktop(phys_screen); ewmh_update_net_desktop_names(phys_screen); /* call hook */ if(globalconf.hooks.tags != LUA_REFNIL) { lua_pushnumber(globalconf.L, screen_index + 1); luaA_object_push(globalconf.L, tag); lua_pushliteral(globalconf.L, "remove"); luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.tags, 3, 0); } screen_t *s = tag->screen; tag->screen = NULL; luaA_object_push(globalconf.L, tag); luaA_object_emit_signal(globalconf.L, -1, "property::screen", 0); screen_emit_signal(globalconf.L, s, "tag::detach", 1); luaA_object_unref(globalconf.L, tag); }
/** Append a tag to a screen. * \param L The Lua VM state. * \param udx The tag index on the stack. * \param s The screen. */ void tag_append_to_screen(lua_State *L, int udx, screen_t *s) { tag_t *tag = luaA_checkudata(globalconf.L, udx, &tag_class); /* can't attach a tag twice */ if(tag->screen) { lua_remove(L, udx); return; } int screen_index = screen_array_indexof(&globalconf.screens, s); int phys_screen = screen_virttophys(screen_index); tag->screen = s; tag_array_append(&s->tags, luaA_object_ref_class(globalconf.L, udx, &tag_class)); ewmh_update_net_numbers_of_desktop(phys_screen); ewmh_update_net_desktop_names(phys_screen); luaA_object_push(globalconf.L, tag); luaA_object_emit_signal(L, -1, "property::screen", 0); lua_pop(L, 1); /* call hook */ if(globalconf.hooks.tags != LUA_REFNIL) { lua_pushnumber(globalconf.L, screen_index + 1); luaA_object_push(globalconf.L, tag); lua_pushliteral(globalconf.L, "add"); luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.tags, 3, 0); } luaA_object_push(globalconf.L, tag); screen_emit_signal(globalconf.L, s, "tag::attach", 1); }
/** 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; }