all repos — dwm @ acdea319162a5a51703a88ca7a8a1b17534be616

fork of suckless dynamic window manager

view.c (view raw)

  1/*
  2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
  3 * See LICENSE file for license details.
  4 */
  5#include "dwm.h"
  6
  7/* static */
  8
  9static Client *
 10minclient(void) {
 11	Client *c, *min;
 12
 13	if((clients && clients->isfloat) || arrange == dofloat)
 14		return clients; /* don't touch floating order */
 15	for(min = c = clients; c; c = c->next)
 16		if(c->weight < min->weight)
 17			min = c;
 18	return min;
 19}
 20
 21static Client *
 22nexttiled(Client *c) {
 23	for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
 24	return c;
 25}
 26
 27static void
 28reorder(void) {
 29	Client *c, *newclients, *tail;
 30
 31	newclients = tail = NULL;
 32	while((c = minclient())) {
 33		detach(c);
 34		if(tail) {
 35			c->prev = tail;
 36			tail->next = c;
 37			tail = c;
 38		}
 39		else
 40			tail = newclients = c;
 41	}
 42	clients = newclients;
 43}
 44
 45static void
 46togglemax(Client *c)
 47{
 48	XEvent ev;
 49	if((c->ismax = !c->ismax)) {
 50		c->rx = c->x; c->x = sx;
 51		c->ry = c->y; c->y = bh;
 52		c->rw = c->w; c->w = sw - 2 * BORDERPX;
 53		c->rh = c->h; c->h = sh - bh - 2 * BORDERPX;
 54	}
 55	else {
 56		c->x = c->rx;
 57		c->y = c->ry;
 58		c->w = c->rw;
 59		c->h = c->rh;
 60	}
 61	resize(c, True, TopLeft);
 62	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
 63}
 64
 65/* extern */
 66
 67void (*arrange)(Arg *) = DEFMODE;
 68
 69void
 70detach(Client *c) {
 71	if(c->prev)
 72		c->prev->next = c->next;
 73	if(c->next)
 74		c->next->prev = c->prev;
 75	if(c == clients)
 76		clients = c->next;
 77	c->next = c->prev = NULL;
 78}
 79
 80void
 81dofloat(Arg *arg) {
 82	Client *c;
 83
 84	for(c = clients; c; c = c->next) {
 85		if(isvisible(c)) {
 86			resize(c, True, TopLeft);
 87		}
 88		else
 89			ban(c);
 90	}
 91	if(!sel || !isvisible(sel)) {
 92		for(c = stack; c && !isvisible(c); c = c->snext);
 93		focus(c);
 94	}
 95	restack();
 96}
 97
 98void
 99dotile(Arg *arg) {
100	unsigned int i, n, mpx, stackw, stackh, th;
101	Client *c;
102
103	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
104		n++;
105
106	mpx = (sw * master) / 1000;
107	stackw = sw - mpx;
108	stackh = sh - bh;
109
110	th = stackh;
111	if(n > 1)
112		th /= (n - 1);
113
114	for(i = 0, c = clients; c; c = c->next, i++)
115		if(isvisible(c)) {
116			if(c->isfloat) {
117				resize(c, True, TopLeft);
118				continue;
119			}
120			c->ismax = False;
121			c->x = sx;
122			c->y = sy + bh;
123			if(n == 1) { /* only 1 window */
124				c->w = sw - 2 * BORDERPX;
125				c->h = sh - 2 * BORDERPX - bh;
126			}
127			else if(i == 0) { /* master window */
128				c->w = mpx - 2 * BORDERPX;
129				c->h = sh - bh - 2 * BORDERPX;
130			}
131			else {  /* tile window */
132				c->x += mpx;
133				c->w = stackw - 2 * BORDERPX;
134				if(th > bh) {
135					c->y = sy + (i - 1) * th + bh;
136					if(i + 1 == n)
137						c->h = sh - c->y - 2 * BORDERPX;
138					else
139						c->h = th - 2 * BORDERPX;
140				}
141				else /* fallback if th < bh */
142					c->h = stackh - 2 * BORDERPX;
143			}
144			resize(c, False, TopLeft);
145		}
146		else
147			ban(c);
148	if(!sel || !isvisible(sel)) {
149		for(c = stack; c && !isvisible(c); c = c->snext);
150		focus(c);
151	}
152	restack();
153}
154
155void
156focusnext(Arg *arg) {
157	Client *c;
158   
159	if(!sel)
160		return;
161
162	if(!(c = getnext(sel->next)))
163		c = getnext(clients);
164	if(c) {
165		focus(c);
166		restack();
167	}
168}
169
170void
171focusprev(Arg *arg) {
172	Client *c;
173
174	if(!sel)
175		return;
176
177	if(!(c = getprev(sel->prev))) {
178		for(c = clients; c && c->next; c = c->next);
179		c = getprev(c);
180	}
181	if(c) {
182		focus(c);
183		restack();
184	}
185}
186
187Bool
188isvisible(Client *c) {
189	unsigned int i;
190
191	for(i = 0; i < ntags; i++)
192		if(c->tags[i] && seltag[i])
193			return True;
194	return False;
195}
196
197void
198resizecol(Arg *arg) {
199	unsigned int n;
200	Client *c;
201
202	for(n = 0, c = clients; c; c = c->next)
203		if(isvisible(c) && !c->isfloat)
204			n++;
205	if(!sel || sel->isfloat || n < 2 || (arrange == dofloat))
206		return;
207
208	if(sel == getnext(clients)) {
209		if(master + arg->i > 950 || master + arg->i < 50)
210			return;
211		master += arg->i;
212	}
213	else {
214		if(master - arg->i > 950 || master - arg->i < 50)
215			return;
216		master -= arg->i;
217	}
218	arrange(NULL);
219}
220
221void
222restack(void) {
223	Client *c;
224	XEvent ev;
225
226	if(!sel) {
227		drawstatus();
228		return;
229	}
230	if(sel->isfloat || arrange == dofloat) {
231		XRaiseWindow(dpy, sel->win);
232		XRaiseWindow(dpy, sel->twin);
233	}
234	if(arrange != dofloat) {
235		if(!sel->isfloat) {
236			XLowerWindow(dpy, sel->twin);
237			XLowerWindow(dpy, sel->win);
238		}
239		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
240			if(c == sel)
241				continue;
242			XLowerWindow(dpy, c->twin);
243			XLowerWindow(dpy, c->win);
244		}
245	}
246	drawall();
247	XSync(dpy, False);
248	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
249}
250
251void
252togglemode(Arg *arg) {
253	arrange = (arrange == dofloat) ? dotile : dofloat;
254	if(sel)
255		arrange(NULL);
256	else
257		drawstatus();
258}
259
260void
261toggleview(Arg *arg) {
262	unsigned int i;
263
264	seltag[arg->i] = !seltag[arg->i];
265	for(i = 0; i < ntags && !seltag[i]; i++);
266	if(i == ntags)
267		seltag[arg->i] = True; /* cannot toggle last view */
268	reorder();
269	arrange(NULL);
270}
271
272void
273view(Arg *arg) {
274	unsigned int i;
275
276	for(i = 0; i < ntags; i++)
277		seltag[i] = False;
278	seltag[arg->i] = True;
279	reorder();
280	arrange(NULL);
281}
282
283void
284viewall(Arg *arg) {
285	unsigned int i;
286
287	for(i = 0; i < ntags; i++)
288		seltag[i] = True;
289	reorder();
290	arrange(NULL);
291}
292
293
294
295void
296zoom(Arg *arg) {
297	unsigned int n;
298	Client *c;
299
300	if(!sel)
301		return;
302
303	if(sel->isfloat || (arrange == dofloat)) {
304		togglemax(sel);
305		return;
306	}
307
308	for(n = 0, c = clients; c; c = c->next)
309		if(isvisible(c) && !c->isfloat)
310			n++;
311	if(n < 2 || (arrange == dofloat))
312		return;
313
314	if((c = sel) == nexttiled(clients))
315		if(!(c = nexttiled(c->next)))
316			return;
317	detach(c);
318	if(clients)
319		clients->prev = c;
320	c->next = clients;
321	clients = c;
322	focus(c);
323	arrange(NULL);
324}