use a linked list for handling tag <-> client relationship

This commit is contained in:
Julien Danjou 2007-12-14 14:29:32 +01:00
parent 2b5ba1f16f
commit 078d224b46
10 changed files with 190 additions and 98 deletions

114
client.c
View File

@ -33,18 +33,39 @@
#include "window.h" #include "window.h"
#include "layouts/floating.h" #include "layouts/floating.h"
/** Get a Client by its window /** Load windows properties, restoring client's tag
* \param list Client list to look info * and floating state before awesome was restarted if any
* \param w Client window to find * \todo this may bug if number of tags is != than before
* \return client * \param c Client ref
* \param ntags tags number
*/ */
Client * static Bool
get_client_bywin(Client *list, Window w) loadprops(Client * c, VirtScreen *scr)
{ {
Client *c; int i;
char *prop;
Bool result = False;
for(c = list; c && c->win != w; c = c->next); prop = p_new(char, scr->ntags + 2);
return c;
if(xgettextprop(c->display, c->win, AWESOMEPROPS_ATOM(c->display), prop, scr->ntags + 2))
{
for(i = 0; i < scr->ntags && prop[i]; i++)
if(prop[i] == '1')
{
tag_client(&scr->tclink, c, &scr->tags[i]);
result = True;
}
else
untag_client(&scr->tclink, c, &scr->tags[i]);
if(i <= scr->ntags && prop[i])
c->isfloating = prop[i] == '1';
}
p_delete(&prop);
return result;
} }
/** Check if client supports protocol WM_DELETE_WINDOW /** Check if client supports protocol WM_DELETE_WINDOW
@ -101,6 +122,20 @@ client_swap(Client **head, Client *c1, Client *c2)
*head = c2; *head = c2;
} }
/** Get a Client by its window
* \param list Client list to look info
* \param w Client window to find
* \return client
*/
Client *
get_client_bywin(Client *list, Window w)
{
Client *c;
for(c = list; c && c->win != w; c = c->next);
return c;
}
void void
updatetitle(Client *c) updatetitle(Client *c)
{ {
@ -180,8 +215,8 @@ focus(Client *c, Bool selscreen, awesome_config *awesomeconf, int screen)
Tag *tag = get_current_tag(awesomeconf->screens[screen]); Tag *tag = get_current_tag(awesomeconf->screens[screen]);
/* if c is NULL or invisible, take next client in the stack */ /* if c is NULL or invisible, take next client in the stack */
if((!c && selscreen) || (c && !isvisible(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags))) if((!c && selscreen) || (c && !isvisible(c, &awesomeconf->screens[screen], screen)))
for(c = awesomeconf->clients; c && !isvisible(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags); c = c->next); for(c = awesomeconf->clients; c && !isvisible(c, &awesomeconf->screens[screen], screen); c = c->next);
/* XXX unfocus other tags clients, this is a bit too much */ /* XXX unfocus other tags clients, this is a bit too much */
for(i = 0; i < awesomeconf->screens[screen].ntags; i++) for(i = 0; i < awesomeconf->screens[screen].ntags; i++)
@ -221,36 +256,6 @@ focus(Client *c, Bool selscreen, awesome_config *awesomeconf, int screen)
XSetInputFocus(awesomeconf->display, RootWindow(awesomeconf->display, get_phys_screen(awesomeconf->display, screen)), RevertToPointerRoot, CurrentTime); XSetInputFocus(awesomeconf->display, RootWindow(awesomeconf->display, get_phys_screen(awesomeconf->display, screen)), RevertToPointerRoot, CurrentTime);
} }
/** 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 Client ref
* \param ntags tags number
*/
Bool
loadprops(Client * c, int ntags)
{
int i;
char *prop;
Bool result = False;
prop = p_new(char, ntags + 2);
if(xgettextprop(c->display, c->win, AWESOMEPROPS_ATOM(c->display), prop, ntags + 2))
{
for(i = 0; i < ntags && prop[i]; i++)
if((c->tags[i] = prop[i] == '1'))
result = True;
if(i <= ntags && prop[i])
c->isfloating = prop[i] == '1';
}
p_delete(&prop);
return result;
}
/** Manage a new client /** Manage a new client
* \param w The window * \param w The window
* \param wa Window attributes * \param wa Window attributes
@ -285,7 +290,7 @@ client_manage(Window w, XWindowAttributes *wa, awesome_config *awesomeconf, int
updatetitle(c); updatetitle(c);
/* loadprops or apply rules if no props */ /* loadprops or apply rules if no props */
if(!loadprops(c, awesomeconf->screens[screen].ntags)) if(!loadprops(c, &awesomeconf->screens[screen]))
tag_client_with_rules(c, awesomeconf); tag_client_with_rules(c, awesomeconf);
screen_info = get_screen_info(awesomeconf->display, screen, NULL, NULL); screen_info = get_screen_info(awesomeconf->display, screen, NULL, NULL);
@ -346,14 +351,15 @@ client_manage(Window w, XWindowAttributes *wa, awesome_config *awesomeconf, int
if((rettrans = XGetTransientForHint(c->display, w, &trans) == Success) if((rettrans = XGetTransientForHint(c->display, w, &trans) == Success)
&& (t = get_client_bywin(awesomeconf->clients, trans))) && (t = get_client_bywin(awesomeconf->clients, trans)))
for(i = 0; i < awesomeconf->screens[c->screen].ntags; i++) for(i = 0; i < awesomeconf->screens[c->screen].ntags; i++)
c->tags[i] = t->tags[i]; if(is_client_tagged(awesomeconf->screens[c->screen].tclink, t, &awesomeconf->screens[c->screen].tags[i]))
tag_client(&awesomeconf->screens[c->screen].tclink, c, &awesomeconf->screens[c->screen].tags[i]);
/* should be floating if transsient or fixed) */ /* should be floating if transsient or fixed) */
if(!c->isfloating) if(!c->isfloating)
c->isfloating = (rettrans == Success) || c->isfixed; c->isfloating = (rettrans == Success) || c->isfixed;
/* save new props */ /* save new props */
saveprops(c, awesomeconf->screens[c->screen].ntags); saveprops(c, &awesomeconf->screens[c->screen]);
/* attach to the stack */ /* attach to the stack */
client_attach(&awesomeconf->clients, c); client_attach(&awesomeconf->clients, c);
@ -457,17 +463,17 @@ client_resize(Client *c, int x, int y, int w, int h, awesome_config *awesomeconf
} }
void void
saveprops(Client * c, int ntags) saveprops(Client * c, VirtScreen *scr)
{ {
int i; int i;
char *prop; char *prop;
prop = p_new(char, ntags + 2); prop = p_new(char, scr->ntags + 2);
for(i = 0; i < ntags; i++) for(i = 0; i < scr->ntags; i++)
prop[i] = c->tags[i] ? '1' : '0'; prop[i] = is_client_tagged(scr->tclink, c, &scr->tags[i]) ? '1' : '0';
if(i <= ntags) if(i <= scr->ntags)
prop[i] = c->isfloating ? '1' : '0'; prop[i] = c->isfloating ? '1' : '0';
prop[++i] = '\0'; prop[++i] = '\0';
@ -508,7 +514,6 @@ client_unmanage(Client *c, long state, awesome_config *awesomeconf)
XUngrabServer(c->display); XUngrabServer(c->display);
if(state != NormalState) if(state != NormalState)
arrange(awesomeconf, c->screen); arrange(awesomeconf, c->screen);
p_delete(&c->tags);
p_delete(&c); p_delete(&c);
} }
@ -595,10 +600,9 @@ tag_client_with_rules(Client *c, awesome_config *awesomeconf)
if(is_tag_match_rules(&awesomeconf->screens[c->screen].tags[i], r)) if(is_tag_match_rules(&awesomeconf->screens[c->screen].tags[i], r))
{ {
matched = True; matched = True;
c->tags[i] = True; tag_client(&awesomeconf->screens[c->screen].tclink, c,
&awesomeconf->screens[c->screen].tags[i]);
} }
else
c->tags[i] = False;
if(!matched) if(!matched)
tag_client_with_current_selected(c, &awesomeconf->screens[c->screen]); tag_client_with_current_selected(c, &awesomeconf->screens[c->screen]);
@ -685,7 +689,7 @@ uicb_client_swapnext(awesome_config *awesomeconf,
if(!sel) if(!sel)
return; return;
for(next = sel->next; next && !isvisible(next, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags); next = next->next); for(next = sel->next; next && !isvisible(next, &awesomeconf->screens[screen], screen); next = next->next);
if(next) if(next)
{ {
client_swap(&awesomeconf->clients, sel, next); client_swap(&awesomeconf->clients, sel, next);
@ -705,7 +709,7 @@ uicb_client_swapprev(awesome_config *awesomeconf,
if(!sel) if(!sel)
return; return;
for(prev = sel->prev; prev && !isvisible(prev, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags); prev = prev->prev); for(prev = sel->prev; prev && !isvisible(prev, &awesomeconf->screens[screen], screen); prev = prev->prev);
if(prev) if(prev)
{ {
client_swap(&awesomeconf->clients, prev, sel); client_swap(&awesomeconf->clients, prev, sel);

View File

@ -28,7 +28,6 @@ Client * get_client_bywin(Client *, Window);
void client_attach(Client **, Client *); void client_attach(Client **, Client *);
void client_detach(Client **, Client *); void client_detach(Client **, Client *);
void client_reattach_after(Client *, Client *); void client_reattach_after(Client *, Client *);
Bool loadprops(Client *, int );
void client_ban(Client *); void client_ban(Client *);
void focus(Client *, Bool, awesome_config *, int); void focus(Client *, Bool, awesome_config *, int);
void client_manage(Window, XWindowAttributes *, awesome_config *, int); void client_manage(Window, XWindowAttributes *, awesome_config *, int);
@ -37,7 +36,7 @@ void client_unban(Client *);
void client_unmanage(Client *, long, awesome_config *); void client_unmanage(Client *, long, awesome_config *);
void updatesizehints(Client *); void updatesizehints(Client *);
void updatetitle(Client *); void updatetitle(Client *);
void saveprops(Client *, int); void saveprops(Client *, VirtScreen *);
void tag_client_with_rules(Client *, awesome_config *); void tag_client_with_rules(Client *, awesome_config *);
UICB_PROTO(uicb_client_kill); UICB_PROTO(uicb_client_kill);

View File

@ -116,8 +116,6 @@ struct Client
Bool isfixed; Bool isfixed;
/** True if the window is maximized */ /** True if the window is maximized */
Bool ismax; Bool ismax;
/** Tags for the client */
Bool *tags;
/** Next client */ /** Next client */
Client *next; Client *next;
/** Previous client */ /** Previous client */
@ -153,6 +151,15 @@ typedef struct
int ncol; int ncol;
} Tag; } Tag;
/** TagClientLink type */
typedef struct TagClientLink TagClientLink;
struct TagClientLink
{
Tag *tag;
Client *client;
TagClientLink *next;
};
/** Padding type */ /** Padding type */
typedef struct typedef struct
{ {
@ -190,6 +197,7 @@ typedef struct
Tag *tags; Tag *tags;
/** Number of tags in **tags */ /** Number of tags in **tags */
int ntags; int ntags;
TagClientLink *tclink;
/** Layout list */ /** Layout list */
Layout *layouts; Layout *layouts;
int nlayouts; int nlayouts;

View File

@ -57,7 +57,7 @@ arrange(awesome_config *awesomeconf, int screen)
for(c = awesomeconf->clients; c; c = c->next) for(c = awesomeconf->clients; c; c = c->next)
{ {
if(isvisible(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags)) if(isvisible(c, &awesomeconf->screens[screen], screen))
client_unban(c); client_unban(c);
/* we don't touch other screens windows */ /* we don't touch other screens windows */
else if(c->screen == screen) else if(c->screen == screen)
@ -89,9 +89,9 @@ uicb_client_focusnext(awesome_config * awesomeconf,
if(!sel) if(!sel)
return; return;
for(c = sel->next; c && !isvisible(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags); c = c->next); for(c = sel->next; c && !isvisible(c, &awesomeconf->screens[screen], screen); c = c->next);
if(!c) if(!c)
for(c = awesomeconf->clients; c && !isvisible(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags); c = c->next); for(c = awesomeconf->clients; c && !isvisible(c, &awesomeconf->screens[screen], screen); c = c->next);
if(c) if(c)
{ {
focus(c, True, awesomeconf, screen); focus(c, True, awesomeconf, screen);
@ -108,11 +108,11 @@ uicb_client_focusprev(awesome_config *awesomeconf,
if(!sel) if(!sel)
return; return;
for(c = sel->prev; c && !isvisible(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags); c = c->prev); for(c = sel->prev; c && !isvisible(c, &awesomeconf->screens[screen], screen); c = c->prev);
if(!c) if(!c)
{ {
for(c = awesomeconf->clients; c && c->next; c = c->next); for(c = awesomeconf->clients; c && c->next; c = c->next);
for(; c && !isvisible(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags); c = c->prev); for(; c && !isvisible(c, &awesomeconf->screens[screen], screen); c = c->prev);
} }
if(c) if(c)
{ {
@ -168,7 +168,7 @@ restack(awesome_config *awesomeconf, int screen)
} }
for(c = awesomeconf->clients; c; c = c->next) for(c = awesomeconf->clients; c; c = c->next)
{ {
if(!IS_TILED(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags) || c == sel) if(!IS_TILED(c, &awesomeconf->screens[screen], screen) || c == sel)
continue; continue;
XConfigureWindow(awesomeconf->display, c->win, CWSibling | CWStackMode, &wc); XConfigureWindow(awesomeconf->display, c->win, CWSibling | CWStackMode, &wc);
wc.sibling = c->win; wc.sibling = c->win;
@ -309,7 +309,7 @@ uicb_client_zoom(awesome_config *awesomeconf,
Client *sel = get_current_tag(awesomeconf->screens[screen])->client_sel; Client *sel = get_current_tag(awesomeconf->screens[screen])->client_sel;
if(awesomeconf->clients == sel) if(awesomeconf->clients == sel)
for(sel = sel->next; sel && !isvisible(sel, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags); sel = sel->next); for(sel = sel->next; sel && !isvisible(sel, &awesomeconf->screens[screen], screen); sel = sel->next);
if(!sel) if(!sel)
return; return;

View File

@ -28,7 +28,7 @@ layout_floating(awesome_config *awesomeconf, int screen)
Client *c; Client *c;
for(c = awesomeconf->clients; c; c = c->next) for(c = awesomeconf->clients; c; c = c->next)
if(isvisible(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags)) if(isvisible(c, &awesomeconf->screens[screen], screen))
client_resize(c, c->rx, c->ry, c->rw, c->rh, awesomeconf, True, False); client_resize(c, c->rx, c->ry, c->rw, c->rh, awesomeconf, True, False);
} }
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99

View File

@ -31,7 +31,7 @@ layout_max(awesome_config *awesomeconf, int screen)
ScreenInfo *si = get_screen_info(awesomeconf->display, screen, &awesomeconf->screens[screen].statusbar, &awesomeconf->screens[screen].padding); ScreenInfo *si = get_screen_info(awesomeconf->display, screen, &awesomeconf->screens[screen].statusbar, &awesomeconf->screens[screen].padding);
for(c = awesomeconf->clients; c; c = c->next) for(c = awesomeconf->clients; c; c = c->next)
if(IS_TILED(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags)) if(IS_TILED(c, &awesomeconf->screens[screen], screen))
client_resize(c, si[screen].x_org, si[screen].y_org, client_resize(c, si[screen].x_org, si[screen].y_org,
si[screen].width - 2 * c->border, si[screen].width - 2 * c->border,
si[screen].height - 2 * c->border, awesomeconf, awesomeconf->screens[screen].resize_hints, False); si[screen].height - 2 * c->border, awesomeconf, awesomeconf->screens[screen].resize_hints, False);

View File

@ -110,7 +110,7 @@ _tile(awesome_config *awesomeconf, int screen, const Bool right)
screens_info = get_screen_info(awesomeconf->display, screen, &awesomeconf->screens[screen].statusbar, &awesomeconf->screens[screen].padding); screens_info = get_screen_info(awesomeconf->display, screen, &awesomeconf->screens[screen].statusbar, &awesomeconf->screens[screen].padding);
for(n = 0, c = awesomeconf->clients; c; c = c->next) for(n = 0, c = awesomeconf->clients; c; c = c->next)
if(IS_TILED(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags)) if(IS_TILED(c, &awesomeconf->screens[screen], screen))
n++; n++;
wah = screens_info[screen].height; wah = screens_info[screen].height;
@ -137,7 +137,7 @@ _tile(awesome_config *awesomeconf, int screen, const Bool right)
for(i = 0, c = awesomeconf->clients; c; c = c->next) for(i = 0, c = awesomeconf->clients; c; c = c->next)
{ {
if(!IS_TILED(c, screen, awesomeconf->screens[screen].tags, awesomeconf->screens[screen].ntags)) if(!IS_TILED(c, &awesomeconf->screens[screen], screen))
continue; continue;
c->ismax = False; c->ismax = False;

View File

@ -27,6 +27,7 @@
#include "draw.h" #include "draw.h"
#include "screen.h" #include "screen.h"
#include "util.h" #include "util.h"
#include "tag.h"
#include "layouts/tile.h" #include "layouts/tile.h"
/** Check if at least a client is tagged with tag number t and is on screen /** Check if at least a client is tagged with tag number t and is on screen
@ -36,12 +37,12 @@
* \return True or False * \return True or False
*/ */
static Bool static Bool
isoccupied(Client *head, unsigned int t, int screen) isoccupied(TagClientLink *tc, int screen, Client *head, Tag *t)
{ {
Client *c; Client *c;
for(c = head; c; c = c->next) for(c = head; c; c = c->next)
if(c->tags[t] && c->screen == screen) if(c->screen == screen && is_client_tagged(tc, c, t))
return True; return True;
return False; return False;
} }
@ -78,7 +79,8 @@ drawstatusbar(awesome_config *awesomeconf, int screen)
awesomeconf->screens[screen].statusbar.height, awesomeconf->screens[screen].statusbar.height,
awesomeconf->screens[screen].font, awesomeconf->screens[screen].font,
awesomeconf->screens[screen].tags[i].name, awesomeconf->screens[screen].colors_selected); awesomeconf->screens[screen].tags[i].name, awesomeconf->screens[screen].colors_selected);
if(isoccupied(awesomeconf->clients, i, screen)) if(isoccupied(awesomeconf->screens[screen].tclink, screen, awesomeconf->clients,
&awesomeconf->screens[screen].tags[i]))
drawrectangle(awesomeconf->display, phys_screen, drawrectangle(awesomeconf->display, phys_screen,
x, y, x, y,
(awesomeconf->screens[screen].font->height + 2) / 4, (awesomeconf->screens[screen].font->height + 2) / 4,
@ -86,7 +88,8 @@ drawstatusbar(awesome_config *awesomeconf, int screen)
drawable, drawable,
awesomeconf->screens[screen].statusbar.width, awesomeconf->screens[screen].statusbar.width,
awesomeconf->screens[screen].statusbar.height, awesomeconf->screens[screen].statusbar.height,
sel && sel->tags[i], sel && is_client_tagged(awesomeconf->screens[screen].tclink, sel,
&awesomeconf->screens[screen].tags[i]),
awesomeconf->screens[screen].colors_selected[ColFG]); awesomeconf->screens[screen].colors_selected[ColFG]);
} }
else else
@ -99,7 +102,8 @@ drawstatusbar(awesome_config *awesomeconf, int screen)
awesomeconf->screens[screen].statusbar.height, awesomeconf->screens[screen].statusbar.height,
awesomeconf->screens[screen].font, awesomeconf->screens[screen].font,
awesomeconf->screens[screen].tags[i].name, awesomeconf->screens[screen].colors_normal); awesomeconf->screens[screen].tags[i].name, awesomeconf->screens[screen].colors_normal);
if(isoccupied(awesomeconf->clients, i, screen)) if(isoccupied(awesomeconf->screens[screen].tclink, screen,
awesomeconf->clients, &awesomeconf->screens[screen].tags[i]))
drawrectangle(awesomeconf->display, phys_screen, drawrectangle(awesomeconf->display, phys_screen,
x, y, x, y,
(awesomeconf->screens[screen].font->height + 2) / 4, (awesomeconf->screens[screen].font->height + 2) / 4,
@ -107,7 +111,8 @@ drawstatusbar(awesome_config *awesomeconf, int screen)
drawable, drawable,
awesomeconf->screens[screen].statusbar.width, awesomeconf->screens[screen].statusbar.width,
awesomeconf->screens[screen].statusbar.height, awesomeconf->screens[screen].statusbar.height,
sel && sel->tags[i], sel && is_client_tagged(awesomeconf->screens[screen].tclink, sel,
&awesomeconf->screens[screen].tags[i]),
awesomeconf->screens[screen].colors_normal[ColFG]); awesomeconf->screens[screen].colors_normal[ColFG]);
} }
x += w; x += w;

113
tag.c
View File

@ -28,23 +28,81 @@
#include "util.h" #include "util.h"
#include "rules.h" #include "rules.h"
static void
detach_tagclientlink(TagClientLink **head, TagClientLink *tc)
{
TagClientLink *tmp;
if(*head == tc)
*head = tc->next;
else
{
for(tmp = *head; tmp && tmp->next != tc; tmp = tmp->next);
tmp->next = tc->next;
}
p_delete(&tc);
}
void
tag_client(TagClientLink **head, Client *c, Tag *t)
{
TagClientLink *tc, *new_tc;
/* don't tag twice */
if(is_client_tagged(*head, c, t))
return;
new_tc = p_new(TagClientLink, 1);
if(!*head)
*head = new_tc;
else
{
for(tc = *head; tc->next; tc = tc->next);
tc->next = new_tc;
}
new_tc->client = c;
new_tc->tag = t;
}
void
untag_client(TagClientLink **head, Client *c, Tag *t)
{
TagClientLink *tc;
for(tc = *head; tc; tc = tc->next)
if(tc->client == c && tc->tag == t)
detach_tagclientlink(head, tc);
}
Bool
is_client_tagged(TagClientLink *head, Client *c, Tag *t)
{
TagClientLink *tc;
for(tc = head; tc; tc = tc->next)
if(tc->client == c && tc->tag == t)
return True;
return False;
}
/** Returns True if a client is tagged /** Returns True if a client is tagged
* with one of the tags * with one of the tags
* \param c Client
* \param tags tag to check
* \param ntags number of tags in *tags
* \return True or False * \return True or False
*/ */
Bool Bool
isvisible(Client * c, int screen, Tag * tags, int ntags) isvisible(Client *c, VirtScreen *scr, int screen)
{ {
int i; int i;
if(c->screen != screen) if(c->screen != screen)
return False; return False;
for(i = 0; i < ntags; i++) for(i = 0; i < scr->ntags; i++)
if(c->tags[i] && tags[i].selected) if(is_client_tagged(scr->tclink, c, &scr->tags[i]) && scr->tags[i].selected)
return True; return True;
return False; return False;
} }
@ -54,9 +112,11 @@ tag_client_with_current_selected(Client *c, VirtScreen *screen)
{ {
int i; int i;
p_realloc(&c->tags, screen->ntags);
for(i = 0; i < screen->ntags; i++) for(i = 0; i < screen->ntags; i++)
c->tags[i] = screen->tags[i].selected; if(screen->tags[i].selected)
tag_client(&screen->tclink, c, &screen->tags[i]);
else
untag_client(&screen->tclink, c, &screen->tags[i]);
} }
/** Tag selected window with tag /** Tag selected window with tag
@ -81,13 +141,19 @@ uicb_client_tag(awesome_config *awesomeconf,
return; return;
} }
for(i = 0; i < awesomeconf->screens[screen].ntags; i++) if(arg)
sel->tags[i] = arg == NULL; for(i = 0; i < awesomeconf->screens[screen].ntags; i++)
untag_client(&awesomeconf->screens[screen].tclink, sel,
&awesomeconf->screens[screen].tags[i]);
else
for(i = 0; i < awesomeconf->screens[screen].ntags; i++)
tag_client(&awesomeconf->screens[screen].tclink, sel,
&awesomeconf->screens[screen].tags[i]);
if(tag_id != -1) if(tag_id != -1)
sel->tags[tag_id] = True; tag_client(&awesomeconf->screens[screen].tclink, sel,
&awesomeconf->screens[screen].tags[tag_id]);
saveprops(sel, awesomeconf->screens[screen].ntags); saveprops(sel, &awesomeconf->screens[screen]);
arrange(awesomeconf, screen); arrange(awesomeconf, screen);
} }
@ -112,7 +178,7 @@ uicb_client_togglefloating(awesome_config * awesomeconf,
else else
client_resize(sel, sel->x, sel->y, sel->w, sel->h, awesomeconf, True, True); client_resize(sel, sel->x, sel->y, sel->w, sel->h, awesomeconf, True, True);
saveprops(sel, awesomeconf->screens[screen].ntags); saveprops(sel, &awesomeconf->screens[screen]);
arrange(awesomeconf, screen); arrange(awesomeconf, screen);
} }
@ -138,18 +204,25 @@ uicb_client_toggletag(awesome_config *awesomeconf,
if(i < 0 || i >= awesomeconf->screens[screen].ntags) if(i < 0 || i >= awesomeconf->screens[screen].ntags)
return; return;
sel->tags[i] = !sel->tags[i]; if(is_client_tagged(awesomeconf->screens[screen].tclink, sel,
&awesomeconf->screens[screen].tags[i]))
untag_client(&awesomeconf->screens[screen].tclink, sel,&awesomeconf->screens[screen].tags[i]);
else
tag_client(&awesomeconf->screens[screen].tclink, sel,&awesomeconf->screens[screen].tags[i]);
/* check that there's at least one tag selected for this client*/ /* check that there's at least one tag selected for this client*/
for(j = 0; j < awesomeconf->screens[screen].ntags && !sel->tags[j]; j++); for(j = 0; j < awesomeconf->screens[screen].ntags
if(j == awesomeconf->screens[screen].ntags) && !is_client_tagged(awesomeconf->screens[screen].tclink, sel,
sel->tags[i] = True; &awesomeconf->screens[screen].tags[j]); j++);
if(j == awesomeconf->screens[screen].ntags)
tag_client(&awesomeconf->screens[screen].tclink, sel,&awesomeconf->screens[screen].tags[i]);
} }
else else
for(i = 0; i < awesomeconf->screens[screen].ntags; i++) for(i = 0; i < awesomeconf->screens[screen].ntags; i++)
sel->tags[i] = True; tag_client(&awesomeconf->screens[screen].tclink, sel,&awesomeconf->screens[screen].tags[i]);
saveprops(sel, awesomeconf->screens[screen].ntags); saveprops(sel, &awesomeconf->screens[screen]);
arrange(awesomeconf, screen); arrange(awesomeconf, screen);
} }

7
tag.h
View File

@ -25,9 +25,12 @@
#include "client.h" #include "client.h"
/** Check if a client is tiled */ /** Check if a client is tiled */
#define IS_TILED(client, screen, tags, ntags) (client && !client->isfloating && isvisible(client, screen, tags, ntags)) #define IS_TILED(client, scr, screen) (client && !client->isfloating && isvisible(client, scr, screen))
Bool isvisible(Client *, int, Tag *, int); Bool isvisible(Client *, VirtScreen *, int);
void tag_client(TagClientLink **, Client *, Tag *);
void untag_client(TagClientLink **, Client *, Tag *);
Bool is_client_tagged(TagClientLink *, Client *, Tag *);
void tag_client_with_current_selected(Client *, VirtScreen *); void tag_client_with_current_selected(Client *, VirtScreen *);
UICB_PROTO(uicb_client_tag); UICB_PROTO(uicb_client_tag);