separated layout-specific stuff into separate .h and .c files which are included in config.h resp. config.mk - this allows writing layouts for dwm without any need to patch existing code 2d81b78b
Anselm R. Garbe · 2007-08-11 12:11 13 file(s) · +164 −134
Makefile +1 −1
3 3
4 4
include config.mk
5 5
6 -
SRC = client.c draw.c event.c layout.c main.c tag.c util.c
6 +
SRC += client.c draw.c event.c layout.c main.c tag.c util.c
7 7
OBJ = ${SRC:.c=.o}
8 8
9 9
all: options dwm
client.c +3 −3
230 230
	setclientstate(c, IconicState);
231 231
	c->isbanned = True;
232 232
	focus(c);
233 -
	lt->arrange(NULL);
233 +
	lt->arrange();
234 234
}
235 235
236 236
void
305 305
	sel->isfloating = !sel->isfloating;
306 306
	if(sel->isfloating)
307 307
		resize(sel, sel->x, sel->y, sel->w, sel->h, True);
308 -
	lt->arrange(NULL);
308 +
	lt->arrange();
309 309
}
310 310
311 311
void
337 337
	XSync(dpy, False);
338 338
	XSetErrorHandler(xerror);
339 339
	XUngrabServer(dpy);
340 -
	lt->arrange(NULL);
340 +
	lt->arrange();
341 341
}
342 342
343 343
void
config.arg.h +4 −3
24 24
};
25 25
26 26
/* layout(s) */
27 -
void tile(const char *arg);		/* arranges all windows tiled */
27 +
#include "tile.h"
28 +
#include "float.h"
28 29
#define LAYOUTS \
29 30
static Layout layout[] = { \
30 31
	/* symbol		function */ \
46 47
		"exec urxvtcd -tr -bg '#111' -fg '#eee' -cr '#eee' +sb -fn '"FONT"'" }, \
47 48
	{ MODKEY,			XK_space,	setlayout,	NULL }, \
48 49
	{ MODKEY,			XK_b,		togglebar,	NULL }, \
49 -
	{ MODKEY,			XK_h,		tile,		"-0.05" }, \
50 50
	{ MODKEY,			XK_j,		focusclient,	"1" }, \
51 51
	{ MODKEY,			XK_k,		focusclient,	"-1" }, \
52 -
	{ MODKEY,			XK_l,		tile,		"0.05" }, \
52 +
	{ MODKEY,			XK_h,		incmaster,	"-0.05" }, \
53 +
	{ MODKEY,			XK_l,		incmaster,	"0.05" }, \
53 54
	{ MODKEY,			XK_m,		togglemax,	NULL }, \
54 55
	{ MODKEY,			XK_Return,	zoom,		NULL }, \
55 56
	{ MODKEY|ShiftMask,		XK_space,	togglefloating,	NULL }, \
config.default.h +4 −3
25 25
};
26 26
27 27
/* layout(s) */
28 -
void tile(const char *arg);		/* arranges all windows tiled */
28 +
#include "tile.h"
29 +
#include "float.h"
29 30
#define LAYOUTS \
30 31
static Layout layout[] = { \
31 32
	/* symbol		function */ \
44 45
	{ MODKEY,			XK_p,		spawn, 		"exe=`dmenu_path | dmenu` && exec $exe" }, \
45 46
	{ MODKEY,			XK_space,	setlayout,	NULL }, \
46 47
	{ MODKEY,			XK_b,		togglebar,	NULL }, \
47 -
	{ MODKEY,			XK_h,		tile,		"-0.05" }, \
48 48
	{ MODKEY,			XK_j,		focusclient,	"1" }, \
49 49
	{ MODKEY,			XK_k,		focusclient,	"-1" }, \
50 -
	{ MODKEY,			XK_l,		tile,		"0.05" }, \
50 +
	{ MODKEY,			XK_h,		incmaster,	"-0.05" }, \
51 +
	{ MODKEY,			XK_l,		incmaster,	"0.05" }, \
51 52
	{ MODKEY,			XK_m,		togglemax,	NULL }, \
52 53
	{ MODKEY,			XK_Return,	zoom,		NULL }, \
53 54
	{ MODKEY|ShiftMask,		XK_space,	togglefloating,	NULL }, \
config.mk +3 −0
3 3
4 4
# Customize below to fit your system
5 5
6 +
# layouts
7 +
SRC = float.c tile.c
8 +
6 9
# paths
7 10
PREFIX = /usr/local
8 11
MANPREFIX = ${PREFIX}/share/man
dwm.h +1 −4
76 76
77 77
typedef struct {
78 78
	const char *symbol;
79 -
	void (*arrange)(const char *);
79 +
	void (*arrange)(void);
80 80
} Layout;
81 81
82 82
extern const char *tags[];			/* all tags */
120 120
void grabkeys(void);			/* grab all keys defined in config.h */
121 121
122 122
/* layout.c */
123 -
void floating(const char *arg);		/* arranges all windows floating */
124 123
void focusclient(const char *arg);	/* focuses next(1)/previous(-1) visible client */
125 124
void initlayouts(void);			/* initialize layout array */
126 125
Client *nexttiled(Client *c);		/* returns tiled successor of c */
127 126
void restack(void);			/* restores z layers of all clients */
128 127
void setlayout(const char *arg);	/* sets layout, NULL means next layout */
129 128
void togglebar(const char *arg);	/* shows/hides the bar */
130 -
void togglemax(const char *arg);	/* toggles maximization of floating client */
131 -
void zoom(const char *arg);		/* zooms the focused client to master area, arg is ignored */
132 129
133 130
/* main.c */
134 131
void updatebarpos(void);		/* updates the bar position */
event.c +2 −2
216 216
		dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
217 217
		XResizeWindow(dpy, barwin, sw, bh);
218 218
		updatebarpos();
219 -
		lt->arrange(NULL);
219 +
		lt->arrange();
220 220
	}
