rearranged several stuff dba23062
Anselm R. Garbe · 2006-07-15 16:30 10 file(s) · +442 −444
Makefile +1 −1
3 3
4 4
include config.mk
5 5
6 -
SRC = client.c draw.c event.c key.c main.c screen.c util.c
6 +
SRC = client.c draw.c event.c main.c tag.c util.c
7 7
OBJ = ${SRC:.c=.o}
8 8
MAN1 = dwm.1 
9 9
BIN = dwm
client.c +87 −58
11 11
12 12
#include "dwm.h"
13 13
14 -
static Rule rule[] = {
15 -
	/* class			instance	tags						floating */
16 -
	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
17 -
};
18 -
19 -
Client *
20 -
getnext(Client *c)
21 -
{
22 -
	for(; c && !c->tags[tsel]; c = c->next);
23 -
	return c;
24 -
}
25 -
26 14
void
27 15
ban(Client *c)
28 16
{
31 19
}
32 20
33 21
static void
34 -
resize_title(Client *c)
22 +
resizetitle(Client *c)
35 23
{
36 24
	int i;
37 25
72 60
		}
73 61
	}
74 62
	XFree(name.value);
75 -
	resize_title(c);
63 +
	resizetitle(c);
76 64
}
77 65
78 66
void
143 131
	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
144 132
}
145 133
146 -
static void
147 -
init_tags(Client *c)
148 -
{
149 -
	XClassHint ch;
150 -
	static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
151 -
	unsigned int i, j;
152 -
	Bool matched = False;
153 -
154 -
	if(!len) {
155 -
		c->tags[tsel] = tags[tsel];
156 -
		return;
157 -
	}
158 -
159 -
	if(XGetClassHint(dpy, c->win, &ch)) {
160 -
		if(ch.res_class && ch.res_name) {
161 -
			for(i = 0; i < len; i++)
162 -
				if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
163 -
					&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
164 -
				{
165 -
					for(j = 0; j < TLast; j++)
166 -
						c->tags[j] = rule[i].tags[j];
167 -
					c->floating = rule[i].floating;
168 -
					matched = True;
169 -
					break;
170 -
				}
171 -
		}
172 -
		if(ch.res_class)
173 -
			XFree(ch.res_class);
174 -
		if(ch.res_name)
175 -
			XFree(ch.res_name);
176 -
	}
177 -
178 -
	if(!matched)
179 -
		c->tags[tsel] = tags[tsel];
180 -
}
181 -
182 134
void
183 135
manage(Window w, XWindowAttributes *wa)
184 136
{
196 148
	c->h = wa->height;
197 149
	c->th = bh;
198 150
	c->border = 1;
199 -
	c->proto = proto(c->win);
151 +
	c->proto = getproto(c->win);
200 152
	setsize(c);
201 153
	XSelectInput(dpy, c->win,
202 154
			StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
211 163
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
212 164
213 165
	settitle(c);
214 -
	init_tags(c);
166 +
	settags(c);
215 167
216 168
	for(l = &clients; *l; l = &(*l)->next);
217 169
	c->next = *l; /* *l == nil */
224 176
	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
225 177
			GrabModeAsync, GrabModeSync, None, None);
226 178
227 -
	if(!c->floating)
228 -
		c->floating = trans
179 +
	if(!c->dofloat)
180 +
		c->dofloat = trans
229 181
			|| ((c->maxw == c->minw) && (c->maxh == c->minh));
230 182
231 183
	arrange(NULL);
321 273
		c->w = c->maxw;
322 274
	if(c->maxh && c->h > c->maxh)
323 275
		c->h = c->maxh;
324 -
	resize_title(c);
276 +
	resizetitle(c);
325 277
	XSetWindowBorderWidth(dpy, c->win, 1);
326 278
	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
327 279
	e.type = ConfigureNotify;
339 291
}
340 292
341 293
static int
342 -
dummy_xerror(Display *dsply, XErrorEvent *err)
294 +
xerrordummy(Display *dsply, XErrorEvent *ee)
343 295
{
344 296
	return 0;
345 297
}
350 302
	Client **l;
351 303
352 304
	XGrabServer(dpy);
353 -
	XSetErrorHandler(dummy_xerror);
305 +
	XSetErrorHandler(xerrordummy);
354 306
355 307
	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
356 308
	XDestroyWindow(dpy, c->title);
