all repos — dwm @ 4633fbec616d2f130dfd5d8677e103cf47d26c15

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	Client *c = getnext(clients);
176
177	if(!sel || !getnext(c->next) || (arrange != dotile))
178		return;
179	if(sel == getnext(clients)) {
180		if(mw + arg->i > sw - 100)
181			return;
182		mw += arg->i;
183	}
184	else {
185		if(mw - arg->i < 100)
186			return;
187		mw -= arg->i;
188	}
189	arrange(NULL);
190}
191
192Bool
193isvisible(Client *c)
194{
195	unsigned int i;
196
197	for(i = 0; i < ntags; i++)
198		if(c->tags[i] && seltag[i])
199			return True;
200	return False;
201}
202
203void
204restack()
205{
206	static unsigned int nwins = 0;
207	static Window *wins = NULL;
208	unsigned int f, fi, m, mi, n;
209	Client *c;
210	XEvent ev;
211
212	for(f = 0, m = 0, c = clients; c; c = c->next)
213		if(isvisible(c)) {
214			if(c->isfloat || arrange == dofloat)
215				f++;
216			else
217				m++;
218		}
219	if(!(n = 2 * (f + m))) {
220		drawstatus();
221		return;
222	}
223	if(nwins < n) {
224		nwins = n;
225		wins = erealloc(wins, nwins * sizeof(Window));
226	}
227
228	fi = 0;
229	mi = 2 * f;
230	if(sel) {
231		if(sel->isfloat || arrange == dofloat) {
232			wins[fi++] = sel->twin;
233			wins[fi++] = sel->win;
234		}
235		else {
236			wins[mi++] = sel->twin;
237			wins[mi++] = sel->win;
238		}
239	}
240	for(c = clients; c; c = c->next)
241		if(isvisible(c) && c != sel) {
242			if(c->isfloat || arrange == dofloat) {
243				wins[fi++] = c->twin;
244				wins[fi++] = c->win;
245			}
246			else {
247				wins[mi++] = c->twin;
248				wins[mi++] = c->win;
249			}
250		}
251	XRestackWindows(dpy, wins, n);
252	drawall();
253	XSync(dpy, False);
254	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
255}
256
257void
258togglemode(Arg *arg)
259{
260	arrange = (arrange == dofloat) ? dotile : dofloat;
261	if(sel)
262		arrange(NULL);
263	else
264		drawstatus();
265}
266
267void
268toggleview(Arg *arg)
269{
270	unsigned int i;
271
272	seltag[arg->i] = !seltag[arg->i];
273	for(i = 0; i < ntags && !seltag[i]; i++);
274	if(i == ntags)
275		seltag[arg->i] = True; /* cannot toggle last view */
276	reorder();
277	arrange(NULL);
278}
279
280void
281view(Arg *arg)
282{
283	unsigned int i;
284
285	for(i = 0; i < ntags; i++)
286		seltag[i] = False;
287	seltag[arg->i] = True;
288	reorder();
289	arrange(NULL);
290}
291
292void
293viewall(Arg *arg)
294{
295	unsigned int i;
296
297	for(i = 0; i < ntags; i++)
298		seltag[i] = True;
299	reorder();
300	arrange(NULL);
301}
302
303void
304zoom(Arg *arg)
305{
306	Client *c = sel;
307
308	if(!c || (arrange != dotile) || c->isfloat || maximized)
309		return;
310
311	if(c == getnext(clients))
312		if(!(c = getnext(c->next)))
313			return;
314	detach(c);
315	c->next = clients;
316	clients->prev = c;
317	clients = c;
318	focus(c);
319	arrange(NULL);
320}