Re: [dwm] using bitaray for tags (PATCH)
On Thu, May 22, 2008 at 9:37 PM, Szabolcs Nagy <[EMAIL PROTECTED]> wrote: > On 5/22/08, David Tweed <[EMAIL PROTECTED]> wrote: > ..but (if eg int is 32 bit and we have 32 tags then) 1<<32 is 0, and > -1 is "all ones" in binary (guaranteed by the c standard) Ah, my mistake. I've spent too long writing 64-bit bitvector manipulation on 64-bit platforms so I jumped to assuming that support up to 64 tags was wanted on that architecture. -- cheers, dave tweed__ [EMAIL PROTECTED] Rm 124, School of Systems Engineering, University of Reading. "while having code so boring anyone can maintain it, use Python." -- attempted insult seen on slashdot
Re: [dwm] using bitaray for tags (PATCH)
On 5/22/08, David Tweed <[EMAIL PROTECTED]> wrote: > #define TAGMASK ((int)((1LL << LENGTH(tags) + 1) - 1)) > > Incidentally, I think in the alphabet soup misdesign of C numeric > constants, I suspect the code probably wants 1ULL and given long long > is 64-bits and int is 32-bit on most 64-bit Linux platforms I don't > understand the cast here. imho the LL (and the + 1 ?) is not needed i guess the purpose of the LL here was to make sure it works for the "all ones" case (so it was enough that long long has at least one more bits than int, the signedness does not matter) ..but (if eg int is 32 bit and we have 32 tags then) 1<<32 is 0, and -1 is "all ones" in binary (guaranteed by the c standard)
Re: [dwm] using bitaray for tags (PATCH)
On Wed, May 21, 2008 at 10:21 AM, Szabolcs Nagy <[EMAIL PROTECTED]> wrote: > probably limiting LENGTH(tags) to 16 is better (simpler, without too > much compromise (i doubt anyone uses more than 16 tags or X on an > architecture with less int bits)) I have 26 tags, partly because I put eg gnuplot windows, xdvi windows, graphical debugger windows, etc, onto their own tags so I can toggle viewing various combinations of them. The patch at the end of this thread has #define TAGMASK ((int)((1LL << LENGTH(tags) + 1) - 1)) Incidentally, I think in the alphabet soup misdesign of C numeric constants, I suspect the code probably wants 1ULL and given long long is 64-bits and int is 32-bit on most 64-bit Linux platforms I don't understand the cast here. -- cheers, dave tweed__ [EMAIL PROTECTED] Rm 124, School of Systems Engineering, University of Reading. "while having code so boring anyone can maintain it, use Python." -- attempted insult seen on slashdot
Re: [dwm] using bitaray for tags (PATCH)
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 instancetitle 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[idxoft
Re: [dwm] using bitaray for tags (PATCH)
On (20/05/08 11:22), Kurt H Maier wrote: > To: dynamic window manager > From: Kurt H Maier <[EMAIL PROTECTED]> > > C has bitfield support inside structs: > > unsigned tagsapplied :8; > > and replace 8 with whatever value you want Not really with whatever value, only that values so whole variable will fit into int/long long > > Bitfields are a bad idea imo; code has to be changed pretty severely > to handle a varying-sized bitfield. You'd have to either limit the > number of tags a user can create or else do a lot of work to > generalize the code. > Yes, we solved this by not using variable-sized bitfields. ;) -- Premysl "Anydot" Hruby, http://www.redrum.cz/
Re: [dwm] using bitaray for tags (PATCH)
On 5/21/08, markus schnalke <[EMAIL PROTECTED]> wrote: > I read, that bit-arrays are not very portable between different > architectures. (It was in "The practice of programming", I think) it's not exactly a bit array (arbitrary number of bits implemented eg. as char array), it's only one int (with bit flags) this is portable (a possible caveat is that some bit operations on negative values are implementation defined by c89 (eg. -1 >> 1) so unsigned int is recommended in those cases)
Re: [dwm] using bitaray for tags (PATCH)
On Wed, May 21, 2008 at 12:14:27PM +0200, Premysl Hruby wrote: > That's the reason why i wrote it as macros. That bitops can also be > written as inline functions, without any harm to binary size or > performance. > > And yes, with bitarrays there are some portability issues. But asside of > limiting number of possible tags, there's no portability downside for > dwm, imho. (it will compile, but maximum of tags is architecture > dependent) Well, if someone needs more than 32 tags, buy a 64bit machine. We should definately get sponsored by the hardware industry at some point. ;) dwm encourages users to buy bigger screens and 64bit hardware. Kind regards, -- Anselm R. Garbe >< http://www.suckless.org/ >< GPG key: 0D73F361
Re: [dwm] using bitaray for tags (PATCH)
On (21/05/08 12:06), markus schnalke wrote: > To: dwm@suckless.org > From: markus schnalke <[EMAIL PROTECTED]> > Subject: Re: [dwm] using bitaray for tags (PATCH) > Mail-Followup-To: dwm@suckless.org > User-Agent: Mutt/1.5.13 (2006-08-11) > Reply-To: dynamic window manager > List-Id: dynamic window manager > > Premysl Hruby <[EMAIL PROTECTED]> wrote: > > > > This is realization of Gottox's proposal discuted on IRC today. > > It handles tags not as Bool [], but as bit-array saved in int. > > I read, that bit-arrays are not very portable between different > architectures. (It was in "The practice of programming", I think) > > Maybe this is not relevant here; also I cannot recall the exact > explanaition, why one should avoid it. > Please check if there is any thruth in that statement. > > > Second, I want to mention, that bit-shifts might look really leet, but > _do_ obfuscate, what could be written much more clearly! > > Please stick to _clear_ code. > > > meillo That's the reason why i wrote it as macros. That bitops can also be written as inline functions, without any harm to binary size or performance. And yes, with bitarrays there are some portability issues. But asside of limiting number of possible tags, there's no portability downside for dwm, imho. (it will compile, but maximum of tags is architecture dependent) -- Premysl "Anydot" Hruby, http://www.redrum.cz/
Re: [dwm] using bitaray for tags (PATCH)
Premysl Hruby <[EMAIL PROTECTED]> wrote: > > This is realization of Gottox's proposal discuted on IRC today. > It handles tags not as Bool [], but as bit-array saved in int. I read, that bit-arrays are not very portable between different architectures. (It was in "The practice of programming", I think) Maybe this is not relevant here; also I cannot recall the exact explanaition, why one should avoid it. Please check if there is any thruth in that statement. Second, I want to mention, that bit-shifts might look really leet, but _do_ obfuscate, what could be written much more clearly! Please stick to _clear_ code. meillo signature.asc Description: Digital signature
Re: [dwm] using bitaray for tags (PATCH)
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
Re: [dwm] using bitaray for tags (PATCH)
2008/5/21, Premysl Hruby <[EMAIL PROTECTED]>: > tagmask can be #define: > > #define TAGMASK ((int)(1LL << (LENGTH(tags) + 1) - 1)) Thanks! Here's the updated patch -- 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 11:23:38 2008 +0200 @@ -19,6 +19,7 @@ Rule rules[] = { /* class instancetitle 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 11:23:38 2008 +0200 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,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 +70,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 +109,7 @@ const char *class; const char *instance; const char *title; - const char *tag; + unsigned int tags; Bool isfloating; } Rule; @@ -198,7 +200,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 +220,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 +233,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 +250,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 +310,7 @@ if(ev->window == barwin) { x = 0; - for(i = 0; i < LENGTH(tags); i++) { + for(i = 0; i < LENGTH(tags) && i < sizeof(int) * CHAR_BIT; i++) { x += textw(tags[i]); if(ev->x < x) { if(ev->button == Button1) { @@ -499,15 +496,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) * CHAR_BIT; 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 +858,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 +883,14 @@ Client *c; for(c = clients; c; c = c->next) - if(c->isurgent && c->tags[t]) + if(c->isurgen
Re: [dwm] using bitaray for tags (PATCH)
On 5/21/08, Enno Gottox Boland <[EMAIL PROTECTED]> wrote: >> 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 see (it would be so nice if c had 0bXXX binary int literals..) >> 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 i thought LENGTH(tags) > INT_BIT does not make sense, but in that case it's ok probably limiting LENGTH(tags) to 16 is better (simpler, without too much compromise (i doubt anyone uses more than 16 tags or X on an architecture with less int bits)) > this at runtime but at compiletime. (maybe we can use "#warning" as > compromise) sizeof(type) is not expanded in the preprocessor so #if LENGTH(tags) > INT_BIT #error too many tags.. #endif doesn't work (so compiletime check with compiler warning/error is not possible (imho)) > Anyway, the CHAR_BIT constant is a good idea. it's a bit paranoid, but more conform ;)
Re: [dwm] using bitaray for tags (PATCH)
On (21/05/08 08:27), Enno Gottox Boland wrote: > To: dynamic window manager > From: Enno Gottox Boland <[EMAIL PROTECTED]> > Subject: Re: [dwm] using bitaray for tags (PATCH) > Reply-To: dynamic window manager > List-Id: dynamic window manager > > Here's my version of a bitarray patch. Please review and comment. > tagmask can be #define: #define TAGMASK ((int)(1LL << (LENGTH(tags) + 1) - 1)) -Ph
Re: [dwm] using bitaray for tags (PATCH)
Hi! 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. > 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". > 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) Anyway, the CHAR_BIT constant is a good idea. Thanks! -- http://www.gnuffy.org - Real Community Distro http://www.gnuffy.org/index.php/GnuEm - Gnuffy on Ipaq (Codename Peggy)
Re: [dwm] using bitaray for tags (PATCH)
On 5/21/08, Enno Gottox Boland <[EMAIL PROTECTED]> wrote: > Here's my version of a bitarray patch. Please review and comment. in config.h referencing tags has changed in rules but not in keys. the (1 << tagnum) in rules is a bit nasty it is probably nicer to do the shifting in setup(); 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();
Re: [dwm] using bitaray for tags (PATCH)
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 instancetitle 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
Re: [dwm] using bitaray for tags (PATCH)
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 .
Re: [dwm] using bitaray for tags (PATCH)
On (20/05/08 11:22), Kurt H Maier wrote: > To: dynamic window manager > From: Kurt H Maier <[EMAIL PROTECTED]> > Subject: Re: [dwm] using bitaray for tags (PATCH) > Reply-To: dynamic window manager > List-Id: dynamic window manager > > C has bitfield support inside structs: > > unsigned tagsapplied :8; > > and replace 8 with whatever value you want > > Bitfields are a bad idea imo; code has to be changed pretty severely > to handle a varying-sized bitfield. You'd have to either limit the > number of tags a user can create or else do a lot of work to > generalize the code. > btw, addition of varying sized bitfield to my patch wouldn't be hard, only declaration of Client must be changed, and that #macros -- Premysl "Anydot" Hruby, http://www.redrum.cz/
Re: [dwm] using bitaray for tags (PATCH)
On (20/05/08 11:22), Kurt H Maier wrote: > To: dynamic window manager > From: Kurt H Maier <[EMAIL PROTECTED]> > Subject: Re: [dwm] using bitaray for tags (PATCH) > Reply-To: dynamic window manager > List-Id: dynamic window manager > > C has bitfield support inside structs: > > unsigned tagsapplied :8; > > and replace 8 with whatever value you want > > Bitfields are a bad idea imo; code has to be changed pretty severely > to handle a varying-sized bitfield. You'd have to either limit the > number of tags a user can create or else do a lot of work to > generalize the code. > Yes, I don't like varying-sized bitfield for this. But even on i386 we can get 64 tags maximum with long long, prety much for everyone :) -Ph -- Premysl "Anydot" Hruby, http://www.redrum.cz/
Re: [dwm] using bitaray for tags (PATCH)
C has bitfield support inside structs: unsigned tagsapplied :8; and replace 8 with whatever value you want Bitfields are a bad idea imo; code has to be changed pretty severely to handle a varying-sized bitfield. You'd have to either limit the number of tags a user can create or else do a lot of work to generalize the code. On Tue, May 20, 2008 at 11:15 AM, Premysl Hruby <[EMAIL PROTECTED]> wrote: > 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/ > -- # Kurt H Maier
[dwm] using bitaray for tags (PATCH)
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/ diff -r cd9fd0986555 dwm.c --- a/dwm.c Mon May 19 20:29:57 2008 +0100 +++ b/dwm.c Tue May 20 18:05:46 2008 +0200 @@ -51,6 +51,10 @@ #define LENGTH(x) (sizeof x / sizeof x[0]) #define MAXTAGLEN 16 #define MOUSEMASK (BUTTONMASK|PointerMotionMask) +#define TMASK(p)(1<<(p)) +#define ISSET(t,p) ((t)&TMASK(p)) +#define SET(t,p,v) {if(v) (t)|=TMASK(p); else (t)&= ~TMASK(p);} +#define TOGGLE(t,p) ((t) ^= TMASK(p)) /* enums */ enum { CurNormal, CurResize, CurMove, CurLast };/* cursor */ @@ -68,7 +72,7 @@ long flags; unsigned int bw, oldbw; Bool isbanned, isfixed, isfloating, isurgent; - Bool *tags; + int tags; Client *next; Client *prev; Client *snext; @@ -218,7 +222,7 @@ Atom wmatom[WMLast], netatom[NetLast]; Bool otherwm, readin; Bool running = True; -Bool *tagset[2]; +int tagset[2] = {1, 1}; /* after start, first tag is selected */ Client *clients = NULL; Client *sel = NULL; Client *stack = NULL; @@ -231,7 +235,6 @@ /* configuration, allows nested code to access above variables */ #include "config.h" -#define TAGSZ (LENGTH(tags) * sizeof(Bool)) /* function implementations */ @@ -251,7 +254,7 @@ && (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance { c->isfloating = r->isfloating; if(r->tag) { -c->tags[idxoftag(r->tag)] = True; +SET(c->tags, idxoftag(r->tag), 1); matched = True; } } @@ -261,7 +264,7 @@ if(ch.res_name) XFree(ch.res_name); if(!matched) - memcpy(c->tags, tagset[seltags], TAGSZ); + c->tags = tagset[seltags]; } void @@ -501,13 +504,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(ISSET(tagset[seltags], i)) { drawtext(tags[i], dc.sel, isurgent(i)); - drawsquare(c && c->tags[i], isoccupied(i), isurgent(i), dc.sel); + drawsquare(c && ISSET(c->tags, 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 && ISSET(c->tags, i), isoccupied(i), isurgent(i), dc.norm); } dc.x += dc.w; } @@ -861,7 +864,7 @@ Client *c; for(c = clients; c; c = c->next) - if(c->tags[t]) + if(ISSET(c->tags, t)) return True; return False; } @@ -886,19 +889,14 @@ Client *c; for(c = clients; c; c = c->next) - if(c->isurgent && c->tags[t]) + if(c->isurgent && ISSET(c->tags, 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 +943,6 @@ XWindowChanges wc; c = emallocz(sizeof(Client)); - c->tags = emallocz(TAGSZ); c->win = w; /* geometry */ @@ -980,7 +977,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 +1393,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); @@ -1464,9 +1456,11 @@ if(!sel) return; - for(i = 0; i < LENGTH(tags); i++) - sel->tags[i] = (arg == NULL); - sel->tags[idxoftag(arg)] = True; + if (arg) + sel->tags = TMASK(idxoftag(arg)); + else + sel->tags = TMASK(LENGTH(tags) + 1) - 1; + arrange(); } @@ -1580,22 +1574,20 @@ 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 */ + TOGGLE(sel->tags, i); + if (!sel->tags) /* at least one tag must be selected */ + SET(sel->tags, i, 1); arrange(); } void toggleview(const char *arg) { unsigned int i, j; - + 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 */ + TOGGLE(tagset[seltags], i); + if (!tagset[seltags]) + SET(tagset[seltags], i