374 326
}
375 327
376 328
Client *
377 -
gettitle(Window w)
329 +
getctitle(Window w)
378 330
{
379 331
	Client *c;
380 332
	for(c = clients; c; c = c->next)
392 344
			return c;
393 345
	return NULL;
394 346
}
347 +
348 +
void
349 +
zoom(Arg *arg)
350 +
{
351 +
	Client **l, *c;
352 +
353 +
	if(!sel)
354 +
		return;
355 +
356 +
	if(sel == getnext(clients) && sel->next)  {
357 +
		if((c = getnext(sel->next)))
358 +
			sel = c;
359 +
	}
360 +
361 +
	for(l = &clients; *l && *l != sel; l = &(*l)->next);
362 +
	*l = sel->next;
363 +
364 +
	sel->next = clients; /* pop */
365 +
	clients = sel;
366 +
	arrange(NULL);
367 +
	focus(sel);
368 +
}
369 +
370 +
void
371 +
maximize(Arg *arg)
372 +
{
373 +
	if(!sel)
374 +
		return;
375 +
	sel->x = sx;
376 +
	sel->y = sy + bh;
377 +
	sel->w = sw - 2 * sel->border;
378 +
	sel->h = sh - 2 * sel->border - bh;
379 +
	higher(sel);
380 +
	resize(sel, False);
381 +
}
382 +
383 +
void
384 +
focusprev(Arg *arg)
385 +
{
386 +
	Client *c;
387 +
388 +
	if(!sel)
389 +
		return;
390 +
391 +
	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
392 +
		higher(c);
393 +
		focus(c);
394 +
	}
395 +
}
396 +
397 +
void
398 +
focusnext(Arg *arg)
399 +
{
400 +
	Client *c;
401 +
   
402 +
	if(!sel)
403 +
		return;
404 +
405 +
	if(!(c = getnext(sel->next)))
406 +
		c = getnext(clients);
407 +
	if(c) {
408 +
		higher(c);
409 +
		c->revert = sel;
410 +
		focus(c);
411 +
	}
412 +
}
413 +
414 +
void
415 +
killclient(Arg *arg)
416 +
{
417 +
	if(!sel)
418 +
		return;
419 +
	if(sel->proto & WM_PROTOCOL_DELWIN)
420 +
		sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
421 +
	else
422 +
		XKillClient(dpy, sel->win);
423 +
}
draw.c +24 −13
11 11
#include "dwm.h"
12 12
13 13
void
14 +
drawall()
15 +
{
16 +
	Client *c;
17 +
18 +
	for(c = clients; c; c = getnext(c->next))
19 +
		drawtitle(c);
20 +
	drawstatus();
21 +
}
22 +
23 +
void
14 24
drawstatus()
15 25
{
16 26
	int i;
27 +
	Bool istile = arrange == dotile;
17 28
18 29
	dc.x = dc.y = 0;
19 30
	dc.w = bw;
20 -
	drawtext(NULL, False, False);
31 +
	drawtext(NULL, !istile, False);
21 32
22 -
	if(arrange == floating) {
23 -
		dc.w = textw("~");
24 -
		drawtext("~", False, False);
25 -
	}
26 -
	else
27 -
		dc.w = 0;
33 +
	dc.w = 0;
28 34
	for(i = 0; i < TLast; i++) {
29 35
		dc.x += dc.w;
30 36
		dc.w = textw(tags[i]);
31 -
		drawtext(tags[i], i == tsel, True);
37 +
		if(istile)
38 +
			drawtext(tags[i], (i == tsel), True);
39 +
		else
40 +
			drawtext(tags[i], (i != tsel), True);
32 41
	}
33 42
	if(sel) {
34 43
		dc.x += dc.w;
35 44
		dc.w = textw(sel->name);
36 -
		drawtext(sel->name, True, True);
45 +
		drawtext(sel->name, istile, True);
37 46
	}
38 47
	dc.w = textw(stext);
39 48
	dc.x = bx + bw - dc.w;
40 -
	drawtext(stext, False, False);
49 +
	drawtext(stext, !istile, False);
41 50
42 51
	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
43 52
	XFlush(dpy);
47 56
drawtitle(Client *c)
48 57
{
49 58
	int i;
59 +
	Bool istile = arrange == dotile;
60 +
50 61
	if(c == sel) {
51 62
		drawstatus();
52 63
		XUnmapWindow(dpy, c->title);
64 75
		if(c->tags[i]) {
65 76
			dc.x += dc.w;
66 77
			dc.w = textw(c->tags[i]);
67 -
			drawtext(c->tags[i], False, True);
78 +
			drawtext(c->tags[i], !istile, True);
68 79
		}
69 80
	}
70 81
	dc.x += dc.w;
71 82
	dc.w = textw(c->name);
72 -
	drawtext(c->name, False, True);
83 +
	drawtext(c->name, !istile, True);
73 84
	XCopyArea(dpy, dc.drawable, c->title, dc.gc,
74 85
			0, 0, c->tw, c->th, 0, 0);
75 86
	XFlush(dpy);
215 226
		if (!dc.font.xfont)
216 227
			dc.font.xfont = XLoadQueryFont(dpy, "fixed");
217 228
		if (!dc.font.xfont)
218 -
			error("error, cannot init 'fixed' font\n");
229 +
			eprint("error, cannot init 'fixed' font\n");
219 230
		dc.font.ascent = dc.font.xfont->ascent;
220 231
		dc.font.descent = dc.font.xfont->descent;
221 232
	}
dwm.h +22 −14
66 66
	int grav;
67 67
	unsigned int border;
68 68
	long flags; 
69 -
	Bool floating;
69 +
	Bool dofloat;
70 70
	Window win;
71 71
	Window title;
72 72
	Client *next;
77 77
	const char *class;
78 78
	const char *instance;
79 79
	char *tags[TLast];
80 -
	Bool floating;
80 +
	Bool dofloat;
81 81
};
82 82
83 83
struct Key {
103 103
extern Client *clients, *sel;
104 104
105 105
/* client.c */
106 +
extern void ban(Client *c);
106 107
extern void manage(Window w, XWindowAttributes *wa);
107 108
extern void unmanage(Client *c);
108 109
extern Client *getclient(Window w);
110 111
extern void settitle(Client *c);
111 112
extern void resize(Client *c, Bool inc);
112 113
extern void setsize(Client *c);
113 -
extern Client *gettitle(Window w);
114 +
extern Client *getctitle(Window w);
114 115
extern void higher(Client *c);
115 116
extern void lower(Client *c);
116 117
extern void gravitate(Client *c, Bool invert);
117 -
extern void ban(Client *c);
118 -
extern Client *getnext(Client *c);
118 +
extern void zoom(Arg *arg);
119 +
extern void maximize(Arg *arg);
120 +
extern void focusprev(Arg *arg);
121 +
extern void focusnext(Arg *arg);
122 +
extern void killclient(Arg *arg);
119 123
120 124
/* draw.c */
125 +
extern void drawall();
121 126
extern void drawstatus();
122 127
extern void drawtitle(Client *c);
123 128
extern void drawtext(const char *text, Bool invert, Bool border);
127 132
extern unsigned int textw(char *text);
128 133
extern unsigned int texth(void);
129 134
130 -
/* key.c */
135 +
/* event.c */
131 136
extern void grabkeys();
132 -
extern void keypress(XEvent *e);
133 137
134 138
/* main.c */
135 -
extern int xerror(Display *dsply, XErrorEvent *e);
139 +
extern void quit(Arg *arg);
140 +
extern int xerror(Display *dsply, XErrorEvent *ee);
136 141
extern void sendevent(Window w, Atom a, long value);
137 -
extern int proto(Window w);
138 -
extern void quit(Arg *arg);
142 +
extern int getproto(Window w);
139 143
140 -
/* screen.c */
141 -
extern void floating(Arg *arg);
142 -
extern void tiling(Arg *arg);
144 +
/* tag.c */
145 +
extern Client *getnext(Client *c);
146 +
extern void settags(Client *c);
147 +
extern void dofloat(Arg *arg);
148 +
extern void dotile(Arg *arg);
143 149
extern void view(Arg *arg);
150 +
extern void appendtag(Arg *arg);
151 +
extern void replacetag(Arg *arg);
144 152
145 153
/* util.c */
146 -
extern void error(const char *errstr, ...);
154 +
extern void eprint(const char *errstr, ...);
147 155
extern void *emallocz(unsigned int size);
148 156
extern void spawn(Arg *arg);
event.c +80 −9
16 16
#define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
17 17
#define MouseMask       (ButtonMask | PointerMotionMask)
18 18
19 +
/********** CUSTOMIZE **********/
20 +
21 +
const char *term[] = { 
22 +
	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
23 +
	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
24 +
};
25 +
const char *browse[] = { "firefox", NULL };
26 +
const char *xlock[] = { "xlock", NULL };
27 +
28 +
Key key[] = {
29 +
	/* modifier				key			function	arguments */
30 +
	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } },
