all repos — dwm @ 15abade2720158fd35dcf59aa2cd5cbb325a849c

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