Here is yet another update to the patch which includes chances
discussed on #dwm.
2008/5/21, Anselm R. Garbe <[EMAIL PROTECTED]>:
> Hi I like your patches (also the version of anydot).
>
>
> On Wed, May 21, 2008 at 10:49:16AM +0200, Enno Gottox Boland wrote:
> > 2008/5/21, Szabolcs Nagy <[EMAIL PROTECTED]>:
> > > in config.h referencing tags has changed in rules but not in keys.
> > Yes, arg has discussed yesterday if it's possible to change const char
> > *arg to void *arg. if this works, i'll change the key behavior too.
>
>
> Ok, I won't touch the code until the evening today, so feel free
> to use the (int[]) 1 syntax, we are going to change the
> argument of Key-functions to void *.
>
>
> > > the (1 << tagnum) in rules is a bit nasty
> > > it is probably nicer to do the shifting in setup();
> > you mean in applyrules? - No I don't think so. It adds much more
> > flexibility. You can define bitmasks as 0b10001 to tag a client to the
> > first and the fifth tag or you can use ~0 to make it "sticky".
>
>
> I agree, that allows also to get rid of cloned rules.
>
>
> > > instead of
> > > i < LENGTH(tags) && i < sizeof(int) * 8;
> > > what about checking once
> > > if(LENGTH(tags) > sizeof(int) * CHAR_BIT)
> > > eprint("Maximum number of tags: %d\n", sizeof(int) * CHAR_BIT);
> > > in setup();
> > The problem about this is it denies users from using one config.h with
> > many tags on different architectures. Furthermore I wouldn't check
> > this at runtime but at compiletime. (maybe we can use "#warning" as
> > compromise)
>
>
> Well, regarding to
>
> http://coding.derkeiler.com/Archive/C_CPP/comp.lang.c/2005-01/1697.html
>
> a compile time evaluation isn't possible. So I think we should
> stick to Szabolcs proposal to reject the setup in setup():
>
> if(sizeof(unsigned int) * CHAR_BIT < LENGTH(tags))
> eprint("error: number of tags is restricted to: %u\n",
> sizeof(unsigned int) * CHAR_BIT);
>
> Usually nobody will use more than 16 tags imho, so that we
> should not expect a problem here if sizeof(int) is only 2 on
> some exotic hosts.
>
> Kind regards,
>
> --
> Anselm R. Garbe >< http://www.suckless.org/ >< GPG key: 0D73F361
>
>
--
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 13:04:59 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 13:04:59 2008 +0200
@@ -51,6 +51,7 @@
#define LENGTH(x) (sizeof x / sizeof x[0])
#define MAXTAGLEN 16
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
+#define TAGMASK ((int)((1LL << LENGTH(tags) + 1) - 1))
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
@@ -68,7 +69,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 +108,7 @@
const char *class;
const char *instance;
const char *title;
- const char *tag;
+ unsigned int tags;
Bool isfloating;
} Rule;
@@ -198,7 +199,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 +219,7 @@
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 */
Client *clients = NULL;
Client *sel = NULL;
Client *stack = NULL;
@@ -231,14 +232,15 @@
/* configuration, allows nested code to access above variables */
#include "config.h"
-#define TAGSZ (LENGTH(tags) * sizeof(Bool))
+
+/* check if all tags will fit into a unsigned int bitarray. */
+static char tags_is_a_sign_that_your_IQ[sizeof(int) * 8 < LENGTH(tags) ? -1 :
1];
/* function implementations */
void
applyrules(Client *c) {
unsigned int i;
- Bool matched = False;
Rule *r;
XClassHint ch = { 0 };
@@ -250,18 +252,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
@@ -501,13 +500,13 @@
for(c = stack; c && !isvisible(c); c = c->snext);
for(i = 0; i < LENGTH(tags); 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 +860,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 +885,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 +939,6 @@
XWindowChanges wc;
c = emallocz(sizeof(Client));
- c->tags = emallocz(TAGSZ);
c->win = w;
/* geometry */
@@ -980,7 +973,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)
@@ -1396,11 +1389,6 @@
if(!dc.font.set)
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;
-
/* init bar */
for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
w = textw(layouts[i].symbol);
@@ -1460,14 +1448,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 << idxoftag(arg) & TAGMASK : TAGMASK;
arrange();
+
}
unsigned int
@@ -1575,27 +1560,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 +1605,6 @@
focus(NULL);
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
setclientstate(c, WithdrawnState);
- free(c->tags);
free(c);
XSync(dpy, False);
XSetErrorHandler(xerror);
@@ -1771,8 +1753,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 << idxoftag(arg) & TAGMASK : TAGMASK;
arrange();
}