31 +
	{ Mod1Mask,				XK_k,		focusprev,		{ 0 } },
32 +
	{ Mod1Mask,				XK_j,		focusnext,		{ 0 } }, 
33 +
	{ Mod1Mask,				XK_m,		maximize,		{ 0 } }, 
34 +
	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } }, 
35 +
	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } }, 
36 +
	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } }, 
37 +
	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } }, 
38 +
	{ Mod1Mask,				XK_space,	dotile,		{ 0 } }, 
39 +
	{ Mod1Mask|ShiftMask,	XK_space,	dofloat,	{ 0 } }, 
40 +
	{ Mod1Mask|ShiftMask,	XK_0,		replacetag,		{ .i = Tscratch } }, 
41 +
	{ Mod1Mask|ShiftMask,	XK_1,		replacetag,		{ .i = Tdev } }, 
42 +
	{ Mod1Mask|ShiftMask,	XK_2,		replacetag,		{ .i = Twww } }, 
43 +
	{ Mod1Mask|ShiftMask,	XK_3,		replacetag,		{ .i = Twork } }, 
44 +
	{ Mod1Mask|ShiftMask,	XK_c,		killclient,		{ 0 } }, 
45 +
	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } },
46 +
	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } },
47 +
	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } },
48 +
	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } },
49 +
	{ ControlMask,			XK_0,		appendtag,	{ .i = Tscratch } }, 
50 +
	{ ControlMask,			XK_1,		appendtag,	{ .i = Tdev } }, 
51 +
	{ ControlMask,			XK_2,		appendtag,	{ .i = Twww } }, 
52 +
	{ ControlMask,			XK_3,		appendtag,	{ .i = Twork } }, 
