all repos — dwm @ be8d6d40f60b45f941bd9cb6896b83ce223b6406

fork of suckless dynamic window manager

layout.c (view raw)

  1/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
  2 * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
  3 * See LICENSE file for license details. */
  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->isfloating)
 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
 73floating(void) {
 74	Client *c;
 75
 76	for(c = clients; c; c = c->next) {
 77		if(isvisible(c)) {
 78			if(c->isbanned)
 79				XMoveWindow(dpy, c->win, c->x, c->y);
 80			c->isbanned = False;
 81			resize(c, c->x, c->y, c->w, c->h, True);
 82		}
 83		else {
 84			c->isbanned = True;
 85			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
 86		}
 87	}
 88	if(!sel || !isvisible(sel)) {
 89		for(c = stack; c && !isvisible(c); c = c->snext);
 90		focus(c);
 91	}
 92	restack();
 93}
 94
 95void
 96focusclient(const char *arg) {
 97	Client *c;
 98   
 99	if(!sel || !arg)
100		return;
101	if(atoi(arg) < 0) {
102		for(c = sel->prev; c && !isvisible(c); c = c->prev);
103		if(!c) {
104			for(c = clients; c && c->next; c = c->next);
105			for(; c && !isvisible(c); c = c->prev);
106		}
107	}
108	else {
109		for(c = sel->next; c && !isvisible(c); c = c->next);
110		if(!c)
111			for(c = clients; c && !isvisible(c); c = c->next);
112	}
113	if(c) {
114		focus(c);
115		restack();
116	}
117}
118
119void
120incmasterw(const char *arg) {
121	int i;
122	if(lt->arrange != tile)
123		return;
124	if(!arg)
125		masterw = MASTERWIDTH;
126	else {
127		i = atoi(arg);
128		if(waw * (masterw + i) / 1000 >= waw - 2 * BORDERPX
129		|| waw * (masterw + i) / 1000 <= 2 * BORDERPX)
130			return;
131		masterw += i;
132	}
133	lt->arrange();
134}
135
136void
137incnmaster(const char *arg) {
138	int i;
139
140	if(!arg)
141		nmaster = NMASTER;
142	else {
143		i = atoi(arg);
144		if((lt->arrange != tile) || (nmaster + i < 1)
145		|| (wah / (nmaster + i) <= 2 * BORDERPX))
146			return;
147		nmaster += i;
148	}
149	if(sel)
150		lt->arrange();
151	else
152		drawstatus();
153}
154
155void
156initlayouts(void) {
157	unsigned int i, w;
158
159	lt = &layout[0];
160	nlayouts = sizeof layout / sizeof layout[0];
161	for(blw = i = 0; i < nlayouts; i++) {
162		w = textw(layout[i].symbol);
163		if(w > blw)
164			blw = w;
165	}
166}
167
168Client *
169nexttiled(Client *c) {
170	for(; c && (c->isfloating || !isvisible(c)); c = c->next);
171	return c;
172}
173
174void
175restack(void) {
176	Client *c;
177	XEvent ev;
178
179	drawstatus();
180	if(!sel)
181		return;
182	if(sel->isfloating || lt->arrange == floating)
183		XRaiseWindow(dpy, sel->win);
184	if(lt->arrange != floating) {
185		if(!sel->isfloating)
186			XLowerWindow(dpy, sel->win);
187		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
188			if(c == sel)
189				continue;
190			XLowerWindow(dpy, c->win);
191		}
192	}
193	XSync(dpy, False);
194	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
195}
196
197void
198setlayout(const char *arg) {
199	int i;
200
201	if(!arg) {
202		for(i = 0; i < nlayouts && lt != &layout[i]; i++);
203		if(i == nlayouts - 1)
204			lt = &layout[0];
205		else
206			lt = &layout[++i];
207	}
208	else {
209		i = atoi(arg);
210		if(i < 0 || i >= nlayouts)
211			return;
212		lt = &layout[i];
213	}
214	if(sel)
215		lt->arrange();
216	else
217		drawstatus();
218}
219
220void
221togglemax(const char *arg) {
222	XEvent ev;
223
224	if(!sel || (lt->arrange != floating && !sel->isfloating) || sel->isfixed)
225		return;
226	if((sel->ismax = !sel->ismax)) {
227		sel->rx = sel->x;
228		sel->ry = sel->y;
229		sel->rw = sel->w;
230		sel->rh = sel->h;
231		resize(sel, wax, way, waw - 2 * BORDERPX, wah - 2 * BORDERPX, True);
232	}
233	else
234		resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
235	drawstatus();
236	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
237}
238
239void
240zoom(const char *arg) {
241	unsigned int n;
242	Client *c;
243
244	if(!sel || lt->arrange != tile || sel->isfloating)
245		return;
246	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
247		n++;
248	if((c = sel) == nexttiled(clients))
249		if(!(c = nexttiled(c->next)))
250			return;
251	detach(c);
252	attach(c);
253	focus(c);
254	lt->arrange();
255}