all repos — dwm @ aa53e39ec0eb39949c5c03d56da08204d14d9ff9

fork of suckless dynamic window manager

layout.c (view raw)

  1/* See LICENSE file for copyright and license details. */
  2#include "dwm.h"
  3#include <stdio.h>
  4#include <stdlib.h>
  5
  6unsigned int blw = 0;
  7Layout *lt = NULL;
  8
  9/* static */
 10
 11static unsigned int nlayouts = 0;
 12
 13LAYOUTS
 14
 15/* extern */
 16
 17void
 18floating(const char *arg) {
 19	Client *c;
 20
 21	if(lt->arrange != floating)
 22		return;
 23
 24	for(c = clients; c; c = c->next)
 25		if(isvisible(c)) {
 26			unban(c);
 27			resize(c, c->x, c->y, c->w, c->h, True);
 28		}
 29		else
 30			ban(c);
 31	focus(NULL);
 32	restack();
 33}
 34
 35void
 36focusclient(const char *arg) {
 37	Client *c;
 38   
 39	if(!sel || !arg)
 40		return;
 41	if(atoi(arg) < 0) {
 42		for(c = sel->prev; c && !isvisible(c); c = c->prev);
 43		if(!c) {
 44			for(c = clients; c && c->next; c = c->next);
 45			for(; c && !isvisible(c); c = c->prev);
 46		}
 47	}
 48	else {
 49		for(c = sel->next; c && !isvisible(c); c = c->next);
 50		if(!c)
 51			for(c = clients; c && !isvisible(c); c = c->next);
 52	}
 53	if(c) {
 54		focus(c);
 55		restack();
 56	}
 57}
 58
 59void
 60initlayouts(void) {
 61	unsigned int i, w;
 62
 63	lt = &layout[0];
 64	nlayouts = sizeof layout / sizeof layout[0];
 65	for(blw = i = 0; i < nlayouts; i++) {
 66		w = textw(layout[i].symbol);
 67		if(w > blw)
 68			blw = w;
 69	}
 70}
 71
 72Client *
 73nexttiled(Client *c) {
 74	for(; c && (c->isfloating || !isvisible(c)); c = c->next);
 75	return c;
 76}
 77
 78void
 79restack(void) {
 80	Client *c;
 81	XEvent ev;
 82	XWindowChanges wc;
 83
 84	drawstatus();
 85	if(!sel)
 86		return;
 87	if(sel->isfloating || lt->arrange == floating)
 88		XRaiseWindow(dpy, sel->win);
 89	if(lt->arrange != floating) {
 90		wc.stack_mode = Below;
 91		wc.sibling = barwin;
 92		if(!sel->isfloating) {
 93			XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc);
 94			wc.sibling = sel->win;
 95		}
 96		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
 97			if(c == sel)
 98				continue;
 99			XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
100			wc.sibling = c->win;
101		}
102	}
103	XSync(dpy, False);
104	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
105}
106
107void
108setlayout(const char *arg) {
109	int i;
110
111	if(!arg) {
112		lt++;
113		if(lt == layout + nlayouts)
114			lt = layout;
115	}
116	else {
117		i = atoi(arg);
118		if(i < 0 || i >= nlayouts)
119			return;
120		lt = &layout[i];
121	}
122	if(sel)
123		lt->arrange(NULL);
124	else
125		drawstatus();
126}
127
128void
129tile(const char *arg) {
130	static double master = MASTER;
131	double delta;
132	unsigned int i, n, nx, ny, nw, nh, mw, th;
133	Client *c;
134
135	if(lt->arrange != tile)
136		return;
137
138	/* arg handling, manipulate master */
139	if(arg && (1 == sscanf(arg, "%lf", &delta))) {
140		if(delta + master > 0.1 && delta + master < 0.9)
141			master += delta;
142	}
143
144	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
145		n++;
146
147	/* window geoms */
148	mw = (n == 1) ? waw : master * waw;
149	th = (n > 1) ? wah / (n - 1) : 0;
150	if(n > 1 && th < bh)
151		th = wah;
152
153	nx = wax;
154	ny = way;
155	for(i = 0, c = clients; c; c = c->next)
156		if(isvisible(c)) {
157			unban(c);
158			if(c->isfloating)
159				continue;
160			c->ismax = False;
161			if(i == 0) { /* master */
162				nw = mw - 2 * c->border;
163				nh = wah - 2 * c->border;
164			}
165			else {  /* tile window */
166				if(i == 1) {
167					ny = way;
168					nx += mw;
169				}
170				nw = waw - mw - 2 * c->border;
171				if(i + 1 == n) /* remainder */
172					nh = (way + wah) - ny - 2 * c->border;
173				else
174					nh = th - 2 * c->border;
175			}
176			resize(c, nx, ny, nw, nh, False);
177			if(n > 1 && th != wah)
178				ny += nh;
179			i++;
180		}
181		else
182			ban(c);
183	focus(NULL);
184	restack();
185}
186
187void
188togglebar(const char *arg) {
189	if(bpos == BarOff)
190		bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
191	else
192		bpos = BarOff;
193	updatebarpos();
194	lt->arrange(NULL);
195}
196
197void
198togglemax(const char *arg) {
199	XEvent ev;
200
201	if(!sel || (lt->arrange != floating && !sel->isfloating) || sel->isfixed)
202		return;
203	if((sel->ismax = !sel->ismax)) {
204		sel->rx = sel->x;
205		sel->ry = sel->y;
206		sel->rw = sel->w;
207		sel->rh = sel->h;
208		resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True);
209	}
210	else
211		resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
212	drawstatus();
213	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
214}
215
216void
217zoom(const char *arg) {
218	Client *c;
219
220	if(!sel || lt->arrange == floating || sel->isfloating)
221		return;
222	if((c = sel) == nexttiled(clients))
223		if(!(c = nexttiled(c->next)))
224			return;
225	detach(c);
226	attach(c);
227	focus(c);
228	lt->arrange(NULL);
229}