rearranged several stuff
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
|  | ||||
| include config.mk | ||||
|  | ||||
| SRC = client.c draw.c event.c key.c main.c screen.c util.c | ||||
| SRC = client.c draw.c event.c main.c tag.c util.c | ||||
| OBJ = ${SRC:.c=.o} | ||||
| MAN1 = dwm.1  | ||||
| BIN = dwm | ||||
|   | ||||
							
								
								
									
										145
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								client.c
									
									
									
									
									
								
							| @@ -11,18 +11,6 @@ | ||||
|  | ||||
| #include "dwm.h" | ||||
|  | ||||
| static Rule rule[] = { | ||||
| 	/* class			instance	tags						floating */ | ||||
| 	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False }, | ||||
| }; | ||||
|  | ||||
| Client * | ||||
| getnext(Client *c) | ||||
| { | ||||
| 	for(; c && !c->tags[tsel]; c = c->next); | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| void | ||||
| ban(Client *c) | ||||
| { | ||||
| @@ -31,7 +19,7 @@ ban(Client *c) | ||||
| } | ||||
|  | ||||
| static void | ||||
| resize_title(Client *c) | ||||
| resizetitle(Client *c) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| @@ -72,7 +60,7 @@ settitle(Client *c) | ||||
| 		} | ||||
| 	} | ||||
| 	XFree(name.value); | ||||
| 	resize_title(c); | ||||
| 	resizetitle(c); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -143,42 +131,6 @@ focus(Client *c) | ||||
| 	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); | ||||
| } | ||||
|  | ||||
| static void | ||||
| init_tags(Client *c) | ||||
| { | ||||
| 	XClassHint ch; | ||||
| 	static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; | ||||
| 	unsigned int i, j; | ||||
| 	Bool matched = False; | ||||
|  | ||||
| 	if(!len) { | ||||
| 		c->tags[tsel] = tags[tsel]; | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if(XGetClassHint(dpy, c->win, &ch)) { | ||||
| 		if(ch.res_class && ch.res_name) { | ||||
| 			for(i = 0; i < len; i++) | ||||
| 				if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) | ||||
| 					&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) | ||||
| 				{ | ||||
| 					for(j = 0; j < TLast; j++) | ||||
| 						c->tags[j] = rule[i].tags[j]; | ||||
| 					c->floating = rule[i].floating; | ||||
| 					matched = True; | ||||
| 					break; | ||||
| 				} | ||||
| 		} | ||||
| 		if(ch.res_class) | ||||
| 			XFree(ch.res_class); | ||||
| 		if(ch.res_name) | ||||
| 			XFree(ch.res_name); | ||||
| 	} | ||||
|  | ||||
| 	if(!matched) | ||||
| 		c->tags[tsel] = tags[tsel]; | ||||
| } | ||||
|  | ||||
| void | ||||
| manage(Window w, XWindowAttributes *wa) | ||||
| { | ||||
| @@ -196,7 +148,7 @@ manage(Window w, XWindowAttributes *wa) | ||||
| 	c->h = wa->height; | ||||
| 	c->th = bh; | ||||
| 	c->border = 1; | ||||
| 	c->proto = proto(c->win); | ||||
| 	c->proto = getproto(c->win); | ||||
| 	setsize(c); | ||||
| 	XSelectInput(dpy, c->win, | ||||
| 			StructureNotifyMask | PropertyChangeMask | EnterWindowMask); | ||||
| @@ -211,7 +163,7 @@ manage(Window w, XWindowAttributes *wa) | ||||
| 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); | ||||
|  | ||||
| 	settitle(c); | ||||
| 	init_tags(c); | ||||
| 	settags(c); | ||||
|  | ||||
| 	for(l = &clients; *l; l = &(*l)->next); | ||||
| 	c->next = *l; /* *l == nil */ | ||||
| @@ -224,8 +176,8 @@ manage(Window w, XWindowAttributes *wa) | ||||
| 	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, | ||||
| 			GrabModeAsync, GrabModeSync, None, None); | ||||
|  | ||||
| 	if(!c->floating) | ||||
| 		c->floating = trans | ||||
| 	if(!c->dofloat) | ||||
| 		c->dofloat = trans | ||||
| 			|| ((c->maxw == c->minw) && (c->maxh == c->minh)); | ||||
|  | ||||
| 	arrange(NULL); | ||||
| @@ -321,7 +273,7 @@ resize(Client *c, Bool inc) | ||||
| 		c->w = c->maxw; | ||||
| 	if(c->maxh && c->h > c->maxh) | ||||
| 		c->h = c->maxh; | ||||
| 	resize_title(c); | ||||
| 	resizetitle(c); | ||||
| 	XSetWindowBorderWidth(dpy, c->win, 1); | ||||
| 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); | ||||
| 	e.type = ConfigureNotify; | ||||
| @@ -339,7 +291,7 @@ resize(Client *c, Bool inc) | ||||
| } | ||||
|  | ||||
| static int | ||||
| dummy_xerror(Display *dsply, XErrorEvent *err) | ||||
| xerrordummy(Display *dsply, XErrorEvent *ee) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| @@ -350,7 +302,7 @@ unmanage(Client *c) | ||||
| 	Client **l; | ||||
|  | ||||
| 	XGrabServer(dpy); | ||||
| 	XSetErrorHandler(dummy_xerror); | ||||
| 	XSetErrorHandler(xerrordummy); | ||||
|  | ||||
| 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win); | ||||
| 	XDestroyWindow(dpy, c->title); | ||||
| @@ -374,7 +326,7 @@ unmanage(Client *c) | ||||
| } | ||||
|  | ||||
| Client * | ||||
| gettitle(Window w) | ||||
| getctitle(Window w) | ||||
| { | ||||
| 	Client *c; | ||||
| 	for(c = clients; c; c = c->next) | ||||
| @@ -392,3 +344,80 @@ getclient(Window w) | ||||
| 			return c; | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| void | ||||
| zoom(Arg *arg) | ||||
| { | ||||
| 	Client **l, *c; | ||||
|  | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	if(sel == getnext(clients) && sel->next)  { | ||||
| 		if((c = getnext(sel->next))) | ||||
| 			sel = c; | ||||
| 	} | ||||
|  | ||||
| 	for(l = &clients; *l && *l != sel; l = &(*l)->next); | ||||
| 	*l = sel->next; | ||||
|  | ||||
| 	sel->next = clients; /* pop */ | ||||
| 	clients = sel; | ||||
| 	arrange(NULL); | ||||
| 	focus(sel); | ||||
| } | ||||
|  | ||||
| void | ||||
| maximize(Arg *arg) | ||||
| { | ||||
| 	if(!sel) | ||||
| 		return; | ||||
| 	sel->x = sx; | ||||
| 	sel->y = sy + bh; | ||||
| 	sel->w = sw - 2 * sel->border; | ||||
| 	sel->h = sh - 2 * sel->border - bh; | ||||
| 	higher(sel); | ||||
| 	resize(sel, False); | ||||
| } | ||||
|  | ||||
| void | ||||
| focusprev(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
|  | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { | ||||
| 		higher(c); | ||||
| 		focus(c); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void | ||||
| focusnext(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
|     | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	if(!(c = getnext(sel->next))) | ||||
| 		c = getnext(clients); | ||||
| 	if(c) { | ||||
| 		higher(c); | ||||
| 		c->revert = sel; | ||||
| 		focus(c); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void | ||||
| killclient(Arg *arg) | ||||
| { | ||||
| 	if(!sel) | ||||
| 		return; | ||||
| 	if(sel->proto & WM_PROTOCOL_DELWIN) | ||||
| 		sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | ||||
| 	else | ||||
| 		XKillClient(dpy, sel->win); | ||||
| } | ||||
|   | ||||
							
								
								
									
										37
									
								
								draw.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								draw.c
									
									
									
									
									
								
							| @@ -10,34 +10,43 @@ | ||||
|  | ||||
| #include "dwm.h" | ||||
|  | ||||
| void | ||||
| drawall() | ||||
| { | ||||
| 	Client *c; | ||||
|  | ||||
| 	for(c = clients; c; c = getnext(c->next)) | ||||
| 		drawtitle(c); | ||||
| 	drawstatus(); | ||||
| } | ||||
|  | ||||
| void | ||||
| drawstatus() | ||||
| { | ||||
| 	int i; | ||||
| 	Bool istile = arrange == dotile; | ||||
|  | ||||
| 	dc.x = dc.y = 0; | ||||
| 	dc.w = bw; | ||||
| 	drawtext(NULL, False, False); | ||||
| 	drawtext(NULL, !istile, False); | ||||
|  | ||||
| 	if(arrange == floating) { | ||||
| 		dc.w = textw("~"); | ||||
| 		drawtext("~", False, False); | ||||
| 	} | ||||
| 	else | ||||
| 		dc.w = 0; | ||||
| 	dc.w = 0; | ||||
| 	for(i = 0; i < TLast; i++) { | ||||
| 		dc.x += dc.w; | ||||
| 		dc.w = textw(tags[i]); | ||||
| 		drawtext(tags[i], i == tsel, True); | ||||
| 		if(istile) | ||||
| 			drawtext(tags[i], (i == tsel), True); | ||||
| 		else | ||||
| 			drawtext(tags[i], (i != tsel), True); | ||||
| 	} | ||||
| 	if(sel) { | ||||
| 		dc.x += dc.w; | ||||
| 		dc.w = textw(sel->name); | ||||
| 		drawtext(sel->name, True, True); | ||||
| 		drawtext(sel->name, istile, True); | ||||
| 	} | ||||
| 	dc.w = textw(stext); | ||||
| 	dc.x = bx + bw - dc.w; | ||||
| 	drawtext(stext, False, False); | ||||
| 	drawtext(stext, !istile, False); | ||||
|  | ||||
| 	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0); | ||||
| 	XFlush(dpy); | ||||
| @@ -47,6 +56,8 @@ void | ||||
| drawtitle(Client *c) | ||||
| { | ||||
| 	int i; | ||||
| 	Bool istile = arrange == dotile; | ||||
|  | ||||
| 	if(c == sel) { | ||||
| 		drawstatus(); | ||||
| 		XUnmapWindow(dpy, c->title); | ||||
| @@ -64,12 +75,12 @@ drawtitle(Client *c) | ||||
| 		if(c->tags[i]) { | ||||
| 			dc.x += dc.w; | ||||
| 			dc.w = textw(c->tags[i]); | ||||
| 			drawtext(c->tags[i], False, True); | ||||
| 			drawtext(c->tags[i], !istile, True); | ||||
| 		} | ||||
| 	} | ||||
| 	dc.x += dc.w; | ||||
| 	dc.w = textw(c->name); | ||||
| 	drawtext(c->name, False, True); | ||||
| 	drawtext(c->name, !istile, True); | ||||
| 	XCopyArea(dpy, dc.drawable, c->title, dc.gc, | ||||
| 			0, 0, c->tw, c->th, 0, 0); | ||||
| 	XFlush(dpy); | ||||
| @@ -215,7 +226,7 @@ setfont(const char *fontstr) | ||||
| 		if (!dc.font.xfont) | ||||
| 			dc.font.xfont = XLoadQueryFont(dpy, "fixed"); | ||||
| 		if (!dc.font.xfont) | ||||
| 			error("error, cannot init 'fixed' font\n"); | ||||
| 			eprint("error, cannot init 'fixed' font\n"); | ||||
| 		dc.font.ascent = dc.font.xfont->ascent; | ||||
| 		dc.font.descent = dc.font.xfont->descent; | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										36
									
								
								dwm.h
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								dwm.h
									
									
									
									
									
								
							| @@ -66,7 +66,7 @@ struct Client { | ||||
| 	int grav; | ||||
| 	unsigned int border; | ||||
| 	long flags;  | ||||
| 	Bool floating; | ||||
| 	Bool dofloat; | ||||
| 	Window win; | ||||
| 	Window title; | ||||
| 	Client *next; | ||||
| @@ -77,7 +77,7 @@ struct Rule { | ||||
| 	const char *class; | ||||
| 	const char *instance; | ||||
| 	char *tags[TLast]; | ||||
| 	Bool floating; | ||||
| 	Bool dofloat; | ||||
| }; | ||||
|  | ||||
| struct Key { | ||||
| @@ -103,6 +103,7 @@ extern DC dc; | ||||
| extern Client *clients, *sel; | ||||
|  | ||||
| /* client.c */ | ||||
| extern void ban(Client *c); | ||||
| extern void manage(Window w, XWindowAttributes *wa); | ||||
| extern void unmanage(Client *c); | ||||
| extern Client *getclient(Window w); | ||||
| @@ -110,14 +111,18 @@ extern void focus(Client *c); | ||||
| extern void settitle(Client *c); | ||||
| extern void resize(Client *c, Bool inc); | ||||
| extern void setsize(Client *c); | ||||
| extern Client *gettitle(Window w); | ||||
| extern Client *getctitle(Window w); | ||||
| extern void higher(Client *c); | ||||
| extern void lower(Client *c); | ||||
| extern void gravitate(Client *c, Bool invert); | ||||
| extern void ban(Client *c); | ||||
| extern Client *getnext(Client *c); | ||||
| extern void zoom(Arg *arg); | ||||
| extern void maximize(Arg *arg); | ||||
| extern void focusprev(Arg *arg); | ||||
| extern void focusnext(Arg *arg); | ||||
| extern void killclient(Arg *arg); | ||||
|  | ||||
| /* draw.c */ | ||||
| extern void drawall(); | ||||
| extern void drawstatus(); | ||||
| extern void drawtitle(Client *c); | ||||
| extern void drawtext(const char *text, Bool invert, Bool border); | ||||
| @@ -127,22 +132,25 @@ extern unsigned int textnw(char *text, unsigned int len); | ||||
| extern unsigned int textw(char *text); | ||||
| extern unsigned int texth(void); | ||||
|  | ||||
| /* key.c */ | ||||
| /* event.c */ | ||||
| extern void grabkeys(); | ||||
| extern void keypress(XEvent *e); | ||||
|  | ||||
| /* main.c */ | ||||
| extern int xerror(Display *dsply, XErrorEvent *e); | ||||
| extern void sendevent(Window w, Atom a, long value); | ||||
| extern int proto(Window w); | ||||
| extern void quit(Arg *arg); | ||||
| extern int xerror(Display *dsply, XErrorEvent *ee); | ||||
| extern void sendevent(Window w, Atom a, long value); | ||||
| extern int getproto(Window w); | ||||
|  | ||||
| /* screen.c */ | ||||
| extern void floating(Arg *arg); | ||||
| extern void tiling(Arg *arg); | ||||
| /* tag.c */ | ||||
| extern Client *getnext(Client *c); | ||||
| extern void settags(Client *c); | ||||
| extern void dofloat(Arg *arg); | ||||
| extern void dotile(Arg *arg); | ||||
| extern void view(Arg *arg); | ||||
| extern void appendtag(Arg *arg); | ||||
| extern void replacetag(Arg *arg); | ||||
|  | ||||
| /* util.c */ | ||||
| extern void error(const char *errstr, ...); | ||||
| extern void eprint(const char *errstr, ...); | ||||
| extern void *emallocz(unsigned int size); | ||||
| extern void spawn(Arg *arg); | ||||
|   | ||||
							
								
								
									
										89
									
								
								event.c
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								event.c
									
									
									
									
									
								
							| @@ -16,6 +16,44 @@ | ||||
| #define ButtonMask      (ButtonPressMask | ButtonReleaseMask) | ||||
| #define MouseMask       (ButtonMask | PointerMotionMask) | ||||
|  | ||||
| /********** CUSTOMIZE **********/ | ||||
|  | ||||
| const char *term[] = {  | ||||
| 	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn", | ||||
| 	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL | ||||
| }; | ||||
| const char *browse[] = { "firefox", NULL }; | ||||
| const char *xlock[] = { "xlock", NULL }; | ||||
|  | ||||
| Key key[] = { | ||||
| 	/* modifier				key			function	arguments */ | ||||
| 	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } }, | ||||
| 	{ Mod1Mask,				XK_k,		focusprev,		{ 0 } }, | ||||
| 	{ Mod1Mask,				XK_j,		focusnext,		{ 0 } },  | ||||
| 	{ Mod1Mask,				XK_m,		maximize,		{ 0 } },  | ||||
| 	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } },  | ||||
| 	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } },  | ||||
| 	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } },  | ||||
| 	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } },  | ||||
| 	{ Mod1Mask,				XK_space,	dotile,		{ 0 } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_space,	dofloat,	{ 0 } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_0,		replacetag,		{ .i = Tscratch } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_1,		replacetag,		{ .i = Tdev } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_2,		replacetag,		{ .i = Twww } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_3,		replacetag,		{ .i = Twork } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_c,		killclient,		{ 0 } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } }, | ||||
| 	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } }, | ||||
| 	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } }, | ||||
| 	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } }, | ||||
| 	{ ControlMask,			XK_0,		appendtag,	{ .i = Tscratch } },  | ||||
| 	{ ControlMask,			XK_1,		appendtag,	{ .i = Tdev } },  | ||||
| 	{ ControlMask,			XK_2,		appendtag,	{ .i = Twww } },  | ||||
| 	{ ControlMask,			XK_3,		appendtag,	{ .i = Twork } },  | ||||
| }; | ||||
|  | ||||
| /********** CUSTOMIZE **********/ | ||||
|  | ||||
| /* local functions */ | ||||
| static void buttonpress(XEvent *e); | ||||
| static void configurerequest(XEvent *e); | ||||
| @@ -23,6 +61,7 @@ static void destroynotify(XEvent *e); | ||||
| static void enternotify(XEvent *e); | ||||
| static void leavenotify(XEvent *e); | ||||
| static void expose(XEvent *e); | ||||
| static void keypress(XEvent *e); | ||||
| static void maprequest(XEvent *e); | ||||
| static void propertynotify(XEvent *e); | ||||
| static void unmapnotify(XEvent *e); | ||||
| @@ -40,8 +79,40 @@ void (*handler[LASTEvent]) (XEvent *) = { | ||||
| 	[UnmapNotify] = unmapnotify | ||||
| }; | ||||
|  | ||||
| void | ||||
| grabkeys() | ||||
| { | ||||
| 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | ||||
| 	unsigned int i; | ||||
| 	KeyCode code; | ||||
|  | ||||
| 	for(i = 0; i < len; i++) { | ||||
| 		code = XKeysymToKeycode(dpy, key[i].keysym); | ||||
| 		XUngrabKey(dpy, code, key[i].mod, root); | ||||
| 		XGrabKey(dpy, code, key[i].mod, root, True, | ||||
| 				GrabModeAsync, GrabModeAsync); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| mresize(Client *c) | ||||
| keypress(XEvent *e) | ||||
| { | ||||
| 	XKeyEvent *ev = &e->xkey; | ||||
| 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | ||||
| 	unsigned int i; | ||||
| 	KeySym keysym; | ||||
|  | ||||
| 	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); | ||||
| 	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].arg); | ||||
| 			return; | ||||
| 		} | ||||
| } | ||||
|  | ||||
| static void | ||||
| resizemouse(Client *c) | ||||
| { | ||||
| 	XEvent ev; | ||||
| 	int ocx, ocy; | ||||
| @@ -75,7 +146,7 @@ mresize(Client *c) | ||||
| } | ||||
|  | ||||
| static void | ||||
| mmove(Client *c) | ||||
| movemouse(Client *c) | ||||
| { | ||||
| 	XEvent ev; | ||||
| 	int x1, y1, ocx, ocy, di; | ||||
| @@ -117,7 +188,7 @@ buttonpress(XEvent *e) | ||||
| 	Client *c; | ||||
|  | ||||
| 	if(barwin == ev->window) { | ||||
| 		x = (arrange == floating) ? textw("~") : 0; | ||||
| 		x = (arrange == dofloat) ? textw("~") : 0; | ||||
| 		for(a.i = 0; a.i < TLast; a.i++) { | ||||
| 			x += textw(tags[a.i]); | ||||
| 			if(ev->x < x) { | ||||
| @@ -127,20 +198,20 @@ buttonpress(XEvent *e) | ||||
| 		} | ||||
| 	} | ||||
| 	else if((c = getclient(ev->window))) { | ||||
| 		if(arrange == tiling && !c->floating) | ||||
| 		if(arrange == dotile && !c->dofloat) | ||||
| 			return; | ||||
| 		higher(c); | ||||
| 		switch(ev->button) { | ||||
| 		default: | ||||
| 			break; | ||||
| 		case Button1: | ||||
| 			mmove(c); | ||||
| 			movemouse(c); | ||||
| 			break; | ||||
| 		case Button2: | ||||
| 			lower(c); | ||||
| 			break; | ||||
| 		case Button3: | ||||
| 			mresize(c); | ||||
| 			resizemouse(c); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| @@ -226,7 +297,7 @@ expose(XEvent *e) | ||||
| 	if(ev->count == 0) { | ||||
| 		if(barwin == ev->window) | ||||
| 			drawstatus(); | ||||
| 		else if((c = gettitle(ev->window))) | ||||
| 		else if((c = getctitle(ev->window))) | ||||
| 			drawtitle(c); | ||||
| 	} | ||||
| } | ||||
| @@ -262,14 +333,14 @@ propertynotify(XEvent *e) | ||||
|  | ||||
| 	if((c = getclient(ev->window))) { | ||||
| 		if(ev->atom == wm_atom[WMProtocols]) { | ||||
| 			c->proto = proto(c->win); | ||||
| 			c->proto = getproto(c->win); | ||||
| 			return; | ||||
| 		} | ||||
| 		switch (ev->atom) { | ||||
| 			default: break; | ||||
| 			case XA_WM_TRANSIENT_FOR: | ||||
| 				XGetTransientForHint(dpy, c->win, &trans); | ||||
| 				if(!c->floating && (c->floating = (trans != 0))) | ||||
| 				if(!c->dofloat && (c->dofloat = (trans != 0))) | ||||
| 					arrange(NULL); | ||||
| 				break; | ||||
| 			case XA_WM_NORMAL_HINTS: | ||||
|   | ||||
							
								
								
									
										192
									
								
								key.c
									
									
									
									
									
								
							
							
						
						
									
										192
									
								
								key.c
									
									
									
									
									
								
							| @@ -1,192 +0,0 @@ | ||||
| /* | ||||
|  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | ||||
|  * See LICENSE file for license details. | ||||
|  */ | ||||
|  | ||||
| #include <fcntl.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <X11/keysym.h> | ||||
| #include <X11/Xatom.h> | ||||
|  | ||||
| #include "dwm.h" | ||||
|  | ||||
| static void ckill(Arg *arg); | ||||
| static void nextc(Arg *arg); | ||||
| static void prevc(Arg *arg); | ||||
| static void max(Arg *arg); | ||||
| static void ttrunc(Arg *arg); | ||||
| static void tappend(Arg *arg); | ||||
| static void zoom(Arg *arg); | ||||
|  | ||||
| /********** CUSTOMIZE **********/ | ||||
|  | ||||
| const char *term[] = {  | ||||
| 	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn", | ||||
| 	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL | ||||
| }; | ||||
| const char *browse[] = { "firefox", NULL }; | ||||
| const char *xlock[] = { "xlock", NULL }; | ||||
|  | ||||
| Key key[] = { | ||||
| 	/* modifier				key			function	arguments */ | ||||
| 	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } }, | ||||
| 	{ Mod1Mask,				XK_k,		prevc,		{ 0 } }, | ||||
| 	{ Mod1Mask,				XK_j,		nextc,		{ 0 } },  | ||||
| 	{ Mod1Mask,				XK_m,		max,		{ 0 } },  | ||||
| 	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } },  | ||||
| 	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } },  | ||||
| 	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } },  | ||||
| 	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } },  | ||||
| 	{ Mod1Mask,				XK_space,	tiling,		{ 0 } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_space,	floating,	{ 0 } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_0,		ttrunc,		{ .i = Tscratch } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_1,		ttrunc,		{ .i = Tdev } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_2,		ttrunc,		{ .i = Twww } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_3,		ttrunc,		{ .i = Twork } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_c,		ckill,		{ 0 } },  | ||||
| 	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } }, | ||||
| 	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } }, | ||||
| 	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } }, | ||||
| 	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } }, | ||||
| 	{ ControlMask,			XK_0,		tappend,	{ .i = Tscratch } },  | ||||
| 	{ ControlMask,			XK_1,		tappend,	{ .i = Tdev } },  | ||||
| 	{ ControlMask,			XK_2,		tappend,	{ .i = Twww } },  | ||||
| 	{ ControlMask,			XK_3,		tappend,	{ .i = Twork } },  | ||||
| }; | ||||
|  | ||||
| /********** CUSTOMIZE **********/ | ||||
|  | ||||
| void | ||||
| grabkeys() | ||||
| { | ||||
| 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | ||||
| 	unsigned int i; | ||||
| 	KeyCode code; | ||||
|  | ||||
| 	for(i = 0; i < len; i++) { | ||||
| 		code = XKeysymToKeycode(dpy, key[i].keysym); | ||||
| 		XUngrabKey(dpy, code, key[i].mod, root); | ||||
| 		XGrabKey(dpy, code, key[i].mod, root, True, | ||||
| 				GrabModeAsync, GrabModeAsync); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void | ||||
| keypress(XEvent *e) | ||||
| { | ||||
| 	XKeyEvent *ev = &e->xkey; | ||||
| 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | ||||
| 	unsigned int i; | ||||
| 	KeySym keysym; | ||||
|  | ||||
| 	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); | ||||
| 	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].arg); | ||||
| 			return; | ||||
| 		} | ||||
| } | ||||
|  | ||||
| static void | ||||
| zoom(Arg *arg) | ||||
| { | ||||
| 	Client **l, *c; | ||||
|  | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	if(sel == getnext(clients) && sel->next)  { | ||||
| 		if((c = getnext(sel->next))) | ||||
| 			sel = c; | ||||
| 	} | ||||
|  | ||||
| 	for(l = &clients; *l && *l != sel; l = &(*l)->next); | ||||
| 	*l = sel->next; | ||||
|  | ||||
| 	sel->next = clients; /* pop */ | ||||
| 	clients = sel; | ||||
| 	arrange(NULL); | ||||
| 	focus(sel); | ||||
| } | ||||
|  | ||||
| static void | ||||
| max(Arg *arg) | ||||
| { | ||||
| 	if(!sel) | ||||
| 		return; | ||||
| 	sel->x = sx; | ||||
| 	sel->y = sy + bh; | ||||
| 	sel->w = sw - 2 * sel->border; | ||||
| 	sel->h = sh - 2 * sel->border - bh; | ||||
| 	higher(sel); | ||||
| 	resize(sel, False); | ||||
| } | ||||
|  | ||||
| static void | ||||
| tappend(Arg *arg) | ||||
| { | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	sel->tags[arg->i] = tags[arg->i]; | ||||
| 	arrange(NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| ttrunc(Arg *arg) | ||||
| { | ||||
| 	int i; | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	for(i = 0; i < TLast; i++) | ||||
| 		sel->tags[i] = NULL; | ||||
| 	tappend(arg); | ||||
| } | ||||
|  | ||||
| static void | ||||
| prevc(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
|  | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { | ||||
| 		higher(c); | ||||
| 		focus(c); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| nextc(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
|     | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	if(!(c = getnext(sel->next))) | ||||
| 		c = getnext(clients); | ||||
| 	if(c) { | ||||
| 		higher(c); | ||||
| 		c->revert = sel; | ||||
| 		focus(c); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| ckill(Arg *arg) | ||||
| { | ||||
| 	if(!sel) | ||||
| 		return; | ||||
| 	if(sel->proto & WM_PROTOCOL_DELWIN) | ||||
| 		sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); | ||||
| 	else | ||||
| 		XKillClient(dpy, sel->win); | ||||
| } | ||||
|  | ||||
							
								
								
									
										112
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								main.c
									
									
									
									
									
								
							| @@ -43,16 +43,16 @@ DC dc = {0}; | ||||
| Client *clients = NULL; | ||||
| Client *sel = NULL; | ||||
|  | ||||
| static Bool other_wm_running; | ||||
| static Bool otherwm; | ||||
| static const char version[] = | ||||
| 	"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; | ||||
| static int (*x_xerror) (Display *, XErrorEvent *); | ||||
| static int (*xerrorxlib)(Display *, XErrorEvent *); | ||||
|  | ||||
| static void | ||||
| usage() {	error("usage: dwm [-v]\n"); } | ||||
| usage() {	eprint("usage: dwm [-v]\n"); } | ||||
|  | ||||
| static void | ||||
| scan_wins() | ||||
| scan() | ||||
| { | ||||
| 	unsigned int i, num; | ||||
| 	Window *wins; | ||||
| @@ -73,6 +73,22 @@ scan_wins() | ||||
| 		XFree(wins); | ||||
| } | ||||
|  | ||||
| static void | ||||
| cleanup() | ||||
| { | ||||
| 	while(sel) { | ||||
| 		resize(sel, True); | ||||
| 		unmanage(sel); | ||||
| 	} | ||||
| 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); | ||||
| } | ||||
|  | ||||
| void | ||||
| quit(Arg *arg) | ||||
| { | ||||
| 	running = False; | ||||
| } | ||||
|  | ||||
| static int | ||||
| win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) | ||||
| { | ||||
| @@ -94,7 +110,7 @@ win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) | ||||
| } | ||||
|  | ||||
| int | ||||
| proto(Window w) | ||||
| getproto(Window w) | ||||
| { | ||||
| 	unsigned char *protocols; | ||||
| 	long res; | ||||
| @@ -128,6 +144,17 @@ sendevent(Window w, Atom a, long value) | ||||
| 	XFlush(dpy); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Startup Error handler to check if another window manager | ||||
|  * is already running. | ||||
|  */ | ||||
| static int | ||||
| xerrorstart(Display *dsply, XErrorEvent *ee) | ||||
| { | ||||
| 	otherwm = True; | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * There's no way to check accesses to destroyed windows, thus | ||||
|  * those cases are ignored (especially on UnmapNotify's). | ||||
| @@ -135,52 +162,25 @@ sendevent(Window w, Atom a, long value) | ||||
|  * calls exit(). | ||||
|  */ | ||||
| int | ||||
| xerror(Display *dpy, XErrorEvent *error) | ||||
| xerror(Display *dpy, XErrorEvent *ee) | ||||
| { | ||||
| 	if(error->error_code == BadWindow | ||||
| 			|| (error->request_code == X_SetInputFocus | ||||
| 				&& error->error_code == BadMatch) | ||||
| 			|| (error->request_code == X_PolyText8 | ||||
| 				&& error->error_code == BadDrawable) | ||||
| 			|| (error->request_code == X_PolyFillRectangle | ||||
| 				&& error->error_code == BadDrawable) | ||||
| 			|| (error->request_code == X_PolySegment | ||||
| 				&& error->error_code == BadDrawable) | ||||
| 			|| (error->request_code == X_ConfigureWindow | ||||
| 				&& error->error_code == BadMatch) | ||||
| 			|| (error->request_code == X_GrabKey | ||||
| 				&& error->error_code == BadAccess)) | ||||
| 	if(ee->error_code == BadWindow | ||||
| 			|| (ee->request_code == X_SetInputFocus | ||||
| 				&& ee->error_code == BadMatch) | ||||
| 			|| (ee->request_code == X_PolyText8 | ||||
| 				&& ee->error_code == BadDrawable) | ||||
| 			|| (ee->request_code == X_PolyFillRectangle | ||||
| 				&& ee->error_code == BadDrawable) | ||||
| 			|| (ee->request_code == X_PolySegment | ||||
| 				&& ee->error_code == BadDrawable) | ||||
| 			|| (ee->request_code == X_ConfigureWindow | ||||
| 				&& ee->error_code == BadMatch) | ||||
| 			|| (ee->request_code == X_GrabKey | ||||
| 				&& ee->error_code == BadAccess)) | ||||
| 		return 0; | ||||
| 	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", | ||||
| 			error->request_code, error->error_code); | ||||
| 	return x_xerror(dpy, error); /* may call exit() */ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Startup Error handler to check if another window manager | ||||
|  * is already running. | ||||
|  */ | ||||
| static int | ||||
| startup_xerror(Display *dpy, XErrorEvent *error) | ||||
| { | ||||
| 	other_wm_running = True; | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cleanup() | ||||
| { | ||||
| 	while(sel) { | ||||
| 		resize(sel, True); | ||||
| 		unmanage(sel); | ||||
| 	} | ||||
| 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); | ||||
| } | ||||
|  | ||||
| void | ||||
| quit(Arg *arg) | ||||
| { | ||||
| 	running = False; | ||||
| 			ee->request_code, ee->error_code); | ||||
| 	return xerrorxlib(dpy, ee); /* may call exit() */ | ||||
| } | ||||
|  | ||||
| int | ||||
| @@ -208,23 +208,23 @@ main(int argc, char *argv[]) | ||||
|  | ||||
| 	dpy = XOpenDisplay(0); | ||||
| 	if(!dpy) | ||||
| 		error("dwm: cannot connect X server\n"); | ||||
| 		eprint("dwm: cannot connect X server\n"); | ||||
|  | ||||
| 	screen = DefaultScreen(dpy); | ||||
| 	root = RootWindow(dpy, screen); | ||||
|  | ||||
| 	/* check if another WM is already running */ | ||||
| 	other_wm_running = False; | ||||
| 	XSetErrorHandler(startup_xerror); | ||||
| 	otherwm = False; | ||||
| 	XSetErrorHandler(xerrorstart); | ||||
| 	/* this causes an error if some other WM is running */ | ||||
| 	XSelectInput(dpy, root, SubstructureRedirectMask); | ||||
| 	XFlush(dpy); | ||||
|  | ||||
| 	if(other_wm_running) | ||||
| 		error("dwm: another window manager is already running\n"); | ||||
| 	if(otherwm) | ||||
| 		eprint("dwm: another window manager is already running\n"); | ||||
|  | ||||
| 	XSetErrorHandler(0); | ||||
| 	x_xerror = XSetErrorHandler(xerror); | ||||
| 	xerrorxlib = XSetErrorHandler(xerror); | ||||
|  | ||||
| 	/* init atoms */ | ||||
| 	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | ||||
| @@ -278,7 +278,7 @@ main(int argc, char *argv[]) | ||||
| 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); | ||||
|  | ||||
| 	strcpy(stext, "dwm-"VERSION); | ||||
| 	scan_wins(); | ||||
| 	scan(); | ||||
|  | ||||
| 	/* main event loop, reads status text from stdin as well */ | ||||
| Mainloop: | ||||
| @@ -292,7 +292,7 @@ Mainloop: | ||||
| 		if(i == -1 && errno == EINTR) | ||||
| 			continue; | ||||
| 		if(i < 0) | ||||
| 			error("select failed\n"); | ||||
| 			eprint("select failed\n"); | ||||
| 		else if(i > 0) { | ||||
| 			if(FD_ISSET(ConnectionNumber(dpy), &rd)) { | ||||
| 				while(XPending(dpy)) { | ||||
|   | ||||
							
								
								
									
										100
									
								
								screen.c
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								screen.c
									
									
									
									
									
								
							| @@ -1,100 +0,0 @@ | ||||
| /* | ||||
|  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | ||||
|  * See LICENSE file for license details. | ||||
|  */ | ||||
|  | ||||
| #include "dwm.h" | ||||
|  | ||||
| void (*arrange)(Arg *) = tiling; | ||||
|  | ||||
| void | ||||
| view(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
|  | ||||
| 	tsel = arg->i; | ||||
| 	arrange(NULL); | ||||
|  | ||||
| 	for(c = clients; c; c = getnext(c->next)) | ||||
| 		drawtitle(c); | ||||
| 	drawstatus(); | ||||
| } | ||||
|  | ||||
| void | ||||
| floating(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
|  | ||||
| 	arrange = floating; | ||||
| 	for(c = clients; c; c = c->next) { | ||||
| 		if(c->tags[tsel]) | ||||
| 			resize(c, True); | ||||
| 		else | ||||
| 			ban(c); | ||||
| 	} | ||||
| 	if(sel && !sel->tags[tsel]) { | ||||
| 		if((sel = getnext(clients))) { | ||||
| 			higher(sel); | ||||
| 			focus(sel); | ||||
| 		} | ||||
| 	} | ||||
| 	drawstatus(); | ||||
| } | ||||
|  | ||||
| void | ||||
| tiling(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
| 	int n, i, w, h; | ||||
|  | ||||
| 	w = sw - mw; | ||||
| 	arrange = tiling; | ||||
| 	for(n = 0, c = clients; c; c = c->next) | ||||
| 		if(c->tags[tsel] && !c->floating) | ||||
| 			n++; | ||||
|  | ||||
| 	if(n > 1) | ||||
| 		h = (sh - bh) / (n - 1); | ||||
| 	else | ||||
| 		h = sh - bh; | ||||
|  | ||||
| 	for(i = 0, c = clients; c; c = c->next) { | ||||
| 		if(c->tags[tsel]) { | ||||
| 			if(c->floating) { | ||||
| 				higher(c); | ||||
| 				resize(c, True); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if(n == 1) { | ||||
| 				c->x = sx; | ||||
| 				c->y = sy + bh; | ||||
| 				c->w = sw - 2 * c->border; | ||||
| 				c->h = sh - 2 * c->border - bh; | ||||
| 			} | ||||
| 			else if(i == 0) { | ||||
| 				c->x = sx; | ||||
| 				c->y = sy + bh; | ||||
| 				c->w = mw - 2 * c->border; | ||||
| 				c->h = sh - 2 * c->border - bh; | ||||
| 			} | ||||
| 			else { | ||||
| 				c->x = sx + mw; | ||||
| 				c->y = sy + (i - 1) * h + bh; | ||||
| 				c->w = w - 2 * c->border; | ||||
| 				c->h = h - 2 * c->border; | ||||
| 			} | ||||
| 			resize(c, False); | ||||
| 			i++; | ||||
| 		} | ||||
| 		else | ||||
| 			ban(c); | ||||
| 	} | ||||
| 	if(!sel || (sel && !sel->tags[tsel])) { | ||||
| 		if((sel = getnext(clients))) { | ||||
| 			higher(sel); | ||||
| 			focus(sel); | ||||
| 		} | ||||
| 	} | ||||
| 	drawstatus(); | ||||
| } | ||||
|  | ||||
							
								
								
									
										171
									
								
								tag.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								tag.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | ||||
| /* | ||||
|  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | ||||
|  * See LICENSE file for license details. | ||||
|  */ | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <X11/Xatom.h> | ||||
| #include <X11/Xutil.h> | ||||
|  | ||||
| #include "dwm.h" | ||||
|  | ||||
| static Rule rule[] = { | ||||
| 	/* class			instance	tags						dofloat */ | ||||
| 	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False }, | ||||
| }; | ||||
|  | ||||
| void (*arrange)(Arg *) = dotile; | ||||
|  | ||||
| Client * | ||||
| getnext(Client *c) | ||||
| { | ||||
| 	for(; c && !c->tags[tsel]; c = c->next); | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| void | ||||
| settags(Client *c) | ||||
| { | ||||
| 	XClassHint ch; | ||||
| 	static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; | ||||
| 	unsigned int i, j; | ||||
| 	Bool matched = False; | ||||
|  | ||||
| 	if(!len) { | ||||
| 		c->tags[tsel] = tags[tsel]; | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if(XGetClassHint(dpy, c->win, &ch)) { | ||||
| 		if(ch.res_class && ch.res_name) { | ||||
| 			for(i = 0; i < len; i++) | ||||
| 				if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) | ||||
| 					&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) | ||||
| 				{ | ||||
| 					for(j = 0; j < TLast; j++) | ||||
| 						c->tags[j] = rule[i].tags[j]; | ||||
| 					c->dofloat = rule[i].dofloat; | ||||
| 					matched = True; | ||||
| 					break; | ||||
| 				} | ||||
| 		} | ||||
| 		if(ch.res_class) | ||||
| 			XFree(ch.res_class); | ||||
| 		if(ch.res_name) | ||||
| 			XFree(ch.res_name); | ||||
| 	} | ||||
|  | ||||
| 	if(!matched) | ||||
| 		c->tags[tsel] = tags[tsel]; | ||||
| } | ||||
|  | ||||
| void | ||||
| view(Arg *arg) | ||||
| { | ||||
| 	tsel = arg->i; | ||||
| 	arrange(NULL); | ||||
| 	drawall(); | ||||
| } | ||||
|  | ||||
| void | ||||
| dofloat(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
|  | ||||
| 	arrange = dofloat; | ||||
| 	for(c = clients; c; c = c->next) { | ||||
| 		if(c->tags[tsel]) | ||||
| 			resize(c, True); | ||||
| 		else | ||||
| 			ban(c); | ||||
| 	} | ||||
| 	if(sel && !sel->tags[tsel]) { | ||||
| 		if((sel = getnext(clients))) { | ||||
| 			higher(sel); | ||||
| 			focus(sel); | ||||
| 		} | ||||
| 	} | ||||
| 	drawall(); | ||||
| } | ||||
|  | ||||
| void | ||||
| dotile(Arg *arg) | ||||
| { | ||||
| 	Client *c; | ||||
| 	int n, i, w, h; | ||||
|  | ||||
| 	w = sw - mw; | ||||
| 	arrange = dotile; | ||||
| 	for(n = 0, c = clients; c; c = c->next) | ||||
| 		if(c->tags[tsel] && !c->dofloat) | ||||
| 			n++; | ||||
|  | ||||
| 	if(n > 1) | ||||
| 		h = (sh - bh) / (n - 1); | ||||
| 	else | ||||
| 		h = sh - bh; | ||||
|  | ||||
| 	for(i = 0, c = clients; c; c = c->next) { | ||||
| 		if(c->tags[tsel]) { | ||||
| 			if(c->dofloat) { | ||||
| 				higher(c); | ||||
| 				resize(c, True); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if(n == 1) { | ||||
| 				c->x = sx; | ||||
| 				c->y = sy + bh; | ||||
| 				c->w = sw - 2 * c->border; | ||||
| 				c->h = sh - 2 * c->border - bh; | ||||
| 			} | ||||
| 			else if(i == 0) { | ||||
| 				c->x = sx; | ||||
| 				c->y = sy + bh; | ||||
| 				c->w = mw - 2 * c->border; | ||||
| 				c->h = sh - 2 * c->border - bh; | ||||
| 			} | ||||
| 			else { | ||||
| 				c->x = sx + mw; | ||||
| 				c->y = sy + (i - 1) * h + bh; | ||||
| 				c->w = w - 2 * c->border; | ||||
| 				c->h = h - 2 * c->border; | ||||
| 			} | ||||
| 			resize(c, False); | ||||
| 			i++; | ||||
| 		} | ||||
| 		else | ||||
| 			ban(c); | ||||
| 	} | ||||
| 	if(!sel || (sel && !sel->tags[tsel])) { | ||||
| 		if((sel = getnext(clients))) { | ||||
| 			higher(sel); | ||||
| 			focus(sel); | ||||
| 		} | ||||
| 	} | ||||
| 	drawall(); | ||||
| } | ||||
|  | ||||
| void | ||||
| appendtag(Arg *arg) | ||||
| { | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	sel->tags[arg->i] = tags[arg->i]; | ||||
| 	arrange(NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| replacetag(Arg *arg) | ||||
| { | ||||
| 	int i; | ||||
| 	if(!sel) | ||||
| 		return; | ||||
|  | ||||
| 	for(i = 0; i < TLast; i++) | ||||
| 		sel->tags[i] = NULL; | ||||
| 	appendtag(arg); | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user