about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--client.c170
-rw-r--r--dev.c27
-rw-r--r--dwm.h30
-rw-r--r--main.c11
-rw-r--r--util.c3
5 files changed, 156 insertions, 85 deletions
diff --git a/client.c b/client.c
index d3b731b..2403d74 100644
--- a/client.c
+++ b/client.c
@@ -11,44 +11,76 @@
 
 #include "dwm.h"
 
-static void (*arrange)(void *) = floating;
+static void (*arrange)(Arg *) = floating;
+
+static Client *
+next(Client *c)
+{
+	for(c = c->next; c && !c->tags[tsel]; c = c->next);
+	return c;
+}
+
+static Client *
+prev(Client *c)
+{
+	for(c = c->prev; c && !c->tags[tsel]; c = c->prev);
+	return c;
+}
 
 void
-max(void *aux)
+max(Arg *arg)
 {
-	if(!stack)
+	if(!csel)
 		return;
-	stack->x = sx;
-	stack->y = sy;
-	stack->w = sw - 2 * stack->border;
-	stack->h = sh - 2 * stack->border;
-	craise(stack);
-	resize(stack);
+	csel->x = sx;
+	csel->y = sy;
+	csel->w = sw - 2 * csel->border;
+	csel->h = sh - 2 * csel->border;
+	craise(csel);
+	resize(csel);
 	discard_events(EnterWindowMask);
 }
 
 void
-floating(void *aux)
+tag(Arg *arg)
+{
+	if(!csel)
+		return;
+
+	if(arg->i == tsel)
+		return;
+
+	if(csel->tags[arg->i])
+		csel->tags[arg->i] = NULL; /* toggle tag */
+	else
+		csel->tags[arg->i] = tags[arg->i];
+	arrange(NULL);
+}
+
+void
+floating(Arg *arg)
 {
 	Client *c;
 
 	arrange = floating;
-	for(c = stack; c; c = c->snext)
+	if(!csel)
+		return;
+	for(c = csel; c; c = next(c))
 		resize(c);
 	discard_events(EnterWindowMask);
 }
 
 void
