From ff4fc9cee749084594914252b6b83a9c1456e39c Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Fri, 11 Jun 2010 04:18:40 -0400 Subject: [PATCH] Require that clients be given permission to activate themselves. --- alternative_wmiircs/plan9port/wmiirc | 5 + alternative_wmiircs/python/wmiirc.py | 9 +- cmd/wmii/client.c | 117 ++++--------- cmd/wmii/column.c | 75 ++++----- cmd/wmii/dat.h | 23 ++- cmd/wmii/debug.h | 4 +- cmd/wmii/ewmh.c | 36 +++- cmd/wmii/fns.h | 5 +- cmd/wmii/main.c | 10 +- cmd/wmii/message.c | 238 +++++++++++++++++---------- cmd/wmii/rule.c | 2 +- include/stuff/util.h | 1 + include/stuff/x11.h | 2 + lib/libstuff/Makefile | 1 + lib/libstuff/fmt/fmtbuf.c | 15 ++ man/wmii.1 | 34 +++- man/wmii.man1 | 24 ++- rc/wmiirc.sh | 30 ++-- 18 files changed, 364 insertions(+), 267 deletions(-) create mode 100644 lib/libstuff/fmt/fmtbuf.c diff --git a/alternative_wmiircs/plan9port/wmiirc b/alternative_wmiircs/plan9port/wmiirc index 58010597..fec03532 100755 --- a/alternative_wmiircs/plan9port/wmiirc +++ b/alternative_wmiircs/plan9port/wmiirc @@ -47,8 +47,13 @@ wmiir write /colrules <tags, sizeof c->tags); else { refree(&c->tagre); refree(&c->tagvre); } - strlcat(buf, &tags[n], sizeof buf); - - n = 0; - add = true; - if(buf[0] == '+') - n++; - else if(buf[0] == '-') { - n++; - add = false; - } - - found = false; + strlcat(buf, tags, sizeof buf); j = 0; - while(buf[n] && n < sizeof buf && j < 32) { + s = buf; + old = '+'; + while((cur = mask(&s, &add, &old))) { /* Check for regex. */ - if(buf[n] == '/') { - for(i=n+1; i < sizeof buf - 1; i++) - if(buf[i] == '/') break; - if(buf[i] == '/') { - i++; - if(buf[i] == '+' - || buf[i] == '-' - || buf[i] == '\0') { /* Don't be lenient */ - buf[i-1] = '\0'; - if(add) - reinit(&c->tagre, buf+n+1); - else - reinit(&c->tagvre, buf+n+1); - last = buf[i]; - buf[i] = '\0'; + if(cur[0] == '/') { + cur++; + *strchr(cur, '/') = '\0'; + if(add == '+') + reinit(&c->tagre, cur); + else if(add == '-') + reinit(&c->tagvre, cur); + } - found = true; - goto next; + trim(cur, " \t\r\n"); + if(!strcmp(cur, "~")) + c->floating = add ? On : Never; + else { + if(!strcmp(cur, "!") || !strcmp(cur, "sel")) + cur = selview->name; + else if(Mbsearch(cur, badtags, bsstrcmp)) + continue; + + if(j < nelem(toks)-1) { + if(add == '^') + add = bsearch(cur, toks, j, sizeof *toks, bsstrcmp) ? '-' : '+'; + if(add == '+') + toks[j++] = cur; + else { + for(i = 0, k = 0; i < j; i++) + if(strcmp(toks[i], cur)) + toks[k++] = toks[i]; + j = k; } } } - - for(i = n; i < sizeof buf - 1; i++) - if(buf[i] == '+' - || buf[i] == '-' - || buf[i] == '\0') - break; - last = buf[i]; - buf[i] = '\0'; - - trim(buf+n, " \t/"); - - cur = nil; - if(!strcmp(buf+n, "~")) - c->floating = add ? On : Never; - else - if(!strcmp(buf+n, "!") || !strcmp(buf+n, "sel")) - cur = selview->name; - else - if(!Mbsearch(buf+n, badtags, bsstrcmp)) - cur = buf+n; - - if(cur && j < nelem(toks)-1) { - if(add) { - found = true; - toks[j++] = cur; - }else { - for(i = 0, k = 0; i < j; i++) - if(strcmp(toks[i], cur)) - toks[k++] = toks[i]; - j = k; - } - } - - next: - n = i + 1; - if(last == '+') - add = true; - if(last == '-') - add = false; - if(last == '\0') - break; } toks[j] = nil; @@ -1241,6 +1196,6 @@ client_applytags(Client *c, const char *tags) { p = comm(~0, c->retags, toks); client_setviews(c, p); free(p); - return found; + return true; } diff --git a/cmd/wmii/column.c b/cmd/wmii/column.c index 3aaa6aea..6bb78623 100644 --- a/cmd/wmii/column.c +++ b/cmd/wmii/column.c @@ -17,8 +17,8 @@ char *modes[] = { bool column_setmode(Area *a, const char *mode) { - char *str, *tok, *orig; - char add, old; + char *str, *tok; + int add, old; /* * The mapping between the current internal @@ -27,49 +27,36 @@ column_setmode(Area *a, const char *mode) { * change. */ - orig = strdup(mode); - str = orig; - old = '\0'; - while(*(tok = str)) { - add = old; - while((old=*str) && !strchr("+-^", old)) - str++; - *str = '\0'; - if(str > tok) { - if(!strcmp(tok, "max")) { - if(add == '\0' || add == '+') - a->max = true; - else if(add == '-') - a->max = false; - else - a->max = !a->max; - }else - if(!strcmp(tok, "stack")) { - if(add == '\0' || add == '+') - a->mode = Colstack; - else if(add == '-') - a->mode = Coldefault; - else - a->mode = a->mode == Colstack ? Coldefault : Colstack; - }else - if(!strcmp(tok, "default")) { - if(add == '\0' || add == '+') { - a->mode = Coldefault; - column_arrange(a, true); - }else if(add == '-') - a->mode = Colstack; - else - a->mode = a->mode == Coldefault ? Colstack : Coldefault; - }else { - free(orig); - return false; - } - } - if(old) - str++; - + str = freelater(estrdup(mode)); + old = '+'; + while((tok = mask(&str, &add, &old))) { + if(!strcmp(tok, "max")) { + if(add == '\0' || add == '+') + a->max = true; + else if(add == '-') + a->max = false; + else + a->max = !a->max; + }else + if(!strcmp(tok, "stack")) { + if(add == '\0' || add == '+') + a->mode = Colstack; + else if(add == '-') + a->mode = Coldefault; + else + a->mode = a->mode == Colstack ? Coldefault : Colstack; + }else + if(!strcmp(tok, "default")) { + if(add == '\0' || add == '+') { + a->mode = Coldefault; + column_arrange(a, true); + }else if(add == '-') + a->mode = Colstack; + else + a->mode = a->mode == Coldefault ? Colstack : Coldefault; + }else + return false; } - free(orig); return true; } diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h index d1bbd66e..7cca1942 100644 --- a/cmd/wmii/dat.h +++ b/cmd/wmii/dat.h @@ -43,6 +43,10 @@ enum { UrgClient, }; +enum ClientPermission { + PermActivate = 1<<0, +}; + enum { SourceUnknown, SourceClient, @@ -169,25 +173,26 @@ struct Client { Group* group; Strut* strut; Cursor cursor; - Rectangle r; Rectangle configr; + Rectangle r; char** retags; - char name[256]; char class[256]; - char tags[256]; + char name[256]; char props[512]; + char tags[256]; + long permission; long proto; - uint border; - int pid; + int border; int dead; - int fullscreen; int floating; - bool fixedsize; - bool urgent; + int fullscreen; + int pid; bool borderless; - bool titleless; + bool fixedsize; bool nofocus; bool noinput; + bool titleless; + bool urgent; }; struct Divide { diff --git a/cmd/wmii/debug.h b/cmd/wmii/debug.h index afcfa830..00b6cb7b 100644 --- a/cmd/wmii/debug.h +++ b/cmd/wmii/debug.h @@ -20,5 +20,5 @@ void dwrite(int, void*, int, bool); bool setdebug(int); void vdebug(int, const char*, va_list); -int debugflag; -int debugfile; +long debugflag; +long debugfile; diff --git a/cmd/wmii/ewmh.c b/cmd/wmii/ewmh.c index e2704d53..730ccec5 100644 --- a/cmd/wmii/ewmh.c +++ b/cmd/wmii/ewmh.c @@ -50,6 +50,8 @@ ewmh_init(void) { NET("WM_PID"), NET("WM_STRUT"), NET("WM_STRUT_PARTIAL"), + /* Set this so clients don't update Net("USER_TIME") */ + NET("USER_TIME_WINDOW"), /* States */ NET("WM_STATE"), STATE("DEMANDS_ATTENTION"), @@ -179,6 +181,25 @@ ewmh_destroyclient(Client *c) { free(c->strut); } +#ifdef notdef +static ulong +usertime(Window *w) { + long *l; + long ret; + + ret = 0; + if(getprop_long(w, Net("WM_USER_TIME_WINDOW"), "CARDINAL", 0, &l, 1)) { + w = window(*l); + free(l); + } + if(getprop_long(w, Net("WM_USER_TIME"), "CARDINAL", 0, &l, 1)) { + ret = *l; + free(l); + } + return ret; +} +#endif + static bool event_client_clientmessage(Window *w, void *aux, XClientMessageEvent *e) { Client *c; @@ -215,11 +236,13 @@ event_client_clientmessage(Window *w, void *aux, XClientMessageEvent *e) { if(msg == NET("ACTIVE_WINDOW")) { if(e->format != 32) return false; + Dprint(DEwmh, "\tsource: %uld\n", l[0]); + Dprint(DEwmh, "\ttimestamp: %,uld\n", l[1]); + Dprint(DEwmh, "\tactive: %#ulx\n", l[2]); + Dprint(DEwmh, "\twindow: %#ulx\n", e->window); + Dprint(DEwmh, "\tclient: %C\n", c); - Dprint(DEwmh, "\tsource: %ld\n", l[0]); - Dprint(DEwmh, "\twindow: %#ulx\n", e->window); - Dprint(DEwmh, "\tclient: %C\n", c); - if(l[0] == SourceClient && abs(event_xtime - l[1]) > 5000) + if(l[0] == SourceClient && !(c->permission & PermActivate)) return false; if(l[0] == SourceClient || l[0] == SourcePager) focus(c, true); @@ -421,7 +444,9 @@ event_root_clientmessage(Window *w, void *aux, XClientMessageEvent *e) { l = (ulong*)e->data.l; msg = e->message_type; - Dprint(DEwmh, "ClientMessage: %A\n", msg); + Debug(DEwmh) + if(msg != xatom("WM_PROTOCOLS") && l[0] != NET("WM_PING")) + Dprint(DEwmh, "ClientMessage: %A\n", msg); if(msg == NET("CURRENT_DESKTOP")) { if(e->format != 32) @@ -447,7 +472,6 @@ event_root_clientmessage(Window *w, void *aux, XClientMessageEvent *e) { c->w.ewmh.lag = (c->w.ewmh.ping & 0xffffffff) - (l[1] & 0xffffffff); if(i == false) frame_draw(c->sel); - Dprint(DEwmh, "\twindow=%W lag=%,uld\n", &c->w, c->w.ewmh.lag); return false; } return false; diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h index a9376e08..2c64eab3 100644 --- a/cmd/wmii/fns.h +++ b/cmd/wmii/fns.h @@ -203,12 +203,13 @@ void init_screens(void); void spawn_command(const char*); /* message.c */ +char* mask(char**, int*, int*); char* message_client(Client*, IxpMsg*); char* message_root(void*, IxpMsg*); char* message_view(View*, IxpMsg*); -char* msg_debug(IxpMsg*); +void msg_debug(char*); void msg_eatrunes(IxpMsg*, int (*)(Rune), int); -char* msg_getword(IxpMsg*); +char* msg_getword(IxpMsg*, char*); void msg_parsecolors(IxpMsg*, CTuple*); char* msg_selectarea(Area*, IxpMsg*); char* msg_sendclient(View*, IxpMsg*, bool swap); diff --git a/cmd/wmii/main.c b/cmd/wmii/main.c index 05afcdec..c6548f6c 100644 --- a/cmd/wmii/main.c +++ b/cmd/wmii/main.c @@ -330,9 +330,8 @@ printfcall(IxpFcall *f) { int main(int argc, char *argv[]) { - IxpMsg m; char **oargv; - char *wmiirc, *s; + char *wmiirc; int i; setlocale(LC_CTYPE, ""); @@ -356,9 +355,10 @@ main(int argc, char *argv[]) { lprint(1, "%s", version); exit(0); case 'D': - s = EARGF(usage()); - m = ixp_message(s, strlen(s), 0); - msg_debug(&m); + if(waserror()) + fatal("parsing debug flags: %r"); + msg_debug(EARGF(usage())); + poperror(); break; default: usage(); diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c index dc8c91f5..6d0461b1 100644 --- a/cmd/wmii/message.c +++ b/cmd/wmii/message.c @@ -24,6 +24,7 @@ static char /* Edit |sort Edit |sed 's/"([^"]+)"/L\1/g' | tr 'a-z' 'A-Z' */ enum { + LALLOW, LBAR, LBORDER, LCLIENT, @@ -62,6 +63,7 @@ enum { LTILDE, }; char *symtab[] = { + "allow", "bar", "border", "client", @@ -100,6 +102,9 @@ char *symtab[] = { "~", }; +static char* barpostab[] = { + "bottom", "top", +}; char* debugtab[] = { "9p", "dnd", @@ -108,16 +113,13 @@ char* debugtab[] = { "focus", "generic", "stack", + nil }; - -static char* barpostab[] = { - "bottom", - "top", +static char* permtab[] = { + "activate", nil }; static char* incmodetab[] = { - "ignore", - "show", - "squeeze", + "ignore", "show", "squeeze", }; static char* floatingtab[] = { "never", "off", "on", "always" @@ -204,7 +206,7 @@ static int getdirection(IxpMsg *m) { int i; - switch(i = getsym(msg_getword(m))) { + switch(i = getsym(msg_getword(m, 0))) { case LLEFT: case LRIGHT: case LUP: @@ -249,7 +251,7 @@ msg_eatrunes(IxpMsg *m, int (*p)(Rune), int val) { } char* -msg_getword(IxpMsg *m) { +msg_getword(IxpMsg *m, char *errmsg) { char *ret; Rune r; int n; @@ -271,10 +273,102 @@ msg_getword(IxpMsg *m) { if(ret[1] == '\\' || ret[1] == '#') ret++; if(*ret == '\0') - return nil; + ret = nil; + if(ret == nil && errmsg) + error(errmsg); return ret; } +typedef struct Mask Mask; +struct Mask { + long* mask; + char** table; +}; + +static int +Mfmt(Fmt *f) { + Mask m; + int i; + + m = va_arg(f->args, Mask); + for(i=0; m.table[i]; i++) + if(*m.mask & (1<sel; else { l = msg_getulong(s); @@ -389,6 +483,7 @@ char* readctl_client(Client *c) { bufclear(); bufprint("%#C\n", c); + bufprint("allow %M\n", (Mask){&c->permission, permtab}); bufprint("floating %s\n", floatingtab[c->floating + 1]); if(c->fullscreen >= 0) bufprint("fullscreen %d\n", c->fullscreen); @@ -407,7 +502,7 @@ message_client(Client *c, IxpMsg *m) { char *s; long l; - s = msg_getword(m); + s = msg_getword(m, Ebadcmd); /* * Toggle ::= on @@ -423,11 +518,14 @@ message_client(Client *c, IxpMsg *m) { */ switch(getsym(s)) { + case LALLOW: + unmask((Mask){&c->permission, permtab}, msg_getword(m, 0)); + break; case LFLOATING: - c->floating = -1 + _lsearch(msg_getword(m), floatingtab, nelem(floatingtab)); + c->floating = -1 + _lsearch(msg_getword(m, Ebadvalue), floatingtab, nelem(floatingtab)); break; case LFULLSCREEN: - s = msg_getword(m); + s = msg_getword(m, Ebadvalue); if(getlong(s, &l)) fullscreen(c, On, l); else @@ -435,7 +533,7 @@ message_client(Client *c, IxpMsg *m) { break; case LGROUP: group_remove(c); - c->w.hints->group = msg_getulong(msg_getword(m)); + c->w.hints->group = msg_getulong(msg_getword(m, Ebadvalue)); if(c->w.hints->group) group_init(c); break; @@ -449,7 +547,7 @@ message_client(Client *c, IxpMsg *m) { client_applytags(c, m->pos); break; case LURGENT: - client_seturgent(c, gettoggle(msg_getword(m)), UrgManager); + client_seturgent(c, gettoggle(msg_getword(m, Ebadvalue)), UrgManager); break; default: error(Ebadcmd); @@ -466,7 +564,7 @@ message_root(void *p, IxpMsg *m) { USED(p); ret = nil; - s = msg_getword(m); + s = msg_getword(m, 0); if(s == nil) return nil; @@ -477,21 +575,21 @@ message_root(void *p, IxpMsg *m) { switch(getsym(s)) { case LBAR: /* bar on? <"top" | "bottom"> */ - s = msg_getword(m); + s = msg_getword(m, Ebadvalue); if(!strcmp(s, "on")) - s = msg_getword(m); + s = msg_getword(m, Ebadvalue); setdef(&screen->barpos, s, barpostab, nelem(barpostab)); view_update(selview); break; case LBORDER: - def.border = msg_getulong(msg_getword(m));; + def.border = msg_getulong(msg_getword(m, 0));; view_update(selview); break; case LCOLMODE: - setdef(&def.colmode, msg_getword(m), modes, Collast); + setdef(&def.colmode, msg_getword(m, 0), modes, Collast); break; case LDEBUG: - ret = msg_debug(m); + msg_debug(msg_getword(m, 0)); break; case LEXEC: execstr = strdup(m->pos); @@ -516,10 +614,10 @@ message_root(void *p, IxpMsg *m) { view_update(selview); break; case LFONTPAD: - if(!getint(msg_getword(m), &def.font->pad.min.x) || - !getint(msg_getword(m), &def.font->pad.max.x) || - !getint(msg_getword(m), &def.font->pad.max.y) || - !getint(msg_getword(m), &def.font->pad.min.y)) + if(!getint(msg_getword(m, 0), &def.font->pad.min.x) || + !getint(msg_getword(m, 0), &def.font->pad.max.x) || + !getint(msg_getword(m, 0), &def.font->pad.max.y) || + !getint(msg_getword(m, 0), &def.font->pad.min.y)) ret = "invalid rectangle"; else { for(n=0; n < nscreens; n++) @@ -528,7 +626,7 @@ message_root(void *p, IxpMsg *m) { } break; case LGRABMOD: - s = msg_getword(m); + s = msg_getword(m, Ebadvalue); if(!parsekey(s, &i, nil) || i == 0) return Ebadvalue; @@ -536,7 +634,7 @@ message_root(void *p, IxpMsg *m) { def.mod = i; break; case LINCMODE: - setdef(&def.incmode, msg_getword(m), incmodetab, nelem(incmodetab)); + setdef(&def.incmode, msg_getword(m, 0), incmodetab, nelem(incmodetab)); view_update(selview); break; case LNORMCOLORS: @@ -558,33 +656,17 @@ message_root(void *p, IxpMsg *m) { return ret; } -static void -printdebug(int mask) { - int i, j; - - for(i=0, j=0; i < nelem(debugtab); i++) - if(mask & (1< 0) bufprint(" "); - bufprint("%s", debugtab[i]); - } -} - char* readctl_root(void) { + fmtinstall('M', Mfmt); bufclear(); bufprint("bar on %s\n", barpostab[screen->barpos]); bufprint("border %d\n", def.border); bufprint("colmode %s\n", modes[def.colmode]); - if(debugflag) { - bufprint("debug "); - printdebug(debugflag); - bufprint("\n"); - } - if(debugfile) { - bufprint("debugfile "); - printdebug(debugfile); - bufprint("\n"); - } + if(debugflag) + bufprint("debug %M\n", (Mask){&debugflag, debugtab}); + if(debugfile) + bufprint("debugfile %M", (Mask){&debugfile, debugtab}); bufprint("focuscolors %s\n", def.focuscolor.colstr); bufprint("font %s\n", def.font->name); bufprint("fontpad %d %d %d %d\n", def.font->pad.min.x, def.font->pad.max.x, @@ -601,7 +683,7 @@ message_view(View *v, IxpMsg *m) { Area *a; char *s; - s = msg_getword(m); + s = msg_getword(m, 0); if(s == nil) return nil; @@ -648,11 +730,11 @@ message_view(View *v, IxpMsg *m) { switch(getsym(s)) { case LCOLMODE: - s = msg_getword(m); + s = msg_getword(m, Ebadvalue); a = strarea(v, screen->idx, s); - s = msg_getword(m); - if(s == nil || !column_setmode(a, s)) + s = msg_getword(m, Ebadvalue); + if(!column_setmode(a, s)) return Ebadvalue; column_arrange(a, false); @@ -699,38 +781,12 @@ readctl_view(View *v) { return buffer; } -char* -msg_debug(IxpMsg *m) { - char *opt; - int d; - char add; - - bufclear(); - while((opt = msg_getword(m))) { - add = '+'; - if(opt[0] == '+' || opt[0] == '-') - add = *opt++; - d = _bsearch(opt, debugtab, nelem(debugtab)); - if(d == -1) { - bufprint(", %s", opt); - continue; - } - if(add == '+') - debugflag |= 1<view; - s = msg_getword(m); + s = msg_getword(m, Ebadvalue); sym = getsym(s); switch(sym) { @@ -889,7 +945,8 @@ msg_selectarea(Area *a, IxpMsg *m) { ap = strarea(v, a->screen, s); if(ap->floating) return Ebadvalue; - if((s = msg_getword(m))) { + + if((s = msg_getword(m, 0))) { i = msg_getulong(s); for(f = ap->frame; f; f = f->anext) if(--i == 0) break; @@ -917,14 +974,14 @@ msg_selectframe(Area *a, IxpMsg *m, int sym) { stack = false; if(sym == LUP || sym == LDOWN) - if((s = msg_getword(m))) + if((s = msg_getword(m, 0))) if(!strcmp(s, "stack")) stack = true; else return Ebadvalue; if(sym == LCLIENT) { - s = msg_getword(m); + s = msg_getword(m, Ebadvalue); i = msg_getulong(s); c = win2client(i); if(c == nil) @@ -985,8 +1042,7 @@ msg_sendclient(View *v, IxpMsg *m, bool swap) { char *s; int sym; - s = msg_getword(m); - c = strclient(v, s); + c = strclient(v, msg_getword(m, 0)); f = client_viewframe(c, v); if(f == nil) return Ebadvalue; @@ -994,7 +1050,7 @@ msg_sendclient(View *v, IxpMsg *m, bool swap) { a = f->area; to = nil; - s = msg_getword(m); + s = msg_getword(m, Ebadvalue); sym = getsym(s); /* FIXME: Should use a helper function. */ diff --git a/cmd/wmii/rule.c b/cmd/wmii/rule.c index 0d79485a..710b341c 100644 --- a/cmd/wmii/rule.c +++ b/cmd/wmii/rule.c @@ -88,7 +88,7 @@ value: valuebuf.end = valuebuf.pos; valuebuf.pos = valuebuf.data; rvp = &r->values; - while((w = msg_getword(&valuebuf))) { + while((w = msg_getword(&valuebuf, 0))) { free(r->value); r->value = estrdup(w); if(strchr(w, '=')) { diff --git a/include/stuff/util.h b/include/stuff/util.h index 6c872a3c..3cb4bd10 100644 --- a/include/stuff/util.h +++ b/include/stuff/util.h @@ -56,6 +56,7 @@ void* erealloc(void*, uint); char* estrdup(const char*); char* estrndup(const char*, uint); void fatal(const char*, ...); +Fmt fmtbuf(char*, int); void* freelater(void*); int getbase(const char**, long*); bool getint(const char*, int*); diff --git a/include/stuff/x11.h b/include/stuff/x11.h index 1ce197d5..a15da12c 100644 --- a/include/stuff/x11.h +++ b/include/stuff/x11.h @@ -4,6 +4,7 @@ #define Window XWindow #define Font XFont #define Screen XScreen +#define Mask XMask #include #include #include @@ -16,6 +17,7 @@ #undef Window #undef Font #undef Screen +#undef Mask enum FontType { FX11 = 1, diff --git a/lib/libstuff/Makefile b/lib/libstuff/Makefile index 3a487a4b..3f6f0d0b 100644 --- a/lib/libstuff/Makefile +++ b/lib/libstuff/Makefile @@ -36,6 +36,7 @@ OBJ=\ event/xtime \ fmt/blprint \ fmt/bvlprint \ + fmt/fmtbuf \ fmt/localefmt \ fmt/localelen \ fmt/lprint \ diff --git a/lib/libstuff/fmt/fmtbuf.c b/lib/libstuff/fmt/fmtbuf.c new file mode 100644 index 00000000..69ef23ab --- /dev/null +++ b/lib/libstuff/fmt/fmtbuf.c @@ -0,0 +1,15 @@ +#include "fmtdef.h" + +Fmt +fmtbuf(char *buf, int len) { + Fmt f; + + f.runes = 0; + f.start = buf; + f.to = buf; + f.stop = buf + len - 1; + f.flush = 0; + f.farg = nil; + f.nfmt = 0; + return f; +} diff --git a/man/wmii.1 b/man/wmii.1 index 89fd746d..b6587eed 100644 --- a/man/wmii.1 +++ b/man/wmii.1 @@ -384,9 +384,28 @@ of the client. The following commands may be written to it: .RS 8 .TP -floating \fI\fR +allow \fI\fR +The set of unusual actions the client is allowed to +perform, in the same format as the tag set. +.RS 8 +.TP +activate +The client is allowed to activate +itself – that is, focus its window and, +as the case may require, uncollapse it +and select a tag it resides on. This +flag must be set on a client if you wish +it able to activate itself from the +system tray. +.RS -8 +.TP +floating \fI\fR Defines whether this client is likely to float when -attached to a new view. +attached to a new view. Ordinarilly, the value +changes automatically whenever the window is +moved between the floating and managed layers. +However, setting a value of \fIalways\fR or \fInever\fR +overrides this behavior. .TP fullscreen \fI\fR Sets the client's fullscreen state. @@ -428,11 +447,12 @@ Returns a clients class and label as: .TP tags Set or read a client's tags. Tags are separated by -\fB+\fR or \fB\-\fR. Tags beginning with \fB+\fR are -added, while those beginning with \fB\-\fR are removed. -If the tag string written begins with \fB+\fR or -\fB\-\fR, the written tags are added to or removed from -the client's set, otherwise, the set is overwritten. +\fB+\fR, \fB\-\fR, or \fB^\fR. Tags beginning with \fB+\fR are +added, while those beginning with \fB\-\fR are removed and +those beginning with \fB^\fR are toggled. If the tag +string written begins with \fB+\fR, \fB^\fR, or \fB\-\fR, the +written tags are added to or removed from the client's +set, otherwise the set is overwritten. .SS The /tag/ Hierarchy diff --git a/man/wmii.man1 b/man/wmii.man1 index 7674c751..84eb864b 100644 --- a/man/wmii.man1 +++ b/man/wmii.man1 @@ -332,6 +332,19 @@ represents the currently selected client. of the client. The following commands may be written to it: >> + : allow + The set of unusual actions the client is allowed to + perform, in the same format as the tag set. + >> + : activate + The client is allowed to activate + itself – that is, focus its window and, + as the case may require, uncollapse it + and select a tag it resides on. This + flag must be set on a client if you wish + it able to activate itself from the + system tray. + << : floating Defines whether this client is likely to float when attached to a new view. Ordinarilly, the value @@ -370,11 +383,12 @@ represents the currently selected client. ::