arg@327: /* arg@327: * (C)opyright MMVI Anselm R. Garbe arg@327: * See LICENSE file for license details. arg@327: */ arg@327: #include "dwm.h" arg@382: #include arg@327: arg@380: /* static */ arg@380: arg@382: static Client * arg@382: minclient() arg@382: { arg@382: Client *c, *min; arg@382: arg@382: for(min = c = clients; c; c = c->next) arg@382: if(c->weight < min->weight) arg@382: min = c; arg@382: return min; arg@382: } arg@382: arg@382: arg@381: static void arg@381: reorder() arg@380: { arg@382: Client *c, *newclients, *tail; arg@380: arg@382: newclients = tail = NULL; arg@382: while((c = minclient())) { arg@381: detach(c); arg@382: if(tail) { arg@382: c->prev = tail; arg@382: tail->next = c; arg@382: tail = c; arg@381: } arg@381: else arg@382: tail = newclients = c; arg@380: } arg@382: clients = newclients; arg@380: } arg@380: arg@327: /* extern */ arg@327: arg@327: void (*arrange)(Arg *) = DEFMODE; arg@327: arg@327: void arg@378: detach(Client *c) arg@378: { 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@327: dofloat(Arg *arg) arg@327: { arg@327: Client *c; arg@327: arg@327: for(c = clients; c; c = c->next) { arg@327: c->ismax = False; arg@327: if(isvisible(c)) { arg@327: resize(c, True, TopLeft); arg@327: } arg@327: else arg@327: ban(c); arg@327: } arg@382: if((sel = getnext(clients))) arg@327: focus(sel); arg@327: else arg@327: XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); arg@327: restack(); arg@327: } arg@327: arg@327: void arg@327: dotile(Arg *arg) arg@327: { arg@327: int h, i, n, w; arg@327: Client *c; arg@327: arg@327: w = sw - mw; arg@327: for(n = 0, c = clients; c; c = c->next) arg@327: if(isvisible(c) && !c->isfloat) arg@327: n++; arg@327: arg@327: if(n > 1) arg@327: h = (sh - bh) / (n - 1); arg@327: else arg@327: h = sh - bh; arg@327: arg@327: for(i = 0, c = clients; c; c = c->next) { arg@327: c->ismax = False; arg@327: if(isvisible(c)) { arg@327: if(c->isfloat) { arg@327: resize(c, True, TopLeft); arg@327: continue; arg@327: } arg@327: if(n == 1) { arg@327: c->x = sx; arg@327: c->y = sy + bh; arg@327: c->w = sw - 2; arg@327: c->h = sh - 2 - bh; arg@327: } arg@327: else if(i == 0) { arg@327: c->x = sx; arg@327: c->y = sy + bh; arg@327: c->w = mw - 2; arg@327: c->h = sh - 2 - bh; arg@327: } arg@327: else if(h > bh) { arg@327: c->x = sx + mw; arg@327: c->y = sy + (i - 1) * h + bh; arg@327: c->w = w - 2; arg@327: if(i + 1 == n) arg@327: c->h = sh - c->y - 2; arg@327: else arg@327: c->h = h - 2; arg@327: } arg@327: else { /* fallback if h < bh */ arg@327: c->x = sx + mw; arg@327: c->y = sy + bh; arg@327: c->w = w - 2; arg@327: c->h = sh - 2 - bh; arg@327: } arg@327: resize(c, False, TopLeft); arg@327: i++; arg@327: } arg@327: else arg@327: ban(c); arg@327: } arg@382: if((sel = getnext(clients))) arg@327: focus(sel); arg@327: else arg@327: XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); arg@327: restack(); arg@327: } arg@327: arg@327: void arg@327: focusnext(Arg *arg) arg@327: { arg@327: Client *c; arg@327: arg@327: if(!sel) arg@327: return; arg@327: 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@327: focusprev(Arg *arg) arg@327: { arg@327: Client *c; arg@327: arg@327: if(!sel) arg@327: return; arg@327: 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@327: Bool arg@327: isvisible(Client *c) arg@327: { arg@327: unsigned int i; arg@327: arg@327: for(i = 0; i < ntags; i++) arg@327: if(c->tags[i] && seltag[i]) arg@327: return True; arg@327: return False; arg@327: } arg@327: arg@327: void arg@327: restack() arg@327: { arg@327: static unsigned int nwins = 0; arg@327: static Window *wins = NULL; arg@327: unsigned int f, fi, m, mi, n; arg@327: Client *c; arg@327: XEvent ev; arg@327: arg@327: for(f = 0, m = 0, c = clients; c; c = c->next) arg@327: if(isvisible(c)) { arg@327: if(c->isfloat || arrange == dofloat) arg@327: f++; arg@327: else arg@327: m++; arg@327: } arg@327: if(!(n = 2 * (f + m))) { arg@327: drawstatus(); arg@327: return; arg@327: } arg@327: if(nwins < n) { arg@327: nwins = n; arg@327: wins = erealloc(wins, nwins * sizeof(Window)); arg@327: } arg@327: arg@327: fi = 0; arg@327: mi = 2 * f; arg@327: if(sel->isfloat || arrange == dofloat) { arg@342: wins[fi++] = sel->twin; arg@327: wins[fi++] = sel->win; arg@327: } arg@327: else { arg@342: wins[mi++] = sel->twin; arg@327: wins[mi++] = sel->win; arg@327: } arg@327: for(c = clients; c; c = c->next) arg@327: if(isvisible(c) && c != sel) { arg@327: if(c->isfloat || arrange == dofloat) { arg@342: wins[fi++] = c->twin; arg@327: wins[fi++] = c->win; arg@327: } arg@327: else { arg@342: wins[mi++] = c->twin; arg@327: wins[mi++] = c->win; arg@327: } arg@327: } arg@327: XRestackWindows(dpy, wins, n); arg@327: drawall(); arg@327: XSync(dpy, False); arg@327: while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); arg@327: } arg@327: arg@327: void arg@327: togglemode(Arg *arg) arg@327: { arg@333: arrange = (arrange == dofloat) ? dotile : dofloat; arg@327: if(sel) arg@327: arrange(NULL); arg@327: else arg@327: drawstatus(); arg@327: } arg@327: arg@327: void arg@327: toggleview(Arg *arg) arg@327: { 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@381: reorder(); arg@327: arrange(NULL); arg@327: } arg@327: arg@327: void arg@327: view(Arg *arg) arg@327: { arg@327: unsigned int i; arg@327: arg@327: for(i = 0; i < ntags; i++) arg@327: seltag[i] = False; arg@327: seltag[arg->i] = True; arg@381: reorder(); arg@327: arrange(NULL); arg@327: } arg@327: arg@327: void arg@327: zoom(Arg *arg) arg@327: { arg@378: Client *c = sel; arg@327: arg@378: if(!c || (arrange != dotile) || c->isfloat || c->ismax) arg@327: return; arg@327: arg@378: if(c == getnext(clients)) arg@378: if(!(c = getnext(c->next))) arg@327: return; arg@378: detach(c); arg@381: c->next = clients; arg@381: clients->prev = c; arg@381: clients = c; arg@378: focus(c); arg@327: arrange(NULL); arg@327: }