rearranged 29355bd3
Anselm R. Garbe · 2006-07-14 22:33 10 file(s) · +461 −464
Makefile +1 −1
3 3
4 4
include config.mk
5 5
6 -
SRC = bar.c client.c dev.c draw.c event.c main.c util.c
6 +
SRC = client.c draw.c event.c key.c main.c screen.c util.c
7 7
OBJ = ${SRC:.c=.o}
8 8
MAN1 = dwm.1 
9 9
BIN = dwm
bar.c (deleted) +0 −54
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
9 -
barclick(XButtonPressedEvent *e)
10 -
{
11 -
	int x = 0;
12 -
	Arg a;
13 -
	for(a.i = 0; a.i < TLast; a.i++) {
14 -
		x += textw(tags[a.i]) + dc.font.height;
15 -
		if(e->x < x) {
16 -
			view(&a);
17 -
			return;
18 -
		}
19 -
	}
20 -
}
21 -
22 -
void
23 -
draw_bar()
24 -
{
25 -
	int i, modw;
26 -
	char *mode = arrange == tiling ? "#" : "~";
27 -
28 -
	dc.x = dc.y = 0;
29 -
	dc.w = bw;
30 -
	drawtext(NULL, False, False);
31 -
32 -
	modw = textw(mode) + dc.font.height;
33 -
	dc.w = 0;
34 -
	for(i = 0; i < TLast; i++) {
35 -
		dc.x += dc.w;
36 -
		dc.w = textw(tags[i]) + dc.font.height;
37 -
		drawtext(tags[i], i == tsel, True);
38 -
	}
39 -
	if(sel) {
40 -
		dc.x += dc.w;
41 -
		dc.w = textw(sel->name) + dc.font.height;
42 -
		drawtext(sel->name, True, True);
43 -
	}
44 -
	dc.w = textw(stext) + dc.font.height;
45 -
	dc.x = bx + bw - dc.w - modw;
46 -
	drawtext(stext, False, False);
47 -
48 -
	dc.x = bx + bw - modw;
49 -
	dc.w = modw;
50 -
	drawtext(mode, True, True);
51 -
52 -
	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
53 -
	XFlush(dpy);
54 -
}
client.c +3 −227
11 11
12 12
#include "dwm.h"
13 13
14 -
void (*arrange)(Arg *) = tiling;
15 -
16 14
static Rule rule[] = {
17 15
	/* class			instance	tags						floating */
18 16
	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
19 17
};
20 18
21 -
static Client *
19 +
Client *
22 20
next(Client *c)
23 21
{
24 22
	for(; c && !c->tags[tsel]; c = c->next);
26 24
}
27 25
28 26
void
29 -
zoom(Arg *arg)
30 -
{
31 -
	Client **l, *c;
32 -
33 -
	if(!sel)
34 -
		return;
35 -
36 -
	if(sel == next(clients) && sel->next)  {
37 -
		if((c = next(sel->next)))
38 -
			sel = c;
39 -
	}
40 -
41 -
	for(l = &clients; *l && *l != sel; l = &(*l)->next);
42 -
	*l = sel->next;
43 -
44 -
	sel->next = clients; /* pop */
45 -
	clients = sel;
46 -
	arrange(NULL);
47 -
	focus(sel);
48 -
}
49 -
50 -
void
51 -
max(Arg *arg)
52 -
{
53 -
	if(!sel)
54 -
		return;
55 -
	sel->x = sx;
56 -
	sel->y = sy + bh;
57 -
	sel->w = sw - 2 * sel->border;
58 -
	sel->h = sh - 2 * sel->border - bh;
59 -
	craise(sel);
60 -
	resize(sel, False);
61 -
}
62 -
63 -
void
64 -
view(Arg *arg)
65 -
{
66 -
	Client *c;
67 -
68 -
	tsel = arg->i;
69 -
	arrange(NULL);
70 -
71 -
	for(c = clients; c; c = next(c->next))
72 -
		draw_client(c);
73 -
	draw_bar();
74 -
}
75 -
76 -
void
77 -
tappend(Arg *arg)
78 -
{
79 -
	if(!sel)
80 -
		return;
81 -
82 -
	sel->tags[arg->i] = tags[arg->i];
83 -
	arrange(NULL);
84 -
}
85 -
86 -
void
87 -
ttrunc(Arg *arg)
88 -
{
89 -
	int i;
90 -
	if(!sel)
91 -
		return;
92 -
93 -
	for(i = 0; i < TLast; i++)
94 -
		sel->tags[i] = NULL;
95 -
	tappend(arg);
96 -
}
97 -
98 -
static void
99 27
ban_client(Client *c)
100 28
{
101 29
	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
102 30
	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
103 31
}
104 32
105 -
void
106 -
floating(Arg *arg)
107 -
{
108 -
	Client *c;
109 -
110 -
	arrange = floating;
111 -
	for(c = clients; c; c = c->next) {
112 -
		if(c->tags[tsel])
113 -
			resize(c, True);
114 -
		else
115 -
			ban_client(c);
116 -
	}
117 -
	if(sel && !sel->tags[tsel]) {
118 -
		if((sel = next(clients))) {
119 -
			craise(sel);
120 -
			focus(sel);
121 -
		}
122 -
	}
123 -
	draw_bar();
124 -
}
125 -
126 -
void
127 -
tiling(Arg *arg)
128 -
{
129 -
	Client *c;
130 -
	int n, i, w, h;
131 -
132 -
	w = sw - mw;
133 -
	arrange = tiling;
134 -
	for(n = 0, c = clients; c; c = c->next)
135 -
		if(c->tags[tsel] && !c->floating)
136 -
			n++;
137 -
138 -
	if(n > 1)
139 -
		h = (sh - bh) / (n - 1);
140 -
	else
141 -
		h = sh - bh;
142 -
143 -
	for(i = 0, c = clients; c; c = c->next) {
144 -
		if(c->tags[tsel]) {
145 -
			if(c->floating) {
146 -
				craise(c);
147 -
				resize(c, True);
148 -
				continue;
149 -
			}
150 -
			if(n == 1) {
151 -
				c->x = sx;
152 -
				c->y = sy + bh;
153 -
				c->w = sw - 2 * c->border;
154 -
				c->h = sh - 2 * c->border - bh;
155 -
			}
156 -
			else if(i == 0) {
157 -
				c->x = sx;
158 -
				c->y = sy + bh;
159 -
				c->w = mw - 2 * c->border;
160 -
				c->h = sh - 2 * c->border - bh;
161 -
			}
162 -
			else {
163 -
				c->x = sx + mw;
164 -
				c->y = sy + (i - 1) * h + bh;
165 -
				c->w = w - 2 * c->border;
166 -
				c->h = h - 2 * c->border;
167 -
			}
168 -
			resize(c, False);
169 -
			i++;
170 -
		}
171 -
		else
172 -
			ban_client(c);
173 -
	}
174 -
	if(!sel || (sel && !sel->tags[tsel])) {
175 -
		if((sel = next(clients))) {
176 -
			craise(sel);
177 -
			focus(sel);
178 -
		}
179 -
	}
180 -
	draw_bar();
181 -
}
182 -
183 -
void
184 -
prevc(Arg *arg)
185 -
{
186 -
	Client *c;
187 -
188 -
	if(!sel)
189 -
		return;
190 -
191 -
	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
192 -
		craise(c);
193 -
		focus(c);
194 -
	}
