[hackers] [wmii] Fix some bugs. Add support for struts (think pagers, docks, panels...). /debug/* files for my convenience.

From: Kris Maglione <jg_AT_suckless.org>
Date: Tue Jan 22 23:58:16 2008

changeset: 2253:da34a112f02f
tag: tip
user: Kris Maglione <jg_AT_suckless.org>
date: Tue Jan 22 17:55:53 2008 -0500
summary: Fix some bugs. Add support for struts (think pagers, docks, panels...). /debug/* files for my convenience.

diff -r 868fa3e8da2a -r da34a112f02f cmd/util.c
--- a/cmd/util.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/util.c Tue Jan 22 17:55:53 2008 -0500
@@ -81,7 +81,7 @@ void
 void
 _die(char *file, int line, char *msg) {
         fprint(2, "%s: dieing at %s:%d: %s\n",
- file, line, msg);
+ argv0, file, line, msg);
         kill(getpid(), SIGABRT);
         abort(); /* Adds too many frames:
                   * _die()
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/area.c
--- a/cmd/wmii/area.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/area.c Tue Jan 22 17:55:53 2008 -0500
@@ -119,6 +119,8 @@ area_destroy(Area *a) {
 
         if(v->revert == a)
                 v->revert = nil;
+ if(v->oldsel == a)
+ v->oldsel = nil;
 
         idx = area_idx(a);
 
@@ -190,7 +192,7 @@ area_attach(Area *a, Frame *f) {
         else
                 column_attach(a, f);
 
- view_restack(a->view);
+ view_arrange(a->view);
 
         if(a->frame)
                 assert(a->sel);
@@ -206,6 +208,7 @@ area_detach(Frame *f) {
                 float_detach(f);
         else
                 column_detach(f);
+ view_arrange(a->view);
 }
 
 void
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/bar.c
--- a/cmd/wmii/bar.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/bar.c Tue Jan 22 17:55:53 2008 -0500
@@ -46,6 +46,29 @@ bar_resize(WMScreen *s) {
         bar_draw(s);
         for(v=view; v; v=v->next)
                 view_arrange(v);
+}
+
+void
+bar_setbounds(int left, int right) {
+ Rectangle *r;
+
+ r = &screen->brect;
+ r->min.x = left;
+ r->max.x = right;
+ reshapewin(screen->barwin, *r);
+}
+
+void
+bar_sety(int y) {
+ Rectangle *r;
+ int dy;
+
+ r = &screen->brect;
+
+ dy = y - r->min.y;
+ r->min.y += dy;
+ r->max.y += dy;
+ reshapewin(screen->barwin, *r);
 }
 
 Bar*
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/client.c
--- a/cmd/wmii/client.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/client.c Tue Jan 22 17:55:53 2008 -0500
@@ -140,7 +140,6 @@ client_create(XWindow w, XWindowAttribut
         p.y = labelh(def.font);
         reparentwindow(&c->w, c->framewin, p);
 
- ewmh_initclient(c);
         group_init(c);
 
         grab_button(c->framewin->w, AnyButton, AnyModifier);
@@ -151,6 +150,8 @@ client_create(XWindow w, XWindowAttribut
                         *t = c;
                         break;
                 }
+
+ ewmh_initclient(c);
 
         event("CreateClient %C\n", c);
         client_manage(c);
@@ -269,7 +270,7 @@ client_viewframe(Client *c, View *v) {
         Frame *f;
 
         for(f=c->frame; f; f=f->cnext)
- if(f->area->view == v)
+ if(f->view == v)
                         break;
         return f;
 }
@@ -372,7 +373,7 @@ frame_hints(Frame *f, Rectangle r, Align
         if(!f->area->floating) {
                 /* Not allowed to grow */
                 if(Dx(r) > Dx(or))
- r.max.x =r.min.x+Dx(or);
+ r.max.x = r.min.x+Dx(or);
                 if(Dy(r) > Dy(or))
                         r.max.y = r.min.y+Dy(or);
         }
