all repos — dwm @ 154497541d1378d3aded02df06029de94d8af586

fork of suckless dynamic window manager

layout.c (view raw)

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