195 -
}
196 -
197 -
void
198 -
nextc(Arg *arg)
199 -
{
200 -
	Client *c;
201 -
   
202 -
	if(!sel)
203 -
		return;
204 -
205 -
	if(!(c = next(sel->next)))
206 -
		c = next(clients);
207 -
	if(c) {
208 -
		craise(c);
209 -
		c->revert = sel;
210 -
		focus(c);
211 -
	}
212 -
}
213 -
214 -
void
215 -
ckill(Arg *arg)
216 -
{
217 -
	if(!sel)
218 -
		return;
219 -
	if(sel->proto & WM_PROTOCOL_DELWIN)
220 -
		send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
221 -
	else
222 -
		XKillClient(dpy, sel->win);
223 -
}
224 -
225 33
static void
226 34
resize_title(Client *c)
227 35
{
230 38
	c->tw = 0;
231 39
	for(i = 0; i < TLast; i++)
232 40
		if(c->tags[i])
233 -
			c->tw += textw(c->tags[i]) + dc.font.height;
234 -
	c->tw += textw(c->name) + dc.font.height;
41 +
			c->tw += textw(c->tags[i]);
42 +
	c->tw += textw(c->name);
235 43
	if(c->tw > c->w)
236 44
		c->tw = c->w + 2;
237 45
	c->tx = c->x + c->w - c->tw + 2;
584 392
			return c;
585 393
	return NULL;
586 394
}
587 -
588 -
void
589 -
draw_client(Client *c)
590 -
{
591 -
	int i;
592 -
	if(c == sel) {
593 -
		draw_bar();
594 -
		XUnmapWindow(dpy, c->title);
595 -
		XSetWindowBorder(dpy, c->win, dc.fg);
596 -
		return;
597 -
	}
598 -
599 -
	XSetWindowBorder(dpy, c->win, dc.bg);
600 -
	XMapWindow(dpy, c->title);
601 -
602 -
	dc.x = dc.y = 0;
603 -
604 -
	dc.w = 0;
605 -
	for(i = 0; i < TLast; i++) {
606 -
		if(c->tags[i]) {
607 -
			dc.x += dc.w;
608 -
			dc.w = textw(c->tags[i]) + dc.font.height;
609 -
			drawtext(c->tags[i], False, True);
610 -
		}
611 -
	}
612 -
	dc.x += dc.w;
613 -
	dc.w = textw(c->name) + dc.font.height;
614 -
	drawtext(c->name, False, True);
615 -
	XCopyArea(dpy, dc.drawable, c->title, dc.gc,
616 -
			0, 0, c->tw, c->th, 0, 0);
617 -
	XFlush(dpy);
618 -
}
dev.c (deleted) +0 −151
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 -
#include <stdlib.h>
9 -
#include <string.h>
10 -
#include <unistd.h>
11 -
#include <X11/keysym.h>
12 -
13 -
/********** CUSTOMIZE **********/
14 -
15 -
const char *term[] = { 
16 -
	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
17 -
	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
18 -
};
19 -
const char *browse[] = { "firefox", NULL };
20 -
const char *xlock[] = { "xlock", NULL };
21 -
22 -
static Key key[] = {
23 -
	/* modifier				key			function	arguments */
24 -
	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } },
