| @ -0,0 +1,253 @@ | |||
| /* | |||
| * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | |||
| * See LICENSE file for license details. | |||
| */ | |||
| #include "dwm.h" | |||
| /* extern */ | |||
| void (*arrange)(Arg *) = DEFMODE; | |||
| void | |||
| dofloat(Arg *arg) | |||
| { | |||
| Client *c; | |||
| for(c = clients; c; c = c->next) { | |||
| c->ismax = False; | |||
| if(isvisible(c)) { | |||
| resize(c, True, TopLeft); | |||
| } | |||
| else | |||
| ban(c); | |||
| } | |||
| if(!sel || !isvisible(sel)) | |||
| sel = getnext(clients); | |||
| if(sel) | |||
| focus(sel); | |||
| else | |||
| XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); | |||
| restack(); | |||
| } | |||
| void | |||
| dotile(Arg *arg) | |||
| { | |||
| int h, i, n, w; | |||
| Client *c; | |||
| w = sw - mw; | |||
| for(n = 0, c = clients; c; c = c->next) | |||
| if(isvisible(c) && !c->isfloat) | |||
| n++; | |||
| if(n > 1) | |||
| h = (sh - bh) / (n - 1); | |||
| else | |||
| h = sh - bh; | |||
| for(i = 0, c = clients; c; c = c->next) { | |||
| c->ismax = False; | |||
| if(isvisible(c)) { | |||
| if(c->isfloat) { | |||
| resize(c, True, TopLeft); | |||
| continue; | |||
| } | |||
| if(n == 1) { | |||
| c->x = sx; | |||
| c->y = sy + bh; | |||
| c->w = sw - 2; | |||
| c->h = sh - 2 - bh; | |||
| } | |||
| else if(i == 0) { | |||
| c->x = sx; | |||
| c->y = sy + bh; | |||
| c->w = mw - 2; | |||
| c->h = sh - 2 - bh; | |||
| } | |||
| else if(h > bh) { | |||
| c->x = sx + mw; | |||
| c->y = sy + (i - 1) * h + bh; | |||
| c->w = w - 2; | |||
| if(i + 1 == n) | |||
| c->h = sh - c->y - 2; | |||
| else | |||
| c->h = h - 2; | |||
| } | |||
| else { /* fallback if h < bh */ | |||
| c->x = sx + mw; | |||
| c->y = sy + bh; | |||
| c->w = w - 2; | |||
| c->h = sh - 2 - bh; | |||
| } | |||
| resize(c, False, TopLeft); | |||
| i++; | |||
| } | |||
| else | |||
| ban(c); | |||
| } | |||
| if(!sel || !isvisible(sel)) | |||
| sel = getnext(clients); | |||
| if(sel) | |||
| focus(sel); | |||
| else | |||
| XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); | |||
| restack(); | |||
| } | |||
| void | |||
| focusnext(Arg *arg) | |||
| { | |||
| Client *c; | |||
| if(!sel) | |||
| return; | |||
| if(!(c = getnext(sel->next))) | |||
| c = getnext(clients); | |||
| if(c) { | |||
| focus(c); | |||
| restack(); | |||
| } | |||
| } | |||
| void | |||
| focusprev(Arg *arg) | |||
| { | |||
| Client *c; | |||
| if(!sel) | |||
| return; | |||
| if(!(c = getprev(sel->prev))) { | |||
| for(c = clients; c && c->next; c = c->next); | |||
| c = getprev(c); | |||
| } | |||
| if(c) { | |||
| focus(c); | |||
| restack(); | |||
| } | |||
| } | |||
| Bool | |||
| isvisible(Client *c) | |||
| { | |||
| unsigned int i; | |||
| for(i = 0; i < ntags; i++) | |||
| if(c->tags[i] && seltag[i]) | |||
| return True; | |||
| return False; | |||
| } | |||
| void | |||
| restack() | |||
| { | |||
| static unsigned int nwins = 0; | |||
| static Window *wins = NULL; | |||
| unsigned int f, fi, m, mi, n; | |||
| Client *c; | |||
| XEvent ev; | |||
| for(f = 0, m = 0, c = clients; c; c = c->next) | |||
| if(isvisible(c)) { | |||
| if(c->isfloat || arrange == dofloat) | |||
| f++; | |||
| else | |||
| m++; | |||
| } | |||
| if(!(n = 2 * (f + m))) { | |||
| drawstatus(); | |||
| return; | |||
| } | |||
| if(nwins < n) { | |||
| nwins = n; | |||
| wins = erealloc(wins, nwins * sizeof(Window)); | |||
| } | |||
| fi = 0; | |||
| mi = 2 * f; | |||
| if(sel->isfloat || arrange == dofloat) { | |||
| wins[fi++] = sel->title; | |||
| wins[fi++] = sel->win; | |||
| } | |||
| else { | |||
| wins[mi++] = sel->title; | |||
| wins[mi++] = sel->win; | |||
| } | |||
| for(c = clients; c; c = c->next) | |||
| if(isvisible(c) && c != sel) { | |||
| if(c->isfloat || arrange == dofloat) { | |||
| wins[fi++] = c->title; | |||
| wins[fi++] = c->win; | |||
| } | |||
| else { | |||
| wins[mi++] = c->title; | |||
| wins[mi++] = c->win; | |||
| } | |||
| } | |||
| XRestackWindows(dpy, wins, n); | |||
| drawall(); | |||
| XSync(dpy, False); | |||
| while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); | |||
| } | |||
| void | |||
| togglemode(Arg *arg) | |||
| { | |||
| arrange = arrange == dofloat ? dotile : dofloat; | |||
| if(sel) | |||
| arrange(NULL); | |||
| else | |||
| drawstatus(); | |||
| } | |||
| void | |||
| toggleview(Arg *arg) | |||
| { | |||
| unsigned int i; | |||
| seltag[arg->i] = !seltag[arg->i]; | |||
| for(i = 0; i < ntags && !seltag[i]; i++); | |||
| if(i == ntags) | |||
| seltag[arg->i] = True; /* cannot toggle last view */ | |||
| arrange(NULL); | |||
| } | |||
| void | |||
| view(Arg *arg) | |||
| { | |||
| unsigned int i; | |||
| for(i = 0; i < ntags; i++) | |||
| seltag[i] = False; | |||
| seltag[arg->i] = True; | |||
| arrange(NULL); | |||
| } | |||
| void | |||
| zoom(Arg *arg) | |||
| { | |||
| Client *c; | |||
| if(!sel || (arrange != dotile) || sel->isfloat || sel->ismax) | |||
| return; | |||
| if(sel == getnext(clients)) { | |||
| if((c = getnext(sel->next))) | |||
| sel = c; | |||
| else | |||
| return; | |||
| } | |||
| /* pop */ | |||
| sel->prev->next = sel->next; | |||
| if(sel->next) | |||
| sel->next->prev = sel->prev; | |||
| sel->prev = NULL; | |||
| clients->prev = sel; | |||
| sel->next = clients; | |||
| clients = sel; | |||
| focus(sel); | |||
| arrange(NULL); | |||
| } | |||