53 +
};
54 +
55 +
/********** CUSTOMIZE **********/
56 +
19 57
/* local functions */
20 58
static void buttonpress(XEvent *e);
21 59
static void configurerequest(XEvent *e);
23 61
static void enternotify(XEvent *e);
24 62
static void leavenotify(XEvent *e);
25 63
static void expose(XEvent *e);
64 +
static void keypress(XEvent *e);
26 65
static void maprequest(XEvent *e);
27 66
static void propertynotify(XEvent *e);
28 67
static void unmapnotify(XEvent *e);
40 79
	[UnmapNotify] = unmapnotify
41 80
};
42 81
82 +
void
83 +
grabkeys()
84 +
{
85 +
	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
86 +
	unsigned int i;
87 +
	KeyCode code;
88 +
89 +
	for(i = 0; i < len; i++) {
90 +
		code = XKeysymToKeycode(dpy, key[i].keysym);
91 +
		XUngrabKey(dpy, code, key[i].mod, root);
92 +
		XGrabKey(dpy, code, key[i].mod, root, True,
93 +
				GrabModeAsync, GrabModeAsync);
94 +
	}
95 +
}
96 +
43 97
static void
44 -
mresize(Client *c)
98 +
keypress(XEvent *e)
99 +
{
100 +
	XKeyEvent *ev = &e->xkey;
101 +
	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
102 +
	unsigned int i;
103 +
	KeySym keysym;
104 +
105 +
	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
106 +
	for(i = 0; i < len; i++)
107 +
		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
108 +
			if(key[i].func)
109 +
				key[i].func(&key[i].arg);
110 +
			return;
111 +
		}
112 +
}
113 +
114 +
static void
115 +
resizemouse(Client *c)
45 116
{
46 117
	XEvent ev;
47 118
	int ocx, ocy;
75 146
}
76 147
77 148
static void
78 -
mmove(Client *c)
149 +
movemouse(Client *c)
79 150
{
80 151
	XEvent ev;
81 152
	int x1, y1, ocx, ocy, di;
117 188
	Client *c;
118 189
119 190
	if(barwin == ev->window) {
120 -
		x = (arrange == floating) ? textw("~") : 0;
191 +
		x = (arrange == dofloat) ? textw("~") : 0;
121 192
		for(a.i = 0; a.i < TLast; a.i++) {
122 193
			x += textw(tags[a.i]);
123 194
			if(ev->x < x) {
127 198
		}
128 199
	}
129 200
	else if((c = getclient(ev->window))) {
130 -
		if(arrange == tiling && !c->floating)
201 +
		if(arrange == dotile && !c->dofloat)
131 202
			return;
132 203
		higher(c);
133 204
		switch(ev->button) {
134 205
		default:
135 206
			break;
136 207
		case Button1:
137 -
			mmove(c);
208 +
			movemouse(c);
138 209
			break;
139 210
		case Button2:
140 211
			lower(c);
141 212
			break;
142 213
		case Button3:
143 -
			mresize(c);
214 +
			resizemouse(c);
144 215
			break;
145 216
		}
146 217
	}
226 297
	if(ev->count == 0) {
227 298
		if(barwin == ev->window)
228 299
			drawstatus();
229 -
		else if((c = gettitle(ev->window)))
300 +
		else if((c = getctitle(ev->window)))
230 301
			drawtitle(c);
231 302
	}
232 303
}
262 333
263 334
	if((c = getclient(ev->window))) {
264 335
		if(ev->atom == wm_atom[WMProtocols]) {
265 -
			c->proto = proto(c->win);
336 +
			c->proto = getproto(c->win);
266 337
			return;
267 338
		}
268 339
		switch (ev->atom) {
269 340
			default: break;
270 341
			case XA_WM_TRANSIENT_FOR:
271 342
				XGetTransientForHint(dpy, c->win, &trans);
272 -
				if(!c->floating && (c->floating = (trans != 0)))
343 +
				if(!c->dofloat && (c->dofloat = (trans != 0)))
273 344
					arrange(NULL);
274 345
				break;
275 346
			case XA_WM_NORMAL_HINTS:
key.c (deleted) +0 −192
1 -
/*
2 -
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 -
 * See LICENSE file for license details.
4 -
 */
5 -
6 -
#include <fcntl.h>
7 -
#include <stdio.h>
8 -
#include <stdlib.h>
9 -
#include <string.h>
10 -
#include <unistd.h>
11 -
#include <X11/keysym.h>
12 -
#include <X11/Xatom.h>
13 -
14 -
#include "dwm.h"
15 -
16 -
static void ckill(Arg *arg);
17 -
static void nextc(Arg *arg);
18 -
static void prevc(Arg *arg);
19 -
static void max(Arg *arg);
20 -
static void ttrunc(Arg *arg);
21 -
static void tappend(Arg *arg);
22 -
static void zoom(Arg *arg);
23 -
24 -
/********** CUSTOMIZE **********/
25 -
26 -
const char *term[] = { 
27 -
	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
28 -
	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
29 -
};
30 -
const char *browse[] = { "firefox", NULL };
31 -
const char *xlock[] = { "xlock", NULL };
32 -
33 -
Key key[] = {
34 -
	/* modifier				key			function	arguments */
35 -
	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } },
36 -
	{ Mod1Mask,				XK_k,		prevc,		{ 0 } },
37 -
	{ Mod1Mask,				XK_j,		nextc,		{ 0 } }, 
38 -
	{ Mod1Mask,				XK_m,		max,		{ 0 } }, 
39 -
	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } }, 
