before leaning things up da2bbd37
Anselm R. Garbe · 2006-07-13 01:04 9 file(s) · +150 −112
bar.c +17 −5
8 8
void
9 9
draw_bar()
10 10
{
11 +
	int i;
11 12
	brush.x = brush.y = 0;
12 13
	brush.w = bw;
13 14
	brush.h = bh;
14 15
	draw(dpy, &brush, False, NULL);
15 16
17 +
	brush.w = 0;
18 +
	for(i = 0; i < TLast; i++) {
19 +
		brush.x += brush.w;
20 +
		brush.w = textw(&brush.font, tags[i]) + bh;
21 +
		if(i == tsel) {
22 +
			swap((void **)&brush.fg, (void **)&brush.bg);
23 +
			draw(dpy, &brush, True, tags[i]);
24 +
			swap((void **)&brush.fg, (void **)&brush.bg);
25 +
		}
26 +
		else
27 +
			draw(dpy, &brush, True, tags[i]);
28 +
	}
16 29
	if(stack) {
17 -
		brush.w = textw(&brush.font, stack->name) + bh;
18 30
		swap((void **)&brush.fg, (void **)&brush.bg);
31 +
		brush.x += brush.w;
32 +
		brush.w = textw(&brush.font, stack->name) + bh;
19 33
		draw(dpy, &brush, True, stack->name);
20 34
		swap((void **)&brush.fg, (void **)&brush.bg);
21 -
		brush.x += brush.w;
22 35
	}
23 -
24 -
	brush.w = textw(&brush.font, statustext) + bh;
36 +
	brush.w = textw(&brush.font, stext) + bh;
25 37
	brush.x = bx + bw - brush.w;
26 -
	draw(dpy, &brush, False, statustext);
38 +
	draw(dpy, &brush, False, stext);
27 39
	XCopyArea(dpy, brush.drawable, barwin, brush.gc, 0, 0, bw, bh, 0, 0);
28 40
	XFlush(dpy);
29 41
}
client.c +52 −9
11 11
#include "util.h"
12 12
#include "wm.h"
13 13
14 +
void (*arrange)(void *aux);
15 +
14 16
void
15 17
max(void *aux)
16 18
{
25 27
}
26 28
27 29
void
28 -
arrange(void *aux)
30 +
floating(void *aux)
31 +
{
32 +
	Client *c;
33 +
34 +
	arrange = floating;
35 +
	for(c = stack; c; c = c->snext)
36 +
		resize(c);
37 +
	discard_events(EnterWindowMask);
38 +
}
39 +
40 +
void
41 +
grid(void *aux)
29 42
{
30 43
	Client *c;
31 44
	int n, cols, rows, gw, gh, i, j;
32 45
    float rt, fd;
33 46
47 +
	arrange = grid;
34 48
	if(!clients)
35 49
		return;
36 50
	for(n = 0, c = clients; c; c = c->next, n++);
95 109
static void
96 110
resize_title(Client *c)
97 111
{
98 -
	c->tw = textw(&brush.font, c->name) + bh;
112 +
	int i;
113 +
114 +
	c->tw = 0;
115 +
	for(i = 0; i < TLast; i++)
116 +
		if(c->tags[i])
117 +
			c->tw += textw(&brush.font, c->tags[i]) + bh;
118 +
	c->tw += textw(&brush.font, c->name) + bh;
99 119
	if(c->tw > c->w)
100 120
		c->tw = c->w + 2;
101 121
	c->tx = c->x + c->w - c->tw + 2;
190 210
191 211
	old = stack;
192 212
	for(l = &stack; *l && *l != c; l = &(*l)->snext);
193 -
	eassert(*l == c);
194 -
	*l = c->snext;
213 +
	if(*l)
214 +
		*l = c->snext;
195 215
	c->snext = stack;
196 216
	stack = c;
197 217
	if(old && old != c) {
230 250
	twa.background_pixmap = ParentRelative;
231 251
	twa.event_mask = ExposureMask;
232 252
253 +
	c->tags[tsel] = tags[tsel];
233 254
	c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
234 255
			0, DefaultDepth(dpy, screen), CopyFromParent,
235 256
			DefaultVisual(dpy, screen),
236 257
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
237 -
	update_name(c);
238 258
259 +
	update_name(c);
239 260
	for(l=&clients; *l; l=&(*l)->next);
240 261
	c->next = *l; /* *l == nil */
241 262
	*l = c;
242 -
	c->snext = stack;
243 -
	stack = c;
244 263
	XMapRaised(dpy, c->win);
245 264
	XMapRaised(dpy, c->title);
246 265
	XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
249 268
			GrabModeAsync, GrabModeSync, None, None);
250 269
	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
251 270
			GrabModeAsync, GrabModeSync, None, None);
252 -
	resize(c);
271 +
	arrange(NULL);
253 272
	focus(c);
254 273
}
255 274
308 327
	c->y += dy;
