all repos — dwm @ d22abeee867397c366f69cf89524b94e01c2e0e2

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		focus(getnext(clients));
 81	restack();
 82}
 83
 84void
 85dotile(Arg *arg)
 86{
 87	int h, i, n, w;
 88	Client *c;
 89
 90	maximized = False;
 91
 92	w = sw - mw;
 93	for(n = 0, c = clients; c; c = c->next)
 94		if(isvisible(c) && !c->isfloat)
 95			n++;
 96
 97	if(n > 1)
 98		h = (sh - bh) / (n - 1);
 99	else
100		h = sh - bh;
101
102	for(i = 0, c = clients; c; c = c->next) {
103		if(isvisible(c)) {
104			if(c->isfloat) {
105				resize(c, True, TopLeft);
106				continue;
107			}
108			if(n == 1) {
109				c->x = sx;
110				c->y = sy + bh;
111				c->w = sw - 2;
112				c->h = sh - 2 - bh;
113			}
114			else if(i == 0) {
115				c->x = sx;
116				c->y = sy + bh;
117				c->w = mw - 2;
118				c->h = sh - 2 - bh;
119			}
120			else if(h > bh) {
121				c->x = sx + mw;
122				c->y = sy + (i - 1) * h + bh;
123				c->w = w - 2;
124				if(i + 1 == n)
125					c->h = sh - c->y - 2;
126				else
127					c->h = h - 2;
128			}
129			else { /* fallback if h < bh */
130				c->x = sx + mw;
131				c->y = sy + bh;
132				c->w = w - 2;
133				c->h = sh - 2 - bh;
134			}
135			resize(c, False, TopLeft);
136			i++;
137		}
138		else
139			ban(c);
140	}
141	if(!sel || !isvisible(sel))
142		focus(getnext(clients));
143	restack();
144}
145
146void
147focusnext(Arg *arg)
148{
149	Client *c;
150   
151	if(!sel)
152		return;
153
154	if(!(c = getnext(sel->next)))
155		c = getnext(clients);
156	if(c) {
157		focus(c);
158		restack();
159	}
160}
161
162void
163focusprev(Arg *arg)
164{
165	Client *c;
166
167	if(!sel)
168		return;
169
170	if(!(c = getprev(sel->prev))) {
171		for(c = clients; c && c->next; c = c->next);
172		c = getprev(c);
173	}
174	if(c) {
175		focus(c);
176		restack();
177	}
178}
179
180Bool
181isvisible(Client *c)
182{
183	unsigned int i;
184
185	for(i = 0; i < ntags; i++)
186		if(c->tags[i] && seltag[i])
187			return True;
188	return False;
189}
190
191void
192resizecol(Arg *arg)
193{
194	unsigned int n;
195	Client *c;
196
197	for(n = 0, c = clients; c; c = c->next)
198		if(isvisible(c) && !c->isfloat)
199			n++;
200	if(!sel || sel->isfloat || n < 2 || (arrange != dotile) || maximized)
201		return;
202
203	if(sel == getnext(clients)) {
204		if(mw + arg->i > sw - 100 || mw + arg->i < 100)
205			return;
206		mw += arg->i;
207	}
208	else {
209		if(mw - arg->i > sw - 100 || mw - arg->i < 100)
210			return;
211		mw -= arg->i;
212	}
213	arrange(NULL);
214}
215
216void
217restack()
218{
219	Client *c;
220	XEvent ev;
221	
222	if(!sel) {
223		drawstatus();
224		return;
225	}
226	if(sel->isfloat || arrange == dofloat) {
227		XRaiseWindow(dpy, sel->win);
228		XRaiseWindow(dpy, sel->twin);
229	}
230	if(arrange != dofloat) 
231		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
232			XLowerWindow(dpy, c->twin);
233			XLowerWindow(dpy, c->win);
234		}
235	drawall();
236	XSync(dpy, False);
237	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
238}
239
240void
241togglemode(Arg *arg)
242{
243	arrange = (arrange == dofloat) ? dotile : dofloat;
244	if(sel)
245		arrange(NULL);
246	else
247		drawstatus();
248}
249
250void
251toggleview(Arg *arg)
252{
253	unsigned int i;
254
255	seltag[arg->i] = !seltag[arg->i];
256	for(i = 0; i < ntags && !seltag[i]; i++);
257	if(i == ntags)
258		seltag[arg->i] = True; /* cannot toggle last view */
259	reorder();
260	arrange(NULL);
261}
262
263void
264view(Arg *arg)
265{
266	unsigned int i;
267
268	for(i = 0; i < ntags; i++)
269		seltag[i] = False;
270	seltag[arg->i] = True;
271	reorder();
272	arrange(NULL);
273}
274
275void
276viewall(Arg *arg)
277{
278	unsigned int i;
279
280	for(i = 0; i < ntags; i++)
281		seltag[i] = True;
282	reorder();
283	arrange(NULL);
284}
285
286void
287zoom(Arg *arg)
288{
289	unsigned int n;
290	Client *c;
291
292	for(n = 0, c = clients; c; c = c->next)
293		if(isvisible(c) && !c->isfloat)
294			n++;
295	if(!sel || sel->isfloat || n < 2 || (arrange != dotile) || maximized)
296		return;
297
298	if((c = sel) == nexttiled(clients))
299		if(!(c = nexttiled(c->next)))
300			return;
301	detach(c);
302	if(clients)
303		clients->prev = c;
304	c->next = clients;
305	clients = c;
306	focus(c);
307	arrange(NULL);
308}