wmii

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

commit 3f38f6433cdee083f593d2d8e1f9b27416218f9a
parent 916c1cf0b8bdc115878cd972af5bed6ea92b73cd
Author: Kris Maglione <jg@suckless.org>
Date:   Tue, 22 Jan 2008 17:55:53 -0500

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

Diffstat:
cmd/util.c | 2+-
cmd/wmii/area.c | 5++++-
cmd/wmii/bar.c | 23+++++++++++++++++++++++
cmd/wmii/client.c | 9+++++----
cmd/wmii/column.c | 42++++++++++++++++++++----------------------
cmd/wmii/dat.h | 10+++++++---
cmd/wmii/div.c | 3++-
cmd/wmii/ewmh.c | 30++++++++++++++++++++++--------
cmd/wmii/float.c | 4++--
cmd/wmii/fns.h | 11++++++++++-
cmd/wmii/frame.c | 21++++++++++-----------
cmd/wmii/fs.c | 392++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
cmd/wmii/main.c | 3---
cmd/wmii/message.c | 25+++++++++++++++----------
cmd/wmii/printevent.c | 128+++++++++++++++++++++++++++++++++++++++++--------------------------------------
cmd/wmii/view.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
cmd/wmii/x11.c | 5-----
17 files changed, 544 insertions(+), 253 deletions(-)

diff --git a/cmd/util.c b/cmd/util.c @@ -81,7 +81,7 @@ sxprint(const char *fmt, ...) { 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 --git a/cmd/wmii/area.c b/cmd/wmii/area.c @@ -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 --git a/cmd/wmii/bar.c b/cmd/wmii/bar.c @@ -48,6 +48,29 @@ bar_resize(WMScreen *s) { 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* bar_create(Bar **bp, const char *name) { static uint id = 1; diff --git a/cmd/wmii/client.c b/cmd/wmii/client.c @@ -140,7 +140,6 @@ client_create(XWindow w, XWindowAttributes *wa) { p.y = labelh(def.font); reparentwindow(&c->w, c->framewin, p); - ewmh_initclient(c); group_init(c); grab_button(c->framewin->w, AnyButton, AnyModifier); @@ -152,6 +151,8 @@ client_create(XWindow w, XWindowAttributes *wa) { break; } + ewmh_initclient(c); + event("CreateClient %C\n", c); client_manage(c); return 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 sticky) { 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 --git a/cmd/wmii/column.c b/cmd/wmii/column.c @@ -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 *r) { 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 *r) { 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; - al = a->prev; ar = a->next; + al = a->prev; + 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); + r->max.x = min(r->max.x, ar->r.max.x - minw); else - maxx = min(maxx, v->r.max.x); + r->max.x = min(r->max.x, v->r.max.x); - dx = a->r.min.x - r->min.x; - dw = maxx - a->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 --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h @@ -80,6 +80,7 @@ enum DebugOpt { DEwmh = 1<<2, DFocus = 1<<3, DGeneric= 1<<4, + NDebugOpt = 5, }; /* Data Structures */ @@ -329,9 +330,12 @@ EXTERN XHandler handler[LASTEvent]; 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 --git a/cmd/wmii/div.c b/cmd/wmii/div.c @@ -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 --git a/cmd/wmii/ewmh.c b/cmd/wmii/ewmh.c @@ -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 --git a/cmd/wmii/float.c b/cmd/wmii/float.c @@ -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 --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h @@ -28,6 +28,8 @@ void bar_draw(WMScreen*); 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_reparent(Client*, Window*, Point); 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_root(void); 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_restack(View*); 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 --git a/cmd/wmii/frame.c b/cmd/wmii/frame.c @@ -275,9 +275,10 @@ frame_client2rect(Frame *f, Rectangle r) { void frame_resize(Frame *f, Rectangle r) { - Align stickycorner; - Point pt; Client *c; + Rectangle cr; + Point pt; + Align stickycorner; 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 --git a/cmd/wmii/fs.c b/cmd/wmii/fs.c @@ -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 @@ static Dirtab 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, FsDClient, 0500|DMDIR }, {"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, 0500|DMDIR }, {"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); +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); - f->p.buf = nil; - }else{ - r->aux = peventread; - peventread = r; + 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; + pending_write(&events, buffer, strlen(buffer)); +} - for(f=peventfid; f; f=f->next) { - fi = f->fid->aux; +static int dflags; +bool +setdebug(int flag) { + dflags = flag; + return true; +} - 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); - } +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; + return true; - ret = False; + 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,8 +1037,9 @@ 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; @@ -876,6 +1050,27 @@ fs_clunk(Ixp9Req *r) { 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; + } + switch(f->tab.type) { case FsFColRules: update_rules(&f->p.rule->rule, f->p.rule->string); @@ -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 --git a/cmd/wmii/main.c b/cmd/wmii/main.c @@ -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 --git a/cmd/wmii/message.c b/cmd/wmii/message.c @@ -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 swap) { 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 swap) { 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 swap) { } 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 --git a/cmd/wmii/printevent.c b/cmd/wmii/printevent.c @@ -113,36 +113,36 @@ strign(int key) { /******************************************************************************/ static void -TInt(Biobuf *b, va_list *ap) { - Bprint(b, "%d", va_arg(*ap, int)); +TInt(Fmt *b, va_list *ap) { + fmtprint(b, "%d", va_arg(*ap, int)); } static void -TWindow(Biobuf *b, va_list *ap) { +TWindow(Fmt *b, va_list *ap) { Window w; w = va_arg(*ap, Window); - Bprint(b, "0x%ux", (uint)w); + fmtprint(b, "0x%ux", (uint)w); } static void -TData(Biobuf *b, va_list *ap) { +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*); +typedef void (*Tfn)(Fmt*, va_list*); static void -pevent(void *ev, ...) { - static Biobuf *b; +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 @@ struct Handler { 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 --git a/cmd/wmii/view.c b/cmd/wmii/view.c @@ -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 --git a/cmd/wmii/x11.c b/cmd/wmii/x11.c @@ -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) {