25 -
	{ Mod1Mask,				XK_k,		prevc,		{ 0 } },
26 -
	{ Mod1Mask,				XK_j,		nextc,		{ 0 } }, 
27 -
	{ Mod1Mask,				XK_m,		max,		{ 0 } }, 
28 -
	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } }, 
29 -
	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } }, 
30 -
	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } }, 
31 -
	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } }, 
32 -
	{ Mod1Mask,				XK_space,	tiling,		{ 0 } }, 
33 -
	{ Mod1Mask|ShiftMask,	XK_space,	floating,	{ 0 } }, 
34 -
	{ Mod1Mask|ShiftMask,	XK_0,		ttrunc,		{ .i = Tscratch } }, 
35 -
	{ Mod1Mask|ShiftMask,	XK_1,		ttrunc,		{ .i = Tdev } }, 
36 -
	{ Mod1Mask|ShiftMask,	XK_2,		ttrunc,		{ .i = Twww } }, 
37 -
	{ Mod1Mask|ShiftMask,	XK_3,		ttrunc,		{ .i = Twork } }, 
38 -
	{ Mod1Mask|ShiftMask,	XK_c,		ckill,		{ 0 } }, 
39 -
	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } },
40 -
	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } },
41 -
	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } },
42 -
	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } },
43 -
	{ ControlMask,			XK_0,		tappend,	{ .i = Tscratch } }, 
