wmii

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

commit 558c0f1154552dcdcf409135c699f9e4641c0228
parent dbe75862ef2e9a1e7946a28eeab7a3357a2da8a8
Author: Kris Maglione <kris@suckless.org>
Date:   Tue,  8 Jun 2010 23:59:01 -0400

Cleanup, minor fixes.

Diffstat:
cmd/tray/main.c | 2+-
cmd/wmii/Makefile | 6++++--
cmd/wmii/area.c | 23++++++-----------------
cmd/wmii/client.c | 159+++++++++++++++++++++++++++++++++++++++----------------------------------------
cmd/wmii/column.c | 138-------------------------------------------------------------------------------
cmd/wmii/dat.h | 10++++++----
cmd/wmii/event.c | 49-------------------------------------------------
cmd/wmii/fns.h | 15++++++++++-----
cmd/wmii/frame.c | 34++++++++++++----------------------
cmd/wmii/layout.c | 4++--
cmd/wmii/message.c | 49++++++++++++++++++++++---------------------------
cmd/wmii/stack.c | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmd/wmii/view.c | 2+-
man/wmii.1 | 154++++++++++++++++++++++++++++++++++++++-----------------------------------------
man/wmii.man1 | 156++++++++++++++++++++++++++++++++++++++-----------------------------------------
man/wmiir.1 | 21+++++++++++++++++++--
16 files changed, 453 insertions(+), 511 deletions(-)

