wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit dff6fb2502cec103edb8bc3fad2aa4143bb37165
parent d89153c109f7de77e0d82af996a31a648ac329d2
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Wed, 15 Mar 2006 09:02:25 +0100

began to store tags in a different way


Diffstat:
cmd/wm/client.c | 52++++++++++++++++++++++++++++++++++++++++++++--------
cmd/wm/fs.c | 28+++++++++++++++++-----------
cmd/wm/rule.c | 54+++++++++++++++++++++++++-----------------------------
cmd/wm/tag.c | 59+++++++++++++++++++++++++++++++++--------------------------
cmd/wm/wm.h | 10+++++++++-
rc/wmiirc | 2+-
6 files changed, 129 insertions(+), 76 deletions(-)

diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -215,6 +215,7 @@ draw_client(Client *c) { Draw d = { 0 }; char buf[512]; + unsigned int i; if(!c->nframe) return; /* might not have been attached atm */ @@ -242,7 +243,12 @@ draw_client(Client *c) d.rect.width = c->frame[c->sel]->rect.width; d.rect.height = bar_height(); d.notch = nil; - snprintf(buf, sizeof(buf), "%s | %s", c->tags, c->name); + buf[0] = 0; + for(i = 0; i < c->ntag; i++) { + cext_strlcat(buf, c->tag[i], sizeof(buf)); + cext_strlcat(buf, " | ", sizeof(buf)); + } + cext_strlcat(buf, c->name, sizeof(buf) - strlen(buf)); d.data = buf; blitz_drawlabel(dpy, &d); blitz_drawborder(dpy, &d); @@ -315,20 +321,22 @@ manage_client(Client *c) { Tag *t; Client *trans; + unsigned int i; - if(c->trans && (trans = win2client(c->trans))) - cext_strlcpy(c->tags, trans->tags, sizeof(c->tags)); + if(c->trans && (trans = win2client(c->trans))) { + for(i = 0; i < trans->ntag; i++) + cext_strlcpy(c->tag[i], trans->tag[i], sizeof(c->tag[i])); + c->ntag = trans->ntag; + } else match_tags(c); reparent_client(c, c->framewin, c->rect.x, c->rect.y); t = ntag ? tag[sel] : alloc_tag(def.tag); - if(c->tags[0] == 0) - cext_strlcpy(c->tags, t->name, sizeof(c->tags)); - else if(!strncmp(c->tags, "~", 2)) { - c->tags[1] = ' '; - cext_strlcpy(c->tags + 2, t->name, sizeof(c->tags) - 2); + if(!c->ntag) { + c->ntag++; + cext_strlcpy(c->tag[0], t->name, sizeof(c->tag[0])); } update_tags(); @@ -561,3 +569,31 @@ cid2index(unsigned short id) return i; return -1; } + +void +client2tags(Client *c, char *tags, unsigned int tagsz) +{ + unsigned int i, len = 0, l; + + tags[0] = 0; + for(i = 0; i < c->ntag; i++) { + l = strlen(c->tag[i]); + if(len + l + 1 >= tagsz) + return; + if(len) + tags[len++] = ' '; + memcpy(tags + len, c->tag[i], l); + len += l; + tags[len] = 0; + } +} + +Bool +clienthastag(Client *c, const char *t) +{ + unsigned int i; + for(i = 0; i < c->ntag; i++) + if(!strncmp(c->tag[i], t, sizeof(c->tag[i]))) + return True; + return False; +} diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c @@ -522,10 +522,12 @@ type2stat(Stat *stat, char *wname, Qid *dir) switch(dir_type) { case FsDclient: f = tag[dir_i1]->area[dir_i2]->frame[dir_i3]; - return mkstat(stat, dir, wname, strlen(f->client->tags), DMREAD | DMWRITE); + client2tags(f->client, buf, sizeof(buf)); + return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE); break; case FsDGclient: - return mkstat(stat, dir, wname, strlen(client[dir_i1]->tags), DMREAD | DMWRITE); + client2tags(client[dir_i1], buf, sizeof(buf)); + return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE); break; default: { @@ -1053,12 +1055,14 @@ xread(IXPConn *c, Fcall *fcall) case FsFtags: switch(m->qid.dir_type) { case FsDclient: - if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->tags))) - memcpy(p, tag[i1]->area[i2]->frame[i3]->client->tags, fcall->count); + client2tags(tag[i1]->area[i2]->frame[i3]->client, buf, sizeof(buf)); + if((fcall->count = strlen(buf))) + memcpy(p, buf, fcall->count); break; case FsDGclient: - if((fcall->count = strlen(client[i1]->tags))) - memcpy(p, client[i1]->tags, fcall->count); + client2tags(client[i1], buf, sizeof(buf)); + if((fcall->count = strlen(buf))) + memcpy(p, buf, fcall->count); break; default: for(i = 0; i < nctag; i++) { @@ -1254,10 +1258,10 @@ xwrite(IXPConn *c, Fcall *fcall) buf[fcall->count] = 0; if(m->qid.dir_type == FsDclient) { f = tag[i1]->area[i2]->frame[i3]; - cext_strlcpy(f->client->tags, buf, sizeof(f->client->tags)); + f->client->ntag = str2tags(buf, f->client->tag); } else - cext_strlcpy(client[i1]->tags, buf, sizeof(client[i1]->tags)); + client[i1]->ntag = str2tags(buf, client[i1]->tag); update_tags(); break; case FsFgeom: @@ -1373,9 +1377,11 @@ xwrite(IXPConn *c, Fcall *fcall) case FsFevent: if(fcall->count > sizeof(buf)) return Ebadvalue; - memcpy(buf, fcall->data, fcall->count); - buf[fcall->count] = 0; - write_event(buf); + if(fcall->count) { + memcpy(buf, fcall->data, fcall->count); + buf[fcall->count] = 0; + write_event(buf); + } break; default: return Enoperm; diff --git a/cmd/wm/rule.c b/cmd/wm/rule.c @@ -19,7 +19,8 @@ typedef struct { char regex[256]; - char tags[256]; + char tag[8][32]; + unsigned int ntag; } Rule; enum { @@ -57,7 +58,7 @@ parse(char *data, unsigned int *n) } else if(*p == '>') { mode = TAGS; - tags = rules[i].tags; + tags = rules[i].tag[0]; } break; case PATTERN: @@ -77,9 +78,14 @@ parse(char *data, unsigned int *n) i++; } else { - if(!strlen(tags) && (*p == ' ' || *p == '\t')) - continue; /* skip prefixed whitespaces */ - *tags = *p; + if(*p == ' ' || *p == '\t') { + if(*tags == 0) + continue; /* skip prefixed whitespaces */ + *tags = 0; + tags = rules[i].tag[++rules[i].ntag]; + } + else + *tags = *p; tags++; } break; @@ -89,24 +95,26 @@ parse(char *data, unsigned int *n) } -static char * -match(Rule *rule, unsigned int nrule, char *prop) +static void +match(Rule *rule, unsigned int rulesz, Client *c, const char *prop) { - unsigned int i; + unsigned int i, j; regex_t regex; regmatch_t tmpregm; - static char result[256]; - result[0] = 0; - for(i = 0; i < nrule; i++) { + c->ntag = 0; + for(i = 0; i < rulesz && c->ntag < 8; i++) { Rule r = rule[i]; if(!regcomp(&regex, r.regex, 0)) { - if(!regexec(&regex, prop, 1, &tmpregm, 0)) - cext_strlcat(result, r.tags, sizeof(result)); - regfree(&regex); + if(!regexec(&regex, prop, 1, &tmpregm, 0)) { + for(j = 0; c->ntag < 8 && j < r.ntag; j++) { + cext_strlcpy(c->tag[c->ntag], r.tag[j], sizeof(c->tag[c->ntag])); + c->ntag++; + } + regfree(&regex); + } } } - return result; } void @@ -114,24 +122,12 @@ match_tags(Client *c) { unsigned int n; Rule *rules; - char *tags; if(!def.rules) return; rules = parse(def.rules, &n); - c->tags[0] = 0; - tags = match(rules, n, c->name); - if(strlen(tags)) { - if(strlen(c->tags)) - cext_strlcat(c->tags, " ", sizeof(c->tags)); - cext_strlcat(c->tags, tags, sizeof(c->tags)); - } - tags = match(rules, n, c->classinst); - if(strlen(tags)) { - if(strlen(c->tags)) - cext_strlcat(c->tags, " ", sizeof(c->tags)); - cext_strlcat(c->tags, tags, sizeof(c->tags)); - } + match(rules, n, c, c->name); + match(rules, n, c, c->classinst); free(rules); } diff --git a/cmd/wm/tag.c b/cmd/wm/tag.c @@ -151,7 +151,7 @@ get_tag(char *name) unsigned int i, n = 0, j, nt; Tag *t = nil; char buf[256]; - char *tags[128]; + char *tags[8]; for(i = 0; i < ntag; i++) { t = tag[i]; @@ -160,18 +160,20 @@ get_tag(char *name) } cext_strlcpy(buf, name, sizeof(buf)); - nt = cext_tokenize(tags, 128, buf, '+'); + nt = cext_tokenize(tags, 8, buf, ' '); for(i = 0; i < nclient; i++) for(j = 0; j < nt; j++) - if(strstr(client[i]->tags, tags[j])) + if(clienthastag(client[i], tags[j])) { n++; + break; + } if(!n) return nil; t = alloc_tag(name); for(i = 0; i < nclient; i++) for(j = 0; j < nt; j++) - if(strstr(client[i]->tags, tags[j]) && !clientoftag(t, client[i])) + if(clienthastag(client[i], tags[j]) && !clientoftag(t, client[i])) attach_totag(t, client[i]); return t; } @@ -223,22 +225,19 @@ clientoftag(Tag *t, Client *c) void update_tags() { - unsigned int i, j, k, nt; + unsigned int i, j; char buf[256]; - char *tags[128]; char **newctag = nil; unsigned int newctagsz = 0; unsigned int nnewctag = 0; for(i = 0; i < nclient; i++) { - cext_strlcpy(buf, client[i]->tags, sizeof(buf)); - nt = cext_tokenize(tags, 128, buf, ' '); - for(k = 0; k < nt; k++) { - if(!strncmp(tags[k], "~", 2)) /* magic floating tag */ + for(j = 0; j < client[i]->ntag; j++) { + if(!strncmp(client[i]->tag[j], "~", 2)) /* magic floating tag */ continue; - if(!istag(newctag, nnewctag, tags[k])) { - newctag = (char **)cext_array_attach((void **)newctag, strdup(tags[k]), + if(!istag(newctag, nnewctag, client[i]->tag[j])) { + newctag = (char **)cext_array_attach((void **)newctag, strdup(client[i]->tag[j]), sizeof(char *), &newctagsz); nnewctag++; } @@ -266,20 +265,14 @@ update_tags() for(i = 0; i < nclient; i++) for(j = 0; j < ntag; j++) { - Bool detach = False, attach = False; - cext_strlcpy(buf, tag[j]->name, sizeof(buf)); - nt = cext_tokenize(tags, 128, buf, '+'); - for(k = 0; k < nt; k++) { - if(strstr(client[i]->tags, tags[k]) && !clientoftag(tag[j], client[i])) - attach = True; + if(!clienthastag(client[i], tag[j]->name)) { + if(clientoftag(tag[j], client[i])) + detach_fromtag(tag[j], client[i]); + } + else { + if(!clientoftag(tag[j], client[i])) + attach_totag(tag[j], client[i]); } - if(!strstr(client[i]->tags, tag[j]->name) && clientoftag(tag[j], client[i])) - detach = True; - - if(detach) - detach_fromtag(tag[j], client[i]); - else if(attach) - attach_totag(tag[j], client[i]); } if(!ntag && nctag) @@ -306,7 +299,7 @@ attach_totag(Tag *t, Client *c) { Area *a; - if(c->trans || strchr(c->tags, '~')) + if(c->trans || clienthastag(c, "~")) a = t->area[0]; else a = t->area[t->sel]; @@ -356,3 +349,17 @@ restack_tag(Tag *t) if(n) XRestackWindows(dpy, wins, n); } + +unsigned int +str2tags(const char *stags, char tags[MAX_TAGS][MAX_TAGLEN]) +{ + unsigned int i, n; + char buf[256]; + char *toks[MAX_TAGS]; + + cext_strlcpy(buf, stags, sizeof(buf)); + n = cext_tokenize(toks, MAX_TAGS, buf, ' '); + for(i = 0; i < n; i++) + cext_strlcpy(tags[i], toks[i], MAX_TAGLEN); + return n; +} diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -73,6 +73,9 @@ enum { FsFmode }; +#define MAX_TAGS 8 +#define MAX_TAGLEN 32 + #define DEF_BORDER 3 #define DEF_SNAP 20 @@ -116,7 +119,8 @@ struct Frame { struct Client { unsigned short id; char name[256]; - char tags[256]; + char tag[MAX_TAGS][MAX_TAGLEN]; + unsigned int ntag; char classinst[256]; int proto; unsigned int border; @@ -254,6 +258,9 @@ void send2area_client(Client *c, char *arg); void resize_all_clients(); void focus(Client *c); int cid2index(unsigned short id); +void tags4client(Client *c, const char *tags); +void client2tags(Client *c, char *tags, unsigned int tagsz); +Bool clienthastag(Client *c, const char *t); /* event.c */ void init_x_event_handler(); @@ -302,6 +309,7 @@ void detach_fromtag(Tag *t, Client *c); void attach_totag(Tag *t, Client *c); Client *sel_client_of_tag(Tag *t); void restack_tag(Tag *t); +unsigned int str2tags(const char *stags, char tags[MAX_TAGS][MAX_TAGLEN]); /* wm.c */ void scan_wins(); diff --git a/rc/wmiirc b/rc/wmiirc @@ -7,7 +7,7 @@ xwrite() { } proglist() { - find -L `echo "$@" | tr ':' '\n' | uniq` -perm -u+x -type f -print | + find `echo "$@" | tr ':' '\n' | uniq` -perm -u+x -type f -print | sed 's,^.*/,, ' | sort | uniq }