309 328
}
310 329
330 +
311 331
void
312 332
resize(Client *c)
313 333
{
314 334
	XConfigureEvent e;
315 335
336 +
	if(c->incw)
337 +
		c->w -= (c->w - c->basew) % c->incw;
338 +
	if(c->inch)
339 +
		c->h -= (c->h - c->baseh) % c->inch;
340 +
	if(c->minw && c->w < c->minw)
341 +
		c->w = c->minw;
342 +
	if(c->minh && c->h < c->minh)
343 +
		c->h = c->minh;
344 +
	if(c->maxw && c->w > c->maxw)
345 +
		c->w = c->maxw;
346 +
	if(c->maxh && c->h > c->maxh)
347 +
		c->h = c->maxh;
316 348
	resize_title(c);
317 349
	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
318 350
	e.type = ConfigureNotify;
357 389
	XFlush(dpy);
358 390
	XSetErrorHandler(error_handler);
359 391
	XUngrabServer(dpy);
392 +
	arrange(NULL);
360 393
	if(stack)
361 394
		focus(stack);
362 395
}
384 417
void
385 418
draw_client(Client *c)
386 419
{
420 +
	int i;
387 421
	if(c == stack) {
388 422
		draw_bar();
389 423
		return;
390 424
	}
391 425
392 426
	brush.x = brush.y = 0;
393 -
	brush.w = c->tw;
394 427
	brush.h = c->th;
395 428
429 +
	brush.w = 0;
430 +
	for(i = 0; i < TLast; i++) {
431 +
		if(c->tags[i]) {
432 +
			brush.x += brush.w;
433 +
			brush.w = textw(&brush.font, c->tags[i]) + bh;
434 +
			draw(dpy, &brush, True, c->tags[i]);
435 +
		}
436 +
	}
437 +
	brush.x += brush.w;
438 +
	brush.w = textw(&brush.font, c->name) + bh;
396 439
	draw(dpy, &brush, True, c->name);
397 440
	XCopyArea(dpy, brush.drawable, c->title, brush.gc,
398 441
			0, 0, c->tw, c->th, 0, 0);
config.h +5 −0
8 8
#define FGCOLOR		"#ffffff"
9 9
#define BORDERCOLOR	"#9999CC"
10 10
#define STATUSDELAY	10 /* seconds */
11 +
12 +
/* tags, see wm.c for further config */
13 +
enum { Tscratch, Tdev, Tirc, Twww, Twork, /* never remove: */ TLast };
14 +
15 +
/* see kb.c for shortcut customization */
event.c +2 −2
126 126
	if((c = getclient(ev->window)))
127 127
		focus(c);
128 128
	else if(ev->window == root)
129 -
		sel_screen = True;
129 +
		issel = True;
130 130
}
131 131
132 132
static void
135 135
	XCrossingEvent *ev = &e->xcrossing;
136 136
137 137
	if((ev->window == root) && !ev->same_screen)
138 -
		sel_screen = True;
138 +
		issel = True;