diff --git a/cmd/tray/main.c b/cmd/tray/main.c @@ -183,7 +183,7 @@ main(int argc, char *argv[]) { if(tray.selection == nil) fatal("Another system tray is already running."); if(tray.selection->oldowner) - lprint(1, "Replacing currently running system tray.\n"); + lprint(1, "%s: Replacing currently running system tray.\n", argv0); xext_init(); tray_init(); diff --git a/cmd/wmii/Makefile b/cmd/wmii/Makefile @@ -4,8 +4,9 @@ include $(ROOT)/mk/wmii.mk main.c: $(ROOT)/mk/wmii.mk -TARG = wmii -HFILES= dat.h fns.h +TARG = wmii +HFILES = dat.h fns.h +TAGFILES = dat.h PACKAGES += $(X11PACKAGES) xext xrandr xrender xinerama @@ -34,6 +35,7 @@ OBJ = area \ root \ rule \ screen \ + stack \ utf \ view \ xdnd diff --git a/cmd/wmii/area.c b/cmd/wmii/area.c @@ -300,29 +300,18 @@ area_focus(Area *a) { if(a != old_a) v->oldsel = nil; - if((old_a) && (a->floating != old_a->floating)) { + if(old_a && a->floating != old_a->floating) { v->revert = old_a; if(v->floating->max) view_update(v); } - if(v != selview) - return; - - move_focus(old_a->sel, f); + if(v == selview) { + move_focus(old_a->sel, f); + client_focus(f ? f->client : nil); - if(f) - client_focus(f->client); - else - client_focus(nil); - - if(a != old_a) { - event("AreaFocus %a\n", a); - /* Deprecated */ - if(a->floating) - event("FocusFloating\n"); - else - event("ColumnFocus %d\n", area_idx(a)); + if(a != old_a) + event("AreaFocus %a\n", a); } } diff --git a/cmd/wmii/client.c b/cmd/wmii/client.c @@ -12,6 +12,7 @@ #define Mbsearch(k, l, cmp) bsearch(k, l, nelem(l), sizeof(*l), cmp) static Handlers handlers; +static Handlers ignorehandlers; enum { ClientMask = StructureNotifyMask @@ -95,8 +96,9 @@ Client* client_create(XWindow w, XWindowAttributes *wa) { Client **t, *c; WinAttr fwa; - Point p; Visual *vis; + char **host = nil; + ulong *pid = nil; int depth; c = emallocz(sizeof *c); @@ -110,15 +112,7 @@ client_create(XWindow w, XWindowAttributes *wa) { c->w.xid = w; c->w.r = c->r; - depth = scr.depth; - vis = scr.visual; - /* XXX: Multihead. */ - c->ibuf = &ibuf; - if(render_argb_p(wa->visual)) { - depth = 32; - vis = scr.visual32; - c->ibuf = &ibuf32; - } + setborder(&c->w, 0, (Color){0}); client_prop(c, xatom("WM_PROTOCOLS")); client_prop(c, xatom("WM_TRANSIENT_FOR")); @@ -128,21 +122,35 @@ client_create(XWindow w, XWindowAttributes *wa) { client_prop(c, xatom("WM_NAME")); client_prop(c, xatom("_MOTIF_WM_HINTS")); - XSetWindowBorderWidth(display, w, 0); - XAddToSaveSet(display, w); + if(getprop_textlist(&c->w, "WM_CLIENT_MACHINE", &host) && + getprop_ulong(&c->w, Net("WM_PID"), "CARDINAL", 0, &pid, 1) && + !strcmp(hostname, *host)) + c->pid = (int)*pid; + freestringlist(host); + free(pid); + + if(render_argb_p(wa->visual)) { + depth = 32; + vis = scr.visual32; + c->ibuf = &ibuf32; + }else { + depth = scr.depth; + vis = scr.visual; + c->ibuf = &ibuf; + } fwa.background_pixmap = None; fwa.bit_gravity = NorthWestGravity; - fwa.border_pixel = 0; + fwa.border_pixel = 0; /* Required for ARGB windows. */ fwa.colormap = XCreateColormap(display, scr.root.xid, vis, AllocNone); - fwa.event_mask = SubstructureRedirectMask - | SubstructureNotifyMask - | StructureNotifyMask - | ExposureMask + fwa.event_mask = ButtonPressMask + | ButtonReleaseMask | EnterWindowMask + | ExposureMask | PointerMotionMask - | ButtonPressMask - | ButtonReleaseMask; + | StructureNotifyMask + | SubstructureNotifyMask + | SubstructureRedirectMask; fwa.override_redirect = true; c->framewin = createwindow_visual(&scr.root, c->r, depth, vis, InputOutput, @@ -158,13 +166,12 @@ client_create(XWindow w, XWindowAttributes *wa) { c->framewin->aux = c; c->w.aux = c; sethandler(c->framewin, &framehandler); + pushhandler(c->framewin, &ignorehandlers, nil); sethandler(&c->w, &handlers); + pushhandler(&c->w, &ignorehandlers, nil); selectinput(&c->w, ClientMask); - p.x = def.border; - p.y = labelh(def.font); - group_init(c); grab_button(c->framewin->xid, AnyButton, AnyModifier); @@ -184,7 +191,8 @@ client_create(XWindow w, XWindowAttributes *wa) { * perceptibly empty frame before it's destroyed. */ traperrors(true); - reparentwindow(&c->w, c->framewin, p); + XAddToSaveSet(display, w); + reparentwindow(&c->w, c->framewin, ZP); if(traperrors(false)) { client_destroy(c); return nil; @@ -204,7 +212,7 @@ apply_rules(Client *c) { Ruleval *rv; bool ret, more; - ret = false; + ret = true; for(r=def.rules.rule; r; r=r->next) if(regexec(r->regex, c->props, nil, 0)) { more = false; @@ -213,9 +221,9 @@ apply_rules(Client *c) { more = true; else if(!strcmp(rv->key, "tags")) utflcpy(c->tags, rv->value, sizeof c->tags); - else if(!strcmp(rv->key, "default-tags")) { + else if(!strcmp(rv->key, "force-tags")) { utflcpy(c->tags, rv->value, sizeof c->tags); - ret = true; + ret = false; }else { bufclear(); bufprint("%s %s", rv->key, rv->value); @@ -489,12 +497,12 @@ client_unmap(Client *c, int state) { } int -map_frame(Client *c) { +client_mapframe(Client *c) { return mapwin(c->framewin); } int -unmap_frame(Client *c) { +client_unmapframe(Client *c) { return unmapwin(c->framewin); } @@ -503,22 +511,14 @@ focus(Client *c, bool user) { View *v; Frame *f; - if(!user && c->nofocus) - return; - - f = c->sel; - if(!f) - return; - /* - if(!user && c->noinput) - return; - */ - - v = f->view; - if(v != selview) - view_focus(screen, v); - frame_focus(c->sel); - view_restack(c->sel->view); + if(!c->nofocus || user) + if((f = c->sel)) { + v = f->view; + if(v != selview) + view_focus(screen, v); + frame_focus(c->sel); + view_restack(c->sel->view); + } } void @@ -535,8 +535,9 @@ client_focus(Client *c) { Dprint(DFocus, "\t[%#C]%C\n\t=> [%#C]%C\n", disp.focus, disp.focus, c, c); + if(disp.focus != c) { - if(c) { + if(c && !c->sel->collapsed) { if(!c->noinput) setfocus(&c->w, RevertToParent); else if(c->proto & ProtoTakeFocus) { @@ -560,7 +561,7 @@ client_resize(Client *c, Rectangle r) { if(f->view != selview) { client_unmap(c, IconicState); - unmap_frame(c); + client_unmapframe(c); return; } @@ -568,18 +569,18 @@ client_resize(Client *c, Rectangle r) { if(f->collapsed) { if(f->area->max && !resizing) - unmap_frame(c); + client_unmapframe(c); else { reshapewin(c->framewin, f->r); movewin(&c->w, f->crect.min); - map_frame(c); + client_mapframe(c); } client_unmap(c, IconicState); }else { client_map(c); reshapewin(c->framewin, f->r); reshapewin(&c->w, f->crect); - map_frame(c); + client_mapframe(c); if(!eqrect(c->r, c->configr)) client_configure(c); ewmh_framesize(c); @@ -625,18 +626,10 @@ client_message(Client *c, char *msg, long l2) { void client_kill(Client *c, bool nice) { - char **host; - ulong *pid; - long n; if(!nice) { - getprop_textlist(&c->w, "WM_CLIENT_MACHINE", &host); - n = getprop_ulong(&c->w, Net("WM_PID"), "CARDINAL", 0, &pid, 1); - if(n && *host && !strcmp(hostname, *host)) - kill((uint)*pid, SIGKILL); - freestringlist(host); - free(pid); - + if(c->pid) + kill(c->pid, SIGKILL); XKillClient(display, c->w.xid); } else if(c->proto & ProtoDelete) { @@ -746,16 +739,8 @@ client_seturgent(Client *c, int urgent, int from) { /* X11 stuff */ void update_class(Client *c) { - char *str; - str = utfrune(c->props, L':'); - if(str) - str = utfrune(str+1, L':'); - if(str == nil) { - strcpy(c->props, "::"); - str = c->props + 1; - } - utflcpy(str+1, c->name, sizeof c->props); + snprint(c->props, sizeof c->props, "%s:%s", c->class, c->name); } static void @@ -764,10 +749,10 @@ client_updatename(Client *c) { c->name[0] = '\0'; - str = windowname(&c->w); - if(str) + if((str = windowname(&c->w))) { utflcpy(c->name, str, sizeof c->name); - free(str); + free(str); + } update_class(c); if(c->sel) @@ -815,7 +800,7 @@ updatemwm(Client *c) { } free(ret); - if(c->sel && false) { + if(false && c->sel) { c->sel->floatr = client_grav(c, r); if(c->sel->area->floating) { client_resize(c, c->sel->floatr); @@ -854,8 +839,8 @@ client_prop(Client *c, Atom a) { if(c->w.hints) c->fixedsize = eqpt(c->w.hints->min, c->w.hints->max); if(memcmp(&h, c->w.hints, sizeof h)) - if(c->sel) - view_update(c->sel->view); + if(c->sel) + view_update(c->sel->view); break; case XA_WM_HINTS: wmh = XGetWMHints(display, c->w.xid); @@ -867,9 +852,9 @@ client_prop(Client *c, Atom a) { break; case XA_WM_CLASS: n = getprop_textlist(&c->w, "WM_CLASS", &class); - snprint(c->props, sizeof c->props, "%s:%s:", - (n > 0 ? class[0] : "<nil>"), - (n > 1 ? class[1] : "<nil>")); + snprint(c->class, sizeof c->class, "%s:%s", + (n > 0 ? class[0] : "<nil>"), + (n > 1 ? class[1] : "<nil>")); freestringlist(class); update_class(c); break; @@ -908,9 +893,9 @@ configreq_event(Window *w, void *aux, XConfigureRequestEvent *e) { cr = r; r = client_grav(c, r); - if(c->sel->area->floating) { + if(c->sel->area->floating) client_resize(c, r); - }else { + else { c->sel->floatr = r; client_configure(c); } @@ -989,7 +974,7 @@ unmap_event(Window *w, void *aux, XUnmapEvent *e) { c->w.unmapped++; if(e->send_event || c->w.unmapped < 0) client_destroy(c); - return false; + return true; } static bool @@ -1001,7 +986,7 @@ map_event(Window *w, void *aux, XMapEvent *e) { c = aux; if(c == selclient()) client_focus(c); - return false; + return true; } static bool @@ -1023,6 +1008,18 @@ static Handlers handlers = { .property = property_event, }; +static bool +ignoreenter_event(Window *w, void *aux, XAnyEvent *e) { + ignoreenter = e->serial; + return true; +} + +static Handlers ignorehandlers = { + .map = (bool(*)(Window*, void*, XMapEvent*))ignoreenter_event, + .unmap = (bool(*)(Window*, void*, XUnmapEvent*))ignoreenter_event, + .config = (bool(*)(Window*, void*, XConfigureEvent*))ignoreenter_event, +}; + /* Other */ void client_setviews(Client *c, char **tags) { diff --git a/cmd/wmii/column.c b/cmd/wmii/column.c @@ -113,144 +113,6 @@ column_insert(Area *a, Frame *f, Frame *pos) { area_setsel(a, f); } -/* Temporary. */ -static void -stack_scale(Frame *first, int height) { - Frame *f; - Area *a; - uint dy; - int surplus; - - a = first->area; - - /* - * Will need something like this. - column_fit(a, &ncol, &nuncol); - */ - - dy = 0; - for(f=first; f && !f->collapsed; f=f->anext) - dy += Dy(f->colr); - - /* Distribute the surplus. - */ - surplus = height - dy; - for(f=first; f && !f->collapsed; f=f->anext) - f->colr.max.y += ((float)Dy(f->r) / dy) * surplus; -} - -static void -stack_info(Frame *f, Frame **firstp, Frame **lastp, int *dyp, int *nframep) { - Frame *ft, *first, *last; - int dy, nframe; - - nframe = 0; - dy = 0; - first = f; - last = f; - - for(ft=f; ft && ft->collapsed; ft=ft->anext) - ; - if(ft && ft != f) { - f = ft; - dy += Dy(f->colr); - } - for(ft=f; ft && !ft->collapsed; ft=ft->aprev) { - first = ft; - nframe++; - dy += Dy(ft->colr); - } - for(ft=f->anext; ft && !ft->collapsed; ft=ft->anext) { - if(first == nil) - first = ft; - last = ft; - nframe++; - dy += Dy(ft->colr); - } - if(nframep) *nframep = nframe; - if(firstp) *firstp = first; - if(lastp) *lastp = last; - if(dyp) *dyp = dy; -} - -int -stack_count(Frame *f, int *mp) { - Frame *fp; - int n, m; - - n = 0; - for(fp=f->aprev; fp && fp->collapsed; fp=fp->aprev) - n++; - m = ++n; - for(fp=f->anext; fp && fp->collapsed; fp=fp->anext) - n++; - if(mp) *mp = m; - return n; -} - -Frame* -stack_find(Area *a, Frame *f, int dir, bool stack) { - Frame *fp; - -#define predicate(f) !((f)->collapsed && stack || (f)->client->nofocus) - switch (dir) { - default: - die("not reached"); - case North: - if(f) - for(f=f->aprev; f && !predicate(f); f=f->aprev) - ; - else { - f = nil; - for(fp=a->frame; fp; fp=fp->anext) - if(predicate(fp)) - f = fp; - } - break; - case South: - if(f) - for(f=f->anext; f && !predicate(f); f=f->anext) - ; - else - for(f=a->frame; f && !predicate(f); f=f->anext) - ; - break; - } -#undef predicate - return f; -} - -/* TODO: Move elsewhere. */ -bool -find(Area **ap, Frame **fp, int dir, bool wrap, bool stack) { - Rectangle r; - Frame *f; - Area *a; - - f = *fp; - a = *ap; - r = f ? f->r : a->r; - - if(dir == North || dir == South) { - *fp = stack_find(a, f, dir, stack); - if(*fp) - return true; - if(!a->floating) - *ap = area_find(a->view, r, dir, wrap); - if(!*ap) - return false; - *fp = stack_find(*ap, *fp, dir, stack); - return true; - } - if(dir != East && dir != West) - die("not reached"); - *ap = area_find(a->view, r, dir, wrap); - if(!*ap) - return false; - *fp = ap[0]->sel; - return true; -} - void column_attach(Area *a, Frame *f) { Frame *first; diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h @@ -63,10 +63,10 @@ enum { extern char* modes[]; -#define toggle(val, x) \ - ((x) == On ? true : \ - (x) == Off ? false : \ - (x) == Toggle ? !(val) : (val)) +#define toggle(val, x) \ + ((val) = ((x) == On ? true : \ + (x) == Off ? false : \ + (x) == Toggle ? !(val) : (val))) #define TOGGLE(x) \ ((x) == On ? "on" : \ (x) == Off ? "off" : \ @@ -165,10 +165,12 @@ struct Client { Rectangle configr; char** retags; char name[256]; + char class[256]; char tags[256]; char props[512]; long proto; uint border; + int pid; int dead; int fullscreen; bool floating; diff --git a/cmd/wmii/event.c b/cmd/wmii/event.c @@ -11,27 +11,6 @@ debug_event(XEvent *e) { } void -event_configurenotify(XConfigureEvent *ev) { - Window *w; - - ignoreenter = ev->serial; - if((w = findwin(ev->window))) - event_handle(w, config, ev); -} - -void -event_destroynotify(XDestroyWindowEvent *ev) { - Window *w; - Client *c; - - if((w = findwin(ev->window))) - event_handle(w, destroy, ev); - else if((c = win2client(ev->window))) - fprint(2, "Badness: Unhandled DestroyNotify: Client: %p, Window: %W, Name: %s\n", - c, &c->w, c->name); -} - -void print_focus(const char *fn, Client *c, const char *to) { Dprint(DFocus, "%s() disp.focus:\n", fn); Dprint(DFocus, "\t%#C => %#C\n", disp.focus, c); @@ -98,31 +77,3 @@ event_focusout(XFocusChangeEvent *ev) { event_handle(w, focusout, ev); } -void -event_mapnotify(XMapEvent *ev) { - Window *w; - - ignoreenter = ev->serial; - if((w = findwin(ev->event))) - event_handle(w, map, ev); - if(ev->send_event && (w = findwin(ev->event))) - event_handle(w, map, ev); -} - -void -event_unmapnotify(XUnmapEvent *ev) { - Window *w; - - ignoreenter = ev->serial; - if((w = findwin(ev->window))) { - if(!ev->send_event) - w->mapped = false; - if(!ev->send_event && ev->event == ev->window) - w->unmapped--; - if(ev->send_event && ev->event != ev->window) - event_handle(w, unmap, ev); - } - if((w = findwin(ev->event))) - event_handle(w, unmap, ev); -} - diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h @@ -95,9 +95,9 @@ void fullscreen(Client*, int, long); void group_init(Client*); Client* group_leader(Group*); void group_remove(Client*); -int map_frame(Client*); +int client_mapframe(Client*); Client* selclient(void); -int unmap_frame(Client*); +int client_unmapframe(Client*); void update_class(Client*); Client* win2client(XWindow); Rectangle client_grav(Client*, Rectangle); @@ -120,9 +120,6 @@ void column_settle(Area*); void div_draw(Divide*); void div_set(Divide*, int x); void div_update_all(void); -bool find(Area**, Frame**, int, bool, bool); -int stack_count(Frame*, int*); -Frame* stack_find(Area*, Frame*, int, bool); /* error.c */ #define waserror() setjmp(*pusherror()) @@ -253,6 +250,14 @@ int ownerscreen(Rectangle); /* rule.c */ void update_rules(Rule**, char*); +/* stack.c */ +bool find(Area* *, Frame**, int, bool, bool); +int stack_count(Frame*, int*); +Frame* stack_find(Area*, Frame*, int, bool); +void stack_info(Frame*, Frame**, Frame**, int*, int*); +void stack_scale(Frame*, int); + + /* view.c */ void view_arrange(View*); void view_attach(View*, Frame*); diff --git a/cmd/wmii/frame.c b/cmd/wmii/frame.c @@ -198,13 +198,6 @@ bdown_event(Window *w, void *aux, XButtonEvent *e) { } static bool -config_event(Window *w, void *aux, XConfigureEvent *e) { - - USED(w, e); - return false; -} - -static bool enter_event(Window *w, void *aux, XCrossingEvent *e) { Client *c; Frame *f; @@ -250,7 +243,6 @@ motion_event(Window *w, void *aux, XMotionEvent *e) { Handlers framehandler = { .bup = bup_event, .bdown = bdown_event, - .config = config_event, .enter = enter_event, .expose = expose_event, .motion = motion_event, @@ -498,9 +490,9 @@ frame_draw(Frame *f) { if((s = client_extratags(c))) { pushlabel(img, &r, s, col); free(s); - }else /* Make sure floating clients have room for their indicators. */ - if(c->floating) + }else if(f->area->floating) /* Make sure floating clients have room for their indicators. */ r.max.x -= Dx(f->grabbox); + if(!ewmh_responsive_p(c)) r.min.x += drawstring(img, def.font, r, West, "(wedged) ", col->fg); w = drawstring(img, def.font, r, West, c->name, col->fg); @@ -508,7 +500,7 @@ frame_draw(Frame *f) { /* Draw inner border on floating clients. */ if(f->area->floating) { r.min.x = r.min.x + w + 10; - r.max.x += Dx(f->grabbox) - 2; + r.max.x += Dx(f->grabbox); r.min.y = f->grabbox.min.y; r.max.y = f->grabbox.max.y; border(img, r, 1, col->border); @@ -623,18 +615,16 @@ frame_focus(Frame *f) { if(f->area->floating) f->collapsed = false; - if(v != selview || a != v->sel || resizing) - return; - - move_focus(old_f, f); - if(a->floating) - float_arrange(a); - client_focus(f->client); + if(v == selview && a == v->sel && !resizing) { + move_focus(old_f, f); + if(a->floating) + float_arrange(a); + client_focus(f->client); - /* - if(!a->floating && ((a->mode == Colstack) || (a->mode == Colmax))) - */ - column_arrange(a, false); + // if(!a->floating && ((a->mode == Colstack) || (a->mode == Colmax))) + if(true) + column_arrange(a, false); + } } int diff --git a/cmd/wmii/layout.c b/cmd/wmii/layout.c @@ -586,7 +586,7 @@ tfloat(Frame *f, bool moved) { view_update(f->view); warppointer(grabboxcenter(f)); } - map_frame(f->client); + client_mapframe(f->client); if(!f->collapsed) focus(f->client, false); @@ -635,7 +635,7 @@ shut_up_ken: case ButtonPress: if(button != 3) continue; - unmap_frame(f->client); + client_unmapframe(f->client); ret = THCol; goto done; } diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c @@ -15,7 +15,7 @@ static char* msg_sendframe(Frame*, int, bool); s == LDOWN ? South : \ s == LLEFT ? West : \ s == LRIGHT ? East : \ - (abort(), 0)) + (error(Ebadvalue), 0)) static char Ebadcmd[] = "bad command", @@ -390,6 +390,8 @@ readctl_client(Client *c) { else bufprint("fullscreen off\n"); bufprint("group %#ulx\n", c->group ? c->group->leader : 0); + if(c->pid) + bufprint("pid %d\n", c->pid); bufprint("tags %s\n", c->tags); bufprint("urgent %s\n", TOGGLE(c->urgent)); return buffer; @@ -417,7 +419,7 @@ message_client(Client *c, IxpMsg *m) { switch(getsym(s)) { case LFLOATING: - c->floating = toggle(c->floating, gettoggle(m->pos)); + toggle(c->floating, gettoggle(m->pos)); break; case LFULLSCREEN: s = msg_getword(m); @@ -909,48 +911,43 @@ msg_selectframe(Area *a, IxpMsg *m, int sym) { fp = f; stack = false; - if(sym == LUP || sym == LDOWN) { - s = msg_getword(m); - if(s) + if(sym == LUP || sym == LDOWN) + if((s = msg_getword(m))) if(!strcmp(s, "stack")) stack = true; else return Ebadvalue; - } if(sym == LCLIENT) { s = msg_getword(m); i = msg_getulong(s); c = win2client(i); if(c == nil) - return "unknown client"; + return Ebadvalue; f = client_viewframe(c, a->view); if(!f) return Ebadvalue; } - else { - if(!find(&a, &f, DIR(sym), true, stack)) - return Ebadvalue; - } + else if(!find(&a, &f, DIR(sym), true, stack)) + return Ebadvalue; area_focus(a); - if(!f) - return nil; + if(f != nil) { + /* XXX */ + if(fp && fp->area == a) + if(f->collapsed && !f->area->floating && f->area->mode == Coldefault) { + dy = Dy(f->colr); + f->colr.max.y = f->colr.min.y + Dy(fp->colr); + fp->colr.max.y = fp->colr.min.y + dy; + column_arrange(a, false); + } - /* XXX */ - if(fp && fp->area == a) - if(f->collapsed && !f->area->floating && f->area->mode == Coldefault) { - dy = Dy(f->colr); - f->colr.max.y = f->colr.min.y + Dy(fp->colr); - fp->colr.max.y = fp->colr.min.y + dy; - column_arrange(a, false); + frame_focus(f); + frame_restack(f, nil); + if(f->view == selview) + view_restack(a->view); } - - frame_focus(f); - frame_restack(f, nil); - if(f->view == selview) - view_restack(a->view); return nil; } @@ -984,9 +981,7 @@ msg_sendclient(View *v, IxpMsg *m, bool swap) { int sym; s = msg_getword(m); - c = strclient(v, s); - f = client_viewframe(c, v); if(f == nil) return Ebadvalue; diff --git a/cmd/wmii/stack.c b/cmd/wmii/stack.c @@ -0,0 +1,142 @@ +/* Copyright ©2009-2010 Kris Maglione <maglione.k at Gmail> + * See LICENSE file for license details. + */ +#include "dat.h" +#include "fns.h" + +void +stack_scale(Frame *first, int height) { + Frame *f; + Area *a; + uint dy; + int surplus; + + a = first->area; + + /* + * Will need something like this. + column_fit(a, &ncol, &nuncol); + */ + + dy = 0; + for(f=first; f && !f->collapsed; f=f->anext) + dy += Dy(f->colr); + + /* Distribute the surplus. + */ + surplus = height - dy; + for(f=first; f && !f->collapsed; f=f->anext) + f->colr.max.y += ((float)Dy(f->r) / dy) * surplus; +} + +void +stack_info(Frame *f, Frame **firstp, Frame **lastp, int *dyp, int *nframep) { + Frame *ft, *first, *last; + int dy, nframe; + + nframe = 0; + dy = 0; + first = f; + last = f; + + for(ft=f; ft && ft->collapsed; ft=ft->anext) + ; + if(ft && ft != f) { + f = ft; + dy += Dy(f->colr); + } + for(ft=f; ft && !ft->collapsed; ft=ft->aprev) { + first = ft; + nframe++; + dy += Dy(ft->colr); + } + for(ft=f->anext; ft && !ft->collapsed; ft=ft->anext) { + if(first == nil) + first = ft; + last = ft; + nframe++; + dy += Dy(ft->colr); + } + if(nframep) *nframep = nframe; + if(firstp) *firstp = first; + if(lastp) *lastp = last; + if(dyp) *dyp = dy; +} + +int +stack_count(Frame *f, int *mp) { + Frame *fp; + int n, m; + + n = 0; + for(fp=f->aprev; fp && fp->collapsed; fp=fp->aprev) + n++; + m = ++n; + for(fp=f->anext; fp && fp->collapsed; fp=fp->anext) + n++; + if(mp) *mp = m; + return n; +} + +Frame* +stack_find(Area *a, Frame *f, int dir, bool stack) { + Frame *fp; + +#define predicate(f) !((f)->collapsed && stack || (f)->client->nofocus) + switch (dir) { + default: + die("not reached"); + case North: + if(f) + for(f=f->aprev; f && !predicate(f); f=f->aprev) + ; + else { + f = nil; + for(fp=a->frame; fp; fp=fp->anext) + if(predicate(fp)) + f = fp; + } + break; + case South: + if(f) + for(f=f->anext; f && !predicate(f); f=f->anext) + ; + else + for(f=a->frame; f && !predicate(f); f=f->anext) + ; + break; + } +#undef predicate + return f; +} + +bool +find(Area **ap, Frame **fp, int dir, bool wrap, bool stack) { + Rectangle r; + Frame *f; + Area *a; + + f = *fp; + a = *ap; + r = f ? f->r : a->r; + + if(dir == North || dir == South) { + *fp = stack_find(a, f, dir, stack); + if(*fp) + return true; + if(!a->floating) + *ap = area_find(a->view, r, dir, wrap); + if(!*ap) + return false; + *fp = stack_find(*ap, *fp, dir, stack); + return true; + } + if(dir != East && dir != West) + die("not reached"); + *ap = area_find(a->view, r, dir, wrap); + if(!*ap) + return false; + *fp = ap[0]->sel; + return true; +} + diff --git a/cmd/wmii/view.c b/cmd/wmii/view.c @@ -314,7 +314,7 @@ view_update(View *v) { if(f->area) client_resize(c, f->r); }else { - unmap_frame(c); + client_unmapframe(c); client_unmap(c, IconicState); } ewmh_updatestate(c); diff --git a/man/wmii.1 b/man/wmii.1 @@ -23,13 +23,13 @@ trying to shoehorn all windows and applications into it. .P \fBwmii\fR supports classic and tiled window management with -extended keyboard and mouse control. The classic window -management arranges windows in a floating layer in which windows -can be moved and resized freely. The tiled window management is -based on columns which split up the screen horizontally. Each -column handles arbitrary windows and arranges them vertically in -a non\-overlapping way. They can then be moved and resized -between and within columns at will. +extended keyboard and mouse control. Classic window management +arranges windows in a floating layer in which tyen can be moved +and resized freely. Tiled window management arranges windows in +vertical columns. Each column holds an arbitrary number +arbitrary windows and arranges them vertically in a +non\-overlapping manner. They can then be moved and resized, +among and within columns, at will. .P \fBwmii\fR provides a virtual filesystem which represents the @@ -40,11 +40,6 @@ accessed through 9P\-capable client programs, like wmiir(1). This allows simple and powerful remote control of the core window manager. -.P -\fBwmii\fR basically consists of clients, columns, views, and -the bar, which are described in detail in the -\fBTerminology\fR section. - .SS Command Line Arguments .TP \-a \fI<address>\fR @@ -52,13 +47,19 @@ Specifies the address on which \fBwmii\fR should listen for connections. The address takes the form \fB\fI<protocol>\fR!\fI<address>\fR\fR. The default is of the form: -unix!/tmp/ns.\fB$USER\fR.\fB${DISPLAY\fR%.0\fB}\fR/wmii +.nf + unix!/tmp/ns.\fB$USER\fR.\fB${DISPLAY\fR%.0\fB}\fR/wmii +.fi + which opens a unix socket per Plan 9 Port conventions. To open a TCP socket, listening at port 4332 on the loopback interface, use: -tcp!localhost!4332 +.nf + tcp!localhost!4332 +.fi + \fB$WMII_NAMESPACE\fR is automatically set to this value. @@ -70,8 +71,7 @@ Otherwise, it is passed to the shell for evaluation. The environment variables \fB$WMII_ADDRESS\fR and \fB$WMII_CONFPATH\fR are preset for the script. -== Terminology == - +.SS Terminology .TP Display A running X server instance consisting of input @@ -79,8 +79,7 @@ devices and screens. .TP Screen A physical or virtual (Xinerama or Xnest(1)) -screen of an X display. A screen displays a bar window -and a view at a time. +screen of an X display. .TP Window A (rectangular) drawable X object which is @@ -89,20 +88,18 @@ displayed on a screen, usually an application window. Client An application window surrounded by a frame window containing a border and a titlebar. - .TP Floating layer -A screen layer of \fBwmii\fR on top of -all other layers, where clients are arranged in a -classic (floating) way. They can be resized or moved -freely. +A screen layer of \fBwmii\fR on top of all other layers, +where clients are arranged in a classic (floating) +manner. They can be resized or moved freely. .TP Managed layer -A screen layer of \fBwmii\fR behind the -floating layer, where clients are arranged in a -non\-overlapping (managed) way. Here, the window -manager dynamically assigns each client a size and -position. The managed layer consists of columns. +A screen layer of \fBwmii\fR underneath the floating layer, +where clients are arranged in a non\-overlapping +(managed) manner. Here, the window manager dynamically +assigns each client a size and position. The managed +layer consists of columns. .TP Tag Alphanumeric strings which can be assigned to a @@ -113,15 +110,13 @@ Tags are separated with the \fI+\fR character. .TP View A set of clients containing a specific tag, quite -similar to a workspace in other window managers. It +similar to a workspace in other window managers. It consists of the floating and managed layers. .TP Column A column is a screen area which arranges clients -vertically in a non\-overlapping way. Columns provide -three different modes, which arrange clients with equal -size, stacked, or maximized respectively. Clients can -be moved and resized between and within columns freely. +vertically in a non\-overlapping way. Clients can be +moved and resized between and within columns freely. .TP Bar The bar at the bottom of the screen displays a label @@ -137,40 +132,36 @@ a different 9P\-client. .SS Basic window management .P -Running a raw \fBwmii\fR process without a wmiirc(1) -script provides basic window management capabilities already. -However, to use it effectively, remote control through its -filesystem interface is necessary. By default it is only usable -with the mouse in conjunction with the \fIMod1 (Alt)\fR -modifier key. Other interactions, such as customizing the style, -killing or retagging clients, and grabbing keys, cannot be -achieved without accessing the filesystem. +Running a raw \fBwmii\fR process without a wmiirc(1) script provides +basic window management capabilities. However, to use it +effectively, remote control through its filesystem interface is +necessary. Without such a script, it is only possible to move +and resize clients with the mouse, but not to change their tags +or to switch views. Other interactions, such as customizing the +style, killing or retagging clients, and grabbing keys, cannot +be achieved without accessing the filesystem. .P -The filesystem can be accessed by connecting to the -\fIaddress\fR of \fBwmii\fR with any 9P\-capable client, such -as wmiir(1) +The filesystem can be accessed by connecting to the \fIaddress\fR +of \fBwmii\fR with any 9P\-capable client, such as wmiir(1) .SS Actions .P -An action is a shell script in the default setup, but it can -actually be any executable file. It is executed usually by -selecting it from the actions menu. You can customize an action -by copying it from the global action directory -\&'@CONFPREFIX@/wmii@CONFVERSION@' to '\fB$HOME\fR/.wmii@CONFVERSION@' and then -editing the copy to fit your needs. Of course you can also -create your own actions there; make sure that they are -executable. +The default configuration provides for a special menu of +actions. These consist of either shell scripts in \fB$WMII_CONFPATH\fR +or action definitions included in wmiirc. .P Here is a list of the default actions: .TS tab(^); ll. - quit^leave the window manager nicely - status^periodically print date and load average to the bar - welcome^display a welcome message that contains the wmii tutorial - wmiirc^configure wmii + exec^Replace the window manager with another program + quit^Leave the window manager nicely + rehash^Refresh the program list + showkeys^Display a list of key bindings recognized by wmii + status^Periodically print date and load average to the bar + welcome^Display a welcome message that contains the wmii tutorial .TE .SS Default Key Bindings @@ -228,17 +219,20 @@ the bar labels, etc. .SS Filesystem .P -Most aspects of \fBwmii\fR are controlled via the filesystem. -It is usually accessed via the wmiir(1) command, but it -can be accessed by any 9P, including plan9port's -9P\fI[1]\fR, and can be mounted natively on Linux via v9fs\fI[1]\fR, -and on Inferno (which man run on top of Linux). +Most aspects of \fBwmii\fR are controlled via the filesystem. It is +usually accessed via the wmiir(1) command, but it can be +accessed by any 9P, including plan9port's 9P\fI[1]\fR, and can be +mounted natively on Linux via v9fs\fI[1]\fR, and on Inferno (which man +run on top of Linux). All data in the filesystem, including +filenames, is UTF\-8 encoded. However, when accessed via +wmiir(1), text is automatically translated to and from your +locale encoding. .P The filesystem is, as are many other 9P filesystems, entirely synthetic. The files exist only in memory, and are not written to disk. They are generally initiated on wmii startup via a -script such as rc.wmii or wmiirc. Several files read commands, +script such as wmiirc. Several files are used to issue commands, others simply act as if they were ordinary files (their contents are updated and returned exactly as written), though writing them has side\-effects (such as changing key bindings). A @@ -307,24 +301,18 @@ Additionally, the following keys are accepted and have special meaning: .RS 8 - -.RS -: continue -.RS +.TP +continue Normally, when a matching rule is encountered, rule matching stops. When the continue key is provided (with any value), matching continues at the next rule. -.RE -.RE .TP -default\-tags=\fI<tags>\fR -Like \fItags\fR, but only sets the tags if they can't be +force\-tags=\fI<tags>\fR +Like \fItags\fR, but overrides any settings obtained obtained from the client's group or from the -_WMII_TAGS window property. This key should be -preferred to the \fItags\fR key in most cases. +\fB_WMII_TAGS\fR window property. .RS -8 - .TP keys The \fIkeys\fR file contains a list of keys which @@ -357,9 +345,8 @@ has a button pressed over it. \fI[Left|Right]\fRBar\fI[Click|MouseDown]\fR \fI<button>\fR \fI<bar>\fR A left or right bar has been clicked or has a button pressed over it. -.TP .RS -8 + For a more comprehensive list of available events, see \fIwmii.pdf\fR\fI[2]\fR @@ -414,10 +401,15 @@ done via the rules file. kill Close the client's window. .TP +pid +Read\-only value of the PID of the program that +owns the window, if the value is available and +the process is on the same machine as wmii. +.TP slay Forcibly kill the client's connection to the X server, closing all of its windows. Kill the parent -process if the client provides its PID. +process if the client's PID is available. .TP tags \fI<tags>\fR The client's tags. The same as the tags file. @@ -600,18 +592,22 @@ thus can be used in actions: \fB$WMII_ADDRESS\fR The address on which \fBwmii\fR is listening. .TP +\fB$WMII_CONFPATH\fR +The path that wmii searches for its configuration +scripts and actions. +.TP \fB$NAMESPACE\fR The namespace directory to use if no address is provided. .SH SEE ALSO .P -dmenu(1), wmiir(1) - +wimenu(1), wmii9menu(1), witray(1), wmiir(1), wihack(1) .P @DOCDIR@/wmii.pdf .P -\fI[1]\fR http://www.suckless.org/wiki/wmii/tips/9p_tips +\fI[1]\fR http://www.suckless.org/wiki/wmii/tips/9p_tips +.P \fI[2]\fR @DOCDIR@/wmii.pdf diff --git a/man/wmii.man1 b/man/wmii.man1 @@ -26,13 +26,13 @@ user, rather than forcing him to use a preset, fixed layout and trying to shoehorn all windows and applications into it. `wmii` supports classic and tiled window management with -extended keyboard and mouse control. The classic window -management arranges windows in a floating layer in which windows -can be moved and resized freely. The tiled window management is -based on columns which split up the screen horizontally. Each -column handles arbitrary windows and arranges them vertically in -a non-overlapping way. They can then be moved and resized -between and within columns at will. +extended keyboard and mouse control. Classic window management +arranges windows in a floating layer in which tyen can be moved +and resized freely. Tiled window management arranges windows in +vertical columns. Each column holds an arbitrary number +arbitrary windows and arranges them vertically in a +non-overlapping manner. They can then be moved and resized, +among and within columns, at will. `wmii` provides a virtual filesystem which represents the internal state similar to the procfs of Unix operating systems. @@ -42,10 +42,6 @@ accessed through 9P-capable client programs, like wmiir(1). This allows simple and powerful remote control of the core window manager. -`wmii` basically consists of clients, columns, views, and -the bar, which are described in detail in the -**Terminology** section. - == Command Line Arguments == : -a <address> @@ -53,13 +49,13 @@ the bar, which are described in detail in the connections. The address takes the form `<protocol>!<address>`. The default is of the form: - unix!/tmp/ns.$USER.${DISPLAY%.0}/wmii +``` unix!/tmp/ns.$USER.${DISPLAY%.0}/wmii which opens a unix socket per Plan 9 Port conventions. To open a TCP socket, listening at port 4332 on the loopback interface, use: - tcp!localhost!4332 +``` tcp!localhost!4332 $WMII_NAMESPACE is automatically set to this value. @@ -69,7 +65,7 @@ the bar, which are described in detail in the Otherwise, it is passed to the shell for evaluation. The environment variables $WMII_ADDRESS and $WMII_CONFPATH are preset for the script. - +: == Terminology == : Display @@ -77,26 +73,23 @@ the bar, which are described in detail in the devices and screens. : Screen A physical or virtual (Xinerama or Xnest(1)) - screen of an X display. A screen displays a bar window - and a view at a time. + screen of an X display. : Window A (rectangular) drawable X object which is displayed on a screen, usually an application window. : Client An application window surrounded by a frame window containing a border and a titlebar. - : Floating layer - A screen layer of `wmii` on top of - all other layers, where clients are arranged in a - classic (floating) way. They can be resized or moved - freely. + A screen layer of `wmii` on top of all other layers, + where clients are arranged in a classic (floating) + manner. They can be resized or moved freely. : Managed layer - A screen layer of `wmii` behind the - floating layer, where clients are arranged in a - non-overlapping (managed) way. Here, the window - manager dynamically assigns each client a size and - position. The managed layer consists of columns. + A screen layer of `wmii` underneath the floating layer, + where clients are arranged in a non-overlapping + (managed) manner. Here, the window manager dynamically + assigns each client a size and position. The managed + layer consists of columns. : Tag Alphanumeric strings which can be assigned to a client. This provides a mechanism to group clients with @@ -105,14 +98,12 @@ the bar, which are described in detail in the Tags are separated with the _+_ character. : View A set of clients containing a specific tag, quite - similar to a workspace in other window managers. It + similar to a workspace in other window managers. It consists of the floating and managed layers. : Column A column is a screen area which arranges clients - vertically in a non-overlapping way. Columns provide - three different modes, which arrange clients with equal - size, stacked, or maximized respectively. Clients can - be moved and resized between and within columns freely. + vertically in a non-overlapping way. Clients can be + moved and resized between and within columns freely. : Bar The bar at the bottom of the screen displays a label for each view and allows the creation of arbitrary @@ -126,36 +117,32 @@ the bar, which are described in detail in the == Basic window management == -Running a raw `wmii` process without a wmiirc(1) -script provides basic window management capabilities already. -However, to use it effectively, remote control through its -filesystem interface is necessary. By default it is only usable -with the mouse in conjunction with the //Mod1 (Alt)// -modifier key. Other interactions, such as customizing the style, -killing or retagging clients, and grabbing keys, cannot be -achieved without accessing the filesystem. +Running a raw `wmii` process without a wmiirc(1) script provides +basic window management capabilities. However, to use it +effectively, remote control through its filesystem interface is +necessary. Without such a script, it is only possible to move +and resize clients with the mouse, but not to change their tags +or to switch views. Other interactions, such as customizing the +style, killing or retagging clients, and grabbing keys, cannot +be achieved without accessing the filesystem. -The filesystem can be accessed by connecting to the -//address// of `wmii` with any 9P-capable client, such -as wmiir(1) +The filesystem can be accessed by connecting to the //address// +of `wmii` with any 9P-capable client, such as wmiir(1) == Actions == -An action is a shell script in the default setup, but it can -actually be any executable file. It is executed usually by -selecting it from the actions menu. You can customize an action -by copying it from the global action directory -'@CONFPREFIX@/wmii@CONFVERSION@' to '$HOME/.wmii@CONFVERSION@' and then -editing the copy to fit your needs. Of course you can also -create your own actions there; make sure that they are -executable. +The default configuration provides for a special menu of +actions. These consist of either shell scripts in $WMII_CONFPATH +or action definitions included in wmiirc. Here is a list of the default actions: -| quit | leave the window manager nicely -| status | periodically print date and load average to the bar -| welcome | display a welcome message that contains the wmii tutorial -| wmiirc | configure wmii +| exec | Replace the window manager with another program +| quit | Leave the window manager nicely +| rehash | Refresh the program list +| showkeys | Display a list of key bindings recognized by wmii +| status | Periodically print date and load average to the bar +| welcome | Display a welcome message that contains the wmii tutorial == Default Key Bindings == @@ -206,23 +193,24 @@ the bar labels, etc. == Filesystem == -Most aspects of `wmii` are controlled via the filesystem. -It is usually accessed via the wmiir(1) command, but it -can be accessed by any ``9P``, including plan9port's -9P[1], and can be mounted natively on Linux via v9fs[1], -and on Inferno (which man run on top of Linux). All data in the -filesystem, including filenames, is UTF-8 encoded. However, when -accessed via wmiir(1), text is automatically translated to and -from your locale encoding. +Most aspects of `wmii` are controlled via the filesystem. It is +usually accessed via the wmiir(1) command, but it can be +accessed by any ``9P``, including plan9port's 9P[1], and can be +mounted natively on Linux via v9fs[1], and on Inferno (which man +run on top of Linux). All data in the filesystem, including +filenames, is UTF-8 encoded. However, when accessed via +wmiir(1), text is automatically translated to and from your +locale encoding. The filesystem is, as are many other 9P filesystems, entirely synthetic. The files exist only in memory, and are not written to disk. They are generally initiated on wmii startup via a -script such as wmiirc. Several files read commands, others -simply act as if they were ordinary files (their contents are -updated and returned exactly as written), though writing them -has side-effects (such as changing key bindings). A description -of the filesystem layout and control commands follows. +script such as wmiirc. Several files are used to issue commands, +others simply act as if they were ordinary files (their contents +are updated and returned exactly as written), though writing +them has side-effects (such as changing key bindings). A +description of the filesystem layout and control commands +follows. == Hierarchy == @@ -273,16 +261,15 @@ of the filesystem layout and control commands follows. special meaning: >> - : continue - Normally, when a matching rule is encountered, rule - matching stops. When the continue key is provided - (with any value), matching continues at the next - rule. - : default-tags=<tags> - Like _tags_, but only sets the tags if they can't be + : continue + Normally, when a matching rule is encountered, rule + matching stops. When the continue key is provided + (with any value), matching continues at the next + rule. + : force-tags=<tags> + Like _tags_, but overrides any settings obtained obtained from the client's group or from the - \_WMII_TAGS window property. This key should be - preferred to the _tags_ key in most cases. + **\_WMII_TAGS** window property. << : keys The _keys_ file contains a list of keys which @@ -310,8 +297,9 @@ of the filesystem layout and control commands follows. : [Left|Right]Bar[Click|MouseDown] <button> <bar> A left or right bar has been clicked or has a button pressed over it. - :   + : << + For a more comprehensive list of available events, see _wmii.pdf_[2] @@ -357,10 +345,14 @@ represents the currently selected client. done via the rules file. : kill Close the client's window. + : pid + Read-only value of the PID of the program that + owns the window, if the value is available and + the process is on the same machine as wmii. : slay Forcibly kill the client's connection to the X server, closing all of its windows. Kill the parent - process if the client provides its PID. + process if the client's PID is available. : tags <tags> The client's tags. The same as the tags file. : urgent <on | off | toggle> @@ -498,14 +490,16 @@ thus can be used in actions: : $WMII_ADDRESS The address on which `wmii` is listening. +: $WMII_CONFPATH + The path that wmii searches for its configuration + scripts and actions. : $NAMESPACE The namespace directory to use if no address is provided. : = SEE ALSO = -dmenu(1), wmiir(1) - +wimenu(1), wmii9menu(1), witray(1), wmiir(1), wihack(1) + @DOCDIR@/wmii.pdf -[1] http://www.suckless.org/wiki/wmii/tips/9p_tips +[1] http://www.suckless.org/wiki/wmii/tips/9p_tips + [2] @DOCDIR@/wmii.pdf diff --git a/man/wmiir.1 b/man/wmiir.1 @@ -6,9 +6,9 @@ wmiir \- The wmii 9P filesystem client .SH SYNOPSIS .P -wmiir \fI[\-a \fI<address>\fR]\fR {create | ls \fI[\-dlp]\fR | read | remove | write} \fI<file>\fR +wmiir \fI[\-a \fI<address>\fR]\fR \fI[\-b]\fR {create | ls \fI[\-dlp]\fR | read | remove | write} \fI<file>\fR .P -wmiir \fI[\-a \fI<address>\fR]\fR xwrite \fI<file>\fR \fI<data>\fR ... +wmiir \fI[\-a \fI<address>\fR]\fR \fI[\-b]\fR xwrite \fI<file>\fR \fI<data>\fR ... .P wmiir \-v @@ -19,10 +19,27 @@ to its virtual filesystem by default. \fBwmiir\fR is most often used to query an issue commands to \fBwmii\fR, both from the command line and from its \fBsh\fR\-based configuration scripts. +.P +Since the default encoding of 9P filesystems is UTF\-8, \fBwmiir\fR +assumes that all data read and written is text data and +translates to or from your locale character encoding as +necessary. When working with non\-text data in a non\-UTF\-8 +locale, the \fI\-b\fR flag should be specified to disable this +behavior. + .SH ARGUMENTS .TP \-a The address at which to connect to \fBwmii\fR. +.TP +\-b + +.RS +With the \fI\-b\fR flag, data that you intend to read or +write is treated as binary data. +.RE +.P +: .SH COMMANDS .P