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:
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(®ex, r.regex, 0)) {
- if(!regexec(®ex, prop, 1, &tmpregm, 0))
- cext_strlcat(result, r.tags, sizeof(result));
- regfree(®ex);
+ if(!regexec(®ex, 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(®ex);
+ }
}
}
- 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
}