all repos — dwm @ 6499fc4f938eb7e61ab3e25df3904db9c890c693

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