221 221
}
222 222
317 317
			case XA_WM_TRANSIENT_FOR:
318 318
				XGetTransientForHint(dpy, c->win, &trans);
319 319
				if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL)))
320 -
					lt->arrange(NULL);
320 +
					lt->arrange();
321 321
				break;
322 322
			case XA_WM_NORMAL_HINTS:
323 323
				updatesizehints(c);
float.c (added) +41 −0
1 +
/* See LICENSE file for copyright and license details. */
2 +
#include "dwm.h"
3 +
4 +
/* extern */
5 +
6 +
void
7 +
floating(void) {
8 +
	Client *c;
9 +
10 +
	if(lt->arrange != floating)
11 +
		return;
12 +
13 +
	for(c = clients; c; c = c->next)
14 +
		if(isvisible(c)) {
15 +
			unban(c);
16 +
			resize(c, c->x, c->y, c->w, c->h, True);
17 +
		}
18 +
		else
19 +
			ban(c);
20 +
	focus(NULL);
21 +
	restack();
22 +
}
23 +
24 +
void
25 +
togglemax(const char *arg) {
26 +
	XEvent ev;
27 +
28 +
	if(!sel || (lt->arrange != floating && !sel->isfloating) || sel->isfixed)
29 +
		return;
30 +
	if((sel->ismax = !sel->ismax)) {
31 +
		sel->rx = sel->x;
32 +
		sel->ry = sel->y;
33 +
		sel->rw = sel->w;
34 +
		sel->rh = sel->h;
35 +
		resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True);
36 +
	}
37 +
	else
38 +
		resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
39 +
	drawstatus();
40 +
	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
41 +
}
float.h (added) +5 −0
1 +
/* See LICENSE file for copyright and license details. */
2 +
3 +
/* float.c */
4 +
void floating(void);			/* arranges all windows floating */
5 +
void togglemax(const char *arg);	/* toggles maximization of floating client */
layout.c +2 −114
1 1
/* See LICENSE file for copyright and license details. */
2 2
#include "dwm.h"
3 -
#include <stdio.h>
4 3
#include <stdlib.h>
5 4
6 5
unsigned int blw = 0;
13 12
LAYOUTS
14 13
15 14
/* extern */
16 -
17 -
void
18 -
floating(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 15
35 16
void
36 17
focusclient(const char *arg) {
120 101
		lt = &layout[i];
121 102
	}
122 103
	if(sel)
123 -
		lt->arrange(NULL);
104 +
		lt->arrange();
124 105
	else
125 106
		drawstatus();
126 107
}
127 108
128 109
void
129 -
tile(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 + 2 * c->border;
179 -
			i++;
180 -
		}
181 -
		else
182 -
			ban(c);
183 -
	focus(NULL);
184 -
	restack();
185 -
}
186 -
187 -
void
188 110
togglebar(const char *arg) {
189 111
	if(bpos == BarOff)
190 112
		bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
191 113
	else
192 114
		bpos = BarOff;
193 115
	updatebarpos();
194 -
	lt->arrange(NULL);
195 -
}
196 -
197 -
void
198 -
togglemax(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 -
216 -
void
217 -
zoom(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);
116 +
	lt->arrange();
229 117
}
tag.c +4 −4
110 110
	i = arg ? atoi(arg) : 0;
