cleaned up settags-handling - dwm - dynamic window manager
 (HTM) git clone https://git.parazyd.org/dwm
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 50be6c8b67c500ee4aa07919609fa80785fd389d
 (DIR) parent 7d156dee1e80f7d26aa0a31a6d2c75af06cbaa9a
 (HTM) Author: Anselm R. Garbe <garbeam@gmail.com>
       Date:   Sat, 18 Aug 2007 13:48:05 +0200
       
       cleaned up settags-handling
       Diffstat:
         M client.c                            |      45 ++++++++++++++++++++++++++++++-
         M dwm.h                               |       4 +++-
         M layout.c                            |      18 +++++++++---------
         M tag.c                               |     104 ++++++++++---------------------
       
       4 files changed, 90 insertions(+), 81 deletions(-)
       ---
 (DIR) diff --git a/client.c b/client.c
       @@ -7,6 +7,8 @@
        
        /* static */
        
       +static char config[128];
       +
        static void
        attachstack(Client *c) {
                c->snext = stack;
       @@ -179,8 +181,31 @@ killclient(const char *arg) {
                        XKillClient(dpy, sel->win);
        }
        
       +Bool
       +loadconfig(Client *c) {
       +        unsigned int i;
       +        Bool result = False;
       +        XTextProperty name;
       +
       +        /* check if window has set a property */
       +        name.nitems = 0;
       +        XGetTextProperty(dpy, c->win, &name, dwmconfig);
       +        if(name.nitems && name.encoding == XA_STRING) {
       +                strncpy(config, (char *)name.value, sizeof config - 1);
       +                config[sizeof config - 1] = '\0';
       +                XFree(name.value);
       +                for(i = 0; i < ntags && i < sizeof config - 1 && config[i] != '\0'; i++)
       +                        if((c->tags[i] = config[i] == '1'))
       +                                result = True;
       +                if(i < sizeof config - 1 && config[i] != '\0')
       +                        c->isfloating = config[i] == '1';
       +        }
       +        return result;
       +}
       +
        void
        manage(Window w, XWindowAttributes *wa) {
       +        unsigned int i;
                Client *c, *t = NULL;
                Window trans;
                Status rettrans;
       @@ -221,9 +246,14 @@ manage(Window w, XWindowAttributes *wa) {
                updatetitle(c);
                if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
                        for(t = clients; t && t->win != trans; t = t->next);
       -        settags(c, t);
       +        if(t)
       +                for(i = 0; i < ntags; i++)
       +                        c->tags[i] = t->tags[i];
       +        if(!loadconfig(c))
       +                applyrules(c);
                if(!c->isfloating)
                        c->isfloating = (rettrans == Success) || c->isfixed;
       +        saveconfig(c);
                attach(c);
                attachstack(c);
                XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */
       @@ -295,6 +325,19 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
        }
        
        void
       +saveconfig(Client *c) {
       +        unsigned int i;
       +
       +        for(i = 0; i < ntags && i < sizeof config - 1; i++)
       +                config[i] = c->tags[i] ? '1' : '0';
       +        if(i < sizeof config - 1)
       +                config[i++] = c->isfloating ? '1' : '0';
       +        config[i] = '\0';
       +        XChangeProperty(dpy, c->win, dwmconfig, XA_STRING, 8,
       +                        PropModeReplace, (unsigned char *)config, i);
       +}
       +
       +void
        unban(Client *c) {
                if(!c->isbanned)
                        return;
 (DIR) diff --git a/dwm.h b/dwm.h
       @@ -96,9 +96,11 @@ void configure(Client *c);                /* send synthetic configure event */
        void detach(Client *c);                        /* detaches c from global client list */
        void focus(Client *c);                        /* focus c if visible && !NULL, or focus top visible */
        void killclient(const char *arg);        /* kill sel  nicely */
       +Bool loadconfig(Client *c);                /* loads client properties */
        void manage(Window w, XWindowAttributes *wa);        /* manage new client */
        void resize(Client *c, int x, int y,
                        int w, int h, Bool sizehints);        /* resize with given coordinates c*/
       +void saveconfig(Client *c);                /* saves client properties */
        void unban(Client *c);                        /* unbans c */
        void unmanage(Client *c, long state);        /* unmanage c */
        void updatesizehints(Client *c);        /* update the size hint variables of c */
       @@ -132,9 +134,9 @@ void quit(const char *arg);                /* quit dwm nicely */
        int xerror(Display *dsply, XErrorEvent *ee);        /* dwm's X error handler */
        
        /* tag.c */
       +void applyrules(Client *c);                /* applies rules to c */
        void compileregs(void);                        /* initialize regexps of rules defined in config.h */
        Bool isvisible(Client *c);                /* returns True if client is visible */
       -void settags(Client *c, Client *trans);        /* sets tags of c */
        void tag(const char *arg);                /* tags sel with arg's index */
        void togglefloating(const char *arg);        /* toggles sel between floating/tiled state */
        void toggletag(const char *arg);        /* toggles sel tags with arg's index */
 (DIR) diff --git a/layout.c b/layout.c
       @@ -10,7 +10,7 @@ typedef struct {
        } Layout;
        
        unsigned int blw = 0;
       -static unsigned int sellayout = 0; /* default */
       +static unsigned int ltidx = 0; /* default */
        
        static void
        floating(void) { /* default floating layout */
       @@ -36,7 +36,7 @@ arrange(void) {
                                unban(c);
                        else
                                ban(c);
       -        layouts[sellayout].arrange();
       +        layouts[ltidx].arrange();
                focus(NULL);
                restack();
        }
       @@ -76,25 +76,25 @@ focusprev(const char *arg) {
        const char *
        getsymbol(void)
        {
       -        return layouts[sellayout].symbol;
       +        return layouts[ltidx].symbol;
        }
        
        Bool
        isfloating(void) {
       -        return layouts[sellayout].arrange == floating;
       +        return layouts[ltidx].arrange == floating;
        }
        
        Bool
        isarrange(void (*func)())
        {
       -        return func == layouts[sellayout].arrange;
       +        return func == layouts[ltidx].arrange;
        }
        
        void
        initlayouts(void) {
                unsigned int i, w;
        
       -        /* TODO deserialize sellayout if present */
       +        /* TODO deserialize ltidx if present */
                nlayouts = sizeof layouts / sizeof layouts[0];
                for(blw = i = 0; i < nlayouts; i++) {
                        w = textw(layouts[i].symbol);
       @@ -143,14 +143,14 @@ setlayout(const char *arg) {
                int i;
        
                if(!arg) {
       -                if(++sellayout == nlayouts)
       -                        sellayout = 0;;
       +                if(++ltidx == nlayouts)
       +                        ltidx = 0;;
                }
                else {
                        i = atoi(arg);
                        if(i < 0 || i >= nlayouts)
                                return;
       -                sellayout = i;
       +                ltidx = i;
                }
                if(sel)
                        arrange();
 (DIR) diff --git a/tag.c b/tag.c
       @@ -27,19 +27,6 @@ static Regs *regs = NULL;
        static unsigned int nrules = 0;
        static char prop[512];
        
       -static void
       -persistconfig(Client *c) {
       -        unsigned int i;
       -
       -        for(i = 0; i < ntags && i < sizeof prop - 1; i++)
       -                prop[i] = c->tags[i] ? '1' : '0';
       -        if(i < sizeof prop - 1)
       -                prop[i++] = c->isfloating ? '1' : '0';
       -        prop[i] = '\0';
       -        XChangeProperty(dpy, c->win, dwmconfig, XA_STRING, 8,
       -                        PropModeReplace, (unsigned char *)prop, i);
       -}
       -
        static unsigned int
        idxoftag(const char *tag) {
                unsigned int i;
       @@ -53,6 +40,37 @@ idxoftag(const char *tag) {
        /* extern */
        
        void
       +applyrules(Client *c) {
       +        unsigned int i, j;
       +        regmatch_t tmp;
       +        Bool matched = False;
       +        XClassHint ch = { 0 };
       +
       +        /* rule matching */
       +        XGetClassHint(dpy, c->win, &ch);
       +        snprintf(prop, sizeof prop, "%s:%s:%s",
       +                        ch.res_class ? ch.res_class : "",
       +                        ch.res_name ? ch.res_name : "", c->name);
       +        for(i = 0; i < nrules; i++)
       +                if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
       +                        c->isfloating = rules[i].isfloating;
       +                        for(j = 0; regs[i].tagregex && j < ntags; j++) {
       +                                if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
       +                                        matched = True;
       +                                        c->tags[j] = True;
       +                                }
       +                        }
       +                }
       +        if(ch.res_class)
       +                XFree(ch.res_class);
       +        if(ch.res_name)
       +                XFree(ch.res_name);
       +        if(!matched)
       +                for(i = 0; i < ntags; i++)
       +                        c->tags[i] = seltags[i];
       +}
       +
       +void
        compileregs(void) {
                unsigned int i;
                regex_t *reg;
       @@ -90,60 +108,6 @@ isvisible(Client *c) {
        }
        
        void
       -settags(Client *c, Client *trans) {
       -        unsigned int i, j;
       -        regmatch_t tmp;
       -        Bool matched = trans != NULL;
       -        XClassHint ch = { 0 };
       -        XTextProperty name;
       -
       -        if(matched) {
       -                for(i = 0; i < ntags; i++)
       -                        c->tags[i] = trans->tags[i];
       -        }
       -        else {
       -                /* check if window has set a property */
       -                name.nitems = 0;
       -                XGetTextProperty(dpy, c->win, &name, dwmconfig);
       -                if(name.nitems && name.encoding == XA_STRING) {
       -                        strncpy(prop, (char *)name.value, sizeof prop - 1);
       -                        prop[sizeof prop - 1] = '\0';
       -                        XFree(name.value);
       -                        for(i = 0; i < ntags && i < sizeof prop - 1 && prop[i] != '\0'; i++)
       -                                if((c->tags[i] = prop[i] == '1'))
       -                                        matched = True;
       -                        if(i < sizeof prop - 1 && prop[i] != '\0')
       -                                c->isfloating = prop[i] == '1';
       -                }
       -        }
       -        if(!matched) {
       -                /* rule matching */
       -                XGetClassHint(dpy, c->win, &ch);
       -                snprintf(prop, sizeof prop, "%s:%s:%s",
       -                                ch.res_class ? ch.res_class : "",
       -                                ch.res_name ? ch.res_name : "", c->name);
       -                for(i = 0; i < nrules; i++)
       -                        if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
       -                                c->isfloating = rules[i].isfloating;
       -                                for(j = 0; regs[i].tagregex && j < ntags; j++) {
       -                                        if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
       -                                                matched = True;
       -                                                c->tags[j] = True;
       -                                        }
       -                                }
       -                        }
       -                if(ch.res_class)
       -                        XFree(ch.res_class);
       -                if(ch.res_name)
       -                        XFree(ch.res_name);
       -        }
       -        if(!matched)
       -                for(i = 0; i < ntags; i++)
       -                        c->tags[i] = seltags[i];
       -        persistconfig(c);
       -}
       -
       -void
        tag(const char *arg) {
                unsigned int i;
        
       @@ -154,7 +118,7 @@ tag(const char *arg) {
                i = idxoftag(arg);
                if(i >= 0 && i < ntags)
                        sel->tags[i] = True;
       -        persistconfig(sel);
       +        saveconfig(sel);
                arrange();
        }
        
       @@ -165,7 +129,7 @@ togglefloating(const char *arg) {
                sel->isfloating = !sel->isfloating;
                if(sel->isfloating) {
                        resize(sel, sel->x, sel->y, sel->w, sel->h, True);
       -                persistconfig(sel);
       +                saveconfig(sel);
                }
                arrange();
        }
       @@ -181,7 +145,7 @@ toggletag(const char *arg) {
                for(j = 0; j < ntags && !sel->tags[j]; j++);
                if(j == ntags)
                        sel->tags[i] = True;
       -        persistconfig(sel);
       +        saveconfig(sel);
                arrange();
        }