40 -
	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } }, 
41 -
	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } }, 
42 -
	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } }, 
43 -
	{ Mod1Mask,				XK_space,	tiling,		{ 0 } }, 
44 -
	{ Mod1Mask|ShiftMask,	XK_space,	floating,	{ 0 } }, 
45 -
	{ Mod1Mask|ShiftMask,	XK_0,		ttrunc,		{ .i = Tscratch } }, 
46 -
	{ Mod1Mask|ShiftMask,	XK_1,		ttrunc,		{ .i = Tdev } }, 
47 -
	{ Mod1Mask|ShiftMask,	XK_2,		ttrunc,		{ .i = Twww } }, 
48 -
	{ Mod1Mask|ShiftMask,	XK_3,		ttrunc,		{ .i = Twork } }, 
49 -
	{ Mod1Mask|ShiftMask,	XK_c,		ckill,		{ 0 } }, 
50 -
	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } },
51 -
	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } },
52 -
	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } },
53 -
	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } },
54 -
	{ ControlMask,			XK_0,		tappend,	{ .i = Tscratch } }, 
55 -
	{ ControlMask,			XK_1,		tappend,	{ .i = Tdev } }, 
56 -
	{ ControlMask,			XK_2,		tappend,	{ .i = Twww } }, 
57 -
	{ ControlMask,			XK_3,		tappend,	{ .i = Twork } }, 
58 -
};
59 -
60 -
/********** CUSTOMIZE **********/
61 -
62 -
void
63 -
grabkeys()
64 -
{
65 -
	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
66 -
	unsigned int i;
67 -
	KeyCode code;
68 -
69 -
	for(i = 0; i < len; i++) {
70 -
		code = XKeysymToKeycode(dpy, key[i].keysym);
71 -
		XUngrabKey(dpy, code, key[i].mod, root);
72 -
		XGrabKey(dpy, code, key[i].mod, root, True,
73 -
				GrabModeAsync, GrabModeAsync);
74 -
	}
75 -
}
76 -
77 -
void
78 -
keypress(XEvent *e)
79 -
{
80 -
	XKeyEvent *ev = &e->xkey;
81 -
	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
82 -
	unsigned int i;
83 -
	KeySym keysym;
84 -
85 -
	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
86 -
	for(i = 0; i < len; i++)
87 -
		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
88 -
			if(key[i].func)
89 -
				key[i].func(&key[i].arg);
90 -
			return;
91 -
		}
92 -
}
93 -
94 -
static void
95 -
zoom(Arg *arg)
96 -
{
97 -
	Client **l, *c;
98 -
99 -
	if(!sel)
100 -
		return;
101 -
102 -
	if(sel == getnext(clients) && sel->next)  {
103 -
		if((c = getnext(sel->next)))
104 -
			sel = c;
105 -
	}
106 -
107 -
	for(l = &clients; *l && *l != sel; l = &(*l)->next);
108 -
	*l = sel->next;
109 -
110 -
	sel->next = clients; /* pop */
111 -
	clients = sel;
112 -
	arrange(NULL);
113 -
	focus(sel);
114 -
}
115 -
116 -
static void
117 -
max(Arg *arg)
118 -
{
119 -
	if(!sel)
120 -
		return;
121 -
	sel->x = sx;
122 -
	sel->y = sy + bh;
123 -
	sel->w = sw - 2 * sel->border;
124 -
	sel->h = sh - 2 * sel->border - bh;
125 -
	higher(sel);
126 -
	resize(sel, False);
127 -
}
128 -
129 -
static void
130 -
tappend(Arg *arg)
131 -
{
132 -
	if(!sel)
133 -
		return;
134 -
135 -
	sel->tags[arg->i] = tags[arg->i];
136 -
	arrange(NULL);
137 -
}
138 -
139 -
static void
140 -
ttrunc(Arg *arg)
141 -
{
142 -
	int i;
143 -
	if(!sel)
144 -
		return;
145 -
146 -
	for(i = 0; i < TLast; i++)
147 -
		sel->tags[i] = NULL;
148 -
	tappend(arg);
149 -
}
150 -
151 -
static void
152 -
prevc(Arg *arg)
153 -
{
154 -
	Client *c;
155 -
156 -
	if(!sel)
157 -
		return;
158 -
159 -
	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
160 -
		higher(c);
161 -
		focus(c);
162 -
	}
