all repos — dwm @ 12d5a26fd279cc2370954929dedf88d0ab205a16

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#include <stdlib.h>
  6
  7unsigned int blw = 0;
  8Layout *lt = NULL;
  9
 10/* static */
 11
 12static unsigned int nlayouts = 0;
 13static unsigned int masterw = MASTERWIDTH;
 14static unsigned int nmaster = NMASTER;
 15
 16static void
 17tile(void) {
 18	unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
 19	Client *c;
 20
 21	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
 22		n++;
 23	/* window geoms */
 24	mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
 25	mw = (n > nmaster) ? (waw * masterw) / 1000 : waw;
 26	th = (n > nmaster) ? wah / (n - nmaster) : 0;
 27	tw = waw - mw;
 28
 29	for(i = 0, c = clients; c; c = c->next)
 30		if(isvisible(c)) {
 31			if(c->isbanned)
 32				XMoveWindow(dpy, c->win, c->x, c->y);
 33			c->isbanned = False;
 34			if(c->isversatile)
 35				continue;
 36			c->ismax = False;
 37			nx = wax;
 38			ny = way;
 39			if(i < nmaster) {
 40				ny += i * mh;
 41				nw = mw - 2 * BORDERPX;
 42				nh = mh - 2 * BORDERPX;
 43			}
 44			else {  /* tile window */
 45				nx += mw;
 46				nw = tw - 2 * BORDERPX;
 47				if(th > 2 * BORDERPX) {
 48					ny += (i - nmaster) * th;
 49					nh = th - 2 * BORDERPX;
 50				}
 51				else /* fallback if th <= 2 * BORDERPX */
 52					nh = wah - 2 * BORDERPX;
 53			}
 54			resize(c, nx, ny, nw, nh, False);
 55			i++;
 56		}
 57		else {
 58			c->isbanned = True;
 59			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
 60		}
 61	if(!sel || !isvisible(sel)) {
 62		for(c = stack; c && !isvisible(c); c = c->snext);
 63		focus(c);
 64	}
 65	restack();
 66}
 67
 68LAYOUTS
 69
 70/* extern */
 71
 72void
 73focusnext(const char *arg) {
 74	Client *c;
 75   
 76	if(!sel)
 77		return;
 78	for(c = sel->next; c && !isvisible(c); c = c->next);
 79	if(!c)
 80		for(c = clients; c && !isvisible(c); c = c->next);
 81	if(c) {
 82		focus(c);
 83		restack();
 84	}
 85}
 86
 87void
 88focusprev(const char *arg) {
 89	Client *c;
 90
 91	if(!sel)
 92		return;
 93	for(c = sel->prev; c && !isvisible(c); c = c->prev);
 94	if(!c) {
 95		for(c = clients; c && c->next; c = c->next);
 96		for(; c && !isvisible(c); c = c->prev);
 97	}
 98	if(c) {
 99		focus(c);
100		restack();
101	}
102}
103
104void
105incmasterw(const char *arg) {
106	int i;
107	if(lt->arrange != tile)
108		return;
109	if(!arg)
110		masterw = MASTERWIDTH;
111	else {
112		i = atoi(arg);
113		if(waw * (masterw + i) / 1000 >= waw - 2 * BORDERPX
114		|| waw * (masterw + i) / 1000 <= 2 * BORDERPX)
115			return;
116		masterw += i;
117	}
118	lt->arrange();
119}
120
121void
122incnmaster(const char *arg) {
123	int i;
124
125	if(!arg)
126		nmaster = NMASTER;
127	else {
128		i = atoi(arg);
129		if((lt->arrange != tile) || (nmaster + i < 1)
130		|| (wah / (nmaster + i) <= 2 * BORDERPX))
131			return;
132		nmaster += i;
133	}
134	if(sel)
135		lt->arrange();
136	else
137		drawstatus();
138}
139
140void
141initlayouts(void) {
142	unsigned int i, w;
143
144	lt = &layout[0];
145	nlayouts = sizeof layout / sizeof layout[0];
146	for(blw = i = 0; i < nlayouts; i++) {
147		w = textw(layout[i].symbol);
148		if(w > blw)
149			blw = w;
150	}
151}
152
153Client *
154nexttiled(Client *c) {
155	for(; c && (c->isversatile || !isvisible(c)); c = c->next);
156	return c;
157}
158
159void
160restack(void) {
161	Client *c;
162	XEvent ev;
163
164	drawstatus();
165	if(!sel)
166		return;
167	if(sel->isversatile || lt->arrange == versatile)
168		XRaiseWindow(dpy, sel->win);
169	if(lt->arrange != versatile) {
170		if(!sel->isversatile)
171			XLowerWindow(dpy, sel->win);
172		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
173			if(c == sel)
174				continue;
175			XLowerWindow(dpy, c->win);
176		}
177	}
178	XSync(dpy, False);
179	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
180}
181
182void
183setlayout(const char *arg) {
184	int i;
185
186	if(!arg) {
187		for(i = 0; i < nlayouts && lt != &layout[i]; i++);
188		if(i == nlayouts - 1)
189			lt = &layout[0];
190		else
191			lt = &layout[++i];
192	}
193	else {
194		i = atoi(arg);
195		if(i < 0 || i >= nlayouts)
196			return;
197		lt = &layout[i];
198	}
199	if(sel)
200		lt->arrange();
201	else
202		drawstatus();
203}
204
205void
206togglemax(const char *arg) {
207	XEvent ev;
208
209	if(!sel || (lt->arrange != versatile && !sel->isversatile) || sel->isfixed)
210		return;
211	if((sel->ismax = !sel->ismax)) {
212		sel->rx = sel->x;
213		sel->ry = sel->y;
214		sel->rw = sel->w;
215		sel->rh = sel->h;
216		resize(sel, wax, way, waw - 2 * BORDERPX, wah - 2 * BORDERPX, True);
217	}
218	else
219		resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
220	drawstatus();
221	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
222}
223
224void
225versatile(void) {
226	Client *c;
227
228	for(c = clients; c; c = c->next) {
229		if(isvisible(c)) {
230			if(c->isbanned)
231				XMoveWindow(dpy, c->win, c->x, c->y);
232			c->isbanned = False;
233			resize(c, c->x, c->y, c->w, c->h, True);
234		}
235		else {
236			c->isbanned = True;
237			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
238		}
239	}
240	if(!sel || !isvisible(sel)) {
241		for(c = stack; c && !isvisible(c); c = c->snext);
242		focus(c);
243	}
244	restack();
245}
246
247void
248zoom(const char *arg) {
249	unsigned int n;
250	Client *c;
251
252	if(!sel || lt->arrange != tile || sel->isversatile)
253		return;
254	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
255		n++;
256	if((c = sel) == nexttiled(clients))
257		if(!(c = nexttiled(c->next)))
258			return;
259	detach(c);
260	attach(c);
261	focus(c);
262	lt->arrange();
263}