all repos — dwm @ 5056bb952ddd9d667d2897ab09324ef7ce1596ea

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