diff -r ee36ffbd4252 config.def.h --- a/config.def.h Sun Nov 06 20:36:23 2011 +0100 +++ b/config.def.h Mon Nov 07 11:03:20 2011 +0800 @@ -29,9 +29,9 @@ static const Layout layouts[] = { /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, + { "[]=", tileh, tilev, tilev }, /* first entry is default */ + { "><>", NULL, NULL, NULL }, /* no layout function means floating behavior */ + { "[M]", monocle, monocle, monocle }, }; /* key definitions */ diff -r ee36ffbd4252 dwm.c --- a/dwm.c Sun Nov 06 20:36:23 2011 +0100 +++ b/dwm.c Mon Nov 07 11:03:20 2011 +0800 @@ -121,7 +121,9 @@ typedef struct { const char *symbol; - void (*arrange)(Monitor *); + void (*arrange)(Client *, float, XRectangle *, XRectangle *); + void (*master)(Client *, float, XRectangle *, XRectangle *); + void (*slave)(Client *, float, XRectangle *, XRectangle *); } Layout; struct Monitor { @@ -199,7 +201,7 @@ static void manage(Window w, XWindowAttributes *wa); static void mappingnotify(XEvent *e); static void maprequest(XEvent *e); -static void monocle(Monitor *m); +static void monocle(Client *c, float fact, XRectangle *r, XRectangle *rp); static void movemouse(const Arg *arg); static Client *nexttiled(Client *c); static void pop(Client *); @@ -226,7 +228,8 @@ static void tag(const Arg *arg); static void tagmon(const Arg *arg); static int textnw(const char *text, unsigned int len); -static void tile(Monitor *); +static void tileh(Client *c, float fact, XRectangle *r, XRectangle *rp); +static void tilev(Client *c, float fact, XRectangle *r, XRectangle *rp); static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); static void toggletag(const Arg *arg); @@ -403,9 +406,28 @@ void arrangemon(Monitor *m) { + XRectangle r, rm, rt = { m->wx, m->wy, m->ww, m->wh }; + Client *c; + float f; + int i, n; + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if(m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); + if(m->lt[m->sellt]->arrange) { + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if(n > 0) { + if((f = (n > m->nmaster) ? (m->nmaster == 0 ? 0 : m->mfact) : 1) < 0) { + rm = rt; + m->lt[m->sellt]->arrange(NULL, 1 + f, &rm, &rt); + } + else + m->lt[m->sellt]->arrange(NULL, f, &rt, &rm); + for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if(i < m->nmaster) + m->lt[m->sellt]->master(c, 1.0 / (MIN(n, m->nmaster) - i), &rm, &r); + else + m->lt[m->sellt]->slave(c, 1.0 / (n - i), &rt, &r); + } + } restack(m); } @@ -1188,17 +1210,13 @@ } void -monocle(Monitor *m) { - unsigned int n = 0; - Client *c; - - for(c = m->clients; c; c = c->next) - if(ISVISIBLE(c)) - n++; - if(n > 0) /* override layout symbol */ - snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); - for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False); +monocle(Client *c, float fact, XRectangle *r, XRectangle *rp) { + rp->x = r->x; + rp->y = r->y; + rp->width = r->width; + rp->height = r->height; + if(c) + resize(c, r->x, r->y, r->width - (2*c->bw), r->height - (2*c->bw), False); } void @@ -1553,13 +1571,15 @@ void setmfact(const Arg *arg) { float f; + int i; if(!arg || !selmon->lt[selmon->sellt]->arrange) return; - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + i = selmon->mfact < 0 ? -1 : 1; + f = arg->f < 1.0 ? arg->f + selmon->mfact * i : arg->f - 1.0; if(f < 0.1 || f > 0.9) return; - selmon->mfact = f; + selmon->mfact = f * i; arrange(selmon); } @@ -1686,29 +1706,27 @@ } void -tile(Monitor *m) { - unsigned int i, n, h, mw, my, ty; - Client *c; +tileh(Client *c, float fact, XRectangle *r, XRectangle *rp) { + rp->x = r->x; + rp->y = r->y; + rp->width = r->width * fact; + rp->height = r->height; + if(c) + resize(c, rp->x, rp->y, rp->width - (2*c->bw), rp->height - (2*c->bw), False); + r->x += c ? WIDTH(c) : rp->width; + r->width -= c ? WIDTH(c) : rp->width; +} - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if(n == 0) - return; - - if(n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww; - for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if(i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); - my += HEIGHT(c); - } - else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), False); - ty += HEIGHT(c); - } +void +tilev(Client *c, float fact, XRectangle *r, XRectangle *rp) { + rp->x = r->x; + rp->y = r->y; + rp->width = r->width; + rp->height = r->height * fact; + if(c) + resize(c, rp->x, rp->y, rp->width - (2*c->bw), rp->height - (2*c->bw), False); + r->y += c ? HEIGHT(c) : rp->height; + r->height -= c ? HEIGHT(c) : rp->height; } void