44 -
	{ ControlMask,			XK_1,		tappend,	{ .i = Tdev } }, 
45 -
	{ ControlMask,			XK_2,		tappend,	{ .i = Twww } }, 
46 -
	{ ControlMask,			XK_3,		tappend,	{ .i = Twork } }, 
47 -
};
48 -
49 -
/********** CUSTOMIZE **********/
50 -
51 -
void
52 -
update_keys(void)
53 -
{
54 -
	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
55 -
	unsigned int i;
56 -
	KeyCode code;
57 -
58 -
	for(i = 0; i < len; i++) {
59 -
		code = XKeysymToKeycode(dpy, key[i].keysym);
60 -
		XUngrabKey(dpy, code, key[i].mod, root);
61 -
		XGrabKey(dpy, code, key[i].mod, root, True, GrabModeAsync, GrabModeAsync);
62 -
	}
63 -
}
64 -
65 -
void
66 -
keypress(XEvent *e)
67 -
{
68 -
	XKeyEvent *ev = &e->xkey;
69 -
	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
70 -
	unsigned int i;
71 -
	KeySym keysym;
72 -
73 -
	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
74 -
	for(i = 0; i < len; i++)
75 -
		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
76 -
			if(key[i].func)
77 -
				key[i].func(&key[i].arg);
78 -
			return;
79 -
		}
80 -
}
81 -
82 -
#define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
83 -
#define MouseMask       (ButtonMask | PointerMotionMask)
84 -
85 -
void
86 -
mresize(Client *c)
87 -
{
88 -
	XEvent ev;
89 -
	int ocx, ocy;
90 -
91 -
	ocx = c->x;
92 -
	ocy = c->y;
93 -
	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
94 -
				None, cursor[CurResize], CurrentTime) != GrabSuccess)
95 -
		return;
96 -
	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
97 -
	for(;;) {
98 -
		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
99 -
		switch(ev.type) {
100 -
		default: break;
101 -
		case Expose:
102 -
			handler[Expose](&ev);
103 -
			break;
104 -
		case MotionNotify:
105 -
			XFlush(dpy);
106 -
			c->w = abs(ocx - ev.xmotion.x);
107 -
			c->h = abs(ocy - ev.xmotion.y);
108 -
			c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
109 -
			c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
110 -
			resize(c, True);
111 -
			break;
112 -
		case ButtonRelease:
113 -
			XUngrabPointer(dpy, CurrentTime);
114 -
			return;
115 -
		}
116 -
	}
117 -
}
118 -
119 -
void
120 -
mmove(Client *c)
121 -
{
122 -
	XEvent ev;
123 -
	int x1, y1, ocx, ocy, di;
124 -
	unsigned int dui;
125 -
	Window dummy;
126 -
127 -
	ocx = c->x;
128 -
	ocy = c->y;
129 -
	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
130 -
				None, cursor[CurMove], CurrentTime) != GrabSuccess)
131 -
		return;
132 -
	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
133 -
	for(;;) {
134 -
		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
135 -
		switch (ev.type) {
136 -
		default: break;
137 -
		case Expose:
138 -
			handler[Expose](&ev);
139 -
			break;
140 -
		case MotionNotify:
141 -
			XFlush(dpy);
142 -
			c->x = ocx + (ev.xmotion.x - x1);
143 -
			c->y = ocy + (ev.xmotion.y - y1);
144 -
			resize(c, False);
145 -
			break;
146 -
		case ButtonRelease:
147 -
			XUngrabPointer(dpy, CurrentTime);
148 -
			return;
149 -
		}
150 -
	}
