layout.c
changeset 790 48e7c3b45250
parent 788 a61fcdf7b4c1
child 799 30ec8b96a7f6
equal deleted inserted replaced
789:3edec0a35000 790:48e7c3b45250
       
     1 /* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
       
     2  * See LICENSE file for license details.
       
     3  */
       
     4 #include "dwm.h"
       
     5 
       
     6 unsigned int master = MASTER;
       
     7 unsigned int nmaster = NMASTER;
       
     8 unsigned int blw = 0;
       
     9 Layout *lt = NULL;
       
    10 
       
    11 /* static */
       
    12 
       
    13 static unsigned int nlayouts = 0;
       
    14 
       
    15 static void
       
    16 tile(void) {
       
    17 	unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
       
    18 	Client *c;
       
    19 
       
    20 	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
       
    21 		n++;
       
    22 	/* window geoms */
       
    23 	mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
       
    24 	mw = (n > nmaster) ? (waw * master) / 1000 : waw;
       
    25 	th = (n > nmaster) ? wah / (n - nmaster) : 0;
       
    26 	tw = waw - mw;
       
    27 
       
    28 	for(i = 0, c = clients; c; c = c->next)
       
    29 		if(isvisible(c)) {
       
    30 			if(c->isbanned)
       
    31 				XMoveWindow(dpy, c->win, c->x, c->y);
       
    32 			c->isbanned = False;
       
    33 			if(c->isversatile)
       
    34 				continue;
       
    35 			c->ismax = False;
       
    36 			nx = wax;
       
    37 			ny = way;
       
    38 			if(i < nmaster) {
       
    39 				ny += i * mh;
       
    40 				nw = mw - 2 * BORDERPX;
       
    41 				nh = mh - 2 * BORDERPX;
       
    42 			}
       
    43 			else {  /* tile window */
       
    44 				nx += mw;
       
    45 				nw = tw - 2 * BORDERPX;
       
    46 				if(th > 2 * BORDERPX) {
       
    47 					ny += (i - nmaster) * th;
       
    48 					nh = th - 2 * BORDERPX;
       
    49 				}
       
    50 				else /* fallback if th <= 2 * BORDERPX */
       
    51 					nh = wah - 2 * BORDERPX;
       
    52 			}
       
    53 			resize(c, nx, ny, nw, nh, False);
       
    54 			i++;
       
    55 		}
       
    56 		else {
       
    57 			c->isbanned = True;
       
    58 			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
       
    59 		}
       
    60 	if(!sel || !isvisible(sel)) {
       
    61 		for(c = stack; c && !isvisible(c); c = c->snext);
       
    62 		focus(c);
       
    63 	}
       
    64 	restack();
       
    65 }
       
    66 
       
    67 LAYOUTS
       
    68 
       
    69 /* extern */
       
    70 
       
    71 void
       
    72 incnmaster(Arg *arg) {
       
    73 	if((lt->arrange != tile) || (nmaster + arg->i < 1)
       
    74 	|| (wah / (nmaster + arg->i) <= 2 * BORDERPX))
       
    75 		return;
       
    76 	nmaster += arg->i;
       
    77 	if(sel)
       
    78 		lt->arrange();
       
    79 	else
       
    80 		drawstatus();
       
    81 }
       
    82 
       
    83 void
       
    84 initlayouts(void) {
       
    85 	unsigned int i, w;
       
    86 
       
    87 	lt = &layout[0];
       
    88 	nlayouts = sizeof layout / sizeof layout[0];
       
    89 	for(blw = i = 0; i < nlayouts; i++) {
       
    90 		w = textw(layout[i].symbol);
       
    91 		if(w > blw)
       
    92 			blw = w;
       
    93 	}
       
    94 }
       
    95 
       
    96 void
       
    97 resizemaster(Arg *arg) {
       
    98 	if(lt->arrange != tile)
       
    99 		return;
       
   100 	if(arg->i == 0)
       
   101 		master = MASTER;
       
   102 	else {
       
   103 		if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
       
   104 		|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
       
   105 			return;
       
   106 		master += arg->i;
       
   107 	}
       
   108 	lt->arrange();
       
   109 }
       
   110 
       
   111 void
       
   112 restack(void) {
       
   113 	Client *c;
       
   114 	XEvent ev;
       
   115 
       
   116 	drawstatus();
       
   117 	if(!sel)
       
   118 		return;
       
   119 	if(sel->isversatile || lt->arrange == versatile)
       
   120 		XRaiseWindow(dpy, sel->win);
       
   121 	if(lt->arrange != versatile) {
       
   122 		if(!sel->isversatile)
       
   123 			XLowerWindow(dpy, sel->win);
       
   124 		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
       
   125 			if(c == sel)
       
   126 				continue;
       
   127 			XLowerWindow(dpy, c->win);
       
   128 		}
       
   129 	}
       
   130 	XSync(dpy, False);
       
   131 	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
       
   132 }
       
   133 
       
   134 void
       
   135 setlayout(Arg *arg) {
       
   136 	unsigned int i;
       
   137 
       
   138 	if(arg->i == -1) {
       
   139 		for(i = 0; i < nlayouts && lt != &layout[i]; i++);
       
   140 		if(i == nlayouts - 1)
       
   141 			lt = &layout[0];
       
   142 		else
       
   143 			lt = &layout[++i];
       
   144 	}
       
   145 	else {
       
   146 		if(arg->i < 0 || arg->i >= nlayouts)
       
   147 			return;
       
   148 		lt = &layout[arg->i];
       
   149 	}
       
   150 	if(sel)
       
   151 		lt->arrange();
       
   152 	else
       
   153 		drawstatus();
       
   154 }
       
   155 
       
   156 void
       
   157 toggleversatile(Arg *arg) {
       
   158 	if(!sel || lt->arrange == versatile)
       
   159 		return;
       
   160 	sel->isversatile = !sel->isversatile;
       
   161 	lt->arrange();
       
   162 }
       
   163 
       
   164 void
       
   165 versatile(void) {
       
   166 	Client *c;
       
   167 
       
   168 	for(c = clients; c; c = c->next) {
       
   169 		if(isvisible(c)) {
       
   170 			if(c->isbanned)
       
   171 				XMoveWindow(dpy, c->win, c->x, c->y);
       
   172 			c->isbanned = False;
       
   173 			resize(c, c->x, c->y, c->w, c->h, True);
       
   174 		}
       
   175 		else {
       
   176 			c->isbanned = True;
       
   177 			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
       
   178 		}
       
   179 	}
       
   180 	if(!sel || !isvisible(sel)) {
       
   181 		for(c = stack; c && !isvisible(c); c = c->snext);
       
   182 		focus(c);
       
   183 	}
       
   184 	restack();
       
   185 }