-tiling(void *aux)
+tiling(Arg *arg)
 {
 	Client *c;
 	int n, cols, rows, gw, gh, i, j;
     float rt, fd;
 
 	arrange = tiling;
-	if(!clients)
+	if(!csel)
 		return;
-	for(n = 0, c = clients; c; c = c->next, n++);
+	for(n = 0, c = csel; c; c = next(c), n++);
 	rt = sqrt(n);
 	if(modff(rt, &fd) < 0.5)
 		rows = floor(rt);
@@ -62,7 +94,7 @@ tiling(void *aux)
 	gw = (sw - 2)  / cols;
 	gh = (sh - 2) / rows;
 
-	for(i = j = 0, c = clients; c; c = c->next) {
+	for(i = j = 0, c = csel; c; c = next(c)) {
 		c->x = i * gw;
 		c->y = j * gh;
 		c->w = gw;
@@ -77,28 +109,44 @@ tiling(void *aux)
 }
 
 void
-sel(void *aux)
+prevc(Arg *arg)
 {
-	const char *arg = aux;
-	Client *c = NULL;
+	Client *c;
 
-	if(!arg || !stack)
+	if(!csel)
 		return;
-	if(!strncmp(arg, "next", 5))
-		c = stack->snext ? stack->snext : stack;
-	else if(!strncmp(arg, "prev", 5))
-		for(c = stack; c && c->snext; c = c->snext);
-	if(!c)
-		c = stack;
-	craise(c);
-	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
-	focus(c);
+
+	if(!(c = prev(csel)))
+		c = prev(cend);
+	if(c) {
+		craise(c);
+		XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
+		focus(c);
+	}
+}
+
+void
+nextc(Arg *arg)
+{
+	Client *c;
+   
+	if(!csel)
+		return;
+
+	if(!(c = next(csel)))
+		c = next(cstart);
+
+	if(c) {
+		craise(c);
+		XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
+		focus(c);
+	}
 }
 
 void
-ckill(void *aux)
+ckill(Arg *arg)
 {
-	Client *c = stack;
+	Client *c = csel;
 
 	if(!c)
 		return;
@@ -208,19 +256,12 @@ lower(Client *c)
 void
 focus(Client *c)
 {
-	Client **l, *old;
-
-	old = stack;
-	for(l = &stack; *l && *l != c; l = &(*l)->snext);
-	if(*l)
-		*l = c->snext;
-	c->snext = stack;
-	stack = c;
-	if(old && old != c) {
-		XSetWindowBorder(dpy, old->win, dc.bg);
-		XMapWindow(dpy, old->title);
-		draw_client(old);
+	if(csel && csel != c) {
+		XSetWindowBorder(dpy, csel->win, dc.bg);
+		XMapWindow(dpy, csel->title);
+		draw_client(csel);
 	}
+	csel = c;
 	XUnmapWindow(dpy, c->title);
 	XSetWindowBorder(dpy, c->win, dc.fg);
 	draw_client(c);
@@ -232,7 +273,7 @@ focus(Client *c)
 void
 manage(Window w, XWindowAttributes *wa)
 {
-	Client *c, **l;
+	Client *c;
 	XSetWindowAttributes twa;
 
 	c = emallocz(sizeof(Client));
@@ -258,9 +299,15 @@ manage(Window w, XWindowAttributes *wa)
 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
 
 	update_name(c);
-	for(l=&clients; *l; l=&(*l)->next);
-	c->next = *l; /* *l == nil */
-	*l = c;
+
+	if(!cstart)
+		cstart = cend = c;
+	else {
+		cend->next = c;
+		c->prev = cend;
+		cend = c;
+	}
+
 	XSetWindowBorderWidth(dpy, c->win, 1);
 	XMapRaised(dpy, c->win);
 	XMapRaised(dpy, c->title);
@@ -373,33 +420,42 @@ dummy_error_handler(Display *dsply, XErrorEvent *err)
 void
 unmanage(Client *c)
 {
-	Client **l;
-
 	XGrabServer(dpy);
 	XSetErrorHandler(dummy_error_handler);
 
 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
 	XDestroyWindow(dpy, c->title);
 
-	for(l=&clients; *l && *l != c; l=&(*l)->next);
-	*l = c->next;
-	for(l=&stack; *l && *l != c; l=&(*l)->snext);
-	*l = c->snext;
+	if(c->prev) {
+		c->prev->next = c->next;
+		if(csel == c)
+			csel = c->prev;
+	}
+	if(c->next) {
+		c->next->prev = c->prev;
+		if(csel == c)
+			csel = c->next;
+	}
+	if(cstart == c)
+		cstart = c->next;
+	if(cend == c)
+		cend = c->prev;
+
 	free(c);
 
 	XFlush(dpy);
 	XSetErrorHandler(error_handler);
 	XUngrabServer(dpy);
 	arrange(NULL);
-	if(stack)
-		focus(stack);
+	if(csel)
+		focus(csel);
 }
 
 Client *
 gettitle(Window w)
 {
 	Client *c;
-	for(c = clients; c; c = c->next)
+	for(c = cstart; c; c = c->next)
 		if(c->title == w)
 			return c;
 	return NULL;
@@ -409,7 +465,7 @@ Client *
 getclient(Window w)
 {
 	Client *c;
-	for(c = clients; c; c = c->next)
+	for(c = cstart; c; c = c->next)
 		if(c->win == w)
 			return c;
 	return NULL;
@@ -419,7 +475,7 @@ void
 draw_client(Client *c)
 {
 	int i;
-	if(c == stack)
+	if(c == csel)
 		return;
 
 	dc.x = dc.y = 0;
diff --git a/dev.c b/dev.c
index 5ececdf..aaab99a 100644
--- a/dev.c
+++ b/dev.c
@@ -20,16 +20,21 @@ const char *browse[] = { "firefox", NULL };
 const char *xlock[] = { "xlock", NULL };
 
 static Key key[] = {
-	{ Mod1Mask, XK_Return, (void (*)(void *))spawn, term },
-	{ Mod1Mask, XK_w, (void (*)(void *))spawn, browse },
-	{ Mod1Mask, XK_l, (void (*)(void *))spawn, xlock },
-	{ Mod1Mask, XK_k, sel, "prev" }, 
-	{ Mod1Mask, XK_j, sel, "next" }, 
-	{ Mod1Mask, XK_t, tiling, NULL }, 
-	{ Mod1Mask, XK_f, floating, NULL }, 
-	{ Mod1Mask, XK_m, max, NULL }, 
-	{ Mod1Mask | ShiftMask, XK_c, ckill, NULL }, 
-	{ Mod1Mask | ShiftMask, XK_q, quit, NULL },
+	{ Mod1Mask, XK_Return, spawn, { .argv = term } },
+	{ Mod1Mask, XK_w, spawn, { .argv = browse } },
+	{ Mod1Mask, XK_l, spawn, { .argv = xlock } },
+	{ Mod1Mask, XK_k, prevc, { 0 } },
+	{ Mod1Mask, XK_j, nextc, { 0 } }, 
+	{ Mod1Mask, XK_t, tiling, { 0 } }, 
+	{ Mod1Mask, XK_f, floating, { 0 } }, 
+	{ Mod1Mask, XK_m, max, { 0 } }, 
+	{ Mod1Mask, XK_0, tag, { .i = Tscratch } }, 
+	{ Mod1Mask, XK_1, tag, { .i = Tdev } }, 
+	{ Mod1Mask, XK_2, tag, { .i = Tirc } }, 
+	{ Mod1Mask, XK_3, tag, { .i = Twww } }, 
+	{ Mod1Mask, XK_4, tag, { .i = Twork } }, 
+	{ Mod1Mask | ShiftMask, XK_c, ckill, { 0 } }, 
+	{ Mod1Mask | ShiftMask, XK_q, quit, { 0 } },
 };
 
 /********** CUSTOMIZE **********/
@@ -60,7 +65,7 @@ keypress(XEvent *e)
 	for(i = 0; i < len; i++)
 		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
 			if(key[i].func)
-				key[i].func(key[i].aux);
+				key[i].func(&key[i].arg);
 			return;
 		}
 }
diff --git a/dwm.h b/dwm.h
index 1d672fd..cf51c36 100644
--- a/dwm.h
+++ b/dwm.h
@@ -22,6 +22,12 @@ typedef struct DC DC;
 typedef struct Client Client;
 typedef struct Fnt Fnt;
 typedef struct Key Key;
+typedef union Arg Arg;
+
+union Arg {
+	const char **argv;
+	int i;
+};
 
 /* atoms */
 enum { WMProtocols, WMDelete, WMLast };
@@ -62,14 +68,14 @@ struct Client {
 	Window trans;
 	Window title;
 	Client *next;
-	Client *snext;
+	Client *prev;
 };
 
 struct Key {
 	unsigned long mod;
 	KeySym keysym;
-	void (*func)(void *aux);
-	void *aux;
+	void (*func)(Arg *arg);
+	Arg arg;
 };
 
 extern Display *dpy;
@@ -83,7 +89,7 @@ extern int tsel, screen, sx, sy, sw, sh, th;
 extern char stext[1024], *tags[TLast];
 
 extern DC dc;
-extern Client *clients, *stack;
+extern Client *cstart, *cend, *csel;
 
 /* client.c */
 extern void manage(Window w, XWindowAttributes *wa);
@@ -97,11 +103,13 @@ extern void update_size(Client *c);
 extern Client *gettitle(Window w);
 extern void craise(Client *c);
 extern void lower(Client *c);
-extern void ckill(void *aux);
-extern void sel(void *aux);
-extern void max(void *aux);
-extern void floating(void *aux);
-extern void tiling(void *aux);
+extern void ckill(Arg *arg);
+extern void nextc(Arg *arg);
+extern void prevc(Arg *arg);
+extern void max(Arg *arg);
+extern void floating(Arg *arg);
+extern void tiling(Arg *arg);
+void tag(Arg *arg);
 extern void gravitate(Client *c, Bool invert);
 
 /* draw.c */
@@ -125,7 +133,7 @@ extern void mmove(Client *c);
 extern int error_handler(Display *dsply, XErrorEvent *e);
 extern void send_message(Window w, Atom a, long value);
 extern int win_proto(Window w);
-extern void quit(void *aux);
+extern void quit(Arg *arg);
 
 /* util.c */
 extern void error(const char *errstr, ...);
@@ -133,5 +141,5 @@ extern void *emallocz(unsigned int size);
 extern void *emalloc(unsigned int size);
 extern void *erealloc(void *ptr, unsigned int size);
 extern char *estrdup(const char *str);
-extern void spawn(char *argv[]);
+extern void spawn(Arg *arg);
 extern void swap(void **p1, void **p2);
diff --git a/main.c b/main.c
index b63d07e..543d156 100644
--- a/main.c
+++ b/main.c
@@ -38,8 +38,9 @@ int tsel = Tdev; /* default tag */
 int screen, sx, sy, sw, sh, th;
 
 DC dc = {0};
-Client *clients = NULL;
-Client *stack = NULL;
+Client *cstart = NULL;
+Client *cend = NULL;
+Client *csel = NULL;
 
 static Bool other_wm_running;
 static const char version[] =
@@ -168,13 +169,13 @@ startup_error_handler(Display *dpy, XErrorEvent *error)
 static void
 cleanup()
 {
-	while(clients)
-		unmanage(clients);
+	while(csel)
+		unmanage(csel);
 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
 }
 
 void
-quit(void *aux)
+quit(Arg *arg)
 {
 	running = False;
 }
diff --git a/util.c b/util.c
index 14a4511..d8e6612 100644
--- a/util.c
+++ b/util.c
@@ -75,8 +75,9 @@ swap(void **p1, void **p2)
 }
 
 void
-spawn(char *argv[])
+spawn(Arg *arg)
 {
+	char **argv = (char **)arg->argv;
 	if(!argv || !argv[0])
 		return;
 	if(fork() == 0) {
2020-07-06 01:05:10 -0700 6618 - new docs' href='/akkartik/mu/commit/vocabulary.md?h=main&id=9a524793ee01ce47f3963768559a0d6c348631c5'>9a524793 ^
cec5ef31 ^
















b9883225 ^



cec5ef31 ^























































































b9883225 ^



















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249