163 -
}
164 -
165 -
static void
166 -
nextc(Arg *arg)
167 -
{
168 -
	Client *c;
169 -
   
170 -
	if(!sel)
171 -
		return;
172 -
173 -
	if(!(c = getnext(sel->next)))
174 -
		c = getnext(clients);
175 -
	if(c) {
176 -
		higher(c);
177 -
		c->revert = sel;
178 -
		focus(c);
179 -
	}
180 -
}
181 -
182 -
static void
183 -
ckill(Arg *arg)
184 -
{
185 -
	if(!sel)
186 -
		return;
187 -
	if(sel->proto & WM_PROTOCOL_DELWIN)
188 -
		sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
189 -
	else
190 -
		XKillClient(dpy, sel->win);
191 -
}
192 -
main.c +56 −56
43 43
Client *clients = NULL;
44 44
Client *sel = NULL;
45 45
46 -
static Bool other_wm_running;
46 +
static Bool otherwm;
47 47
static const char version[] =
48 48
	"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
49 -
static int (*x_xerror) (Display *, XErrorEvent *);
49 +
static int (*xerrorxlib)(Display *, XErrorEvent *);
50 50
51 51
static void
52 -
usage() {	error("usage: dwm [-v]\n"); }
52 +
usage() {	eprint("usage: dwm [-v]\n"); }
53 53
54 54
static void
55 -
scan_wins()
55 +
scan()
56 56
{
57 57
	unsigned int i, num;
58 58
	Window *wins;
73 73
		XFree(wins);
74 74
}
75 75
76 +
static void
77 +
cleanup()
78 +
{
79 +
	while(sel) {
80 +
		resize(sel, True);
81 +
		unmanage(sel);
82 +
	}
83 +
	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
84 +
}
85 +
86 +
void
87 +
quit(Arg *arg)
88 +
{
89 +
	running = False;
90 +
}
91 +
76 92
static int
77 93
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
78 94
{
94 110
}
95 111
96 112
int
97 -
proto(Window w)
113 +
getproto(Window w)
98 114
{
99 115
	unsigned char *protocols;
100 116
	long res;
129 145
}
130 146
131 147
/*
132 -
 * There's no way to check accesses to destroyed windows, thus
133 -
 * those cases are ignored (especially on UnmapNotify's).
134 -
 * Other types of errors call Xlib's default error handler, which
135 -
 * calls exit().
136 -
 */
137 -
int
138 -
xerror(Display *dpy, XErrorEvent *error)
139 -
{
140 -
	if(error->error_code == BadWindow
141 -
			|| (error->request_code == X_SetInputFocus
142 -
				&& error->error_code == BadMatch)
143 -
			|| (error->request_code == X_PolyText8
144 -
				&& error->error_code == BadDrawable)
145 -
			|| (error->request_code == X_PolyFillRectangle
146 -
				&& error->error_code == BadDrawable)
147 -
			|| (error->request_code == X_PolySegment
148 -
				&& error->error_code == BadDrawable)
149 -
			|| (error->request_code == X_ConfigureWindow
150 -
				&& error->error_code == BadMatch)
151 -
			|| (error->request_code == X_GrabKey
152 -
				&& error->error_code == BadAccess))
153 -
		return 0;
154 -
	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
155 -
			error->request_code, error->error_code);
156 -
	return x_xerror(dpy, error); /* may call exit() */
157 -
}
158 -
159 -
/*
160 148
 * Startup Error handler to check if another window manager
161 149
 * is already running.
162 150
 */
163 151
static int
164 -
startup_xerror(Display *dpy, XErrorEvent *error)
152 +
xerrorstart(Display *dsply, XErrorEvent *ee)
165 153
{
166 -
	other_wm_running = True;
154 +
	otherwm = True;
167 155
	return -1;
168 156
}
169 157
170 -
static void
171 -
cleanup()
172 -
{
173 -
	while(sel) {
174 -
		resize(sel, True);
175 -
		unmanage(sel);
176 -
	}
177 -
	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
178 -
}
179 -
180 -
void
181 -
quit(Arg *arg)
158 +
/*
159 +
 * There's no way to check accesses to destroyed windows, thus
160 +
 * those cases are ignored (especially on UnmapNotify's).
161 +
 * Other types of errors call Xlib's default error handler, which
162 +
 * calls exit().
163 +
 */
164 +
int
165 +
xerror(Display *dpy, XErrorEvent *ee)
182 166
{
183 -
	running = False;
167 +
	if(ee->error_code == BadWindow
168 +
			|| (ee->request_code == X_SetInputFocus
169 +
				&& ee->error_code == BadMatch)
170 +
			|| (ee->request_code == X_PolyText8
171 +
				&& ee->error_code == BadDrawable)
172 +
			|| (ee->request_code == X_PolyFillRectangle
173 +
				&& ee->error_code == BadDrawable)
174 +
			|| (ee->request_code == X_PolySegment
175 +
				&& ee->error_code == BadDrawable)
176 +
			|| (ee->request_code == X_ConfigureWindow
177 +
				&& ee->error_code == BadMatch)
178 +
			|| (ee->request_code == X_GrabKey
179 +
				&& ee->error_code == BadAccess))
180 +
		return 0;
181 +
	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
182 +
			ee->request_code, ee->error_code);
183 +
	return xerrorxlib(dpy, ee); /* may call exit() */
184 184
}
185 185
186 186
int
208 208
209 209
	dpy = XOpenDisplay(0);
210 210
	if(!dpy)
211 -
		error("dwm: cannot connect X server\n");
