wmii

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

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:
cmd/wm/area.c | 6++++++
cmd/wm/client.c | 8+++++---
cmd/wm/fs.c | 132++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
cmd/wm/tag.c | 45++++++++++++++++++++++++++++++++++++++++++++-
cmd/wm/wm.c | 7++++---
cmd/wm/wm.h | 12+++++++++---
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();