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:
parent
236ccc165c
commit
14f4e02e66
88
client.c
88
client.c
|
@ -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);
|
||||
return false;
|
||||
|
||||
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);
|
||||
if (strlen(prop) != tags->len + 2) {
|
||||
/* ignore property if the tag count isn't matching */
|
||||
p_delete(&prop);
|
||||
return false;
|
||||
}
|
||||
|
||||
p_delete(&prop);
|
||||
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]);
|
||||
|
||||
return result;
|
||||
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
103
ewmh.c
|
@ -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
2
lua.c
|
@ -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;
|
||||
|
|
6
screen.c
6
screen.c
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
85
tag.c
|
@ -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;
|
||||
|
|
6
tag.h
6
tag.h
|
@ -29,7 +29,7 @@
|
|||
#define IS_TILED(client, screen) (client && !client->isfloating && !client->ismax && client_isvisible(client, screen))
|
||||
|
||||
/* Contructor, destructor and referencors */
|
||||
tag_t * tag_new(const char *, layout_t *, double, int, int);
|
||||
tag_t *tag_new(const char *, layout_t *, double, int, int);
|
||||
|
||||
static inline void
|
||||
tag_delete(tag_t **tag)
|
||||
|
@ -38,7 +38,7 @@ tag_delete(tag_t **tag)
|
|||
p_delete(tag);
|
||||
}
|
||||
|
||||
tag_t ** tags_get_current(int);
|
||||
tag_t **tags_get_current(int);
|
||||
void tag_client(client_t *, tag_t *);
|
||||
void untag_client(client_t *, tag_t *);
|
||||
bool is_client_tagged(client_t *, tag_t *);
|
||||
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue