all repos — dwm @ 0915da8842fd6e16b804ae3205ec2f6baaaa342c

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