151 -
}
draw.c +66 −1
10 10
11 11
#include "dwm.h"
12 12
13 +
void
14 +
draw_bar()
15 +
{
16 +
	int i;
17 +
18 +
	dc.x = dc.y = 0;
19 +
	dc.w = bw;
20 +
	drawtext(NULL, False, False);
21 +
22 +
	if(arrange == floating) {
23 +
		dc.w = textw("~");
24 +
		drawtext("~", False, False);
25 +
	}
26 +
	else
27 +
		dc.w = 0;
28 +
	for(i = 0; i < TLast; i++) {
29 +
		dc.x += dc.w;
30 +
		dc.w = textw(tags[i]);
31 +
		drawtext(tags[i], i == tsel, True);
32 +
	}
33 +
	if(sel) {
34 +
		dc.x += dc.w;
35 +
		dc.w = textw(sel->name);
36 +
		drawtext(sel->name, True, True);
37 +
	}
38 +
	dc.w = textw(stext);
39 +
	dc.x = bx + bw - dc.w;
40 +
	drawtext(stext, False, False);
41 +
42 +
	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
43 +
	XFlush(dpy);
44 +
}
45 +
46 +
void
47 +
draw_client(Client *c)
48 +
{
49 +
	int i;
50 +
	if(c == sel) {
51 +
		draw_bar();
52 +
		XUnmapWindow(dpy, c->title);
53 +
		XSetWindowBorder(dpy, c->win, dc.fg);
54 +
		return;
55 +
	}
56 +
57 +
	XSetWindowBorder(dpy, c->win, dc.bg);
58 +
	XMapWindow(dpy, c->title);
59 +
60 +
	dc.x = dc.y = 0;
61 +
62 +
	dc.w = 0;
63 +
	for(i = 0; i < TLast; i++) {
64 +
		if(c->tags[i]) {
65 +
			dc.x += dc.w;
66 +
			dc.w = textw(c->tags[i]);
67 +
			drawtext(c->tags[i], False, True);
68 +
		}
69 +
	}
70 +
	dc.x += dc.w;
71 +
	dc.w = textw(c->name);
72 +
	drawtext(c->name, False, True);
73 +
	XCopyArea(dpy, dc.drawable, c->title, dc.gc,
74 +
			0, 0, c->tw, c->th, 0, 0);
75 +
	XFlush(dpy);
76 +
}
77 +
13 78
static void
14 79
drawborder(void)
15 80
{
103 168
unsigned int
104 169
textw(char *text)
105 170
{
106 -
	return textnw(text, strlen(text));
171 +
	return textnw(text, strlen(text)) + dc.font.height;
107 172
}
108 173
109 174
void
dwm.h +12 −19
94 94
extern Bool running, issel;
95 95
extern void (*handler[LASTEvent])(XEvent *);
96 96
extern void (*arrange)(Arg *);
97 +
extern Key key[];
97 98
98 99
extern int tsel, screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
99 100
extern char *tags[TLast], stext[1024];
101 102
extern DC dc;
102 103
extern Client *clients, *sel;
103 104
104 -
/* bar.c */
105 -
extern void draw_bar();
106 -
extern void barclick(XButtonPressedEvent *e);
107 -
108 105
/* client.c */
109 106
extern void manage(Window w, XWindowAttributes *wa);
110 107
extern void unmanage(Client *c);
111 108
extern Client *getclient(Window w);
112 109
extern void focus(Client *c);
113 110
extern void update_name(Client *c);
114 -
extern void draw_client(Client *c);
115 111
extern void resize(Client *c, Bool inc);
116 112
extern void update_size(Client *c);
117 113
extern Client *gettitle(Window w);
118 114
extern void craise(Client *c);
119 115
extern void lower(Client *c);
120 -
extern void ckill(Arg *arg);
121 -
extern void nextc(Arg *arg);
122 -
extern void prevc(Arg *arg);
123 -
extern void max(Arg *arg);
124 -
extern void floating(Arg *arg);
125 -
extern void tiling(Arg *arg);
126 -
extern void ttrunc(Arg *arg);
127 -
extern void tappend(Arg *arg);
128 -
extern void view(Arg *arg);
129 -
extern void zoom(Arg *arg);
130 116
extern void gravitate(Client *c, Bool invert);
117 +
extern void ban_client(Client *c);
118 +
extern Client *next(Client *c);
131 119
132 120
/* draw.c */
121 +
extern void draw_bar();
122 +
extern void draw_client(Client *c);
133 123
extern void drawtext(const char *text, Bool invert, Bool border);
134 124
extern unsigned long initcolor(const char *colstr);
135 125
extern void initfont(const char *fontstr);
137 127
extern unsigned int textw(char *text);
138 128
extern unsigned int texth(void);
139 129
140 -
/* dev.c */
141 -
extern void update_keys(void);
130 +
/* key.c */
131 +
extern void grabkeys();
142 132
extern void keypress(XEvent *e);
143 -
extern void mresize(Client *c);
144 -
extern void mmove(Client *c);
145 133
146 134
/* main.c */
147 135
extern int error_handler(Display *dsply, XErrorEvent *e);
148 136
extern void send_message(Window w, Atom a, long value);
149 137
extern int win_proto(Window w);
150 138
extern void quit(Arg *arg);
139 +
140 +
/* screen.c */
141 +
extern void floating(Arg *arg);
142 +
extern void tiling(Arg *arg);
143 +
extern void view(Arg *arg);
151 144
152 145
/* util.c */
153 146
extern void error(const char *errstr, ...);
event.c +86 −10
7 7
#include <stdio.h>
8 8
#include <stdlib.h>
9 9
#include <string.h>
10 +
#include <unistd.h>
10 11
#include <X11/keysym.h>
11 12
#include <X11/Xatom.h>
12 13
13 14
#include "dwm.h"
14 15
16 +
#define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
17 +
#define MouseMask       (ButtonMask | PointerMotionMask)
18 +
15 19
/* local functions */
16 20
static void buttonpress(XEvent *e);
17 21
static void configurerequest(XEvent *e);
19 23
static void enternotify(XEvent *e);
20 24
static void leavenotify(XEvent *e);
21 25
static void expose(XEvent *e);
22 -
static void keymapnotify(XEvent *e);
23 26
static void maprequest(XEvent *e);
24 27
static void propertynotify(XEvent *e);
25 28
static void unmapnotify(XEvent *e);
32 35
	[LeaveNotify] = leavenotify,
33 36
	[Expose] = expose,
34 37
	[KeyPress] = keypress,
35 -
	[KeymapNotify] = keymapnotify,
36 38
	[MapRequest] = maprequest,
37 39
	[PropertyNotify] = propertynotify,
38 40
	[UnmapNotify] = unmapnotify
39 41
};
40 42
41 43
static void
44 +
mresize(Client *c)
45 +
{
46 +
	XEvent ev;
47 +
	int ocx, ocy;
48 +
49 +
	ocx = c->x;
50 +
	ocy = c->y;
51 +
	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
52 +
				None, cursor[CurResize], CurrentTime) != GrabSuccess)
