Replace tag_t lists with arrays.

This improves lots of code efficiency (we *know* how many tags we have
now, YA'RLY).

Also fix a \todo in client.c: since knowing the number of tags is cheap,
ignore props that don't match it.

Use many p_alloca for things that depends on the number of tags (no sane
user will have *thousands* of tags. This saves a few more mallocs.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
This commit is contained in:
Pierre Habouzit 2008-06-23 17:37:19 +02:00
parent 236ccc165c
commit 14f4e02e66
8 changed files with 145 additions and 179 deletions

View File

@ -61,7 +61,6 @@ DO_LUA_EQ(client_t, client, "client")
/** Load windows properties, restoring client's tag
* and floating state before awesome was restarted if any.
* \todo This may bug if number of tags is != than before.
* \param c A client pointer.
* \param screen A virtual screen.
* \return True if client had property, false otherwise.
@ -69,38 +68,32 @@ DO_LUA_EQ(client_t, client, "client")
static bool
client_loadprops(client_t * c, screen_t *screen)
{
int i, ntags = 0;
tag_t *tag;
tag_array_t *tags = &screen->tags;
char *prop = NULL;
bool result = false;
for(tag = screen->tags; tag; tag = tag->next)
ntags++;
if(xutil_gettextprop(globalconf.connection, c->win, &globalconf.atoms,
if(!xutil_gettextprop(globalconf.connection, c->win, &globalconf.atoms,
xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
xutil_intern_atom(globalconf.connection,
&globalconf.atoms,
"_AWESOME_PROPERTIES")),
&prop))
{
for(i = 0, tag = screen->tags; tag && i < ntags && prop[i]; i++, tag = tag->next)
if(prop[i] == '1')
{
tag_client(c, tag);
result = true;
}
else
untag_client(c, tag);
if(prop[i])
client_setfloating(c, prop[i] == '1',
(prop[i + 1] >= 0 && prop[i + 1] <= LAYER_FULLSCREEN) ? atoi(&prop[i + 1]) : prop[i] == '1' ? LAYER_FLOAT : LAYER_TILE);
}
return false;
if (strlen(prop) != tags->len + 2) {
/* ignore property if the tag count isn't matching */
p_delete(&prop);
return false;
}
return result;
for(int i = 0; i < tags->len; i++)
if(prop[i] == '1')
tag_client(c, tags->tab[i]);
else
untag_client(c, tags->tab[i]);
client_setfloating(c, prop[tags->len] == '1', prop[tags->len + 1] - '0');
p_delete(&prop);
return true;
}
/** Check if client supports protocol WM_DELETE_WINDOW.
@ -139,12 +132,13 @@ window_isprotodel(xcb_window_t win)
bool
client_isvisible(client_t *c, int screen)
{
tag_t *tag;
if(c && !c->ishidden && c->screen == screen)
for(tag = globalconf.screens[screen].tags; tag; tag = tag->next)
if(tag->selected && is_client_tagged(c, tag))
{
tag_array_t *tags = &globalconf.screens[screen].tags;
for(int i = 0; i < tags->len; i++)
if(tags->tab[i]->selected && is_client_tagged(c, tags->tab[i]))
return true;
}
return false;
}
@ -345,7 +339,6 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen)
client_t *c, *t = NULL;
xcb_window_t trans;
bool rettrans, retloadprops;
tag_t *tag;
xcb_size_hints_t *u_size_hints;
const uint32_t select_input_val[] = {
XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE |
@ -383,9 +376,12 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen)
/* check for transient and set tags like its parent */
if((rettrans = xutil_get_transient_for_hint(globalconf.connection, w, &trans))
&& (t = client_getbywin(trans)))
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
if(is_client_tagged(t, tag))
tag_client(c, tag);
{
tag_array_t *tags = &globalconf.screens[c->screen].tags;
for(int i = 0; i < tags->len; i++)
if(is_client_tagged(t, tags->tab[i]))
tag_client(c, tags->tab[i]);
}
/* should be floating if transsient or fixed */
if(rettrans || c->isfixed)
@ -600,32 +596,22 @@ client_setfloating(client_t *c, bool floating, layer_t layer)
void
client_saveprops(client_t *c)
{
int i = 0, ntags = 0;
char *prop;
tag_t *tag;
tag_array_t *tags = &globalconf.screens[c->screen].tags;
unsigned char *prop = p_alloca(unsigned char, tags->len + 3);
xutil_intern_atom_request_t atom_q;
int i;
atom_q = xutil_intern_atom(globalconf.connection, &globalconf.atoms, "_AWESOME_PROPERTIES");
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
ntags++;
for(i = 0; i < tags->len; i++)
prop[i] = is_client_tagged(c, tags->tab[i]) ? '1' : '0';
prop = p_new(char, ntags + 3);
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next, i++)
prop[i] = is_client_tagged(c, tag) ? '1' : '0';
prop[i] = c->isfloating ? '1' : '0';
sprintf(&prop[++i], "%d", c->layer);
prop[++i] = '\0';
prop[i++] = c->isfloating ? '1' : '0';
prop[i++] = '0' + c->layer;
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, c->win,
xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms, atom_q),
STRING, 8, i, (unsigned char *) prop);
p_delete(&prop);
STRING, 8, i, prop);
}
/** Unban a client.
@ -646,7 +632,7 @@ client_unban(client_t *c)
void
client_unmanage(client_t *c)
{
tag_t *tag;
tag_array_t *tags = &globalconf.screens[c->screen].tags;
/* call hook */
luaA_client_userdata_new(globalconf.L, c);
@ -663,8 +649,8 @@ client_unmanage(client_t *c)
client_list_detach(&globalconf.clients, c);
focus_client_delete(c);
stack_client_delete(c);
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
untag_client(c, tag);
for(int i = 0; i < tags->len; i++)
untag_client(c, tags->tab[i]);
if(globalconf.focus->client == c)
client_focus(NULL, c->screen);