211 +
		eprint("dwm: cannot connect X server\n");
212 212
213 213
	screen = DefaultScreen(dpy);
214 214
	root = RootWindow(dpy, screen);
215 215
216 216
	/* check if another WM is already running */
217 -
	other_wm_running = False;
218 -
	XSetErrorHandler(startup_xerror);
217 +
	otherwm = False;
218 +
	XSetErrorHandler(xerrorstart);
219 219
	/* this causes an error if some other WM is running */
220 220
	XSelectInput(dpy, root, SubstructureRedirectMask);
221 221
	XFlush(dpy);
222 222
223 -
	if(other_wm_running)
224 -
		error("dwm: another window manager is already running\n");
223 +
	if(otherwm)
224 +
		eprint("dwm: another window manager is already running\n");
225 225
226 226
	XSetErrorHandler(0);
227 -
	x_xerror = XSetErrorHandler(xerror);
227 +
	xerrorxlib = XSetErrorHandler(xerror);
228 228
229 229
	/* init atoms */
230 230
	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
278 278
	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
279 279
280 280
	strcpy(stext, "dwm-"VERSION);
281 -
	scan_wins();
281 +
	scan();
282 282
283 283
	/* main event loop, reads status text from stdin as well */
284 284
Mainloop:
292 292
		if(i == -1 && errno == EINTR)
293 293
			continue;
294 294
		if(i < 0)
295 -
			error("select failed\n");
295 +
			eprint("select failed\n");