111 111
	if(i >= 0 && i < ntags)
112 112
		sel->tags[i] = True;
113 -
	lt->arrange(NULL);
113 +
	lt->arrange();
114 114
}
115 115
116 116
void
124 124
	for(j = 0; j < ntags && !sel->tags[j]; j++);
125 125
	if(j == ntags)
126 126
		sel->tags[i] = True;
127 -
	lt->arrange(NULL);
127 +
	lt->arrange();
128 128
}
129 129
130 130
void
136 136
	for(j = 0; j < ntags && !seltag[j]; j++);
137 137
	if(j == ntags)
138 138
		seltag[i] = True; /* cannot toggle last view */
139 -
	lt->arrange(NULL);
139 +
	lt->arrange();
140 140
}
141 141
142 142
void
148 148
	i = arg ? atoi(arg) : 0;
149 149
	if(i >= 0 && i < ntags)
150 150
		seltag[i] = True;
151 -
	lt->arrange(NULL);
151 +
	lt->arrange();
152 152
}
tile.c (added) +88 −0
1 +
/* See LICENSE file for copyright and license details. */
2 +
#include "dwm.h"
3 +
#include <stdio.h>
4 +
5 +
/* static */
6 +
7 +
static double master = MASTER;
8 +
9 +
/* extern */
10 +
11 +
void
12 +
incmaster(const char *arg) {
13 +
	double delta;
14 +
15 +
	if(lt->arrange != tile)
16 +
		return;
17 +
18 +
	/* arg handling, manipulate master */
19 +
	if(arg && (1 == sscanf(arg, "%lf", &delta))) {
20 +
		if(delta + master > 0.1 && delta + master < 0.9)
21 +
			master += delta;
22 +
	}
23 +
24 +
	lt->arrange();
25 +
}
26 +
27 +
void
28 +
tile(void) {
29 +
	unsigned int i, n, nx, ny, nw, nh, mw, th;
30 +
	Client *c;
31 +
32 +
	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
33 +
		n++;
34 +
35 +
	/* window geoms */
36 +
	mw = (n == 1) ? waw : master * waw;
37 +
	th = (n > 1) ? wah / (n - 1) : 0;
38 +
	if(n > 1 && th < bh)
39 +
		th = wah;
40 +
41 +
	nx = wax;
42 +
	ny = way;
43 +
	for(i = 0, c = clients; c; c = c->next)
44 +
		if(isvisible(c)) {
45 +
			unban(c);
46 +
			if(c->isfloating)
47 +
				continue;
48 +
			c->ismax = False;
49 +
			if(i == 0) { /* master */
50 +
				nw = mw - 2 * c->border;
51 +
				nh = wah - 2 * c->border;
52 +
			}
53 +
			else {  /* tile window */
54 +
				if(i == 1) {
55 +
					ny = way;
56 +
					nx += mw;
57 +
				}
58 +
				nw = waw - mw - 2 * c->border;
59 +
				if(i + 1 == n) /* remainder */
60 +
					nh = (way + wah) - ny - 2 * c->border;
61 +
				else
62 +
					nh = th - 2 * c->border;
63 +
			}
64 +
			resize(c, nx, ny, nw, nh, False);
65 +
			if(n > 1 && th != wah)
66 +
				ny += nh + 2 * c->border;
67 +
			i++;
68 +
		}
69 +
		else
70 +
			ban(c);
71 +
	focus(NULL);
72 +
	restack();
73 +
}
74 +
75 +
void
76 +
zoom(const char *arg) {
77 +
	Client *c;
78 +
79 +
	if(!sel || lt->arrange == floating || sel->isfloating)
80 +
		return;
81 +
	if((c = sel) == nexttiled(clients))
82 +
		if(!(c = nexttiled(c->next)))
83 +
			return;
84 +
	detach(c);
85 +
	attach(c);
86 +
	focus(c);
87 +
	lt->arrange();
88 +
}
tile.h (added) +6 −0
1 +
/* See LICENSE file for copyright and license details. */
2 +
3 +
/* tile.c */
4 +
void incmaster(const char *arg);	/* arranges all windows tiled */
5 +
void tile(void);			/* arranges all windows tiled */
6 +
void zoom(const char *arg);		/* zooms the focused client to master area, arg is ignored */