53 +
		return;
54 +
	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
55 +
	for(;;) {
56 +
		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
57 +
		switch(ev.type) {
58 +
		default: break;
59 +
		case Expose:
60 +
			handler[Expose](&ev);
61 +
			break;
62 +
		case MotionNotify:
63 +
			XFlush(dpy);
64 +
			c->w = abs(ocx - ev.xmotion.x);
65 +
			c->h = abs(ocy - ev.xmotion.y);
66 +
			c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
67 +
			c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
68 +
			resize(c, True);
69 +
			break;
70 +
		case ButtonRelease:
71 +
			XUngrabPointer(dpy, CurrentTime);
72 +
			return;
73 +
		}
74 +
	}
75 +
}
76 +
77 +
static void
78 +
mmove(Client *c)
79 +
{
80 +
	XEvent ev;
81 +
	int x1, y1, ocx, ocy, di;
82 +
	unsigned int dui;
83 +
	Window dummy;
84 +
85 +
	ocx = c->x;
86 +
	ocy = c->y;
87 +
	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
88 +
				None, cursor[CurMove], CurrentTime) != GrabSuccess)
89 +
		return;
90 +
	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
91 +
	for(;;) {
92 +
		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
93 +
		switch (ev.type) {
94 +
		default: break;
95 +
		case Expose:
96 +
			handler[Expose](&ev);
97 +
			break;
98 +
		case MotionNotify:
99 +
			XFlush(dpy);
100 +
			c->x = ocx + (ev.xmotion.x - x1);
101 +
			c->y = ocy + (ev.xmotion.y - y1);
102 +
			resize(c, False);
103 +
			break;
104 +
		case ButtonRelease:
105 +
			XUngrabPointer(dpy, CurrentTime);
106 +
			return;
107 +
		}
108 +
	}
