Tags: Remove screen property

A tag's screen is now implemented purely in lua and it is no longer C's
business.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2012-10-20 17:33:32 +02:00
parent 9c9b2b52b0
commit 8348d44444
18 changed files with 175 additions and 264 deletions

35
ewmh.c
View File

@ -239,7 +239,7 @@ ewmh_update_net_client_list_stacking(void)
void void
ewmh_update_net_numbers_of_desktop(void) ewmh_update_net_numbers_of_desktop(void)
{ {
uint32_t count = globalconf.screens.tab[0].tags.len; uint32_t count = globalconf.tags.len;
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
globalconf.screen->root, globalconf.screen->root,
@ -249,7 +249,7 @@ ewmh_update_net_numbers_of_desktop(void)
void void
ewmh_update_net_current_desktop(void) ewmh_update_net_current_desktop(void)
{ {
uint32_t idx = tags_get_first_selected_index(&globalconf.screens.tab[0]); uint32_t idx = tags_get_first_selected_index();
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
globalconf.screen->root, globalconf.screen->root,
@ -263,7 +263,7 @@ ewmh_update_net_desktop_names(void)
buffer_inita(&buf, BUFSIZ); buffer_inita(&buf, BUFSIZ);
foreach(tag, globalconf.screens.tab[0].tags) foreach(tag, globalconf.tags)
{ {
buffer_adds(&buf, tag_get_name(*tag)); buffer_adds(&buf, tag_get_name(*tag));
buffer_addc(&buf, '\0'); buffer_addc(&buf, '\0');
@ -380,7 +380,7 @@ ewmh_process_client_message(xcb_client_message_event_t *ev)
client_t *c; client_t *c;
if(ev->type == _NET_CURRENT_DESKTOP) if(ev->type == _NET_CURRENT_DESKTOP)
tag_view_only_byindex(&globalconf.screens.tab[0], ev->data.data32[0]); tag_view_only_byindex(ev->data.data32[0]);
else if(ev->type == _NET_CLOSE_WINDOW) else if(ev->type == _NET_CLOSE_WINDOW)
{ {
if((c = client_getbywin(ev->window))) if((c = client_getbywin(ev->window)))
@ -390,19 +390,17 @@ ewmh_process_client_message(xcb_client_message_event_t *ev)
{ {
if((c = client_getbywin(ev->window))) if((c = client_getbywin(ev->window)))
{ {
tag_array_t *tags = &c->screen->tags;
if(ev->data.data32[0] == 0xffffffff) if(ev->data.data32[0] == 0xffffffff)
c->sticky = true; c->sticky = true;
else else
for(int i = 0; i < tags->len; i++) for(int i = 0; i < globalconf.tags.len; i++)
if((int)ev->data.data32[0] == i) if((int)ev->data.data32[0] == i)
{ {
luaA_object_push(globalconf.L, tags->tab[i]); luaA_object_push(globalconf.L, globalconf.tags.tab[i]);
tag_client(c); tag_client(c);
} }
else else
untag_client(c, tags->tab[i]); untag_client(c, globalconf.tags.tab[i]);
} }
} }
else if(ev->type == _NET_WM_STATE) else if(ev->type == _NET_WM_STATE)
@ -433,10 +431,9 @@ void
ewmh_client_update_desktop(client_t *c) ewmh_client_update_desktop(client_t *c)
{ {
int i; int i;
tag_array_t *tags = &c->screen->tags;
for(i = 0; i < tags->len; i++) for(i = 0; i < globalconf.tags.len; i++)
if(is_client_tagged(c, tags->tab[i])) if(is_client_tagged(c, globalconf.tags.tab[i]))
{ {
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
c->window, _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &i); c->window, _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &i);
@ -509,25 +506,23 @@ ewmh_client_check_hints(client_t *c)
reply = xcb_get_property_reply(globalconf.connection, c0, NULL); reply = xcb_get_property_reply(globalconf.connection, c0, NULL);
if(reply && reply->value_len && (data = xcb_get_property_value(reply))) if(reply && reply->value_len && (data = xcb_get_property_value(reply)))
{ {
tag_array_t *tags = &c->screen->tags;
desktop = *(uint32_t *) data; desktop = *(uint32_t *) data;
if(desktop == -1) if(desktop == -1)
c->sticky = true; c->sticky = true;
else if (desktop >= 0 && desktop < tags->len) else if (desktop >= 0 && desktop < globalconf.tags.len)
for(int i = 0; i < tags->len; i++) for(int i = 0; i < globalconf.tags.len; i++)
if(desktop == i) if(desktop == i)
{ {
luaA_object_push(globalconf.L, tags->tab[i]); luaA_object_push(globalconf.L, globalconf.tags.tab[i]);
tag_client(c); tag_client(c);
} }
else else
untag_client(c, tags->tab[i]); untag_client(c, globalconf.tags.tab[i]);
else else
/* Value out of bounds, just give it the first tag */ /* Value out of bounds, just give it the first tag */
if (tags->len > 0) if (globalconf.tags.len > 0)
{ {
luaA_object_push(globalconf.L, tags->tab[0]); luaA_object_push(globalconf.L, globalconf.tags.tab[0]);
tag_client(c); tag_client(c);
} }
} }

View File

@ -137,6 +137,8 @@ typedef struct
xcb_colormap_t default_cmap; xcb_colormap_t default_cmap;
/** Do we have to reban clients? */ /** Do we have to reban clients? */
bool need_lazy_banning; bool need_lazy_banning;
/** Tag list */
tag_array_t tags;
} awesome_t; } awesome_t;
extern awesome_t globalconf; extern awesome_t globalconf;

View File

@ -24,17 +24,18 @@ local function check_focus(obj)
end end
-- Give focus on tag selection change. -- Give focus on tag selection change.
-- @param obj An object that should have a .screen property. -- @param tag A tag object
local function check_focus_screen(obj) local function check_focus_tag(t)
check_focus(obj) local s = atag.getscreen(t)
if client.focus and client.focus.screen ~= obj.screen then if not s then return end
local c = nil check_focus({ screen = s })
c = aclient.focus.history.get(obj.screen, 0) if client.focus and client.focus.screen ~= s then
local c = aclient.focus.history.get(s, 0)
if c then client.focus = c end if c then client.focus = c end
end end
end end
atag.attached_connect_signal(nil, "property::selected", check_focus_screen) atag.attached_connect_signal(nil, "property::selected", check_focus_tag)
client.connect_signal("unmanage", check_focus) client.connect_signal("unmanage", check_focus)
client.connect_signal("tagged", check_focus) client.connect_signal("tagged", check_focus)
client.connect_signal("untagged", check_focus) client.connect_signal("untagged", check_focus)

View File

@ -453,9 +453,10 @@ end
-- @param c Optional client to move, otherwise the focused one is used. -- @param c Optional client to move, otherwise the focused one is used.
function client.movetotag(target, c) function client.movetotag(target, c)
local sel = c or capi.client.focus local sel = c or capi.client.focus
if sel and target.screen then local s = tag.getscreen(target)
if sel and s then
-- Set client on the same screen as the tag. -- Set client on the same screen as the tag.
sel.screen = target.screen sel.screen = s
sel:tags({ target }) sel:tags({ target })
end end
end end

View File

@ -120,26 +120,24 @@ local function arrange_on_tagged(c, tag)
if c then capi.client.focus = c end if c then capi.client.focus = c end
end end
end end
local function arrange_tag(t)
layout.arrange(tag.getscreen(t))
end
for s = 1, capi.screen.count() do for s = 1, capi.screen.count() do
capi.screen[s]:add_signal("arrange") capi.screen[s]:add_signal("arrange")
tag.attached_connect_signal(s, "property::mwfact", arrange_prop) tag.attached_connect_signal(s, "property::mwfact", arrange_tag)
tag.attached_connect_signal(s, "property::nmaster", arrange_prop) tag.attached_connect_signal(s, "property::nmaster", arrange_tag)
tag.attached_connect_signal(s, "property::ncol", arrange_prop) tag.attached_connect_signal(s, "property::ncol", arrange_tag)
tag.attached_connect_signal(s, "property::layout", arrange_prop) tag.attached_connect_signal(s, "property::layout", arrange_tag)
tag.attached_connect_signal(s, "property::windowfact", arrange_prop) tag.attached_connect_signal(s, "property::windowfact", arrange_tag)
tag.attached_connect_signal(s, "property::selected", arrange_prop) tag.attached_connect_signal(s, "property::selected", arrange_tag)
tag.attached_connect_signal(s, "tagged", arrange_prop) tag.attached_connect_signal(s, "property::activated", arrange_tag)
tag.attached_connect_signal(s, "tagged", arrange_tag)
capi.screen[s]:connect_signal("property::workarea", function(screen) capi.screen[s]:connect_signal("property::workarea", function(screen)
layout.arrange(screen.index) layout.arrange(screen.index)
end) end)
capi.screen[s]:connect_signal("tag::attach", function (screen, tag)
layout.arrange(screen.index)
end)
capi.screen[s]:connect_signal("tag::detach", function (screen, tag)
layout.arrange(screen.index)
end)
capi.screen[s]:connect_signal("padding", function (screen) capi.screen[s]:connect_signal("padding", function (screen)
layout.arrange(screen.index) layout.arrange(screen.index)
end) end)

View File

@ -16,7 +16,8 @@ local capi =
tag = tag, tag = tag,
screen = screen, screen = screen,
mouse = mouse, mouse = mouse,
client = client client = client,
root = root
} }
--- Useful functions for tag manipulation. --- Useful functions for tag manipulation.
@ -60,8 +61,8 @@ end
-- @return The created tag -- @return The created tag
function tag.add(name, props) function tag.add(name, props)
local properties = props or {} local properties = props or {}
local newtag = capi.tag{name = name} local newtag = capi.tag{ name = name, activated = true }
newtag.screen = properties.screen or capi.mouse.screen properties.screen = properties.screen or capi.mouse.screen
for k, v in pairs(properties) do for k, v in pairs(properties) do
tag.setproperty(newtag, k, v) tag.setproperty(newtag, k, v)
@ -232,7 +233,27 @@ end
-- @param s Screen number -- @param s Screen number
-- @return A table with all available tags -- @return A table with all available tags
function tag.gettags(s) function tag.gettags(s)
return capi.screen[s]:tags() local tags = {}
for i, t in ipairs(root.tags()) do
if tag.getscreen(t) == s then
table.insert(tags, t)
end
end
return tags
end
--- Set a tag's screen
-- @param t tag object
-- @param s Screen number
function tag.setscreen(t, s)
tag.setproperty(t, "screen", s)
end
--- Get a tag's screen
-- @param t tag object
-- @return Screen number
function tag.getscreen(t)
return tag.getproperty(t, "screen")
end end
--- Return a table with all visible tags --- Return a table with all visible tags
@ -472,10 +493,17 @@ end
-- @param startup Optional: don't do anything if true. -- @param startup Optional: don't do anything if true.
function tag.withcurrent(c, startup) function tag.withcurrent(c, startup)
if startup ~= true then if startup ~= true then
if #c:tags() == 0 then local tags = {}
c:tags(tag.selectedlist(c.screen)) for k, t in ipairs(c:tags()) do
if tag.getscreen(t) == c.screen then
table.insert(tags, t)
end end
end end
if #tags == 0 then
tags = tag.selectedlist(c.screen)
end
c:tags(tags)
end
end end
local function attached_connect_signal_screen(screen, sig, func) local function attached_connect_signal_screen(screen, sig, func)
@ -524,6 +552,7 @@ capi.tag.add_signal("property::mwfact")
capi.tag.add_signal("property::ncol") capi.tag.add_signal("property::ncol")
capi.tag.add_signal("property::nmaster") capi.tag.add_signal("property::nmaster")
capi.tag.add_signal("property::windowfact") capi.tag.add_signal("property::windowfact")
capi.tag.add_signal("property::screen")
for s = 1, capi.screen.count() do for s = 1, capi.screen.count() do
capi.screen[s]:add_signal("tag::history::update") capi.screen[s]:add_signal("tag::history::update")

View File

@ -30,8 +30,8 @@ function layoutbox.new(screen)
local w = imagebox() local w = imagebox()
update(w, screen) update(w, screen)
local function update_on_tag_selection(tag) local function update_on_tag_selection(t)
return update(w, tag.screen) return update(w, tag.getscreen(t))
end end
tag.attached_connect_signal(screen, "property::selected", update_on_tag_selection) tag.attached_connect_signal(screen, "property::selected", update_on_tag_selection)

View File

@ -143,18 +143,15 @@ function taglist.new(screen, filter, buttons, style)
end end
end end
local uc = function (c) return u(c.screen) end local uc = function (c) return u(c.screen) end
local ut = function (t) return u(tag.getscreen(t)) end
capi.client.connect_signal("focus", uc) capi.client.connect_signal("focus", uc)
capi.client.connect_signal("unfocus", uc) capi.client.connect_signal("unfocus", uc)
tag.attached_connect_signal(screen, "property::selected", uc) tag.attached_connect_signal(screen, "property::selected", ut)
tag.attached_connect_signal(screen, "property::icon", uc) tag.attached_connect_signal(screen, "property::icon", ut)
tag.attached_connect_signal(screen, "property::hide", uc) tag.attached_connect_signal(screen, "property::hide", ut)
tag.attached_connect_signal(screen, "property::name", uc) tag.attached_connect_signal(screen, "property::name", ut)
capi.screen[screen]:connect_signal("tag::attach", function(screen, tag) tag.attached_connect_signal(screen, "property::activated", ut)
u(screen.index) tag.attached_connect_signal(screen, "property::screen", ut)
end)
capi.screen[screen]:connect_signal("tag::detach", function(screen, tag)
u(screen.index)
end)
capi.client.connect_signal("property::urgent", uc) capi.client.connect_signal("property::urgent", uc)
capi.client.connect_signal("property::screen", function(c) capi.client.connect_signal("property::screen", function(c)
-- If client change screen, refresh it anyway since we don't from -- If client change screen, refresh it anyway since we don't from

View File

@ -116,8 +116,8 @@ function tasklist.new(screen, filter, buttons, style)
local data = setmetatable({}, { __mode = 'k' }) local data = setmetatable({}, { __mode = 'k' })
local u = function () tasklist_update(screen, w, buttons, filter, data, style) end local u = function () tasklist_update(screen, w, buttons, filter, data, style) end
capi.screen[screen]:connect_signal("tag::detach", u)
tag.attached_connect_signal(screen, "property::selected", u) tag.attached_connect_signal(screen, "property::selected", u)
tag.attached_connect_signal(screen, "property::activated", u)
capi.client.connect_signal("property::urgent", u) capi.client.connect_signal("property::urgent", u)
capi.client.connect_signal("property::sticky", u) capi.client.connect_signal("property::sticky", u)
capi.client.connect_signal("property::ontop", u) capi.client.connect_signal("property::ontop", u)

View File

@ -44,3 +44,9 @@ module("root")
-- @return A cairo surface or nothing. -- @return A cairo surface or nothing.
-- @name wallpaper -- @name wallpaper
-- @class function -- @class function
--- Get the attached tags.
-- @param -
-- @return A table with all tags.
-- @name tags
-- @class function

View File

@ -34,9 +34,3 @@ module("screen")
-- @param ... Various arguments, optional. -- @param ... Various arguments, optional.
-- @name emit_signal -- @name emit_signal
-- @class function -- @class function
--- Get or set screen tags.
-- @param tags_table None or a table of tags to set to the screen.
-- The table must contains at least one tag.
-- @name tags
-- @class function

View File

@ -5,8 +5,8 @@ module("tag")
--- Tag object. --- Tag object.
-- @field name Tag name. -- @field name Tag name.
-- @field screen Screen number of the tag. -- @field selected True if the tag is selected to be viewed.
-- @field selected True if the client is selected to be viewed. -- @field activated True if the tag is active and can be used.
-- @class table -- @class table
-- @name tag -- @name tag

View File

@ -150,7 +150,7 @@ client_maybevisible(client_t *c)
if(c->sticky) if(c->sticky)
return true; return true;
foreach(tag, c->screen->tags) foreach(tag, globalconf.tags)
if(tag_get_selected(*tag) && is_client_tagged(c, *tag)) if(tag_get_selected(*tag) && is_client_tagged(c, *tag))
return true; return true;
@ -959,8 +959,6 @@ client_unban(client_t *c)
void void
client_unmanage(client_t *c, bool window_valid) client_unmanage(client_t *c, bool window_valid)
{ {
tag_array_t *tags = &c->screen->tags;
/* Reset transient_for attributes of widows that maybe referring to us */ /* Reset transient_for attributes of widows that maybe referring to us */
foreach(_tc, globalconf.clients) foreach(_tc, globalconf.clients)
{ {
@ -980,8 +978,8 @@ client_unmanage(client_t *c, bool window_valid)
break; break;
} }
stack_client_remove(c); stack_client_remove(c);
for(int i = 0; i < tags->len; i++) for(int i = 0; i < globalconf.tags.len; i++)
untag_client(c, tags->tab[i]); untag_client(c, globalconf.tags.tab[i]);
luaA_object_push(globalconf.L, c); luaA_object_push(globalconf.L, c);
luaA_object_emit_signal(globalconf.L, -1, "unmanage", 0); luaA_object_emit_signal(globalconf.L, -1, "unmanage", 0);
@ -1185,13 +1183,12 @@ static int
luaA_client_tags(lua_State *L) luaA_client_tags(lua_State *L)
{ {
client_t *c = luaA_checkudata(L, 1, &client_class); client_t *c = luaA_checkudata(L, 1, &client_class);
tag_array_t *tags = &c->screen->tags;
int j = 0; int j = 0;
if(lua_gettop(L) == 2) if(lua_gettop(L) == 2)
{ {
luaA_checktable(L, 2); luaA_checktable(L, 2);
for(int i = 0; i < tags->len; i++) for(int i = 0; i < globalconf.tags.len; i++)
{ {
/* Only untag if we aren't going to add this tag again */ /* Only untag if we aren't going to add this tag again */
bool found = false; bool found = false;
@ -1201,7 +1198,7 @@ luaA_client_tags(lua_State *L)
tag_t *t = lua_touserdata(L, -1); tag_t *t = lua_touserdata(L, -1);
/* Pop the value from lua_next */ /* Pop the value from lua_next */
lua_pop(L, 1); lua_pop(L, 1);
if (t != tags->tab[i]) if (t != globalconf.tags.tab[i])
continue; continue;
/* Pop the key from lua_next */ /* Pop the key from lua_next */
@ -1210,7 +1207,7 @@ luaA_client_tags(lua_State *L)
break; break;
} }
if(!found) if(!found)
untag_client(c, tags->tab[i]); untag_client(c, globalconf.tags.tab[i]);
} }
lua_pushnil(L); lua_pushnil(L);
while(lua_next(L, 2)) while(lua_next(L, 2))
@ -1219,7 +1216,7 @@ luaA_client_tags(lua_State *L)
} }
lua_newtable(L); lua_newtable(L);
foreach(tag, *tags) foreach(tag, globalconf.tags)
if(is_client_tagged(c, *tag)) if(is_client_tagged(c, *tag))
{ {
luaA_object_push(L, *tag); luaA_object_push(L, *tag);

View File

@ -19,7 +19,6 @@
* *
*/ */
#include "screen.h"
#include "tag.h" #include "tag.h"
#include "client.h" #include "client.h"
#include "ewmh.h" #include "ewmh.h"
@ -31,8 +30,8 @@ struct tag
LUA_OBJECT_HEADER LUA_OBJECT_HEADER
/** Tag name */ /** Tag name */
char *name; char *name;
/** Screen */ /** true if activated */
screen_t *screen; bool activated;
/** true if selected */ /** true if selected */
bool selected; bool selected;
/** clients in this tag */ /** clients in this tag */
@ -62,7 +61,7 @@ OBJECT_EXPORT_PROPERTY(tag, tag_t, name)
/** View or unview a tag. /** View or unview a tag.
* \param L The Lua VM state. * \param L The Lua VM state.
* \param udx The index of the tag on the stack. * \param udx The index of the tag on the stack.
* \param view Set visible or not. * \param view Set selected or not.
*/ */
static void static void
tag_view(lua_State *L, int udx, bool view) tag_view(lua_State *L, int udx, bool view)
@ -71,83 +70,13 @@ tag_view(lua_State *L, int udx, bool view)
if(tag->selected != view) if(tag->selected != view)
{ {
tag->selected = view; tag->selected = view;
if(tag->screen)
{
banning_need_update(); banning_need_update();
ewmh_update_net_current_desktop(); ewmh_update_net_current_desktop();
}
luaA_object_emit_signal(L, udx, "property::selected", 0); luaA_object_emit_signal(L, udx, "property::selected", 0);
} }
} }
/** 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;
}
tag->screen = s;
tag_array_append(&s->tags, luaA_object_ref_class(globalconf.L, udx, &tag_class));
ewmh_update_net_numbers_of_desktop();
ewmh_update_net_desktop_names();
luaA_object_push(globalconf.L, tag);
luaA_object_emit_signal(L, -1, "property::screen", 0);
lua_pop(L, 1);
luaA_object_push(globalconf.L, tag);
screen_emit_signal(globalconf.L, s, "tag::attach", 1);
}
/** 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;
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();
ewmh_update_net_numbers_of_desktop();
ewmh_update_net_desktop_names();
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);
}
static void static void
tag_client_emit_signal(lua_State *L, tag_t *t, client_t *c, const char *signame) tag_client_emit_signal(lua_State *L, tag_t *t, client_t *c, const char *signame)
{ {
@ -221,45 +150,32 @@ is_client_tagged(client_t *c, tag_t *t)
} }
/** Get the index of the first selected tag. /** Get the index of the first selected tag.
* \param screen Screen.
* \return Its index. * \return Its index.
*/ */
int int
tags_get_first_selected_index(screen_t *screen) tags_get_first_selected_index(void)
{ {
foreach(tag, screen->tags) foreach(tag, globalconf.tags)
if((*tag)->selected) if((*tag)->selected)
return tag_array_indexof(&screen->tags, tag); return tag_array_indexof(&globalconf.tags, tag);
return 0; return 0;
} }
/** Set a tag to be the only one viewed.
* \param target the tag to see
*/
static void
tag_view_only(tag_t *target)
{
if(target)
foreach(tag, target->screen->tags)
{
luaA_object_push(globalconf.L, *tag);
tag_view(globalconf.L, -1, *tag == target);
lua_pop(globalconf.L, 1);
}
}
/** View only a tag, selected by its index. /** View only a tag, selected by its index.
* \param screen Screen.
* \param dindex The index. * \param dindex The index.
*/ */
void void
tag_view_only_byindex(screen_t *screen, int dindex) tag_view_only_byindex(int dindex)
{ {
tag_array_t *tags = &screen->tags; if(dindex < 0 || dindex >= globalconf.tags.len)
if(dindex < 0 || dindex >= tags->len)
return; return;
tag_view_only(tags->tab[dindex]);
foreach(tag, globalconf.tags)
{
luaA_object_push(globalconf.L, *tag);
tag_view(globalconf.L, -1, *tag == globalconf.tags.tab[dindex]);
lua_pop(globalconf.L, 1);
}
} }
/** Create a new tag. /** Create a new tag.
@ -335,6 +251,7 @@ luaA_tag_clients(lua_State *L)
LUA_OBJECT_EXPORT_PROPERTY(tag, tag_t, name, lua_pushstring) LUA_OBJECT_EXPORT_PROPERTY(tag, tag_t, name, lua_pushstring)
LUA_OBJECT_EXPORT_PROPERTY(tag, tag_t, selected, lua_pushboolean) LUA_OBJECT_EXPORT_PROPERTY(tag, tag_t, selected, lua_pushboolean)
LUA_OBJECT_EXPORT_PROPERTY(tag, tag_t, activated, lua_pushboolean)
/** Set the tag name. /** Set the tag name.
* \param L The Lua VM state. * \param L The Lua VM state.
@ -349,6 +266,7 @@ luaA_tag_set_name(lua_State *L, tag_t *tag)
p_delete(&tag->name); p_delete(&tag->name);
a_iso2utf8(buf, len, &tag->name, NULL); a_iso2utf8(buf, len, &tag->name, NULL);
luaA_object_emit_signal(L, -3, "property::name", 0); luaA_object_emit_signal(L, -3, "property::name", 0);
ewmh_update_net_desktop_names();
return 0; return 0;
} }
@ -364,45 +282,49 @@ luaA_tag_set_selected(lua_State *L, tag_t *tag)
return 0; return 0;
} }
/** Set the tag screen. /** Set the tag activated status.
* \param L The Lua VM state. * \param L The Lua VM state.
* \param tag The tag to set the screen for. * \param tag The tag to set the activated status for.
* \return The number of elements pushed on stack. * \return The number of elements pushed on stack.
*/ */
static int static int
luaA_tag_set_screen(lua_State *L, tag_t *tag) luaA_tag_set_activated(lua_State *L, tag_t *tag)
{ {
int screen; bool activated = luaA_checkboolean(L, -1);
if(lua_isnil(L, -1)) if(activated == tag->activated)
screen = -1; return 0;
tag->activated = activated;
if(activated)
{
lua_pushvalue(L, -3);
tag_array_append(&globalconf.tags, luaA_object_ref_class(L, -1, &tag_class));
}
else else
{ {
screen = luaL_checknumber(L, -1) - 1; for (int i = 0; i < globalconf.tags.len; i++)
luaA_checkscreen(screen); if(globalconf.tags.tab[i] == tag)
{
tag_array_take(&globalconf.tags, i);
break;
} }
tag_remove_from_screen(tag); if (tag->selected)
{
tag->selected = false;
luaA_object_emit_signal(L, -3, "property::selected", 0);
banning_need_update();
}
luaA_object_unref(L, tag);
}
ewmh_update_net_numbers_of_desktop();
ewmh_update_net_desktop_names();
if(screen != -1) luaA_object_emit_signal(L, -3, "property::activated", 0);
tag_append_to_screen(L, -3, &globalconf.screens.tab[screen]);
return 0; return 0;
} }
/** Get the tag screen.
* \param L The Lua VM state.
* \param tag The tag to get the screen for.
* \return The number of elements pushed on stack.
*/
static int
luaA_tag_get_screen(lua_State *L, tag_t *tag)
{
if(!tag->screen)
return 0;
lua_pushnumber(L, screen_array_indexof(&globalconf.screens, tag->screen) + 1);
return 1;
}
void void
tag_class_setup(lua_State *L) tag_class_setup(lua_State *L)
{ {
@ -431,18 +353,18 @@ tag_class_setup(lua_State *L)
(lua_class_propfunc_t) luaA_tag_set_name, (lua_class_propfunc_t) luaA_tag_set_name,
(lua_class_propfunc_t) luaA_tag_get_name, (lua_class_propfunc_t) luaA_tag_get_name,
(lua_class_propfunc_t) luaA_tag_set_name); (lua_class_propfunc_t) luaA_tag_set_name);
luaA_class_add_property(&tag_class, "screen",
(lua_class_propfunc_t) NULL,
(lua_class_propfunc_t) luaA_tag_get_screen,
(lua_class_propfunc_t) luaA_tag_set_screen);
luaA_class_add_property(&tag_class, "selected", luaA_class_add_property(&tag_class, "selected",
(lua_class_propfunc_t) luaA_tag_set_selected, (lua_class_propfunc_t) luaA_tag_set_selected,
(lua_class_propfunc_t) luaA_tag_get_selected, (lua_class_propfunc_t) luaA_tag_get_selected,
(lua_class_propfunc_t) luaA_tag_set_selected); (lua_class_propfunc_t) luaA_tag_set_selected);
luaA_class_add_property(&tag_class, "activated",
(lua_class_propfunc_t) luaA_tag_set_activated,
(lua_class_propfunc_t) luaA_tag_get_activated,
(lua_class_propfunc_t) luaA_tag_set_activated);
signal_add(&tag_class.signals, "property::name"); signal_add(&tag_class.signals, "property::name");
signal_add(&tag_class.signals, "property::screen");
signal_add(&tag_class.signals, "property::selected"); signal_add(&tag_class.signals, "property::selected");
signal_add(&tag_class.signals, "property::activated");
signal_add(&tag_class.signals, "tagged"); signal_add(&tag_class.signals, "tagged");
signal_add(&tag_class.signals, "untagged"); signal_add(&tag_class.signals, "untagged");
} }

View File

@ -24,13 +24,11 @@
#include "client.h" #include "client.h"
int tags_get_first_selected_index(screen_t *); int tags_get_first_selected_index(void);
void tag_client(client_t *); void tag_client(client_t *);
void untag_client(client_t *, tag_t *); void untag_client(client_t *, tag_t *);
bool is_client_tagged(client_t *, tag_t *); bool is_client_tagged(client_t *, tag_t *);
void tag_view_only_byindex(screen_t *, int); void tag_view_only_byindex(int);
void tag_append_to_screen(lua_State *, int, screen_t *);
void tag_remove_from_screen(tag_t *);
void tag_unref_simplified(tag_t **); void tag_unref_simplified(tag_t **);
ARRAY_FUNCS(tag_t *, tag, tag_unref_simplified) ARRAY_FUNCS(tag_t *, tag, tag_unref_simplified)

20
root.c
View File

@ -383,6 +383,25 @@ luaA_root_wallpaper(lua_State *L)
return 1; return 1;
} }
/** Get the screen's wallpaper
* \param L The Lua VM state.
* \return The number of element pushed on stack.
* \luastack
* \lreturn A cairo surface for the wallpaper.
*/
static int
luaA_root_tags(lua_State *L)
{
lua_createtable(L, globalconf.tags.len, 0);
for(int i = 0; i < globalconf.tags.len; i++)
{
luaA_object_push(L, globalconf.tags.tab[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
const struct luaL_Reg awesome_root_lib[] = const struct luaL_Reg awesome_root_lib[] =
{ {
{ "buttons", luaA_root_buttons }, { "buttons", luaA_root_buttons },
@ -391,6 +410,7 @@ const struct luaL_Reg awesome_root_lib[] =
{ "fake_input", luaA_root_fake_input }, { "fake_input", luaA_root_fake_input },
{ "drawins", luaA_root_drawins }, { "drawins", luaA_root_drawins },
{ "wallpaper", luaA_root_wallpaper }, { "wallpaper", luaA_root_wallpaper },
{ "tags", luaA_root_tags },
{ NULL, NULL } { NULL, NULL }
}; };

View File

@ -60,8 +60,6 @@ static void
screen_add(screen_t new_screen) screen_add(screen_t new_screen)
{ {
signal_add(&new_screen.signals, "property::workarea"); signal_add(&new_screen.signals, "property::workarea");
signal_add(&new_screen.signals, "tag::attach");
signal_add(&new_screen.signals, "tag::detach");
screen_array_append(&globalconf.screens, new_screen); screen_array_append(&globalconf.screens, new_screen);
} }
@ -352,11 +350,6 @@ screen_client_moveto(client_t *c, screen_t *new_screen, bool doresize)
c->screen = new_screen; c->screen = new_screen;
/* If client was on a screen, remove old tags */
if(old_screen)
foreach(old_tag, old_screen->tags)
untag_client(c, *old_tag);
if(!doresize) if(!doresize)
{ {
luaA_object_push(globalconf.L, c); luaA_object_push(globalconf.L, c);
@ -433,45 +426,6 @@ luaA_screen_module_index(lua_State *L)
return luaA_pushscreen(L, &globalconf.screens.tab[screen]); return luaA_pushscreen(L, &globalconf.screens.tab[screen]);
} }
/** Get screen tags.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam None or a table of tags to set to the screen.
* The table must contains at least one tag.
* \return A table with all screen tags.
*/
static int
luaA_screen_tags(lua_State *L)
{
screen_t **ps = luaL_checkudata(L, 1, "screen");
screen_t *s = *ps;
if(lua_gettop(L) == 2)
{
luaA_checktable(L, 2);
/* Detach all tags, but go backward since the array len will change */
for(int i = s->tags.len - 1; i >= 0; i--)
tag_remove_from_screen(s->tags.tab[i]);
lua_pushnil(L);
while(lua_next(L, 2))
tag_append_to_screen(L, -1, s);
}
else
{
lua_createtable(L, s->tags.len, 0);
for(int i = 0; i < s->tags.len; i++)
{
luaA_object_push(L, s->tags.tab[i]);
lua_rawseti(L, -2, i + 1);
}
}
return 1;
}
/** A screen. /** A screen.
* \param L The Lua VM state. * \param L The Lua VM state.
* \return The number of elements pushed on stack. * \return The number of elements pushed on stack.
@ -675,7 +629,6 @@ const struct luaL_Reg awesome_screen_meta[] =
{ "connect_signal", luaA_screen_connect_signal }, { "connect_signal", luaA_screen_connect_signal },
{ "disconnect_signal", luaA_screen_disconnect_signal }, { "disconnect_signal", luaA_screen_disconnect_signal },
{ "emit_signal", luaA_screen_emit_signal }, { "emit_signal", luaA_screen_emit_signal },
{ "tags", luaA_screen_tags },
{ "__index", luaA_screen_index }, { "__index", luaA_screen_index },
{ "__eq", luaA_screen_equal }, { "__eq", luaA_screen_equal },
{ NULL, NULL } { NULL, NULL }

View File

@ -32,8 +32,6 @@ struct a_screen
{ {
/** Screen geometry */ /** Screen geometry */
area_t geometry; area_t geometry;
/** Tag list */
tag_array_t tags;
/** The signals emitted by screen objects */ /** The signals emitted by screen objects */
signal_array_t signals; signal_array_t signals;
/** The screen outputs informations */ /** The screen outputs informations */