arg@644: /* (C)opyright MMVI-MMVII Anselm R. Garbe arg@327: * See LICENSE file for license details. arg@327: */ arg@327: #include "dwm.h" arg@674: #include arg@327: arg@380: /* static */ arg@380: arg@382: static Client * arg@480: nexttiled(Client *c) { arg@480: for(c = getnext(c); c && c->isfloat; c = getnext(c->next)); arg@480: return c; arg@480: } arg@480: arg@442: static void arg@532: togglemax(Client *c) { arg@481: XEvent ev; arg@548: arg@549: if(c->isfixed) arg@548: return; arg@532: arg@480: if((c->ismax = !c->ismax)) { arg@565: c->rx = c->x; c->x = wax; arg@565: c->ry = c->y; c->y = way; arg@565: c->rw = c->w; c->w = waw - 2 * BORDERPX; arg@565: c->rh = c->h; c->h = wah - 2 * BORDERPX; arg@480: } arg@480: else { arg@480: c->x = c->rx; arg@480: c->y = c->ry; arg@481: c->w = c->rw; arg@481: c->h = c->rh; arg@480: } arg@708: resize(c, True); arg@480: while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); arg@430: } arg@430: arg@327: /* extern */ arg@327: arg@533: void (*arrange)(void) = DEFMODE; arg@327: arg@327: void arg@461: detach(Client *c) { arg@378: if(c->prev) arg@378: c->prev->next = c->next; arg@378: if(c->next) arg@378: c->next->prev = c->prev; arg@378: if(c == clients) arg@378: clients = c->next; arg@378: c->next = c->prev = NULL; arg@378: } arg@378: arg@378: void arg@533: dofloat(void) { arg@402: Client *c; arg@400: arg@327: for(c = clients; c; c = c->next) { arg@327: if(isvisible(c)) { arg@708: resize(c, True); arg@327: } arg@327: else arg@687: XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); arg@327: } arg@446: if(!sel || !isvisible(sel)) { arg@450: for(c = stack; c && !isvisible(c); c = c->snext); arg@450: focus(c); arg@446: } arg@327: restack(); arg@327: } arg@327: arg@327: void arg@533: dotile(void) { arg@650: unsigned int i, n, mw, mh, tw, th; arg@402: Client *c; arg@400: arg@488: for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) arg@488: n++; arg@650: /* window geoms */ arg@682: mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1); arg@682: mw = (n > nmaster) ? (waw * master) / 1000 : waw; arg@678: th = (n > nmaster) ? wah / (n - nmaster) : 0; arg@650: tw = waw - mw; arg@327: arg@535: for(i = 0, c = clients; c; c = c->next) arg@327: if(isvisible(c)) { arg@327: if(c->isfloat) { arg@708: resize(c, True); arg@327: continue; arg@327: } arg@488: c->ismax = False; arg@565: c->x = wax; arg@565: c->y = way; arg@682: if(i < nmaster) { arg@650: c->y += i * mh; arg@650: c->w = mw - 2 * BORDERPX; arg@650: c->h = mh - 2 * BORDERPX; arg@507: } arg@523: else { /* tile window */ arg@650: c->x += mw; arg@650: c->w = tw - 2 * BORDERPX; arg@726: if(th > 2 * BORDERPX) { arg@650: c->y += (i - nmaster) * th; arg@565: c->h = th - 2 * BORDERPX; arg@507: } arg@726: else /* fallback if th <= 2 * BORDERPX */ arg@565: c->h = wah - 2 * BORDERPX; arg@327: } arg@708: resize(c, False); arg@535: i++; arg@327: } arg@327: else arg@687: XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); arg@446: if(!sel || !isvisible(sel)) { arg@450: for(c = stack; c && !isvisible(c); c = c->snext); arg@450: focus(c); arg@446: } arg@327: restack(); arg@327: } arg@327: arg@327: void arg@461: focusnext(Arg *arg) { arg@327: Client *c; arg@327: arg@327: if(!sel) arg@327: return; arg@327: if(!(c = getnext(sel->next))) arg@327: c = getnext(clients); arg@327: if(c) { arg@327: focus(c); arg@327: restack(); arg@327: } arg@327: } arg@327: arg@327: void arg@461: focusprev(Arg *arg) { arg@327: Client *c; arg@327: arg@327: if(!sel) arg@327: return; arg@327: if(!(c = getprev(sel->prev))) { arg@327: for(c = clients; c && c->next; c = c->next); arg@327: c = getprev(c); arg@327: } arg@327: if(c) { arg@327: focus(c); arg@327: restack(); arg@327: } arg@327: } arg@327: arg@650: void arg@650: incnmaster(Arg *arg) { arg@721: if((arrange == dofloat) || (nmaster + arg->i < 1) arg@726: || (wah / (nmaster + arg->i) <= 2 * BORDERPX)) arg@650: return; arg@650: nmaster += arg->i; arg@674: if(sel) arg@674: arrange(); arg@674: else arg@674: drawstatus(); arg@650: } arg@650: arg@420: Bool arg@461: isvisible(Client *c) { arg@420: unsigned int i; arg@420: arg@420: for(i = 0; i < ntags; i++) arg@420: if(c->tags[i] && seltag[i]) arg@420: return True; arg@420: return False; arg@420: } arg@420: arg@415: void arg@559: resizemaster(Arg *arg) { arg@561: if(arg->i == 0) arg@561: master = MASTER; arg@561: else { arg@726: if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX arg@726: || waw * (master + arg->i) / 1000 <= 2 * BORDERPX) arg@561: return; arg@561: master += arg->i; arg@561: } arg@533: arrange(); arg@415: } arg@415: arg@327: void arg@487: restack(void) { arg@327: Client *c; arg@327: XEvent ev; arg@481: arg@691: drawstatus(); arg@691: if(!sel) arg@436: return; arg@687: if(sel->isfloat || arrange == dofloat) arg@436: XRaiseWindow(dpy, sel->win); arg@512: if(arrange != dofloat) { arg@687: if(!sel->isfloat) arg@512: XLowerWindow(dpy, sel->win); arg@436: for(c = nexttiled(clients); c; c = nexttiled(c->next)) { arg@512: if(c == sel) arg@512: continue; arg@436: XLowerWindow(dpy, c->win); arg@327: } arg@512: } arg@327: XSync(dpy, False); arg@327: while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); arg@327: } arg@327: arg@327: void arg@584: togglefloat(Arg *arg) { arg@591: if (!sel || arrange == dofloat) arg@584: return; arg@584: sel->isfloat = !sel->isfloat; arg@584: arrange(); arg@584: } arg@584: arg@584: void arg@461: togglemode(Arg *arg) { arg@333: arrange = (arrange == dofloat) ? dotile : dofloat; arg@327: if(sel) arg@533: arrange(); arg@327: else arg@327: drawstatus(); arg@327: } arg@327: arg@327: void arg@461: toggleview(Arg *arg) { arg@327: unsigned int i; arg@327: arg@327: seltag[arg->i] = !seltag[arg->i]; arg@327: for(i = 0; i < ntags && !seltag[i]; i++); arg@327: if(i == ntags) arg@327: seltag[arg->i] = True; /* cannot toggle last view */ arg@533: arrange(); arg@327: } arg@327: arg@327: void arg@461: view(Arg *arg) { arg@327: unsigned int i; arg@327: arg@327: for(i = 0; i < ntags; i++) arg@594: seltag[i] = (arg->i == -1) ? True : False; arg@611: if(arg->i >= 0 && arg->i < ntags) arg@611: seltag[arg->i] = True; arg@533: arrange(); arg@327: } arg@327: arg@327: void arg@461: zoom(Arg *arg) { arg@651: unsigned int n; arg@423: Client *c; arg@473: arg@473: if(!sel) arg@473: return; arg@473: if(sel->isfloat || (arrange == dofloat)) { arg@480: togglemax(sel); arg@473: return; arg@473: } arg@650: for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) arg@650: n++; arg@654: arg@662: if((c = sel) == nexttiled(clients)) arg@662: if(!(c = nexttiled(c->next))) arg@662: return; arg@662: detach(c); arg@662: if(clients) arg@662: clients->prev = c; arg@662: c->next = clients; arg@662: clients = c; arg@662: focus(c); arg@662: arrange(); arg@327: }