all repos — dwm @ 1.6

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() {
 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 void
 22reorder() {
 23	Client *c, *newclients, *tail;
 24
 25	newclients = tail = NULL;
 26	while((c = minclient())) {
 27		detach(c);
 28		if(tail) {
 29			c->prev = tail;
 30			tail->next = c;
 31			tail = c;
 32		}
 33		else
 34			tail = newclients = c;
 35	}
 36	clients = newclients;
 37}
 38
 39static Client *
 40nexttiled(Client *c) {
 41	for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
 42	return c;
 43}
 44
 45/* extern */
 46
 47void (*arrange)(Arg *) = DEFMODE;
 48
 49void
 50detach(Client *c) {
 51	if(c->prev)
 52		c->prev->next = c->next;
 53	if(c->next)
 54		c->next->prev = c->prev;
 55	if(c == clients)
 56		clients = c->next;
 57	c->next = c->prev = NULL;
 58}
 59
 60void
 61dofloat(Arg *arg) {
 62	Client *c;
 63
 64	maximized = False;
 65
 66	for(c = clients; c; c = c->next) {
 67		if(isvisible(c)) {
 68			resize(c, True, TopLeft);
 69		}
 70		else
 71			ban(c);
 72	}
 73	if(!sel || !isvisible(sel)) {
 74		for(c = stack; c && !isvisible(c); c = c->snext);
 75		focus(c);
 76	}
 77	restack();
 78}
 79
 80void
 81dotile(Arg *arg) {
 82	int h, i, n, w;
 83	Client *c;
 84
 85	maximized = False;
 86
 87	w = sw - mw;
 88	for(n = 0, c = clients; c; c = c->next)
 89		if(isvisible(c) && !c->isfloat)
 90			n++;
 91
 92	if(n > 1)
 93		h = (sh - bh) / (n - 1);
 94	else
 95		h = sh - bh;
 96
 97	for(i = 0, c = clients; c; c = c->next) {
 98		if(isvisible(c)) {
 99			if(c->isfloat) {
100				resize(c, True, TopLeft);
101				continue;
102			}
103			if(n == 1) {
104				c->x = sx;
105				c->y = sy + bh;
106				c->w = sw - 2;
107				c->h = sh - 2 - bh;
108			}
109			else if(i == 0) {
110				c->x = sx;
111				c->y = sy + bh;
112				c->w = mw - 2;
113				c->h = sh - 2 - bh;
114			}
115			else if(h > bh) {
116				c->x = sx + mw;
117				c->y = sy + (i - 1) * h + bh;
118				c->w = w - 2;
119				if(i + 1 == n)
120					c->h = sh - c->y - 2;
121				else
122					c->h = h - 2;
123			}
124			else { /* fallback if h < bh */
125				c->x = sx + mw;
126				c->y = sy + bh;
127				c->w = w - 2;
128				c->h = sh - 2 - bh;
129			}
130			resize(c, False, TopLeft);
131			i++;
132		}
133		else
134			ban(c);
135	}
136	if(!sel || !isvisible(sel)) {
137		for(c = stack; c && !isvisible(c); c = c->snext);
138		focus(c);
139	}
140	restack();
141}
142
143void
144focusnext(Arg *arg) {
145	Client *c;
146   
147	if(!sel)
148		return;
149
150	if(!(c = getnext(sel->next)))
151		c = getnext(clients);
152	if(c) {
153		focus(c);
154		restack();
155	}
156}
157
158void
159focusprev(Arg *arg) {
160	Client *c;
161
162	if(!sel)
163		return;
164
165	if(!(c = getprev(sel->prev))) {
166		for(c = clients; c && c->next; c = c->next);
167		c = getprev(c);
168	}
169	if(c) {
170		focus(c);
171		restack();
172	}
173}
174
175Bool
176isvisible(Client *c) {
177	unsigned int i;
178
179	for(i = 0; i < ntags; i++)
180		if(c->tags[i] && seltag[i])
181			return True;
182	return False;
183}
184
185void
186resizecol(Arg *arg) {
187	unsigned int n;
188	Client *c;
189
190	for(n = 0, c = clients; c; c = c->next)
191		if(isvisible(c) && !c->isfloat)
192			n++;
193	if(!sel || sel->isfloat || n < 2 || (arrange != dotile) || maximized)
194		return;
195
196	if(sel == getnext(clients)) {
197		if(mw + arg->i > sw - 100 || mw + arg->i < 100)
198			return;
199		mw += arg->i;
200	}
201	else {
202		if(mw - arg->i > sw - 100 || mw - arg->i < 100)
203			return;
204		mw -= arg->i;
205	}
206	arrange(NULL);
207}
208
209void
210restack() {
211	Client *c;
212	XEvent ev;
213	
214	if(!sel) {
215		drawstatus();
216		return;
217	}
218	if(sel->isfloat || arrange == dofloat) {
219		XRaiseWindow(dpy, sel->win);
220		XRaiseWindow(dpy, sel->twin);
221	}
222	if(arrange != dofloat)
223		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
224			XLowerWindow(dpy, c->twin);
225			XLowerWindow(dpy, c->win);
226		}
227	drawall();
228	XSync(dpy, False);
229	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
230}
231
232void
233togglemode(Arg *arg) {
234	arrange = (arrange == dofloat) ? dotile : dofloat;
235	if(sel)
236		arrange(NULL);
237	else
238		drawstatus();
239}
240
241void
242toggleview(Arg *arg) {
243	unsigned int i;
244
245	seltag[arg->i] = !seltag[arg->i];
246	for(i = 0; i < ntags && !seltag[i]; i++);
247	if(i == ntags)
248		seltag[arg->i] = True; /* cannot toggle last view */
249	reorder();
250	arrange(NULL);
251}
252
253void
254view(Arg *arg) {
255	unsigned int i;
256
257	for(i = 0; i < ntags; i++)
258		seltag[i] = False;
259	seltag[arg->i] = True;
260	reorder();
261	arrange(NULL);
262}
263
264void
265viewall(Arg *arg) {
266	unsigned int i;
267
268	for(i = 0; i < ntags; i++)
269		seltag[i] = True;
270	reorder();
271	arrange(NULL);
272}
273
274void
275zoom(Arg *arg) {
276	unsigned int n;
277	Client *c;
278
279	for(n = 0, c = clients; c; c = c->next)
280		if(isvisible(c) && !c->isfloat)
281			n++;
282	if(!sel || sel->isfloat || n < 2 || (arrange != dotile) || maximized)
283		return;
284
285	if((c = sel) == nexttiled(clients))
286		if(!(c = nexttiled(c->next)))
287			return;
288	detach(c);
289	if(clients)
290		clients->prev = c;
291	c->next = clients;
292	clients = c;
293	focus(c);
294	arrange(NULL);
295}