all repos — dwm @ 57c49fe867b4c31a518bd12f32fda060cbb9d088

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); 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	Client *c;
219	XEvent ev;
220	
221	if(!sel) {
222		drawstatus();
223		return;
224	}
225	if(sel->isfloat || arrange == dofloat) {
226		XRaiseWindow(dpy, sel->win);
227		XRaiseWindow(dpy, sel->twin);
228	}
229	if(arrange != dofloat) 
230		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
231			XLowerWindow(dpy, c->twin);
232			XLowerWindow(dpy, c->win);
233		}
234	drawall();
235	XSync(dpy, False);
236	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
237}
238
239void
240togglemode(Arg *arg)
241{
242	arrange = (arrange == dofloat) ? dotile : dofloat;
243	if(sel)
244		arrange(NULL);
245	else
246		drawstatus();
247}
248
249void
250toggleview(Arg *arg)
251{
252	unsigned int i;
253
254	seltag[arg->i] = !seltag[arg->i];
255	for(i = 0; i < ntags && !seltag[i]; i++);
256	if(i == ntags)
257		seltag[arg->i] = True; /* cannot toggle last view */
258	reorder();
259	arrange(NULL);
260}
261
262void
263view(Arg *arg)
264{
265	unsigned int i;
266
267	for(i = 0; i < ntags; i++)
268		seltag[i] = False;
269	seltag[arg->i] = True;
270	reorder();
271	arrange(NULL);
272}
273
274void
275viewall(Arg *arg)
276{
277	unsigned int i;
278
279	for(i = 0; i < ntags; i++)
280		seltag[i] = True;
281	reorder();
282	arrange(NULL);
283}
284
285void
286zoom(Arg *arg)
287{
288	unsigned int n;
289	Client *c;
290
291	for(n = 0, c = clients; c; c = c->next)
292		if(isvisible(c) && !c->isfloat)
293			n++;
294	if(!sel || sel->isfloat || n < 2 || (arrange != dotile) || maximized)
295		return;
296
297	if((c = sel) == nexttiled(clients))
298		if(!(c = nexttiled(c->next)))
299			return;
300	detach(c);
301	c->next = clients;
302	clients->prev = c;
303	clients = c;
304	focus(c);
305	arrange(NULL);
306}