Here's my version of a bitarray patch. Please review and comment.

2008/5/20, yy <[EMAIL PROTECTED]>:
> 2008/5/20, Premysl Hruby <[EMAIL PROTECTED]>:
>
> > Hi,
>  >
>  > This is realization of Gottox's proposal discuted on IRC today.
>  > It handles tags not as Bool [], but as bit-array saved in int.
>  >
>  > There's only one problem, as I don't find easy solution (in compile time)
>  > for check if there's no more tags than sizeof(int)*8.
>  >
>  > Maybe it can be "asserted" with someting like (possibly global, compiler
>  > take it away as it's not used anywhere):
>  >
>  > static char too_many_tags_test[sizeof(int)*8 - LENGTH(tags)];
>  >
>  > Has anyone better solution?
>  >
>  > -Ph
>  >
>  > --
>  > Premysl "Anydot" Hruby, http://www.redrum.cz/
>  >
>  >
>
>
> But, why so many macros? I don't see TMASK(p) better than 1 << (p),
>  the same with TOGGLE and ISSET, and I don't understand SET at all, you
>  are not using the v for anything (it is always 1), why not t = 1 <<
>  (p) ?
>  And about the int size, I think that since tags are defined in source
>  code it shouldn't be a problem.
>  The only problem I see is that the style doesn't fit too much with the
>  rest of the dwm code, but global Bools could also be changed to a
>  global bitarray with some Enum.
>
>
>  --
>
>
>  - yiyus || JGL .
>
>


-- 
http://www.gnuffy.org - Real Community Distro
http://www.gnuffy.org/index.php/GnuEm - Gnuffy on Ipaq (Codename Peggy)
diff -r cd9fd0986555 config.def.h
--- a/config.def.h      Mon May 19 20:29:57 2008 +0100
+++ b/config.def.h      Wed May 21 08:25:37 2008 +0200
@@ -19,6 +19,7 @@
 Rule rules[] = {
        /* class      instance    title       tags ref      isfloating */
        { "Gimp",     NULL,       NULL,       NULL,         True },
+       { "Firefox",  NULL,       NULL,       1 << 8,       True },
 };
 
 /* layout(s) */
diff -r cd9fd0986555 dwm.c
--- a/dwm.c     Mon May 19 20:29:57 2008 +0100
+++ b/dwm.c     Wed May 21 08:25:37 2008 +0200
@@ -68,7 +68,7 @@
        long flags;
        unsigned int bw, oldbw;
        Bool isbanned, isfixed, isfloating, isurgent;
-       Bool *tags;
+       unsigned int tags;
        Client *next;
        Client *prev;
        Client *snext;
@@ -107,7 +107,7 @@
        const char *class;
        const char *instance;
        const char *title;
-       const char *tag;
+       unsigned int tags;
        Bool isfloating;
 } Rule;
 
@@ -198,7 +198,7 @@
 int screen, sx, sy, sw, sh;
 int bx, by, bw, bh, blw, wx, wy, ww, wh;
 int mx, my, mw, mh, tx, ty, tw, th;
-int seltags = 0;
+unsigned int seltags = 0;
 int (*xerrorxlib)(Display *, XErrorEvent *);
 unsigned int numlockmask = 0;
 void (*handler[LASTEvent]) (XEvent *) = {
@@ -218,7 +218,8 @@
 Atom wmatom[WMLast], netatom[NetLast];
 Bool otherwm, readin;
 Bool running = True;
-Bool *tagset[2];
+unsigned int tagset[] = {1, 1}; /* after start, first tag is selected */
+unsigned int tagmask;
 Client *clients = NULL;
 Client *sel = NULL;
 Client *stack = NULL;
@@ -231,14 +232,12 @@
 
 /* configuration, allows nested code to access above variables */
 #include "config.h"
-#define TAGSZ (LENGTH(tags) * sizeof(Bool))
 
 /* function implementations */
 
 void
 applyrules(Client *c) {
        unsigned int i;
-       Bool matched = False;
        Rule *r;
        XClassHint ch = { 0 };
 
@@ -250,18 +249,15 @@
                && (!r->class || (ch.res_class && strstr(ch.res_class, 
r->class)))
                && (!r->instance || (ch.res_name && strstr(ch.res_name, 
r->instance)))) {
                        c->isfloating = r->isfloating;
-                       if(r->tag) {
-                               c->tags[idxoftag(r->tag)] = True;
-                               matched = True;
-                       }
+                       c->tags |= r->tags & tagmask;
                }
        }
        if(ch.res_class)
                XFree(ch.res_class);
        if(ch.res_name)
                XFree(ch.res_name);
-       if(!matched)
-               memcpy(c->tags, tagset[seltags], TAGSZ);
+       if(!c->tags)
+               c->tags = tagset[seltags];
 }
 
 void