139 139
}
140 140
141 141
static void
kb.c +11 −6
7 7
8 8
#include <X11/keysym.h>
9 9
10 -
static const char *term[] = { 
10 +
/********** CUSTOMIZE **********/
11 +
12 +
char *cmdterm[] = { 
11 13
	"aterm", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
12 -
	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*", 0 
14 +
	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
13 15
};
14 16
15 -
static const char *proglist[] = {
17 +
char *cmdproglist[] = {
16 18
		"sh", "-c", "exec `ls -lL /bin /sbin /usr/bin /usr/local/bin 2>/dev/null "
17 19
		"| awk 'NF>2 && $1 ~ /^[^d].*x/ {print $NF}' | sort | uniq | gridmenu`", 0
18 20
};
19 21
20 22
static Key key[] = {
21 -
	{ Mod1Mask, XK_Return, run, term },
22 -
	{ Mod1Mask, XK_p, run, proglist }, 
23 +
	{ Mod1Mask, XK_Return, run, cmdterm },
24 +
	{ Mod1Mask, XK_p, run, cmdproglist}, 
23 25
	{ Mod1Mask, XK_k, sel, "prev" }, 
24 26
	{ Mod1Mask, XK_j, sel, "next" }, 
25 -
	{ Mod1Mask, XK_g, arrange, NULL }, 
27 +
	{ Mod1Mask, XK_g, grid, NULL }, 
28 +
	{ Mod1Mask, XK_f, floating, NULL }, 
26 29
	{ Mod1Mask, XK_m, max, NULL }, 
27 30
	{ Mod1Mask | ShiftMask, XK_c, kill, NULL }, 
28 31
	{ Mod1Mask | ShiftMask, XK_q, quit, NULL },
29 32
};
33 +
34 +
/********** CUSTOMIZE **********/
30 35
31 36
void
32 37
update_keys()
menu.c +15 −42
12 12
#include <stdlib.h>
13 13
#include <stdio.h>
14 14
#include <string.h>
15 -
#include <sys/stat.h>
16 -
#include <sys/wait.h>
17 -
#include <time.h>
18 15
#include <unistd.h>
19 16
#include <X11/cursorfont.h>
20 17
#include <X11/Xutil.h>
58 55
static char version[] = "gridmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
59 56
60 57
static void
61 -
usage()
62 -
{
63 -
	fprintf(stderr, "%s", "usage: gridmenu [-v] [-t <title>]\n");
64 -
	exit(1);
65 -
}
58 +
usage() { error("usage: gridmenu [-v] [-t <title>]\n"); }
66 59
67 60
static void
68 61
update_offsets()
213 206
	/* first check if a control mask is omitted */
214 207
	if(e->state & ControlMask) {
215 208
		switch (ksym) {
216 -
		case XK_H:
209 +
		default:	/* ignore other control sequences */
210 +
			return;
211 +
			break;
217 212
		case XK_h:
218 213
			ksym = XK_BackSpace;
219 -
			break;
220 -
		case XK_I:
221 -
		case XK_i:
222 -
			ksym = XK_Tab;
223 -
			break;
224 -
		case XK_J:
225 -
		case XK_j:
226 -
			ksym = XK_Return;
227 -
			break;
228 -
		case XK_N:
229 -
		case XK_n:
230 -
			ksym = XK_Right;
231 -
			break;
232 -
		case XK_P:
233 -
		case XK_p:
234 -
			ksym = XK_Left;
235 214
			break;
236 215
		case XK_U:
237 216
		case XK_u:
243 222
		case XK_bracketleft:
244 223
			ksym = XK_Escape;
245 224
			break;
246 -
		default:	/* ignore other control sequences */
247 -
			return;
248 -
			break;
249 225
		}
250 226
	}
251 -
	switch (ksym) {
227 +
	switch(ksym) {
252 228
	case XK_Left:
253 229
		if(!(sel && sel->left))
254 230
			return;
432 408
	XFlush(dpy);
433 409
434 410
	/* main event loop */
435 -
	while(!XNextEvent(dpy, &ev)) {
411 +
	while(!done && !XNextEvent(dpy, &ev)) {
436 412
		switch (ev.type) {
437 -
			case KeyPress:
438 -
				kpress(&ev.xkey);
439 -
				break;
440 -
			case Expose:
441 -
				if(ev.xexpose.count == 0) {
442 -
					draw_menu();
443 -
				}
444 -
				break;
445 -
			default:
446 -
				break;
413 +
		case KeyPress:
414 +
			kpress(&ev.xkey);
415 +
			break;
416 +
		case Expose:
417 +
			if(ev.xexpose.count == 0)
418 +
				draw_menu();
419 +
			break;
420 +
		default:
421 +
			break;
447 422
		}
448 -
		if(done)
449 -
			break;
450 423
	}
451 424
452 425
	XUngrabKeyboard(dpy, CurrentTime);
mouse.c +6 −26
13 13
#define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
14 14
#define MouseMask       (ButtonMask | PointerMotionMask)
15 15
16 -
static void
17 -
mmatch(Client *c, int x1, int y1, int x2, int y2)
18 -
{
19 -
	c->w = abs(x1 - x2);
20 -
	c->h = abs(y1 - y2);
21 -
	if(c->incw)
22 -
		c->w -= (c->w - c->basew) % c->incw;
23 -
	if(c->inch)
24 -
		c->h -= (c->h - c->baseh) % c->inch;
25 -
	if(c->minw && c->w < c->minw)
26 -
		c->w = c->minw;
27 -
	if(c->minh && c->h < c->minh)
28 -
		c->h = c->minh;
29 -
	if(c->maxw && c->w > c->maxw)
30 -
		c->w = c->maxw;
31 -
	if(c->maxh && c->h > c->maxh)
32 -
		c->h = c->maxh;
33 -
	c->x = (x1 <= x2) ? x1 : x1 - c->w;
34 -
	c->y = (y1 <= y2) ? y1 : y1 - c->h;
35 -
}
36 -
37 16
void
38 17
mresize(Client *c)
39 18
{
55 34
			break;
56 35
		case MotionNotify:
57 36
			XFlush(dpy);
58 -
			mmatch(c, old_cx, old_cy, ev.xmotion.x, ev.xmotion.y);
59 -
			XResizeWindow(dpy, c->win, c->w, c->h);
37 +
			c->w = abs(old_cx - ev.xmotion.x);
38 +
			c->h = abs(old_cy - ev.xmotion.y);
39 +
			c->x = (old_cx <= ev.xmotion.x) ? old_cx : old_cx - c->w;
40 +
			c->y = (old_cy <= ev.xmotion.y) ? old_cy : old_cy - c->h;
41 +
			resize(c);
60 42
			break;
61 43
		case ButtonRelease:
62 -
			resize(c);
63 44
			XUngrabPointer(dpy, CurrentTime);
64 45
			return;
65 46
		}
91 72
			XFlush(dpy);
92 73
			c->x = old_cx + (ev.xmotion.x - x1);
93 74
			c->y = old_cy + (ev.xmotion.y - y1);
94 -
			XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
75 +
			resize(c);
95 76
			break;
96 77
		case ButtonRelease:
97 -
			resize(c);
98 78
			XUngrabPointer(dpy, CurrentTime);
99 79
			return;
100 80
		}
wm.c +34 −17
18 18
19 19
#include "wm.h"
20 20
21 +
/********** CUSTOMIZE **********/
22 +
23 +
char *tags[TLast] = {
24 +
	[Tscratch] = "scratch",
25 +
	[Tdev] = "dev",
26 +
	[Tirc] = "irc",
27 +
	[Twww] = "www",
28 +
	[Twork] = "work",
29 +
};
30 +
31 +
/* commands */
32 +
static char *cmdwallpaper[] = {
33 +
	"feh", "--bg-scale", "/home/garbeam/wallpaper/bg.jpg", NULL
34 +
};
35 +
36 +
static char *cmdstatus[] = {
37 +
	"sh", "-c", "echo -n `date '+%Y-%m-%d %H:%M'`" 
38 +
	" `uptime | sed 's/.*://; s/,//g'`"
39 +
	" `acpi | awk '{print $4}' | sed 's/,//'`", NULL
40 +
};
41 +
42 +
/********** CUSTOMIZE **********/
43 +
21 44
/* X structs */
22 45
Display *dpy;
23 46
Window root, barwin;
24 47
Atom wm_atom[WMLast], net_atom[NetLast];
25 48
Cursor cursor[CurLast];
26 49
Bool running = True;
27 -
Bool sel_screen;
50 +
Bool issel;
28 51
29 -
char statustext[1024], tag[256];
52 +
char stext[1024];
53 +
int tsel = Tdev; /* default tag */
30 54
int screen, sx, sy, sw, sh, bx, by, bw, bh;
31 55
32 56
Brush brush = {0};
34 58
Client *stack = NULL;
35 59
36 60
static Bool other_wm_running;
37 -
static const char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
61 +
static const char version[] =
62 +
	"gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
38 63
static int (*x_error_handler) (Display *, XErrorEvent *);
39 64
40 -
static const char *status[] = {
41 -
	"sh", "-c", "echo -n `date '+%Y-%m-%d %H:%M'`" 
42 -
	" `uptime | sed 's/.*://; s/,//g'`"
43 -
	" `acpi | awk '{print $4}' | sed 's/,//'`", 0
44 -
};
45 -
46 65
static void
47 -
usage()
48 -
{
49 -
	fputs("usage: gridwm [-v]\n", stderr);
50 -
	exit(1);
51 -
}
66 +
usage() {	error("usage: gridwm [-v]\n"); }
52 67
53 68
static void
54 69
scan_wins()
230 245
	if(other_wm_running)
231 246
		error("gridwm: another window manager is already running\n");
232 247
248 +
	spawn(dpy, cmdwallpaper);
233 249
	sx = sy = 0;
234 250
	sw = DisplayWidth(dpy, screen);
235 251
	sh = DisplayHeight(dpy, screen);
236 -
	sel_screen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
252 +
	issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
237 253
238 254
	XSetErrorHandler(0);
239 255
	x_error_handler = XSetErrorHandler(error_handler);
275 291
	brush.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
276 292
	brush.gc = XCreateGC(dpy, root, 0, 0);
277 293
278 -
	pipe_spawn(statustext, sizeof(statustext), dpy, (char **)status);
294 +
	pipe_spawn(stext, sizeof(stext), dpy, cmdstatus);
279 295
	draw_bar();
280 296
281 297
	wa.event_mask = SubstructureRedirectMask | EnterWindowMask \
283 299
	wa.cursor = cursor[CurNormal];
284 300
	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
285 301
302 +
	arrange = grid;
286 303
	scan_wins();
287 304
288 305
	while(running) {
298 315
		if(select(ConnectionNumber(dpy) + 1, &fds, NULL, NULL, &t) > 0)
299 316
			continue;
300 317
		else if(errno != EINTR) {
301 -
			pipe_spawn(statustext, sizeof(statustext), dpy, (char **)status);
318 +
			pipe_spawn(stext, sizeof(stext), dpy, cmdstatus);
302 319
			draw_bar();
303 320
		}
304 321
	}
wm.h +8 −5
22 22
enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
23 23
24 24
struct Client {
25 -
	char name[256], tag[256];
25 +
	char name[256];
26 +
	char *tags[TLast];
26 27
	int proto;
27 28
	int x, y, w, h;
28 29
	int tx, ty, tw, th;
48 49
extern Window root, barwin;
49 50
extern Atom wm_atom[WMLast], net_atom[NetLast];
50 51
extern Cursor cursor[CurLast];
51 -
extern Bool running, sel_screen, grid;
52 +
extern Bool running, issel;
52 53
extern void (*handler[LASTEvent]) (XEvent *);
54 +
extern void (*arrange)(void *aux);
53 55
54 -
extern int screen, sx, sy, sw, sh, bx, by, bw, bh;
55 -
extern char statustext[1024], tag[256];
56 +
extern int tsel, screen, sx, sy, sw, sh, bx, by, bw, bh;
57 +
extern char stext[1024], *tags[TLast];
56 58
57 59
extern Brush brush;
58 60
extern Client *clients, *stack;
75 77
extern void kill(void *aux);
76 78
extern void sel(void *aux);
77 79
extern void max(void *aux);
78 -
extern void arrange(void *aux);
80 +
extern void floating(void *aux);
81 +
extern void grid(void *aux);
79 82
extern void gravitate(Client *c, Bool invert);
80 83
81 84
/* event.c */