@@ -703,7 +704,7 @@ client_prop(Client *c, Atom a) {
         int n;
 
         if(a == xatom("WM_PROTOCOLS"))
- c->proto = winprotocols(&c->w);
+ c->proto = ewmh_protocols(&c->w);
         else
         if(a == xatom("_NET_WM_NAME"))
                 goto wmname;
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/column.c
--- a/cmd/wmii/column.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/column.c Tue Jan 22 17:55:53 2008 -0500
@@ -102,7 +102,10 @@ column_detach(Frame *f) {
 
         a = f->area;
         column_remove(f);
- column_arrange(a, false);
+ if(a->frame)
+ column_arrange(a, false);
+ else if(a->view->area->next->next)
+ area_destroy(a);
 }
 
 static void
@@ -238,10 +241,6 @@ column_arrange(Area *a, bool dirty) {
                 return;
 
         v = a->view;
- if(!a->frame) {
- view_arrange(v);
- return;
- }
 
         switch(a->mode) {
         case Coldefault:
@@ -290,7 +289,7 @@ column_resize(Area *a, int w) {
         a->r.max.x += dw;
         an->r.min.x += dw;
 
- view_arrange(a->view);
+ /* view_arrange(a->view); */
         view_focus(screen, a->view);
 }
 
@@ -300,7 +299,7 @@ column_resizeframe_h(Frame *f, Rectangle
         Frame *fn, *fp;
         uint minh;
 
- minh = 2 * labelh(def.font);
+ minh = labelh(def.font);
 
         a = f->area;
         fn = f->anext;
@@ -333,42 +332,41 @@ column_resizeframe(Frame *f, Rectangle *
         Area *a, *al, *ar;
         View *v;
         uint minw;
- int dx, dw, maxx;
 
         a = f->area;
         v = a->view;
- maxx = r->max.x;
 
         minw = Dx(v->r) / NCOL;
 
+ ar = a->next;
         al = a->prev;
- ar = a->next;
+ if(al == v->area)
+ al = nil;
 
         if(al)
                 r->min.x = max(r->min.x, al->r.min.x + minw);
         else
- r->min.x = max(r->min.x, 0);
+ r->min.x = max(r->min.x, v->r.min.x);
 
         if(ar)
- maxx = min(maxx, a->r.max.x - minw);
- else
- maxx = min(maxx, v->r.max.x);
-
- dx = a->r.min.x - r->min.x;
- dw = maxx - a->r.max.x;
+ r->max.x = min(r->max.x, ar->r.max.x - minw);
+ else
+ r->max.x = min(r->max.x, v->r.max.x);
+
+ a->r.min.x = r->min.x;
+ a->r.max.x = r->max.x;
         if(al) {
- al->r.max.x -= dx;
- column_arrange(al, False);
+ al->r.max.x = a->r.min.x;
+ column_arrange(al, false);
         }
         if(ar) {
- ar->r.max.x -= dw;
- column_arrange(ar, False);
+ ar->r.min.x = a->r.max.x;
+ column_arrange(ar, false);
         }
 
         column_resizeframe_h(f, r);
 
- a->r.max.x = maxx;
- view_arrange(a->view);
-
+ /* view_arrange(v); */
         view_focus(screen, v);
 }
+
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/dat.h
--- a/cmd/wmii/dat.h Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/dat.h Tue Jan 22 17:55:53 2008 -0500
@@ -80,6 +80,7 @@ enum DebugOpt {
         DEwmh = 1<<2,
         DFocus = 1<<3,
         DGeneric= 1<<4,
+ NDebugOpt = 5,
 };
 
 /* Data Structures */
@@ -329,9 +330,12 @@ EXTERN bool starting;
 EXTERN bool starting;
 EXTERN char* user;
 EXTERN char* execstr;
-EXTERN int debug;
+EXTERN int debugflag;
+EXTERN int debugfile;
 EXTERN long xtime;
 
-#define Debug(x) if(debug&(x))
-#define Dprint(x, ...) BLOCK( Debug(x) fprint(2, __VA_ARGS__) )
-
+extern char* debugtab[];
+
+#define Debug(x) if((debugflag|debugfile)&(x) && setdebug(x))
+#define Dprint(x, ...) BLOCK( debug(x, __VA_ARGS__) )
+
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/div.c
--- a/cmd/wmii/div.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/div.c Tue Jan 22 17:55:53 2008 -0500
@@ -53,7 +53,8 @@ div_set(Divide *d, int x) {
 
         d->x = x;
         r = rectaddpt(divimg->r, Pt(x - Dx(divimg->r)/2, 0));
- r.max.y = screen->brect.min.y;
+ r.min.y = screen->sel->r.min.y;
+ r.max.y = screen->sel->r.max.y;
 
         reshapewin(d->w, r);
         mapdiv(d);
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/ewmh.c
--- a/cmd/wmii/ewmh.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/ewmh.c Tue Jan 22 17:55:53 2008 -0500
@@ -78,7 +78,8 @@ ewmh_updateclientlist(void) {
         for(c=client; c; c=c->next)
                 i++;
         list = emalloc(i * sizeof *list);
- for(c=client, i=0; c; c=c->next)
+ i = 0;
+ for(c=client; c; c=c->next)
                 list[i++] = c->w.w;
         changeprop_long(&scr.root, Net("CLIENT_LIST"), "WINDOW", list, i);
 }
@@ -93,14 +94,18 @@ ewmh_updatestacking(void) {
         vector_linit(&vec);
 
         for(v=view; v; v=v->next)
- for(f=v->area->stack; f; f=f->snext)
- if(f->client->sel == f)
- vector_lpush(&vec, f->client->w.w);
- for(v=view; v; v=v->next)
                 for(a=v->area->next; a; a=a->next)
                         for(f=a->frame; f; f=f->anext)
                                 if(f->client->sel == f)
                                         vector_lpush(&vec, f->client->w.w);
+ for(v=view; v; v=v->next) {
+ for(f=v->area->stack; f; f=f->snext)
+ if(!f->snext)
+ break;
+ for(; f; f=f->sprev)
+ if(f->client->sel == f)
+ vector_lpush(&vec, f->client->w.w);
+ }
 
         changeprop_long(&scr.root, Net("CLIENT_LIST_STACKING"), "WINDOW", vec.ary, vec.n);
         vector_lfree(&vec);
@@ -115,6 +120,7 @@ ewmh_initclient(Client *c) {
         changeprop_long(&c->w, Net("WM_ALLOWED_ACTIONS"), "ATOM",
                 allowed, nelem(allowed));
         ewmh_getwintype(c);
+ ewmh_getstrut(c);
         ewmh_updateclientlist();
 }
 
@@ -128,6 +134,7 @@ ewmh_destroyclient(Client *c) {
         if(e->timer)
                 if(!ixp_unsettimer(&srv, e->timer))
                         fprint(2, "Badness: %C: Can't unset timer\n", c);
+ free(c->strut);
 }
 
 static void
@@ -252,18 +259,18 @@ ewmh_getstrut(Client *c) {
                 RightMin, RightMax,
                 TopMin, TopMax,
                 BottomMin, BottomMax,
- Last = BottomMax
+ Last
         };
         long *strut;
         ulong n;
 
- if(c->strut)
+ if(c->strut == nil)
                 free(c->strut);
         c->strut = nil;
 
         n = getprop_long(&c->w, Net("WM_STRUT_PARTIAL"), "CARDINAL",
                 0L, &strut, Last);
- if(n != nelem(strut)) {
+ if(n != Last) {
                 free(strut);
                 n = getprop_long(&c->w, Net("WM_STRUT"), "CARDINAL",
                         0L, &strut, 4L);
@@ -271,6 +278,7 @@ ewmh_getstrut(Client *c) {
                         free(strut);
                         return;
                 }
+ Dprint(DEwmh, "ewmh_getstrut(%C[%s]) Using WM_STRUT\n", c, clientname(c));
                 strut = erealloc(strut, Last * sizeof *strut);
                 strut[LeftMin] = strut[RightMin] = 0;
                 strut[LeftMax] = strut[RightMax] = INT_MAX;
@@ -282,7 +290,13 @@ ewmh_getstrut(Client *c) {
         c->strut->right = Rect(-strut[Right], strut[RightMin], 0, strut[RightMax]);
         c->strut->top = Rect(strut[TopMin], 0, strut[TopMax], strut[Top]);
         c->strut->bottom = Rect(strut[BottomMin], -strut[Bottom], strut[BottomMax], 0);
+ Dprint(DEwmh, "ewmh_getstrut(%C[%s])\n", c, clientname(c));
+ Dprint(DEwmh, "\ttop: %R\n", c->strut->top);
+ Dprint(DEwmh, "\tleft: %R\n", c->strut->left);
+ Dprint(DEwmh, "\tright: %R\n", c->strut->right);
+ Dprint(DEwmh, "\tbottom: %R\n", c->strut->bottom);
         free(strut);
+ view_focus(screen, screen->sel);
 }
 
 int
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/float.c
--- a/cmd/wmii/float.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/float.c Tue Jan 22 17:55:53 2008 -0500
@@ -28,7 +28,7 @@ float_detach(Frame *f) {
         v = f->view;
         a = f->area;
         sel = view_findarea(v, v->selcol, false);
- assert(sel);
+ assert(sel || !v->area->next);
         pr = f->aprev;
 
         frame_remove(f);
@@ -44,7 +44,7 @@ float_detach(Frame *f) {
         if(v->oldsel)
                 area_focus(v->oldsel);
         else if(!a->frame)
- if(sel->frame)
+ if(sel && sel->frame)
                         area_focus(sel);
 }
 
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/fns.h
--- a/cmd/wmii/fns.h Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/fns.h Tue Jan 22 17:55:53 2008 -0500
@@ -28,6 +28,8 @@ Bar* bar_find(Bar*, const char*);
 Bar* bar_find(Bar*, const char*);
 void bar_init(WMScreen*);
 void bar_resize(WMScreen*);
+void bar_sety(int);
+void bar_setbounds(int, int);
 
 /* client.c */
 int Cfmt(Fmt *f);
@@ -47,6 +49,7 @@ void client_resize(Client*, Rectangle);
 void client_resize(Client*, Rectangle);
 void client_setcursor(Client*, Cursor);
 void client_seturgent(Client*, bool, int);
+void client_setviews(Client*, char**);
 void client_unmap(Client*, int state);
 Frame* client_viewframe(Client *c, View *v);
 char* clientname(Client*);
@@ -173,6 +176,12 @@ char* readctl_view(View*);
 char* readctl_view(View*);
 Area* strarea(View*, const char*);
 void warning(const char*, ...);
+/* debug */
+void debug(int, const char*, ...);
+void dprint(const char*, ...);
+int getdebug(char*);
+bool setdebug(int);
+void vdebug(int, const char*, va_list);
 
 /* mouse.c */
 void mouse_resize(Client*, bool opaque, Align);
@@ -201,8 +210,8 @@ void view_scale(View*, int w);
 void view_scale(View*, int w);
 Client* view_selclient(View*);
 void view_select(const char*);
-void client_setviews(Client*, char**);
 void view_update_all(void);
+void view_update_rect(View*);
 Rectangle* view_rects(View*, uint *num, Frame *ignore);
 
 /* utf.c */
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/frame.c
--- a/cmd/wmii/frame.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/frame.c Tue Jan 22 17:55:53 2008 -0500
@@ -275,9 +275,10 @@ frame_client2rect(Frame *f, Rectangle r)
 
 void
 frame_resize(Frame *f, Rectangle r) {
+ Client *c;
+ Rectangle cr;
+ Point pt;
         Align stickycorner;
- Point pt;
- Client *c;
         int collapsed;
 
         c = f->client;
@@ -299,8 +300,8 @@ frame_resize(Frame *f, Rectangle r) {
         else
                 f->r = r;
 
- f->crect = frame_rect2client(f, f->crect);
- f->crect = rectsubpt(f->crect, f->crect.min);
+ cr = frame_rect2client(f, f->crect);
+ cr = rectsubpt(cr, cr.min);
 
         collapsed = f->collapsed;
 
@@ -311,14 +312,12 @@ frame_resize(Frame *f, Rectangle r) {
                         f->collapsed = False;
         }
 
- if(Dx(f->crect) < labelh(def.font)) {
+ if(Dx(cr) < labelh(def.font))
                 f->r.max.x = f->r.min.x + frame_delta_h();
- f->collapsed = True;
- }
 
         if(f->collapsed) {
                 f->r.max.y = f->r.min.y + labelh(def.font);
- f->crect = f->r;
+ cr = f->r;
         }
 
         if(collapsed != f->collapsed)
@@ -330,10 +329,10 @@ frame_resize(Frame *f, Rectangle r) {
         if(!f->client->titleless || !f->area->floating)
                 pt.y += labelh(def.font) - 1;
 
- if(f->area->floating)
+ if(f->area->floating && !f->client->strut)
                 f->r = constrain(f->r);
- pt.x = (Dx(f->r) - Dx(f->crect)) / 2;
- f->crect = rectaddpt(f->crect, pt);
+ pt.x = (Dx(f->r) - Dx(cr)) / 2;
+ f->crect = rectaddpt(cr, pt);
 }
 
 void
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/fs.c
--- a/cmd/wmii/fs.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/fs.c Tue Jan 22 17:55:53 2008 -0500
@@ -10,48 +10,96 @@
 
 /* Datatypes: */
 typedef struct Dirtab Dirtab;
+typedef struct FileId FileId;
+typedef struct PLink PLink;
+typedef struct Pending Pending;
+typedef struct RLink RLink;
+typedef struct Queue Queue;
+
+struct PLink {
+ PLink* next;
+ PLink* prev;
+ IxpFid* fid;
+ Queue* queue;
+ Pending* pending;
+};
+
+struct RLink {
+ RLink* next;
+ RLink* prev;
+ Ixp9Req* req;
+};
+
+struct Pending {
+ RLink req;
+ PLink fids;
+};
+
+struct Queue {
+ Queue* link;
+ char* dat;
+ long len;
+};
+
+static Pending events;
+static Pending pdebug[NDebugOpt];
+
 struct Dirtab {
- char *name;
+ char* name;
         uchar qtype;
         uint type;
         uint perm;
+ uint flags;
 };
 
-typedef struct FidLink FidLink;
-struct FidLink {
- FidLink *next;
- Fid *fid;
-};
-
-typedef struct FileId FileId;
 struct FileId {
- FileId *next;
+ FileId* next;
         union {
- void *ref;
- char *buf;
- Bar *bar;
- Bar **bar_p;
- View *view;
- Client *client;
- Ruleset *rule;
- CTuple *col;
+ Bar* bar;
+ Bar** bar_p;
+ CTuple* col;
+ Client* client;
+ PLink* p;
+ Ruleset* rule;
+ View* view;
+ char* buf;
+ void* ref;
         } p;
+ bool pending;
         uint id;
         uint index;
- Dirtab tab;
+ Dirtab tab;
         ushort nref;
         uchar volatil;
 };
 
+enum {
+ FLHide = 1,
+};
+
 /* Constants */
 enum { /* Dirs */
- FsRoot, FsDClient, FsDClients, FsDBars,
- FsDTag, FsDTags,
+ FsDBars,
+ FsDClient,
+ FsDClients,
+ FsDDebug,
+ FsDTag,
+ FsDTags,
+ FsRoot,
         /* Files */
- FsFBar, FsFCctl, FsFColRules, FsFClabel,
- FsFCtags, FsFEvent, FsFKeys, FsFRctl,
- FsFTagRules, FsFTctl, FsFTindex,
- FsFprops
+ FsFBar,
+ FsFCctl,
+ FsFClabel,
+ FsFColRules,
+ FsFCtags,
+ FsFDebug,
+ FsFEvent,
+ FsFKeys,
+ FsFRctl,
+ FsFTagRules,
+ FsFTctl,
+ FsFTindex,
+ FsFprops,
 };
 
 /* Error messages */
@@ -67,10 +115,6 @@ static char
 /* Global Vars */
 /***************/
 FileId *free_fileid;
-/* Pending, outgoing reads on /event */
-Ixp9Req *peventread, *oeventread;
-/* Fids for /event with pending reads */
-FidLink *peventfid;
 
 Ixp9Srv p9srv = {
         .open= fs_open,
@@ -93,6 +137,7 @@ dirtab_root[]= {{".", QTDIR, FsRoot,
 dirtab_root[]= {{".", QTDIR, FsRoot, 0500|DMDIR },
                   {"rbar", QTDIR, FsDBars, 0700|DMDIR },
                   {"lbar", QTDIR, FsDBars, 0700|DMDIR },
+ {"debug", QTDIR, FsDDebug, 0500|DMDIR, FLHide },
                   {"client", QTDIR, FsDClients, 0500|DMDIR },
                   {"tag", QTDIR, FsDTags, 0500|DMDIR },
                   {"ctl", QTAPPEND, FsFRctl, 0600|DMAPPEND },
@@ -110,6 +155,9 @@ dirtab_client[]= {{".", QTDIR, FsDClie
                   {"tags", QTFILE, FsFCtags, 0600 },
                   {"props", QTFILE, FsFprops, 0400 },
                   {nil}},
+dirtab_debug[]= {{".", QTDIR, FsDDebug, 0500|DMDIR, FLHide },
+ {"", QTFILE, FsFDebug, 0400 },
+ {nil}},
 dirtab_bars[]= {{".", QTDIR, FsDBars, 0700|DMDIR },
                   {"", QTFILE, FsFBar, 0600 },
                   {nil}},
@@ -120,11 +168,12 @@ dirtab_tag[]= {{".", QTDIR, FsDTag,
                   {"ctl", QTAPPEND, FsFTctl, 0600|DMAPPEND },
                   {"index", QTFILE, FsFTindex, 0400 },
                   {nil}};
-static Dirtab *dirtab[] = {
+static Dirtab* dirtab[] = {
         [FsRoot] = dirtab_root,
         [FsDBars] = dirtab_bars,
         [FsDClients] = dirtab_clients,
         [FsDClient] = dirtab_client,
+ [FsDDebug] = dirtab_debug,
         [FsDTags] = dirtab_tags,
         [FsDTag] = dirtab_tag,
 };
@@ -146,6 +195,7 @@ get_file(void) {
         temp->volatil = 0;
         temp->nref = 1;
         temp->next = nil;
+ temp->pending = false;
         return temp;
 }
 
@@ -255,52 +305,159 @@ message(Ixp9Req *r, MsgFunc fn) {
         return err;
 }
 
+/* FIXME: Move to external lib */
 static void
-respond_event(Ixp9Req *r) {
- FileId *f = r->fid->aux;
- if(f->p.buf) {
- r->ofcall.data = (void *)f->p.buf;
- r->ofcall.count = strlen(f->p.buf);
- respond(r, nil);
- f->p.buf = nil;
- }else{
- r->aux = peventread;
- peventread = r;
- }
+pending_respond(Ixp9Req *r) {
+ FileId *f;
+ PLink *p;
+ RLink *rl;
+ Queue *q;
+
+ f = r->fid->aux;
+ p = f->p.p;
+ assert(f->pending);
+ if(p->queue) {
+ q = p->queue;
+ p->queue = q->link;
+ r->ofcall.data = q->dat;
+ r->ofcall.count = q->len;
+ if(r->aux) {
+ rl = r->aux;
+ rl->next->prev = rl->prev;
+ rl->prev->next = rl->next;
+ free(rl);
+ }
+ respond(r, nil);
+ free(q);
+ }else {
+ rl = emallocz(sizeof *rl);
+ rl->req = r;
+ rl->next = &p->pending->req;
+ rl->prev = rl->next->prev;
+ rl->next->prev = rl;
+ rl->prev->next = rl;
+ r->aux = rl;
+ }
+}
+
+static void
+pending_write(Pending *p, char *dat, long n) {
+ RLink rl;
+ Queue **qp, *q;
+ PLink *pp;
+ RLink *rp;
+
+ if(n == 0)
+ return;
+
+ if(p->req.next == nil) {
+ p->req.next = &p->req;
+ p->req.prev = &p->req;
+ p->fids.prev = &p->fids;
+ p->fids.next = &p->fids;
+ }
+
+ for(pp=p->fids.next; pp != &p->fids; pp=pp->next) {
+ for(qp=&pp->queue; *qp; qp=&qp[0]->link)
+ ;
+ q = emallocz(sizeof *q);
+ q->dat = emalloc(n);
+ memcpy(q->dat, dat, n);
+ q->len = n;
+ *qp = q;
+ }
+ rl.next = &rl;
+ rl.prev = &rl;
+ if(p->req.next != &p->req) {
+ rl.next = p->req.next;
+ rl.prev = p->req.prev;
+ p->req.prev = &p->req;
+ p->req.next = &p->req;
+ }
+ rl.prev->next = &rl;
+ rl.next->prev = &rl;
+ while((rp = rl.next) != &rl)
+ pending_respond(rp->req);
+}
+
+static void
+pending_pushfid(Pending *p, IxpFid *f) {
+ PLink *pl;
+ FileId *fi;
+
+ if(p->req.next == nil) {
+ p->req.next = &p->req;
+ p->req.prev = &p->req;
+ p->fids.prev = &p->fids;
+ p->fids.next = &p->fids;
+ }
+
+ fi = f->aux;
+ pl = emallocz(sizeof *pl);
+ pl->fid = f;
+ pl->pending = p;
+ pl->next = &p->fids;
+ pl->prev = pl->next->prev;
+ pl->next->prev = pl;
+ pl->prev->next = pl;
+ fi->pending = true;
+ fi->p.p = pl;
 }
 
 void
 event(const char *format, ...) {
- uint len, slen;
         va_list ap;
- FidLink *f;
- FileId *fi;
- Ixp9Req *req;
 
         va_start(ap, format);
         vsnprint(buffer, sizeof(buffer), format, ap);
         va_end(ap);
 
- len = strlen(buffer);
- if(len == 0)
- return;
-
- for(f=peventfid; f; f=f->next) {
- fi = f->fid->aux;
-
- slen = 0;
- if(fi->p.buf)
- slen = strlen(fi->p.buf);
- fi->p.buf = erealloc(fi->p.buf, slen + len + 1);
- fi->p.buf[slen] = '\0';
- strcat(fi->p.buf, buffer);
- }
- oeventread = peventread;
- peventread = nil;
- while((req = oeventread)) {
- oeventread = oeventread->aux;
- respond_event(req);
- }
+ pending_write(&events, buffer, strlen(buffer));
+}
+
+static int dflags;
+bool
+setdebug(int flag) {
+ dflags = flag;
+ return true;
+}
+
+void
+vdebug(int flag, const char *fmt, va_list ap) {
+ char *s;
+ int i, len;
+
+ if(flag == 0)
+ flag = dflags;
+
+ s = vsmprint(fmt, ap);
+ len = strlen(s);
+
+ if(debugflag&flag)
+ print("%s", s);
+ if(debugfile&flag)
+ for(i=0; i < nelem(pdebug); i++)
+ if(flag & (1<<i))
+ pending_write(pdebug+i, s, len);
+ free(s);
+}
+
+void
+debug(int flag, const char *fmt, ...) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ vdebug(flag, fmt, ap);
+ va_end(ap);
+}
+
+void
+dprint(const char *fmt, ...) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ vdebug(0, fmt, ap);
+ va_end(ap);
 }
 
 static void
@@ -331,6 +488,7 @@ lookup_file(FileId *parent, char *name)
         View *v;
         Bar *b;
         uint id;
+ int i;
 
         if(!(parent->tab.perm & DMDIR))
                 return nil;
@@ -339,7 +497,7 @@ lookup_file(FileId *parent, char *name)
         ret = nil;
         for(; dir->name; dir++) {
                 /* Dynamic dirs */
- if(!*dir->name) { /* strlen(dir->name) == 0 */
+ if(dir->name[0] == '\0') {
                         switch(parent->tab.type) {
                         case FsDClients:
                                 if(!name || !strcmp(name, "sel")) {
@@ -347,7 +505,7 @@ lookup_file(FileId *parent, char *name)
                                                 file = get_file();
                                                 *last = file;
                                                 last = &file->next;
- file->volatil = True;
+ file->volatil = true;
                                                 file->p.client = c;
                                                 file->id = c->w.w;
                                                 file->index = c->w.w;
@@ -365,7 +523,7 @@ lookup_file(FileId *parent, char *name)
                                                 file = get_file();
                                                 *last = file;
                                                 last = &file->next;
- file->volatil = True;
+ file->volatil = true;
                                                 file->p.client = c;
                                                 file->id = c->w.w;
                                                 file->index = c->w.w;
@@ -376,13 +534,25 @@ lookup_file(FileId *parent, char *name)
                                         }
                                 }
                                 break;
+ case FsDDebug:
+ for(i=0; i < nelem(pdebug); i++)
+ if(!name || !strcmp(name, debugtab[i])) {
+ file = get_file();
+ *last = file;
+ last = &file->next;
+ file->id = i;
+ file->tab = *dir;
+ file->tab.name = estrdup(debugtab[i]);
+ if(name) goto LastItem;
+ }
+ break;
                         case FsDTags:
                                 if(!name || !strcmp(name, "sel")) {
                                         if(screen->sel) {
                                                 file = get_file();
                                                 *last = file;
                                                 last = &file->next;
- file->volatil = True;
+ file->volatil = true;
                                                 file->p.view = screen->sel;
                                                 file->id = screen->sel->id;
                                                 file->tab = *dir;
@@ -394,7 +564,7 @@ lookup_file(FileId *parent, char *name)
                                                 file = get_file();
                                                 *last = file;
                                                 last = &file->next;
- file->volatil = True;
+ file->volatil = true;
                                                 file->p.view = v;
                                                 file->id = v->id;
                                                 file->tab = *dir;
@@ -409,7 +579,7 @@ lookup_file(FileId *parent, char *name)
                                                 file = get_file();
                                                 *last = file;
                                                 last = &file->next;
- file->volatil = True;
+ file->volatil = true;
                                                 file->p.bar = b;
                                                 file->id = b->id;
                                                 file->tab = *dir;
@@ -420,7 +590,7 @@ lookup_file(FileId *parent, char *name)
                                 break;
                         }
                 }else /* Static dirs */
- if(!name || !strcmp(name, dir->name)) {
+ if(!name && !(dir->flags & FLHide) || name && !strcmp(name, dir->name)) {
                         file = get_file();
                         *last = file;
                         last = &file->next;
@@ -460,14 +630,14 @@ verify_file(FileId *f) {
         int ret;
 
         if(!f->next)
- return True;
-
- ret = False;
+ return true;
+
+ ret = false;
         if(verify_file(f->next)) {
                 nf = lookup_file(f->next, f->tab.name);
                 if(nf) {
                         if(!nf->volatil || nf->p.ref == f->p.ref)
- ret = True;
+ ret = true;
                         free_file(nf);
                 }
         }
@@ -631,6 +801,10 @@ fs_read(Ixp9Req *r) {
                 return;
         }
         else{
+ if(f->pending) {
+ pending_respond(r);
+ return;
+ }
                 switch(f->tab.type) {
                 case FsFprops:
                         write_buf(r, f->p.client->props, strlen(f->p.client->props));
@@ -683,9 +857,6 @@ fs_read(Ixp9Req *r) {
                         write_buf(r, buf, n);
                         respond(r, nil);
                         return;
- case FsFEvent:
- respond_event(r);
- return;
                 }
         }
         /*
@@ -777,8 +948,9 @@ fs_write(Ixp9Req *r) {
 
 void
 fs_open(Ixp9Req *r) {
- FidLink *fl;
- FileId *f = r->fid->aux;
+ FileId *f;
+
+ f = r->fid->aux;
 
         if(!verify_file(f)) {
                 respond(r, Enofile);
@@ -787,10 +959,11 @@ fs_open(Ixp9Req *r) {
 
         switch(f->tab.type) {
         case FsFEvent:
- fl = emallocz(sizeof(FidLink));
- fl->fid = r->fid;
- fl->next = peventfid;
- peventfid = fl;
+ pending_pushfid(&events, r->fid);
+ break;
+ case FsFDebug:
+ pending_pushfid(pdebug+f->id, r->fid);
+ debugfile |= 1<<f->id;
                 break;
         }
         if((r->ifcall.mode&3) == OEXEC) {
@@ -864,14 +1037,36 @@ fs_remove(Ixp9Req *r) {
 
 void
 fs_clunk(Ixp9Req *r) {
- FidLink **fl, *ft;
         FileId *f;
+ PLink *pl;
+ Queue *qu;
         char *p, *q;
         Client *c;
         IxpMsg m;
         
         f = r->fid->aux;
         if(!verify_file(f)) {
+ respond(r, nil);
+ return;
+ }
+
+ if(f->pending) {
+ /* Should probably be in freefid */
+ pl = f->p.p;
+ pl->prev->next = pl->next;
+ pl->next->prev = pl->prev;
+ while((qu = pl->queue)) {
+ pl->queue = qu->link;
+ free(qu->dat);
+ free(qu);
+ };
+ switch(f->tab.type) {
+ case FsFDebug:
+ if(pl->pending->fids.next == &pl->pending->fids)
+ debugfile &= ~(1<<f->id);
+ break;
+ }
+ free(pl);
                 respond(r, nil);
                 return;
         }
@@ -906,33 +1101,27 @@ fs_clunk(Ixp9Req *r) {
 
                 bar_draw(screen);
                 break;
- case FsFEvent:
- for(fl=&peventfid; *fl; fl=&fl[0]->next)
- if(fl[0]->fid == r->fid) {
- ft = fl[0];
- fl[0] = fl[0]->next;
- f = ft->fid->aux;
- free(f->p.buf);
- free(ft);
- break;
- }
- break;
         }
         respond(r, nil);
 }
 
 void
 fs_flush(Ixp9Req *r) {
- Ixp9Req **i, **j;
-
- for(i=&peventread; i != &oeventread; i=&oeventread)
- for(j=i; *j; j=(Ixp9Req**)&j[0]->aux)
- if(*j == r->oldreq) {
- j[0] = j[0]->aux;
- respond(r->oldreq, Einterrupted);
- goto done;
- }
-done:
+ Ixp9Req *or;
+ FileId *f;
+ RLink *rl;
+
+ or = r->oldreq;
+ f = or->fid->aux;
+ if(f->pending) {
+ rl = or->aux;
+ if(rl) {
+ rl->prev->next = rl->next;
+ rl->next->prev = rl->prev;
+ free(rl);
+ }
+ }
+ respond(r->oldreq, Einterrupted);
         respond(r, nil);
 }
 
@@ -946,3 +1135,4 @@ fs_freefid(Fid *f) {
                 free_file(id);
         }
 }
+
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/main.c
--- a/cmd/wmii/main.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/main.c Tue Jan 22 17:55:53 2008 -0500
@@ -379,9 +379,6 @@ main(int argc, char *argv[]) {
         case 'a':
                 address = EARGF(usage());
                 break;
- case 'G':
- debug |= DGeneric;
- break;
         case 'r':
                 wmiirc = EARGF(usage());
                 break;
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/message.c
--- a/cmd/wmii/message.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/message.c Tue Jan 22 17:55:53 2008 -0500
@@ -74,7 +74,7 @@ char *symtab[] = {
         "~",
 };
 
-char *debugtab[] = {
+char* debugtab[] = {
         "dnd",
         "event",
         "ewmh",
@@ -116,7 +116,7 @@ getsym(char *s) {
         return _bsearch(s, symtab, nelem(symtab));
 }
 
-static int
+int
 getdebug(char *s) {
         return _bsearch(s, debugtab, nelem(debugtab));
 }
@@ -429,9 +429,9 @@ msg_debug(IxpMsg *m) {
                         continue;
                 }
                 if(add == '+')
- debug |= 1<<d;
+ debugflag |= 1<<d;
                 else
- debug &= ~(1<<d);
+ debugflag &= ~(1<<d);
         }
         if(buffer[0] != '\0')
                 return sxprint("Bad debug options: %s", buffer+2);
@@ -663,7 +663,7 @@ msg_sendclient(View *v, IxpMsg *m, bool
 
         flushenterevents();
         frame_focus(f);
- view_arrange(v);
+ /* view_arrange(v); */
         view_update_all();
         return nil;
 }
@@ -698,7 +698,7 @@ msg_sendframe(Frame *f, int sym, bool sw
                 frame_insert(f, fp);
         }
 
- view_arrange(f->view);
+ /* view_arrange(f->view); */
 
         flushenterevents();
         frame_focus(f);
@@ -707,11 +707,11 @@ msg_sendframe(Frame *f, int sym, bool sw
 }
 
 static void
-printdebug(void) {
+printdebug(int mask) {
         int i, j;
 
         for(i=0, j=0; i < nelem(debugtab); i++)
- Debug(1<<i) {
+ if(mask & (1<<i)) {
                         if(j++ > 0)
                                 bufprint(" ");
                         bufprint("%s", debugtab[i]);
@@ -727,9 +727,14 @@ readctl_root(void) {
         bufprint("font %s\n", def.font->name);
         bufprint("grabmod %s\n", def.grabmod);
         bufprint("border %d\n", def.border);
- if(debug) {
+ if(debugflag) {
                 bufprint("debug ");
- printdebug();
+ printdebug(debugflag);
+ bufprint("\n");
+ }
+ if(debugfile) {
+ bufprint("debugfile ");
+ printdebug(debugfile);
                 bufprint("\n");
         }
         return buffer;
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/printevent.c
--- a/cmd/wmii/printevent.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/printevent.c Tue Jan 22 17:55:53 2008 -0500
@@ -113,36 +113,36 @@ strign(int key) {
 /******************************************************************************/
 
 static void
-TInt(Biobuf *b, va_list *ap) {
- Bprint(b, "%d", va_arg(*ap, int));
-}
-
-static void
-TWindow(Biobuf *b, va_list *ap) {
+TInt(Fmt *b, va_list *ap) {
+ fmtprint(b, "%d", va_arg(*ap, int));
+}
+
+static void
+TWindow(Fmt *b, va_list *ap) {
         Window w;
 
         w = va_arg(*ap, Window);
- Bprint(b, "0x%ux", (uint)w);
-}
-
-static void
-TData(Biobuf *b, va_list *ap) {
+ fmtprint(b, "0x%ux", (uint)w);
+}
+
+static void
+TData(Fmt *b, va_list *ap) {
         long *l;
         int i;
 
         l = va_arg(*ap, long*);
- Bprint(b, "{");
+ fmtprint(b, "{");
         for (i = 0; i < 5; i++) {
                 if(i > 0)
- Bprint(b, ", ");
- Bprint(b, "0x%08lx", l[i]);
+ fmtprint(b, ", ");
+ fmtprint(b, "0x%08lx", l[i]);
         }
- Bprint(b, "}");
+ fmtprint(b, "}");
 }
 
 /* Returns the string equivalent of a timestamp */
 static void
-TTime(Biobuf *b, va_list *ap) {
+TTime(Fmt *b, va_list *ap) {
         ldiv_t d;
         ulong msec;
         ulong sec;
@@ -169,12 +169,12 @@ TTime(Biobuf *b, va_list *ap) {
                 day, day == 1 ? "" : "(s)", hr, min, sec, msec);
 #endif
 
- Bprint(b, "%ludd_%ludh_%ludm_%lud.%03luds", day, hr, min, sec, msec);
+ fmtprint(b, "%ludd_%ludh_%ludm_%lud.%03luds", day, hr, min, sec, msec);
 }
 
 /* Returns the string equivalent of a boolean parameter */
 static void
-TBool(Biobuf *b, va_list *ap) {
+TBool(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {True, "True"},
                 {False, "False"},
@@ -183,12 +183,12 @@ TBool(Biobuf *b, va_list *ap) {
         Bool key;
 
         key = va_arg(*ap, Bool);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a property notify state */
 static void
-TPropState(Biobuf *b, va_list *ap) {
+TPropState(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {PropertyNewValue, "PropertyNewValue"},
                 {PropertyDelete, "PropertyDelete"},
@@ -197,12 +197,12 @@ TPropState(Biobuf *b, va_list *ap) {
         uint key;
 
         key = va_arg(*ap, uint);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a visibility notify state */
 static void
-TVis(Biobuf *b, va_list *ap) {
+TVis(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {VisibilityUnobscured, "VisibilityUnobscured"},
                 {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"},
@@ -212,12 +212,12 @@ TVis(Biobuf *b, va_list *ap) {
         int key;
 
         key = va_arg(*ap, int);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a mask of buttons and/or modifier keys */
 static void
-TModState(Biobuf *b, va_list *ap) {
+TModState(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {Button1Mask, "Button1Mask"},
                 {Button2Mask, "Button2Mask"},
@@ -237,12 +237,12 @@ TModState(Biobuf *b, va_list *ap) {
         uint state;
 
         state = va_arg(*ap, uint);
- Bprint(b, "%s", unmask(list, state));
+ fmtprint(b, "%s", unmask(list, state));
 }
 
 /* Returns the string equivalent of a mask of configure window values */
 static void
-TConfMask(Biobuf *b, va_list *ap) {
+TConfMask(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {CWX, "CWX"},
                 {CWY, "CWY"},
@@ -256,13 +256,13 @@ TConfMask(Biobuf *b, va_list *ap) {
         uint valuemask;
 
         valuemask = va_arg(*ap, uint);
- Bprint(b, "%s", unmask(list, valuemask));
+ fmtprint(b, "%s", unmask(list, valuemask));
 }
 
 /* Returns the string equivalent of a motion hint */
 #if 0
 static void
-IsHint(Biobuf *b, va_list *ap) {
+IsHint(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {NotifyNormal, "NotifyNormal"},
                 {NotifyHint, "NotifyHint"},
@@ -271,13 +271,13 @@ IsHint(Biobuf *b, va_list *ap) {
         char key;
 
         key = va_arg(*ap, char);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 #endif
 
 /* Returns the string equivalent of an id or the value "None" */
 static void
-TIntNone(Biobuf *b, va_list *ap) {
+TIntNone(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {None, "None"},
                 {0, nil},
@@ -285,12 +285,12 @@ TIntNone(Biobuf *b, va_list *ap) {
         int key;
 
         key = va_arg(*ap, int);
- Bprint(b, "%s", search(list, key, strhex));
+ fmtprint(b, "%s", search(list, key, strhex));
 }
 
 /* Returns the string equivalent of a colormap state */
 static void
-TColMap(Biobuf *b, va_list *ap) {
+TColMap(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {ColormapInstalled, "ColormapInstalled"},
                 {ColormapUninstalled, "ColormapUninstalled"},
@@ -299,12 +299,12 @@ TColMap(Biobuf *b, va_list *ap) {
         int key;
 
         key = va_arg(*ap, int);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a crossing detail */
 static void
-TXing(Biobuf *b, va_list *ap) {
+TXing(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {NotifyAncestor, "NotifyAncestor"},
                 {NotifyInferior, "NotifyInferior"},
@@ -316,12 +316,12 @@ TXing(Biobuf *b, va_list *ap) {
         int key;
 
         key = va_arg(*ap, int);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a focus change detail */
 static void
-TFocus(Biobuf *b, va_list *ap) {
+TFocus(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {NotifyAncestor, "NotifyAncestor"},
                 {NotifyInferior, "NotifyInferior"},
@@ -336,12 +336,12 @@ TFocus(Biobuf *b, va_list *ap) {
         int key;
 
         key = va_arg(*ap, int);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a configure detail */
 static void
-TConfDetail(Biobuf *b, va_list *ap) {
+TConfDetail(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {Above, "Above"},
                 {Below, "Below"},
@@ -353,12 +353,12 @@ TConfDetail(Biobuf *b, va_list *ap) {
         int key;
 
         key = va_arg(*ap, int);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a grab mode */
 static void
-TGrabMode(Biobuf *b, va_list *ap) {
+TGrabMode(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {NotifyNormal, "NotifyNormal"},
                 {NotifyGrab, "NotifyGrab"},
@@ -369,12 +369,12 @@ TGrabMode(Biobuf *b, va_list *ap) {
         int key;
 
         key = va_arg(*ap, int);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a mapping request */
 static void
-TMapping(Biobuf *b, va_list *ap) {
+TMapping(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {MappingModifier, "MappingModifier"},
                 {MappingKeyboard, "MappingKeyboard"},
@@ -384,12 +384,12 @@ TMapping(Biobuf *b, va_list *ap) {
         int key;
 
         key = va_arg(*ap, int);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a stacking order place */
 static void
-TPlace(Biobuf *b, va_list *ap) {
+TPlace(Fmt *b, va_list *ap) {
         static Pair list[] = {
                 {PlaceOnTop, "PlaceOnTop"},
                 {PlaceOnBottom, "PlaceOnBottom"},
@@ -398,12 +398,12 @@ TPlace(Biobuf *b, va_list *ap) {
         int key;
 
         key = va_arg(*ap, int);
- Bprint(b, "%s", search(list, key, strign));
+ fmtprint(b, "%s", search(list, key, strign));
 }
 
 /* Returns the string equivalent of a major code */
 static void
-TMajor(Biobuf *b, va_list *ap) {
+TMajor(Fmt *b, va_list *ap) {
         static char *list[] = { XMajors };
         char *s;
         uint key;
@@ -412,7 +412,7 @@ TMajor(Biobuf *b, va_list *ap) {
         s = "<nil>";
         if(key < nelem(list))
                 s = list[key];
- Bprint(b, "%s", s);
+ fmtprint(b, "%s", s);
 }
 
 static char*
@@ -457,7 +457,7 @@ eventtype(int key) {
 }
 /* Returns the string equivalent the keycode contained in the key event */
 static void
-TKeycode(Biobuf *b, va_list *ap) {
+TKeycode(Fmt *b, va_list *ap) {
         KeySym keysym_str;
         XKeyEvent *ev;
         char *keysym_name;
@@ -473,55 +473,65 @@ TKeycode(Biobuf *b, va_list *ap) {
         if(keysym_name == nil)
                 keysym_name = "(no name)";
 
- Bprint(b, "%ud (keysym 0x%x \"%s\")", (int)ev->keycode,
+ fmtprint(b, "%ud (keysym 0x%x \"%s\")", (int)ev->keycode,
                         (int)keysym_str, keysym_name);
 }
 
 /* Returns the string equivalent of an atom or "None" */
 static void
-TAtom(Biobuf *b, va_list *ap) {
+TAtom(Fmt *b, va_list *ap) {
         char *atom_name;
         Atom atom;
 
         atom = va_arg(*ap, Atom);
         atom_name = XGetAtomName(display, atom);
- Bprint(b, "%s", atom_name);
+ fmtprint(b, "%s", atom_name);
         XFree(atom_name);
 }
 
 #define _(m) #m, ev->m
 #define TEnd nil
-typedef void (*Tfn)(Biobuf*, va_list*);
-
-static void
-pevent(void *ev, ...) {
- static Biobuf *b;
+typedef void (*Tfn)(Fmt*, va_list*);
+
+static void
+pevent(void *e, ...) {
+ Fmt f;
         va_list ap;
         Tfn fn;
- char *key;
+ XAnyEvent *ev;
+ char *key, *s;
         int n;
 
- if(b == nil)
- b = Bfdopen(2, O_WRONLY);
+ if(fmtstrinit(&f) < 0)
+ return;
+
+ ev = e;
+ fmtprint(&f, "%3ld %-20s ", ev->serial, eventtype(ev->type));
+ if(ev->send_event)
+ fmtprint(&f, "(sendevent) ");
 
         n = 0;
- va_start(ap, ev);
+ va_start(ap, e);
         for(;;) {
                 fn = va_arg(ap, Tfn);
                 if(fn == TEnd)
                         break;
 
                 if(n++ != 0)
- Bprint(b, "%s", sep);
+ fmtprint(&f, "%s", sep);
 
                 key = va_arg(ap, char*);
- Bprint(b, "%s=", key);
- fn(b, &ap);
+ fmtprint(&f, "%s=", key);
+ fn(&f, &ap);
         }
         va_end(ap);
 
- Bprint(b, "\n");
- Bflush(b);
+ fmtprint(&f, "\n");
+ s = fmtstrflush(&f);
+
+ void dprint(const char*, ...);
+ dprint("%s", s);
+ free(s);
 }
 
 /*****************************************************************************/
@@ -937,10 +947,6 @@ void
 void
 printevent(XEvent *e) {
         XAnyEvent *ev = &e->xany;
-
- fprint(2, "%3ld %-20s ", ev->serial, eventtype(e->xany.type));
- if(ev->send_event)
- fprint(2, "(sendevent) ");
         /*
                 fprintf(stderr, "type=%s%s", eventtype(e->xany.type), sep);
                 fprintf(stderr, "serial=%lu%s", ev->serial, sep);
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/view.c
--- a/cmd/wmii/view.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/view.c Tue Jan 22 17:55:53 2008 -0500
@@ -68,6 +68,7 @@ view_create(const char *name) {
         v->next = *i;
         *i = v;
 
+ view_arrange(v);
         if(!screen->sel)
                 _view_select(v);
         ewmh_updateviews();
@@ -122,6 +123,54 @@ update_frame_selectors(View *v) {
 }
 
 void
+view_update_rect(View *v) {
+ Rectangle r, sr, brect;
+ Strut *strut;
+ Frame *f;
+ int left, right, top, bottom;
+
+ top = 0;
+ left = 0;
+ right = 0;
+ bottom = 0;
+ for(f=v->area->frame; f; f=f->anext) {
+ strut = f->client->strut;
+ if(!strut)
+ continue;
+ /* Can do better in the future. */
+ top = max(top, strut->top.max.y);
+ left = max(left, strut->left.max.x);
+ right = min(right, strut->right.min.x);
+ bottom = min(bottom, strut->bottom.min.y);
+ }
+ r = screen->r;
+ r.min.y += min(top, .3 * Dy(screen->r));
+ r.min.x += min(left, .3 * Dx(screen->r));
+ r.max.x += max(right, -.3 * Dx(screen->r));
+ r.max.y += max(bottom, -.3 * Dy(screen->r));
+ r.max.y -= Dy(screen->brect);
+ v->r = r;
+
+ bar_sety(r.max.y);
+ brect = screen->brect;
+ brect.min.x = screen->r.min.x;
+ brect.max.x = screen->r.max.x;
+ for(f=v->area->frame; f; f=f->anext) {
+ /* This is not pretty. :( */
+ strut = f->client->strut;
+ if(!strut)
+ continue;
+ sr = strut->left;
+ if(rect_intersect_p(brect, sr))
+ brect.min.x = sr.max.x;
+ sr = rectaddpt(strut->right, screen->r.max);
+ if(rect_intersect_p(brect, sr))
+ brect.max.x = sr.min.x;
+ }
+ bar_setbounds(brect.min.x, brect.max.x);
+}
+
+void
 view_focus(WMScreen *s, View *v) {
         Client *c;
         Frame *f, *fnext;
@@ -133,6 +182,7 @@ view_focus(WMScreen *s, View *v) {
         XGrabServer(display);
 
         _view_select(v);
+ view_arrange(v);
         update_frame_selectors(v);
         div_update_all();
         fscrn = false;
@@ -257,7 +307,7 @@ view_scale(View *v, int w) {
         uint minwidth;
         Area *a;
         float scale;
- int wdiff, dx;
+ int dx;
 
         minwidth = Dx(v->r)/NCOL;
 
@@ -272,12 +322,12 @@ view_scale(View *v, int w) {
         }
 
         scale = (float)w / dx;
- xoff = 0;
+ xoff = v->r.min.x;
         for(a=v->area->next; a; a=a->next) {
                 a->r.max.x = xoff + Dx(a->r) * scale;
                 a->r.min.x = xoff;
                 if(!a->next)
- a->r.max.x = w;
+ a->r.max.x = v->r.min.x + w;
                 xoff = a->r.max.x;
         }
 
@@ -286,42 +336,38 @@ view_scale(View *v, int w) {
         if(numcol * minwidth > w)
                 return;
 
- dx = numcol * minwidth;
- xoff = 0;
- for(a=v->area->next, numcol--; a; a=a->next, numcol--) {
+ xoff = v->r.min.x;
+ for(a=v->area->next; a; a=a->next) {
                 a->r.min.x = xoff;
 
                 if(Dx(a->r) < minwidth)
                         a->r.max.x = xoff + minwidth;
- else if((wdiff = xoff + Dx(a->r) - w + dx) > 0)
- a->r.max.x -= wdiff;
                 if(!a->next)
- a->r.max.x = w;
+ a->r.max.x = v->r.min.x + w;
                 xoff = a->r.max.x;
         }
 }
 
 void
 view_arrange(View *v) {
- uint xoff;
- Area *a, *anext;
+ Area *a;
 
         if(!v->area->next)
                 return;
-
- view_scale(v, Dx(v->r));
- xoff = 0;
+ /*
         for(a=v->area->next; a; a=anext) {
                 anext = a->next;
                 if(!a->frame && v->area->next->next)
                         area_destroy(a);
         }
+ */
+ view_update_rect(v);
+ view_scale(v, Dx(v->r));
         for(a=v->area->next; a; a=a->next) {
- a->r.min.x = xoff;
- a->r.min.y = 0;
- a->r.max.y = screen->brect.min.y;
- xoff = a->r.max.x;
- column_arrange(a, False);
+ /* This is wrong... */
+ a->r.min.y = v->r.min.y;
+ a->r.max.y = v->r.max.y;
+ column_arrange(a, false);
         }
         if(v == screen->sel)
                 div_update_all();
diff -r 868fa3e8da2a -r da34a112f02f cmd/wmii/x11.c
--- a/cmd/wmii/x11.c Mon Jan 21 23:25:30 2008 -0500
+++ b/cmd/wmii/x11.c Tue Jan 22 17:55:53 2008 -0500
@@ -332,11 +332,6 @@ findwin(XWindow w) {
         return nil;
 }
 
-long
-winprotocols(Window *w) {
- return ewmh_protocols(w);
-}
-
 /* Shape */
 void
 setshapemask(Window *dst, Image *src, Point pt) {
Received on Tue Jan 22 2008 - 23:58:16 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 15:59:08 UTC