109 +
}
110 +
111 +
static void
42 112
buttonpress(XEvent *e)
43 113
{
114 +
	int x;
115 +
	Arg a;
44 116
	XButtonPressedEvent *ev = &e->xbutton;
45 117
	Client *c;
46 118
47 -
	if(barwin == ev->window)
48 -
		barclick(ev);
119 +
	if(barwin == ev->window) {
120 +
		x = (arrange == floating) ? textw("~") : 0;
121 +
		for(a.i = 0; a.i < TLast; a.i++) {
122 +
			x += textw(tags[a.i]);
123 +
			if(ev->x < x) {
124 +
				view(&a);
125 +
				break;
126 +
			}
127 +
		}
128 +
	}
49 129
	else if((c = getclient(ev->window))) {
130 +
		if(arrange == tiling && !c->floating)
131 +
			return;
50 132
		craise(c);
51 133
		switch(ev->button) {
52 134
		default:
147 229
		else if((c = gettitle(ev->window)))
148 230
			draw_client(c);
149 231
	}
150 -
}
151 -
152 -
static void
153 -
keymapnotify(XEvent *e)
154 -
{
155 -
	update_keys();
156 232
}
157 233
158 234
static void
key.c (added) +192 −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 <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 == next(clients) && sel->next)  {
103 +
		if((c = next(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 +
	craise(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 +
		craise(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 = next(sel->next)))
174 +
		c = next(clients);
175 +
	if(c) {
176 +
		craise(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 +
		send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
189 +
	else
190 +
		XKillClient(dpy, sel->win);
191 +
}
192 +
main.c +1 −1
239 239
	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
240 240
	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
241 241
242 -
	update_keys();
242 +
	grabkeys();
243 243
244 244
	/* style */
245 245
	dc.bg = initcolor(BGCOLOR);
screen.c (added) +100 −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 "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 = next(c->next))
19 +
		draw_client(c);
20 +
	draw_bar();
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_client(c);
34 +
	}
35 +
	if(sel && !sel->tags[tsel]) {
36 +
		if((sel = next(clients))) {
37 +
			craise(sel);
38 +
			focus(sel);
39 +
		}
40 +
	}
41 +
	draw_bar();
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 +
				craise(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_client(c);
91 +
	}
92 +
	if(!sel || (sel && !sel->tags[tsel])) {
93 +
		if((sel = next(clients))) {
94 +
			craise(sel);
95 +
			focus(sel);
96 +
		}
97 +
	}
98 +
	draw_bar();
99 +
}
100 +