103
ewmh.c
View File

@ -273,11 +273,7 @@ ewmh_update_net_client_list_stacking(int phys_screen)
void
ewmh_update_net_numbers_of_desktop(int phys_screen)
{
uint32_t count = 0;
tag_t *tag;
for(tag = globalconf.screens[phys_screen].tags; tag; tag = tag->next)
count++;
uint32_t count = globalconf.screens[phys_screen].tags.len;
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
xutil_screen_get(globalconf.connection, phys_screen)->root,
@ -287,11 +283,11 @@ ewmh_update_net_numbers_of_desktop(int phys_screen)
void
ewmh_update_net_current_desktop(int phys_screen)
{
tag_array_t *tags = &globalconf.screens[phys_screen].tags;
uint32_t count = 0;
tag_t *tag, **curtags = tags_get_current(phys_screen);
tag_t **curtags = tags_get_current(phys_screen);
for(tag = globalconf.screens[phys_screen].tags; tag != curtags[0]; tag = tag->next)
count++;
for(count = 0; tags->tab[count] != curtags[0]; count++);
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
xutil_screen_get(globalconf.connection, phys_screen)->root,
@ -303,23 +299,21 @@ ewmh_update_net_current_desktop(int phys_screen)
void
ewmh_update_net_desktop_names(int phys_screen)
{
char buf[1024], *pos;
ssize_t len, curr_size;
tag_t *tag;
tag_array_t *tags = &globalconf.screens[phys_screen].tags;
buffer_t buf;
pos = buf;
len = 0;
for(tag = globalconf.screens[phys_screen].tags; tag; tag = tag->next)
buffer_inita(&buf, BUFSIZ);
for(int i = 0; i < tags->len; i++)
{
curr_size = a_strlen(tag->name);
a_strcpy(pos, sizeof(buf), tag->name);
pos += curr_size + 1;
len += curr_size + 1;
buffer_adds(&buf, tags->tab[i]->name);
buffer_addc(&buf, '\0');
}
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
xutil_screen_get(globalconf.connection, phys_screen)->root,
net_desktop_names, utf8_string, 8, len, buf);
net_desktop_names, utf8_string, 8, buf.len, buf.s);
buffer_wipe(&buf);
}
/** Update the work area space for each physical screen and each desktop.
@ -328,29 +322,24 @@ ewmh_update_net_desktop_names(int phys_screen)
void
ewmh_update_workarea(int phys_screen)
{
uint32_t *area;
tag_t *tag;
int count = 0;
tag_array_t *tags = &globalconf.screens[phys_screen].tags;
uint32_t *area = p_alloca(uint32_t, tags->len * 4);
area_t geom = screen_area_get(phys_screen,
globalconf.screens[phys_screen].statusbar,
&globalconf.screens[phys_screen].padding);
for(tag = globalconf.screens[phys_screen].tags; tag; tag = tag->next)
count++;
area = p_new(uint32_t, count * 4);
for(tag = globalconf.screens[phys_screen].tags, count = 0; tag; tag = tag->next, count++)
for(int i = 0; i < tags->len; i++)
{
area[4 * count + 0] = geom.x;
area[4 * count + 1] = geom.y;
area[4 * count + 2] = geom.width;
area[4 * count + 3] = geom.height;
area[4 * i + 0] = geom.x;
area[4 * i + 1] = geom.y;
area[4 * i + 2] = geom.width;
area[4 * i + 3] = geom.height;
}
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE,
xutil_screen_get(globalconf.connection, phys_screen)->root,
net_workarea, CARDINAL, 32, count * 4, area);
p_delete(&area);
net_workarea, CARDINAL, 32, tags->len * 4, area);
}
void
@ -369,13 +358,13 @@ ewmh_update_net_active_window(int phys_screen)
static void
ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set)
{
const uint32_t raise_window_val = XCB_STACK_MODE_ABOVE;
static uint32_t const raise_window_val = XCB_STACK_MODE_ABOVE;
if(state == net_wm_state_sticky)
{
tag_t *tag;
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
tag_client(c, tag);
tag_array_t *tags = &globalconf.screens[c->screen].tags;
for(int i = 0; i < tags->len; i++)
tag_client(c, tags->tab[i]);
}
else if(state == net_wm_state_skip_taskbar)
{
@ -483,8 +472,6 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set)
static void
ewmh_process_window_type_atom(client_t *c, xcb_atom_t state)
{
tag_t *tag;
if(state == net_wm_window_type_normal)
{
/* do nothing. this is REALLY IMPORTANT */
@ -507,12 +494,13 @@ ewmh_process_window_type_atom(client_t *c, xcb_atom_t state)
client_setfloating(c, true, LAYER_MODAL);
else if(state == net_wm_window_type_desktop)
{
tag_array_t *tags = &globalconf.screens[c->screen].tags;
c->noborder = true;
c->isfixed = true;
c->skip = true;
c->layer = LAYER_DESKTOP;
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
tag_client(c, tag);
for(int i = 0; i < tags->len; i++)
tag_client(c, tags->tab[i]);
}
}
@ -520,9 +508,7 @@ int
ewmh_process_client_message(xcb_client_message_event_t *ev)
{
client_t *c;
tag_t *tag;
int screen;
unsigned int i;
if(ev->type == net_current_desktop)
for(screen = 0;
@ -541,15 +527,17 @@ ewmh_process_client_message(xcb_client_message_event_t *ev)
{
if((c = client_getbywin(ev->window)))
{
tag_array_t *tags = &globalconf.screens[c->screen].tags;
if(ev->data.data32[0] == 0xffffffff)
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
tag_client(c, tag);
for(int i = 0; i < tags->len; i++)
tag_client(c, tags->tab[i]);
else
for(i = 0, tag = globalconf.screens[c->screen].tags; tag; tag = tag->next, i++)
if(ev->data.data32[0] == i)
tag_client(c, tag);
for(int i = 0; i < tags->len; i++)
if((int)ev->data.data32[0] == i)
tag_client(c, tags->tab[i]);
else
untag_client(c, tag);
untag_client(c, tags->tab[i]);
}
}
else if(ev->type == net_wm_state)
@ -571,10 +559,9 @@ ewmh_check_client_hints(client_t *c)
{
xcb_atom_t *state;
void *data = NULL;
int i, desktop;
int desktop;
xcb_get_property_cookie_t c0, c1, c2;
xcb_get_property_reply_t *reply;
tag_t *tag;
/* Send the GetProperty requests which will be processed later */
c0 = xcb_get_property_unchecked(globalconf.connection, false, c->win,
@ -589,16 +576,18 @@ ewmh_check_client_hints(client_t *c)
reply = xcb_get_property_reply(globalconf.connection, c0, NULL);
if(reply && reply->value_len && (data = xcb_get_property_value(reply)))
{
tag_array_t *tags = &globalconf.screens[c->screen].tags;
desktop = *(uint32_t *) data;
if(desktop == -1)
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
tag_client(c, tag);
for(int i = 0; i < tags->len; i++)
tag_client(c, tags->tab[i]);
else
for(i = 0, tag = globalconf.screens[c->screen].tags; tag; tag = tag->next, i++)
for(int i = 0; i < tags->len; i++)
if(desktop == i)
tag_client(c, tag);
tag_client(c, tags->tab[i]);
else
untag_client(c, tag);
untag_client(c, tags->tab[i]);
}
p_delete(&reply);
@ -607,7 +596,7 @@ ewmh_check_client_hints(client_t *c)
if(reply && (data = xcb_get_property_value(reply)))
{
state = (xcb_atom_t *) data;
for(i = 0; i < xcb_get_property_value_length(reply); i++)
for(int i = 0; i < xcb_get_property_value_length(reply); i++)
ewmh_process_state_atom(c, state[i], _NET_WM_STATE_ADD);
}
@ -617,7 +606,7 @@ ewmh_check_client_hints(client_t *c)
if(reply && (data = xcb_get_property_value(reply)))
{
state = (xcb_atom_t *) data;
for(i = 0; i < xcb_get_property_value_length(reply); i++)
for(int i = 0; i < xcb_get_property_value_length(reply); i++)
ewmh_process_window_type_atom(c, state[i]);
}

2
lua.c
View File

@ -547,7 +547,7 @@ luaA_parserc(const char* rcfile)
/* Assure there's at least one tag */
for(screen = 0; screen < globalconf.screens_info->nscreen; screen++)
if(!globalconf.screens[screen].tags)
if(!globalconf.screens[screen].tags.len)
tag_append_to_screen(tag_new("default", layout_tile, 0.5, 1, 0), screen);
return true;

View File

@ -128,12 +128,12 @@ screen_virttophys(int screen)
void
screen_client_moveto(client_t *c, int new_screen, bool doresize)
{
tag_t *tag;
int old_screen = c->screen;
tag_array_t *tags = &globalconf.screens[old_screen].tags;
area_t from, to;
for(tag = globalconf.screens[old_screen].tags; tag; tag = tag->next)
untag_client(c, tag);
for(int i = 0; i < tags->len; i++)
untag_client(c, tags->tab[i]);
c->screen = new_screen;

View File

@ -346,9 +346,8 @@ struct _tag_t
int nmaster;
/** Number of columns in tile layout */
int ncol;
/** Next and previous tags */
tag_t *prev, *next;
};
ARRAY_TYPE(tag_t *, tag);
/** Tag client link type */
struct tag_client_node_t
@ -377,7 +376,7 @@ typedef struct
/** true if we need to arrange() */
bool need_arrange;
/** Tag list */
tag_t *tags;
tag_array_t tags;
/** Status bar */
statusbar_t *statusbar;
/** Padding */

85
tag.c
View File

@ -95,8 +95,7 @@ tag_append_to_screen(tag_t *tag, int screen)
int phys_screen = screen_virttophys(screen);
tag->screen = screen;
tag_list_append(&globalconf.screens[screen].tags, tag);
tag_ref(&tag);
tag_array_append(&globalconf.screens[screen].tags, tag_ref(&tag));
ewmh_update_net_numbers_of_desktop(phys_screen);
ewmh_update_net_desktop_names(phys_screen);
ewmh_update_workarea(phys_screen);
@ -173,14 +172,13 @@ is_client_tagged(client_t *c, tag_t *t)
void
tag_client_with_current_selected(client_t *c)
{
tag_t *tag;
screen_t vscreen = globalconf.screens[c->screen];
tag_array_t *tags = &globalconf.screens[c->screen].tags;
for(tag = vscreen.tags; tag; tag = tag->next)
if(tag->selected)
tag_client(c, tag);
for(int i = 0; i < tags->len; i++)
if(tags->tab[i]->selected)
tag_client(c, tags->tab[i]);
else
untag_client(c, tag);
untag_client(c, tags->tab[i]);
}
/** Get the current tags for the specified screen.
@ -191,21 +189,15 @@ tag_client_with_current_selected(client_t *c)
tag_t **
tags_get_current(int screen)
{
tag_t *tag, **tags = NULL;
int n = 1;
tag_array_t *tags = &globalconf.screens[screen].tags;
tag_t **out = p_new(tag_t *, tags->len + 1);
int n = 0;
tags = p_new(tag_t *, n);
for(tag = globalconf.screens[screen].tags; tag; tag = tag->next)
if(tag->selected)
{
p_realloc(&tags, ++n);
tags[n - 2] = tag;
}
for(int i = 0; i < tags->len; i++)
if(tags->tab[i]->selected)
out[n++] = tags->tab[i];
/* finish with null */
tags[n - 1] = NULL;
return tags;
return out;
}
@ -215,12 +207,12 @@ tags_get_current(int screen)
static void
tag_view_only(tag_t *target)
{
tag_t *tag;
if (target) {
tag_array_t *tags = &globalconf.screens[target->screen].tags;
if(!target) return;
for(tag = globalconf.screens[target->screen].tags; tag; tag = tag->next)
tag_view(tag, tag == target);
for(int i = 0; i < tags->len; i++)
tag_view(tags->tab[i], tags->tab[i] == target);
}
}
/** View only a tag, selected by its index.
@ -230,14 +222,11 @@ tag_view_only(tag_t *target)
void
tag_view_only_byindex(int screen, int dindex)
{
tag_t *tag;
tag_array_t *tags = &globalconf.screens[screen].tags;
if(dindex < 0)
if(dindex < 0 || dindex >= tags->len)
return;
for(tag = globalconf.screens[screen].tags; tag && dindex > 0;
tag = tag->next, dindex--);
tag_view_only(tag);
tag_view_only(tags->tab[dindex]);
}
/** Convert a tag to a printable string.
@ -265,16 +254,22 @@ luaA_tag_tostring(lua_State *L)
static int
luaA_tag_add(lua_State *L)
{
tag_t *t, **tag = luaA_checkudata(L, 1, "tag");
int i, screen = luaL_checknumber(L, 2) - 1;
tag_t **tag = luaA_checkudata(L, 1, "tag");
int screen = luaL_checknumber(L, 2) - 1;
luaA_checkscreen(screen);
for(i = 0; i < globalconf.screens_info->nscreen; i++)
for(t = globalconf.screens[i].tags; t; t = t->next)
for(int i = 0; i < globalconf.screens_info->nscreen; i++)
{
tag_array_t *tags = &globalconf.screens[i].tags;
for(int j = 0; j < tags->len; j++)
{
tag_t *t = tags->tab[j];
if(*tag == t)
luaL_error(L, "tag already on screen %d", i + 1);
else if(t->screen == screen && !a_strcmp((*tag)->name, t->name))
luaL_error(L, "a tag with the name `%s' is already on screen %d", t->name, i + 1);
}
}
(*tag)->screen = screen;
tag_append_to_screen(*tag, screen);
@ -292,16 +287,16 @@ static int
luaA_tag_get(lua_State *L)
{
int screen = luaL_checknumber(L, 1) - 1;
tag_t *tag;
tag_array_t *tags = &globalconf.screens[screen].tags;
luaA_checkscreen(screen);
lua_newtable(L);
for(tag = globalconf.screens[screen].tags; tag; tag = tag->next)
for(int i = 0; i < tags->len; i++)
{
luaA_tag_userdata_new(L, tag);
lua_setfield(L, -2, tag->name);
luaA_tag_userdata_new(L, tags->tab[i]);
lua_setfield(L, -2, tags->tab[i]->name);
}
return 1;
@ -318,17 +313,17 @@ luaA_tag_get(lua_State *L)
static int
luaA_tag_geti(lua_State *L)
{
int i = 1, screen = luaL_checknumber(L, 1) - 1;
tag_t *tag;
int screen = luaL_checknumber(L, 1) - 1;
tag_array_t *tags = &globalconf.screens[screen].tags;
luaA_checkscreen(screen);
lua_newtable(L);
for(tag = globalconf.screens[screen].tags; tag; tag = tag->next)
for(int i = 0; i < tags->len; i++)
{
luaA_tag_userdata_new(L, tag);
lua_rawseti(L, -2, i++);
luaA_tag_userdata_new(L, tags->tab[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;

2
tag.h
View File

@ -48,7 +48,7 @@ void tag_append_to_screen(tag_t *, int);
int luaA_tag_userdata_new(lua_State *, tag_t *);
DO_RCNT(tag_t, tag, tag_delete)
DO_SLIST(tag_t, tag, tag_delete)
ARRAY_FUNCS(tag_t *, tag, tag_unref);
DO_SLIST(tag_client_node_t, tag_client_node, p_delete)

View File

@ -134,15 +134,15 @@ taglist_draw(draw_context_t *ctx, int screen, widget_node_t *w,
int used __attribute__ ((unused)),
void *object)
{
tag_t *tag;
taglist_data_t *data = w->widget->data;
client_t *sel = globalconf.focus->client;
screen_t *vscreen = &globalconf.screens[screen];
int i = 0, prev_width = 0;
area_t area, rectangle = { 0, 0, 0, 0 };
char **text = NULL;
taglist_drawn_area_t *tda;
draw_parser_data_t *pdata = NULL;
int prev_width = 0;
tag_array_t *tags = &globalconf.screens[screen].tags;
char **text = p_alloca(char *, tags->len);
draw_parser_data_t *pdata = p_alloca(draw_parser_data_t, tags->len);
w->area.width = w->area.y = 0;
@ -162,10 +162,10 @@ taglist_draw(draw_context_t *ctx, int screen, widget_node_t *w,
tda->areas.len = 0;
/* First compute text and widget width */
for(tag = vscreen->tags; tag; tag = tag->next, i++)
for(int i = 0; i < tags->len; i++)
{
p_realloc(&text, i + 1);
p_realloc(&pdata, i + 1);
tag_t *tag = tags->tab[i];
text[i] = taglist_text_get(tag, data);
text[i] = tag_markup_parse(tag, text[i], a_strlen(text[i]));
draw_parser_data_init(&pdata[i]);
@ -182,8 +182,9 @@ taglist_draw(draw_context_t *ctx, int screen, widget_node_t *w,
w->area.x = widget_calculate_offset(ctx->width, w->area.width,
offset, w->widget->align);
for(i = 0, tag = vscreen->tags; tag && i < tda->areas.len; i++, tag = tag->next)
for(int i = 0; i < tags->len; i++)
{
tag_t *tag = tags->tab[i];
area_t *r = &tda->areas.tab[i];
if(!data->show_empty && !tag->selected && !tag_isoccupied(tag))
@ -209,9 +210,6 @@ taglist_draw(draw_context_t *ctx, int screen, widget_node_t *w,
}
}
p_delete(&text);
p_delete(&pdata);
w->area.height = ctx->height;
return w->area.width;
}
@ -230,20 +228,19 @@ taglist_button_press(widget_node_t *w,
void *object,
awesome_type_t type)
{
screen_t *vscreen = &globalconf.screens[screen];
tag_array_t *tags = &globalconf.screens[screen].tags;
button_t *b;
taglist_data_t *data = w->widget->data;
taglist_drawn_area_t *tda;
tag_t *tag;
int i;
/* Find the good drawn area list */
for(tda = data->drawn_area; tda && tda->object != object; tda = tda->next);
for(b = w->widget->buttons; b; b = b->next)
if(ev->detail == b->button && CLEANMASK(ev->state) == b->mod && b->fct)
for(i = 0, tag = vscreen->tags; tag && i < tda->areas.len; tag = tag->next, i++)
for(int i = 0; i < MIN(tags->len, tda->areas.len); i++)
{
tag_t *tag = tags->tab[i];
area_t *area = &tda->areas.tab[i];
if(ev->event_x >= AREA_LEFT(*area)
&& ev->event_x < AREA_RIGHT(*area)