all repos — dwm @ e7508783e85aba0ce4ab09b0dd76c40342113aed

fork of suckless dynamic window manager

layout.c (view raw)

  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
  6unsigned int master = MASTER;
  7unsigned int nmaster = NMASTER;
  8unsigned int blw = 0;
  9Layout *lt = NULL;
 10
 11/* static */
 12
 13static unsigned int nlayouts = 0;
 14
 15static void
 16tile(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
 67LAYOUTS
 68
 69/* extern */
 70
 71void
 72incnmaster(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
 83void
 84initlayouts(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
 96void
 97resizemaster(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
111void
112restack(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
134void
135setlayout(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
156void
157toggleversatile(Arg *arg) {
158	if(!sel || lt->arrange == versatile)
159		return;
160	sel->isversatile = !sel->isversatile;
161	lt->arrange();
162}
163
164void
165versatile(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}