commit 7e8ab56d9158d5235a5f90d96abb96bcb4c30474
parent dcc6e16302cc4af440b9fa4f90ec0f22077fdd71
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Sun, 5 Mar 2006 19:20:27 +0100
added /tags namespace, added .../tags files to client namespace, added tag display in draw_client
Diffstat:
6 files changed, 155 insertions(+), 55 deletions(-)
diff --git a/cmd/wm/area.c b/cmd/wm/area.c
@@ -126,10 +126,16 @@ attach_toarea(Area *a, Client *c)
a->frame = (Frame **)cext_array_attach(
(void **)a->frame, f, sizeof(Frame *), &a->framesz);
a->nframe++;
+ if(!strstr(c->tags, a->tag->name)) {
+ if(c->tags[0] != 0)
+ cext_strlcat(c->tags, " ", sizeof(c->tags));
+ cext_strlcat(c->tags, a->tag->name, sizeof(c->tags));
+ }
if(area2index(a)) /* column */
arrange_area(a);
else /* floating */
resize_client(c, &f->rect, nil, False);
+ update_ctags();
}
void
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -236,6 +236,7 @@ void
draw_client(Client *c)
{
Draw d = { 0 };
+ char buf[512];
d.align = WEST;
d.drawable = c->framewin;
@@ -259,7 +260,8 @@ draw_client(Client *c)
d.rect.width = c->frame->rect.width;
d.rect.height = bar_height();
d.notch = nil;
- d.data = c->name;
+ snprintf(buf, sizeof(buf), "%s | %s", c->tags, c->name);
+ d.data = buf;
blitz_drawlabel(dpy, &d);
XSync(dpy, False);
}
@@ -341,7 +343,7 @@ attach_client(Client *c)
{
Tag *t;
if(!ntag)
- t = alloc_tag();
+ t = alloc_tag("new");
else
t = tag[sel];
@@ -520,7 +522,7 @@ sendtotag_client(Client *c, char *arg)
Client *to;
if(!strncmp(arg, "new", 4))
- t = alloc_tag();
+ t = alloc_tag("new");
else if(!strncmp(arg, "sel", 4))
t = tag[sel];
else {
diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c
@@ -37,39 +37,41 @@ static char Enocommand[] = "command not supported";
* /def/snap FsFsnap 0..n
* /def/font FsFfont xlib font name
* /def/selcolors FsFselcolors sel color
- * /def/normcolors FsFnormcolors normal colors
+ * /def/normcolors FsFnormcolors normal colors
* /keys/ FsDkeys
* /keys/foo FsFkey
+ * /tags/ FsDtags
+ * /tags/foo FsFtag
* /bar/ FsDbar
- * /bar/expand FsFexpand id of expandable label
+ * /bar/expand FsFexpand id of expandable label
* /bar/new/ FsDlabel
* /bar/1/ FsDlabel
- * /bar/1/data FsFdata <arbitrary data which gets displayed>
+ * /bar/1/data FsFdata <arbitrary data which gets displayed>
* /bar/1/colors FsFcolors <#RRGGBB> <#RRGGBB> <#RRGGBB>
* /event FsFevent
- * /ctl FsFctl command interface (root)
- * /ws/ FsDws returns new tag
- * /ws/ FsDws tag
- * /ws/ctl FsFctl command interface (tag)
+ * /ctl FsFctl command interface (root)
+ * /ws/ FsDws returns new tag
+ * /ws/ FsDws tag
+ * /ws/ctl FsFctl command interface (tag)
* /ws/sel/ FsDarea
- * /ws/float/ FsDarea floating clients in area 0
- * /ws/float/ctl FsFctl command interface (area)
- * /ws/float/mode FsFmode col mode
+ * /ws/float/ FsDarea floating clients in area 0
+ * /ws/float/ctl FsFctl command interface (area)
+ * /ws/float/mode FsFmode col mode
* /ws/float/sel/ FsDclient
* /ws/float/1/ FsDclient
- * /ws/float/1/name FsFname name of client
- * /ws/float/1/tag FsFtag tag of client
- * /ws/float/1/geom FsFgeom geometry of client
- * /ws/float/1/ctl FsFctl command interface (client)
+ * /ws/float/1/name FsFname name of client
+ * /ws/float/1/tags FsFtags tags of client
+ * /ws/float/1/geom FsFgeom geometry of client
+ * /ws/float/1/ctl FsFctl command interface (client)
* /ws/1/ FsDarea
- * /ws/1/ctl FsFctl command interface (area)
- * /ws/1/mode FsFmode col mode
+ * /ws/1/ctl FsFctl command interface (area)
+ * /ws/1/mode FsFmode col mode
* /ws/1/1/sel/ FsDclient
* /ws/1/1/1/ FsDclient
- * /ws/1/1/name FsFname name of client
- * /ws/1/1/tag FsFtag tag of client
- * /ws/1/1/geom FsFgeom geometry of client
- * /ws/1/1/ctl FsFctl command interface (client)
+ * /ws/1/1/name FsFname name of client
+ * /ws/1/1/tags FsFtags tag of client
+ * /ws/1/1/geom FsFgeom geometry of client
+ * /ws/1/1/ctl FsFctl command interface (client)
*/
Qid root_qid;
@@ -152,6 +154,7 @@ qid2name(Qid *qid)
case FsDroot: return "/"; break;
case FsDdef: return "def"; break;
case FsDkeys: return "keys"; break;
+ case FsDtags: return "tags"; break;
case FsDbar: return "bar"; break;
case FsDws:
if(i1 == -1)
@@ -216,10 +219,10 @@ qid2name(Qid *qid)
return nil;
return "name";
break;
- case FsFtag:
+ case FsFtags:
if(i1 == -1 || i2 == -1 || i3 == -1)
return nil;
- return "tag";
+ return "tags";
break;
case FsFmode:
if(i1 == -1 || i2 == -1)
@@ -248,6 +251,12 @@ name2type(char *name, unsigned char dir_type)
case FsDbar: return FsDlabel; break;
}
}
+ if(!strncmp(name, "tags", 5)) {
+ switch(dir_type) {
+ case FsDroot: return FsDtags; break;
+ case FsDclient: return FsFtags; break;
+ }
+ }
if(!strncmp(name, "bar", 4))
return FsDbar;
if(!strncmp(name, "def", 4))
@@ -262,8 +271,6 @@ name2type(char *name, unsigned char dir_type)
return FsFsnap;
if(!strncmp(name, "name", 5))
return FsFname;
- if(!strncmp(name, "tag", 4))
- return FsFtag;
if(!strncmp(name, "border", 7))
return FsFborder;
if(!strncmp(name, "geom", 5))
@@ -284,6 +291,8 @@ name2type(char *name, unsigned char dir_type)
return FsFmode;
if(name2key(name))
return FsFkey;
+ if(has_ctag(name))
+ return FsFtags;
if(!strncmp(name, "sel", 4))
goto dyndir;
i = (unsigned short) cext_strtonum(name, 0, 0xffff, &err);
@@ -317,16 +326,11 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
*new = root_qid;
break;
case FsDdef:
- new->type = IXP_QTDIR;
- new->path = mkqpath(FsDdef, 0, 0, 0);
- break;
case FsDkeys:
- new->type = IXP_QTDIR;
- new->path = mkqpath(FsDkeys, 0, 0, 0);
- break;
+ case FsDtags:
case FsDbar:
new->type = IXP_QTDIR;
- new->path = mkqpath(FsDbar, 0, 0, 0);
+ new->path = mkqpath(type, 0, 0, 0);
break;
case FsDlabel:
new->type = IXP_QTDIR;
@@ -347,7 +351,7 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
new->type = IXP_QTDIR;
if(!strncmp(wname, "new", 4)) {
if(iswalk) {
- Tag *p = alloc_tag();
+ Tag *p = alloc_tag(wname);
new->path = mkqpath(FsDws, p->id, 0, 0);
}
else
@@ -426,7 +430,7 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
break;
case FsFgeom:
case FsFname:
- case FsFtag:
+ case FsFtags:
if(dir_i1 == -1 || dir_i2 == -1 || dir_i3 == -1)
return -1;
new->type = IXP_QTFILE;
@@ -581,6 +585,7 @@ type2stat(Stat *stat, char *wname, Qid *dir)
case FsDws:
case FsDdef:
case FsDkeys:
+ case FsDtags:
case FsDbar:
case FsDlabel:
case FsDroot:
@@ -608,9 +613,16 @@ type2stat(Stat *stat, char *wname, Qid *dir)
f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
return mkstat(stat, dir, wname, strlen(f->client->name), DMREAD);
break;
- case FsFtag:
- f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
- return mkstat(stat, dir, wname, strlen(f->client->tag), DMREAD | DMWRITE);
+ case FsFtags:
+ 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);
+ break;
+ case FsDtags:
+ return mkstat(stat, dir, wname, 0, 0);
+ break;
+ }
break;
case FsFkey:
return mkstat(stat, dir, wname, 0, DMWRITE);
@@ -712,6 +724,7 @@ xread(IXPConn *c, Fcall *fcall)
len += type2stat(&stat, "def", &m->qid);
len += type2stat(&stat, "keys", &m->qid);
len += type2stat(&stat, "bar", &m->qid);
+ len += type2stat(&stat, "tags", &m->qid);
len += type2stat(&stat, "new", &m->qid);
for(i = 0; i < ntag; i++) {
if(i == sel)
@@ -754,6 +767,24 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat);
}
break;
+ case FsDtags:
+ /* jump to offset */
+ len = 0;
+ for(i = 0; i < nctag; i++) {
+ len += type2stat(&stat, ctag[i], &m->qid);
+ if(len <= fcall->offset)
+ continue;
+ break;
+ }
+ /* offset found, proceeding */
+ for(; i < nctag; i++) {
+ len = type2stat(&stat, ctag[i], &m->qid);
+ if(fcall->count + len > fcall->iounit)
+ break;
+ fcall->count += len;
+ p = ixp_enc_stat(p, &stat);
+ }
+ break;
case FsDbar:
/* jump to offset */
len = type2stat(&stat, "expand", &m->qid);
@@ -851,6 +882,8 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "bar", &m->qid);
p = ixp_enc_stat(p, &stat);
+ fcall->count += type2stat(&stat, "tags", &m->qid);
+ p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "new", &m->qid);
p = ixp_enc_stat(p, &stat);
for(i = 0; i < ntag; i++) {
@@ -874,6 +907,15 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat);
}
break;
+ case FsDtags:
+ for(i = 0; i < nctag; i++) {
+ len = type2stat(&stat, ctag[i], &m->qid);
+ if(fcall->count + len > fcall->iounit)
+ break;
+ fcall->count += len;
+ p = ixp_enc_stat(p, &stat);
+ }
+ break;
case FsDbar:
fcall->count = type2stat(&stat, "expand", &m->qid);
p = ixp_enc_stat(p, &stat);
@@ -944,7 +986,7 @@ xread(IXPConn *c, Fcall *fcall)
case FsDclient:
fcall->count += type2stat(&stat, "name", &m->qid);
p = ixp_enc_stat(p, &stat);
- fcall->count += type2stat(&stat, "tag", &m->qid);
+ fcall->count += type2stat(&stat, "tags", &m->qid);
p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "geom", &m->qid);
p = ixp_enc_stat(p, &stat);
@@ -980,9 +1022,9 @@ xread(IXPConn *c, Fcall *fcall)
if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->name)))
memcpy(p, tag[i1]->area[i2]->frame[i3]->client->name, fcall->count);
break;
- case FsFtag:
- if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->tag)))
- memcpy(p, tag[i1]->area[i2]->frame[i3]->client->tag, fcall->count);
+ case FsFtags:
+ if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->tags)))
+ memcpy(p, tag[i1]->area[i2]->frame[i3]->client->tags, fcall->count);
break;
case FsFexpand:
snprintf(buf, sizeof(buf), "%u", iexpand);
@@ -1126,12 +1168,12 @@ xwrite(IXPConn *c, Fcall *fcall)
def.border = i;
resize_all_clients();
break;
- case FsFtag:
+ case FsFtags:
f = tag[i1]->area[i2]->frame[i3];
- if(fcall->count > sizeof(f->client->tag))
- return "tag value too long";
- memcpy(f->client->tag, fcall->data, fcall->count);
- /* TODO: update_tags */
+ if(fcall->count > sizeof(f->client->tags))
+ return "tags value too long";
+ memcpy(f->client->tags, fcall->data, fcall->count);
+ update_ctags();
break;
case FsFgeom:
f = tag[i1]->area[i2]->frame[i3];
diff --git a/cmd/wm/tag.c b/cmd/wm/tag.c
@@ -11,12 +11,13 @@
#include "wm.h"
Tag *
-alloc_tag()
+alloc_tag(char *name)
{
static unsigned short id = 1;
Tag *t = cext_emallocz(sizeof(Tag));
t->id = id++;
+ cext_strlcpy(t->name, name, sizeof(t->name));
alloc_area(t);
alloc_area(t);
tag = (Tag **)cext_array_attach((void **)tag, t, sizeof(Tag *), &tagsz);
@@ -156,3 +157,45 @@ select_tag(char *arg)
if((c = sel_client_of_tag(tag[new])))
focus_client(c);
}
+
+Bool
+has_ctag(char *tag)
+{
+ unsigned int i;
+ for(i = 0; i < nctag; i++)
+ if(!strncmp(ctag[i], tag, strlen(ctag[i])))
+ return True;
+ return False;
+}
+
+void
+update_ctags()
+{
+ unsigned int i;
+ char buf[256];
+ char *tags[128];
+
+ for(i = 0; i < nctag; i++) {
+ free(ctag[i]);
+ ctag[i] = nil;
+ }
+ nctag = 0;
+
+ for(i = 0; i < nclient; i++) {
+ unsigned int j, k;
+ cext_strlcpy(buf, client[i]->tags, sizeof(buf));
+ fprintf(stderr, "update_ctags: %s\n", buf);
+ j = cext_tokenize(tags, 128, buf, ' ');
+ fprintf(stderr, "update_ctags: %d\n", j);
+ for(k = 0; k < j; k++) {
+ fprintf(stderr, "update_ctags: tag=%s\n", tags[k]);
+ if(!has_ctag(tags[k])) {
+ ctag = (char **)cext_array_attach((void **)ctag, strdup(tags[k]),
+ sizeof(char *), &ctagsz);
+ nctag++;
+ }
+ }
+ }
+ for(i = 0; i < nctag; i++)
+ fprintf(stderr, "tag=%s\n", ctag[i]);
+}
diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c
@@ -311,8 +311,9 @@ main(int argc, char *argv[])
ixp_server_open_conn(&srv, ConnectionNumber(dpy), check_x_event, nil);
init_x_event_handler();
- ntag = nclient = tagsz = clientsz = sel = 0;
+ nctag = ctagsz = ntag = nclient = tagsz = clientsz = sel = 0;
tag = nil;
+ ctag = nil;
client = nil;
key = nil;
@@ -356,8 +357,8 @@ main(int argc, char *argv[])
XMapRaised(dpy, winbar);
draw_bar();
- alloc_tag(); /* tag 0 */
- alloc_tag(); /* tag 1 */
+ alloc_tag("scratch");
+ alloc_tag("default");
scan_wins();
/* main event loop */
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -57,6 +57,7 @@ enum {
FsDarea,
FsDclient,
FsDkeys,
+ FsDtags,
FsDbar,
FsDlabel,
FsFexpand,
@@ -73,7 +74,7 @@ enum {
FsFevent,
FsFctl,
FsFname,
- FsFtag,
+ FsFtags,
FsFmode
};
@@ -118,7 +119,7 @@ struct Frame {
struct Client {
char name[256];
- char tag[256];
+ char tags[256];
int proto;
unsigned int border;
Bool destroyed;
@@ -175,6 +176,9 @@ Label **label;
unsigned int nlabel;
unsigned int labelsz;
unsigned int iexpand;
+char **ctag;
+unsigned int nctag;
+unsigned int ctagsz;
Display *dpy;
IXPServer *ixps;
@@ -281,13 +285,15 @@ void ungrab_mouse(Window w, unsigned long mod, unsigned int button);
char *warp_mouse(char *arg);
/* tag.c */
-Tag *alloc_tag();
+Tag *alloc_tag(char *name);
char *destroy_tag(Tag *t);
void focus_tag(Tag *t);
XRectangle *rectangles(unsigned int *num);
int tid2index(unsigned short id);
void select_tag(char *arg);
int tag2index(Tag *t);
+Bool has_ctag(char *tag);
+void update_ctags();
/* wm.c */
void scan_wins();