296 296
		else if(i > 0) {
297 297
			if(FD_ISSET(ConnectionNumber(dpy), &rd)) {
298 298
				while(XPending(dpy)) {
screen.c (deleted) +0 −100
1 -
/*
2 -
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 -
 * See LICENSE file for license details.
4 -
 */
5 -
6 -
#include "dwm.h"
7 -
8 -
void (*arrange)(Arg *) = tiling;
9 -
10 -
void
11 -
view(Arg *arg)
12 -
{
13 -
	Client *c;
14 -
15 -
	tsel = arg->i;
16 -
	arrange(NULL);
17 -
18 -
	for(c = clients; c; c = getnext(c->next))
19 -
		drawtitle(c);
20 -
	drawstatus();
21 -
}
22 -
23 -
void
24 -
floating(Arg *arg)
25 -
{
26 -
	Client *c;
27 -
28 -
	arrange = floating;
29 -
	for(c = clients; c; c = c->next) {
30 -
		if(c->tags[tsel])
31 -
			resize(c, True);
32 -
		else
33 -
			ban(c);
34 -
	}
35 -
	if(sel && !sel->tags[tsel]) {
36 -
		if((sel = getnext(clients))) {
37 -
			higher(sel);
38 -
			focus(sel);
39 -
		}
40 -
	}
41 -
	drawstatus();
42 -
}
43 -
44 -
void
45 -
tiling(Arg *arg)
46 -
{
47 -
	Client *c;
48 -
	int n, i, w, h;
49 -
50 -
	w = sw - mw;
51 -
	arrange = tiling;
52 -
	for(n = 0, c = clients; c; c = c->next)
53 -
		if(c->tags[tsel] && !c->floating)
54 -
			n++;
55 -
56 -
	if(n > 1)
57 -
		h = (sh - bh) / (n - 1);
58 -
	else
59 -
		h = sh - bh;
60 -
61 -
	for(i = 0, c = clients; c; c = c->next) {
62 -
		if(c->tags[tsel]) {
63 -
			if(c->floating) {
64 -
				higher(c);
65 -
				resize(c, True);
66 -
				continue;
67 -
			}
68 -
			if(n == 1) {
69 -
				c->x = sx;
70 -
				c->y = sy + bh;
71 -
				c->w = sw - 2 * c->border;
72 -
				c->h = sh - 2 * c->border - bh;
73 -
			}
74 -
			else if(i == 0) {
75 -
				c->x = sx;
76 -
				c->y = sy + bh;
77 -
				c->w = mw - 2 * c->border;
78 -
				c->h = sh - 2 * c->border - bh;
79 -
			}
80 -
			else {
81 -
				c->x = sx + mw;
82 -
				c->y = sy + (i - 1) * h + bh;
83 -
				c->w = w - 2 * c->border;
84 -
				c->h = h - 2 * c->border;
85 -
			}
86 -
			resize(c, False);
87 -
			i++;
88 -
		}
89 -
		else
90 -
			ban(c);
91 -
	}
92 -
	if(!sel || (sel && !sel->tags[tsel])) {
93 -
		if((sel = getnext(clients))) {
94 -
			higher(sel);
95 -
			focus(sel);
96 -
		}
97 -
	}
98 -
	drawstatus();
99 -
}
100 -
tag.c (added) +171 −0
1 +
/*
2 +
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 +
 * See LICENSE file for license details.
4 +
 */
5 +
6 +
#include <stdlib.h>
7 +
#include <stdio.h>
8 +
#include <string.h>
9 +
#include <X11/Xatom.h>
10 +
#include <X11/Xutil.h>
11 +
12 +
#include "dwm.h"
13 +
14 +
static Rule rule[] = {
15 +
	/* class			instance	tags						dofloat */
16 +
	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
17 +
};
18 +
19 +
void (*arrange)(Arg *) = dotile;
20 +
21 +
Client *
22 +
getnext(Client *c)
23 +
{
24 +
	for(; c && !c->tags[tsel]; c = c->next);
25 +
	return c;
26 +
}
27 +
28 +
void
29 +
settags(Client *c)
30 +
{
31 +
	XClassHint ch;
32 +
	static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
33 +
	unsigned int i, j;
34 +
	Bool matched = False;
35 +
36 +
	if(!len) {
37 +
		c->tags[tsel] = tags[tsel];
38 +
		return;
39 +
	}
40 +
41 +
	if(XGetClassHint(dpy, c->win, &ch)) {
42 +
		if(ch.res_class && ch.res_name) {
43 +
			for(i = 0; i < len; i++)
44 +
				if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
45 +
					&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
46 +
				{
47 +
					for(j = 0; j < TLast; j++)
48 +
						c->tags[j] = rule[i].tags[j];
49 +
					c->dofloat = rule[i].dofloat;
50 +
					matched = True;
51 +
					break;
52 +
				}
53 +
		}
54 +
		if(ch.res_class)
55 +
			XFree(ch.res_class);
56 +
		if(ch.res_name)
57 +
			XFree(ch.res_name);
58 +
	}
59 +
60 +
	if(!matched)
61 +
		c->tags[tsel] = tags[tsel];
62 +
}
63 +
64 +
void
65 +
view(Arg *arg)
66 +
{
67 +
	tsel = arg->i;
68 +
	arrange(NULL);
69 +
	drawall();
70 +
}
71 +
72 +
void
73 +
dofloat(Arg *arg)
74 +
{
75 +
	Client *c;
76 +
77 +
	arrange = dofloat;
78 +
	for(c = clients; c; c = c->next) {
79 +
		if(c->tags[tsel])
80 +
			resize(c, True);
81 +
		else
82 +
			ban(c);
83 +
	}
84 +
	if(sel && !sel->tags[tsel]) {
85 +
		if((sel = getnext(clients))) {
86 +
			higher(sel);
87 +
			focus(sel);
88 +
		}
89 +
	}
90 +
	drawall();
91 +
}
92 +
93 +
void
94 +
dotile(Arg *arg)
95 +
{
96 +
	Client *c;
97 +
	int n, i, w, h;
98 +
99 +
	w = sw - mw;
100 +
	arrange = dotile;
101 +
	for(n = 0, c = clients; c; c = c->next)
102 +
		if(c->tags[tsel] && !c->dofloat)
103 +
			n++;
104 +
105 +
	if(n > 1)
106 +
		h = (sh - bh) / (n - 1);
107 +
	else
108 +
		h = sh - bh;
109 +
110 +
	for(i = 0, c = clients; c; c = c->next) {
111 +
		if(c->tags[tsel]) {
112 +
			if(c->dofloat) {
113 +
				higher(c);
114 +
				resize(c, True);
115 +
				continue;
116 +
			}
117 +
			if(n == 1) {
118 +
				c->x = sx;
119 +
				c->y = sy + bh;
120 +
				c->w = sw - 2 * c->border;
121 +
				c->h = sh - 2 * c->border - bh;
122 +
			}
123 +
			else if(i == 0) {
124 +
				c->x = sx;
125 +
				c->y = sy + bh;
126 +
				c->w = mw - 2 * c->border;
127 +
				c->h = sh - 2 * c->border - bh;
128 +
			}
129 +
			else {
130 +
				c->x = sx + mw;
131 +
				c->y = sy + (i - 1) * h + bh;
132 +
				c->w = w - 2 * c->border;
133 +
				c->h = h - 2 * c->border;
134 +
			}
135 +
			resize(c, False);
136 +
			i++;
137 +
		}
138 +
		else
139 +
			ban(c);
140 +
	}
141 +
	if(!sel || (sel && !sel->tags[tsel])) {
142 +
		if((sel = getnext(clients))) {
143 +
			higher(sel);
144 +
			focus(sel);
145 +
		}
146 +
	}
147 +
	drawall();
148 +
}
149 +
150 +
void
151 +
appendtag(Arg *arg)
152 +
{
153 +
	if(!sel)
154 +
		return;
155 +
156 +
	sel->tags[arg->i] = tags[arg->i];
157 +
	arrange(NULL);
158 +
}
159 +
160 +
void
161 +
replacetag(Arg *arg)
162 +
{
163 +
	int i;
164 +
	if(!sel)
165 +
		return;
166 +
167 +
	for(i = 0; i < TLast; i++)
168 +
		sel->tags[i] = NULL;
169 +
	appendtag(arg);
170 +
}
171 +
util.c +1 −1
13 13
#include "dwm.h"
14 14
15 15
void
16 -
error(const char *errstr, ...) {
16 +
eprint(const char *errstr, ...) {
17 17
	va_list ap;
18 18
	va_start(ap, errstr);
19 19
	vfprintf(stderr, errstr, ap);