@@ -313,7 +309,7 @@
 
        if(ev->window == barwin) {
                x = 0;
-               for(i = 0; i < LENGTH(tags); i++) {
+               for(i = 0; i < LENGTH(tags) && i < sizeof(int) * 8; i++) {
                        x += textw(tags[i]);
                        if(ev->x < x) {
                                if(ev->button == Button1) {
@@ -499,15 +495,15 @@
 
        dc.x = 0;
        for(c = stack; c && !isvisible(c); c = c->snext);
-       for(i = 0; i < LENGTH(tags); i++) {
+       for(i = 0; i < LENGTH(tags) && i < sizeof(int) * 8; i++) {
                dc.w = textw(tags[i]);
-               if(tagset[seltags][i]) {
+               if(tagset[seltags] & 1 << i) {
                        drawtext(tags[i], dc.sel, isurgent(i));
-                       drawsquare(c && c->tags[i], isoccupied(i), isurgent(i), 
dc.sel);
+                       drawsquare(c && c->tags & 1 << i, isoccupied(i), 
isurgent(i), dc.sel);
                }
                else {
                        drawtext(tags[i], dc.norm, isurgent(i));
-                       drawsquare(c && c->tags[i], isoccupied(i), isurgent(i), 
dc.norm);
+                       drawsquare(c && c->tags & 1 << i, isoccupied(i), 
isurgent(i), dc.norm);
                }
                dc.x += dc.w;
        }
@@ -861,7 +857,7 @@
        Client *c;
 
        for(c = clients; c; c = c->next)
-               if(c->tags[t])
+               if(c->tags & 1 << t)
                        return True;
        return False;
 }
@@ -886,19 +882,14 @@
        Client *c;
 
        for(c = clients; c; c = c->next)
-               if(c->isurgent && c->tags[t])
+               if(c->isurgent && c->tags & 1 << t)
                        return True;
        return False;
 }
 
 Bool
 isvisible(Client *c) {
-       unsigned int i;
-
-       for(i = 0; i < LENGTH(tags); i++)
-               if(c->tags[i] && tagset[seltags][i])
-                       return True;
-       return False;
+       return c->tags & tagset[seltags];
 }
 
 void
@@ -945,7 +936,6 @@
        XWindowChanges wc;
 
        c = emallocz(sizeof(Client));
-       c->tags = emallocz(TAGSZ);
        c->win = w;
 
        /* geometry */
@@ -980,7 +970,7 @@
        if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
                for(t = clients; t && t->win != trans; t = t->next);
        if(t)
-               memcpy(c->tags, t->tags, TAGSZ);
+               c->tags = t->tags;
        else
                applyrules(c);
        if(!c->isfloating)
@@ -1397,9 +1387,8 @@
                XSetFont(dpy, dc.gc, dc.font.xfont->fid);
 
        /* init tags */
-       tagset[0] = emallocz(TAGSZ);
-       tagset[1] = emallocz(TAGSZ);
-       tagset[0][0] = tagset[1][0] = True;
+       for(tagmask = i = 0; i < LENGTH(tags) && i < sizeof(int) * 8; i++)
+               tagmask |= 1 << i;
 
        /* init bar */
        for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
@@ -1460,14 +1449,11 @@
 
 void
 tag(const char *arg) {
-       unsigned int i;
-
        if(!sel)
                return;
-       for(i = 0; i < LENGTH(tags); i++)
-               sel->tags[i] = (arg == NULL);
-       sel->tags[idxoftag(arg)] = True;
+       sel->tags = arg ? 1 << MIN(idxoftag(arg), sizeof(int) * 8 - 1) & 
tagmask : tagmask;
        arrange();
+
 }
 
 unsigned int
@@ -1575,27 +1561,25 @@
 
 void
 toggletag(const char *arg) {
-       unsigned int i, j;
+       int i;
 
        if(!sel)
                return;
        i = idxoftag(arg);
-       sel->tags[i] = !sel->tags[i];
-       for(j = 0; j < LENGTH(tags) && !sel->tags[j]; j++);
-       if(j == LENGTH(tags))
-               sel->tags[i] = True; /* at least one tag must be enabled */
+       if(sel->tags ^ 1 << i)
+               sel->tags ^= 1 << i;
        arrange();
 }
 
 void
 toggleview(const char *arg) {
-       unsigned int i, j;
+       int i;
 
+       if(!sel)
+               return;
        i = idxoftag(arg);
-       tagset[seltags][i] = !tagset[seltags][i];
-       for(j = 0; j < LENGTH(tags) && !tagset[seltags][j]; j++);
-       if(j == LENGTH(tags))
-               tagset[seltags][i] = True; /* at least one tag must be viewed */
+       if(sel->tags ^ 1 << i)
+               sel->tags ^= 1 << i;
        arrange();
 }
 
@@ -1622,7 +1606,6 @@
                focus(NULL);
        XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
        setclientstate(c, WithdrawnState);
-       free(c->tags);
        free(c);
        XSync(dpy, False);
        XSetErrorHandler(xerror);
@@ -1771,8 +1754,7 @@
 void
 view(const char *arg) {
        seltags ^= 1; /* toggle sel tagset */
-       memset(tagset[seltags], (NULL == arg), TAGSZ);
-       tagset[seltags][idxoftag(arg)] = True;
+       tagset[seltags] = arg ? 1 << MIN(idxoftag(arg), sizeof(int) * 8 - 1) & 
tagmask : tagmask;
        arrange();
 }
 

Reply via email to