all repos — dwm @ 84ae6e12ebbb1a42a89c3f517952601985ab55d0

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
 72focusnext(Arg *arg) {
 73	Client *c;
 74   
 75	if(!sel)
 76		return;
 77	for(c = sel->next; c && !isvisible(c); c = c->next);
 78	if(!c)
 79		for(c = clients; c && !isvisible(c); c = c->next);
 80	if(c) {
 81		focus(c);
 82		restack();
 83	}
 84}
 85
 86void
 87focusprev(Arg *arg) {
 88	Client *c;
 89
 90	if(!sel)
 91		return;
 92	for(c = sel->prev; c && !isvisible(c); c = c->prev);
 93	if(!c) {
 94		for(c = clients; c && c->next; c = c->next);
 95		for(; c && !isvisible(c); c = c->prev);
 96	}
 97	if(c) {
 98		focus(c);
 99		restack();
100	}
101}
102
103void
104incnmaster(Arg *arg) {
105	if((lt->arrange != tile) || (nmaster + arg->i < 1)
106	|| (wah / (nmaster + arg->i) <= 2 * BORDERPX))
107		return;
108	nmaster += arg->i;
109	if(sel)
110		lt->arrange();
111	else
112		drawstatus();
113}
114
115void
116initlayouts(void) {
117	unsigned int i, w;
118
119	lt = &layout[0];
120	nlayouts = sizeof layout / sizeof layout[0];
121	for(blw = i = 0; i < nlayouts; i++) {
122		w = textw(layout[i].symbol);
123		if(w > blw)
124			blw = w;
125	}
126}
127
128Client *
129nexttiled(Client *c) {
130	for(; c && (c->isversatile || !isvisible(c)); c = c->next);
131	return c;
132}
133
134void
135resizemaster(Arg *arg) {
136	if(lt->arrange != tile)
137		return;
138	if(arg->i == 0)
139		master = MASTER;
140	else {
141		if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
142		|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
143			return;
144		master += arg->i;
145	}
146	lt->arrange();
147}
148
149void
150restack(void) {
151	Client *c;
152	XEvent ev;
153
154	drawstatus();
155	if(!sel)
156		return;
157	if(sel->isversatile || lt->arrange == versatile)
158		XRaiseWindow(dpy, sel->win);
159	if(lt->arrange != versatile) {
160		if(!sel->isversatile)
161			XLowerWindow(dpy, sel->win);
162		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
163			if(c == sel)
164				continue;
165			XLowerWindow(dpy, c->win);
166		}
167	}
168	XSync(dpy, False);
169	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
170}
171
172void
173setlayout(Arg *arg) {
174	unsigned int i;
175
176	if(arg->i == -1) {
177		for(i = 0; i < nlayouts && lt != &layout[i]; i++);
178		if(i == nlayouts - 1)
179			lt = &layout[0];
180		else
181			lt = &layout[++i];
182	}
183	else {
184		if(arg->i < 0 || arg->i >= nlayouts)
185			return;
186		lt = &layout[arg->i];
187	}
188	if(sel)
189		lt->arrange();
190	else
191		drawstatus();
192}
193
194void
195versatile(void) {
196	Client *c;
197
198	for(c = clients; c; c = c->next) {
199		if(isvisible(c)) {
200			if(c->isbanned)
201				XMoveWindow(dpy, c->win, c->x, c->y);
202			c->isbanned = False;
203			resize(c, c->x, c->y, c->w, c->h, True);
204		}
205		else {
206			c->isbanned = True;
207			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
208		}
209	}
210	if(!sel || !isvisible(sel)) {
211		for(c = stack; c && !isvisible(c); c = c->snext);
212		focus(c);
213	}
214	restack();
215}