all repos — dwm @ 39ffc18635686b1a65cd80d19828c4fe2aed982f

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