rearranged several stuff
This commit is contained in:
		
							parent
							
								
									c0705eeb65
								
							
						
					
					
						commit
						dba23062ba
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -3,7 +3,7 @@ | |||||||
| 
 | 
 | ||||||
| include config.mk | 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} | OBJ = ${SRC:.c=.o} | ||||||
| MAN1 = dwm.1  | MAN1 = dwm.1  | ||||||
| BIN = dwm | BIN = dwm | ||||||
|  | |||||||
							
								
								
									
										145
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								client.c
									
									
									
									
									
								
							| @ -11,18 +11,6 @@ | |||||||
| 
 | 
 | ||||||
| #include "dwm.h" | #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 | void | ||||||
| ban(Client *c) | ban(Client *c) | ||||||
| { | { | ||||||
| @ -31,7 +19,7 @@ ban(Client *c) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| resize_title(Client *c) | resizetitle(Client *c) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
| 
 | 
 | ||||||
| @ -72,7 +60,7 @@ settitle(Client *c) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	XFree(name.value); | 	XFree(name.value); | ||||||
| 	resize_title(c); | 	resizetitle(c); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -143,42 +131,6 @@ focus(Client *c) | |||||||
| 	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); | 	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 | void | ||||||
| manage(Window w, XWindowAttributes *wa) | manage(Window w, XWindowAttributes *wa) | ||||||
| { | { | ||||||
| @ -196,7 +148,7 @@ manage(Window w, XWindowAttributes *wa) | |||||||
| 	c->h = wa->height; | 	c->h = wa->height; | ||||||
| 	c->th = bh; | 	c->th = bh; | ||||||
| 	c->border = 1; | 	c->border = 1; | ||||||
| 	c->proto = proto(c->win); | 	c->proto = getproto(c->win); | ||||||
| 	setsize(c); | 	setsize(c); | ||||||
| 	XSelectInput(dpy, c->win, | 	XSelectInput(dpy, c->win, | ||||||
| 			StructureNotifyMask | PropertyChangeMask | EnterWindowMask); | 			StructureNotifyMask | PropertyChangeMask | EnterWindowMask); | ||||||
| @ -211,7 +163,7 @@ manage(Window w, XWindowAttributes *wa) | |||||||
| 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); | 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); | ||||||
| 
 | 
 | ||||||
| 	settitle(c); | 	settitle(c); | ||||||
| 	init_tags(c); | 	settags(c); | ||||||
| 
 | 
 | ||||||
| 	for(l = &clients; *l; l = &(*l)->next); | 	for(l = &clients; *l; l = &(*l)->next); | ||||||
| 	c->next = *l; /* *l == nil */ | 	c->next = *l; /* *l == nil */ | ||||||
| @ -224,8 +176,8 @@ manage(Window w, XWindowAttributes *wa) | |||||||
| 	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, | 	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, | ||||||
| 			GrabModeAsync, GrabModeSync, None, None); | 			GrabModeAsync, GrabModeSync, None, None); | ||||||
| 
 | 
 | ||||||
| 	if(!c->floating) | 	if(!c->dofloat) | ||||||
| 		c->floating = trans | 		c->dofloat = trans | ||||||
| 			|| ((c->maxw == c->minw) && (c->maxh == c->minh)); | 			|| ((c->maxw == c->minw) && (c->maxh == c->minh)); | ||||||
| 
 | 
 | ||||||
| 	arrange(NULL); | 	arrange(NULL); | ||||||
| @ -321,7 +273,7 @@ resize(Client *c, Bool inc) | |||||||
| 		c->w = c->maxw; | 		c->w = c->maxw; | ||||||
| 	if(c->maxh && c->h > c->maxh) | 	if(c->maxh && c->h > c->maxh) | ||||||
| 		c->h = c->maxh; | 		c->h = c->maxh; | ||||||
| 	resize_title(c); | 	resizetitle(c); | ||||||
| 	XSetWindowBorderWidth(dpy, c->win, 1); | 	XSetWindowBorderWidth(dpy, c->win, 1); | ||||||
| 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); | 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); | ||||||
| 	e.type = ConfigureNotify; | 	e.type = ConfigureNotify; | ||||||
| @ -339,7 +291,7 @@ resize(Client *c, Bool inc) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int | static int | ||||||
| dummy_xerror(Display *dsply, XErrorEvent *err) | xerrordummy(Display *dsply, XErrorEvent *ee) | ||||||
| { | { | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| @ -350,7 +302,7 @@ unmanage(Client *c) | |||||||
| 	Client **l; | 	Client **l; | ||||||
| 
 | 
 | ||||||
| 	XGrabServer(dpy); | 	XGrabServer(dpy); | ||||||
| 	XSetErrorHandler(dummy_xerror); | 	XSetErrorHandler(xerrordummy); | ||||||
| 
 | 
 | ||||||
| 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win); | 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win); | ||||||
| 	XDestroyWindow(dpy, c->title); | 	XDestroyWindow(dpy, c->title); | ||||||
| @ -374,7 +326,7 @@ unmanage(Client *c) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Client * | Client * | ||||||
| gettitle(Window w) | getctitle(Window w) | ||||||
| { | { | ||||||
| 	Client *c; | 	Client *c; | ||||||
| 	for(c = clients; c; c = c->next) | 	for(c = clients; c; c = c->next) | ||||||
| @ -392,3 +344,80 @@ getclient(Window w) | |||||||
| 			return c; | 			return c; | ||||||
| 	return NULL; | 	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" | #include "dwm.h" | ||||||
| 
 | 
 | ||||||
|  | void | ||||||
|  | drawall() | ||||||
|  | { | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	for(c = clients; c; c = getnext(c->next)) | ||||||
|  | 		drawtitle(c); | ||||||
|  | 	drawstatus(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| drawstatus() | drawstatus() | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
|  | 	Bool istile = arrange == dotile; | ||||||
| 
 | 
 | ||||||
| 	dc.x = dc.y = 0; | 	dc.x = dc.y = 0; | ||||||
| 	dc.w = bw; | 	dc.w = bw; | ||||||
| 	drawtext(NULL, False, False); | 	drawtext(NULL, !istile, False); | ||||||
| 
 | 
 | ||||||
| 	if(arrange == floating) { | 	dc.w = 0; | ||||||
| 		dc.w = textw("~"); |  | ||||||
| 		drawtext("~", False, False); |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 		dc.w = 0; |  | ||||||
| 	for(i = 0; i < TLast; i++) { | 	for(i = 0; i < TLast; i++) { | ||||||
| 		dc.x += dc.w; | 		dc.x += dc.w; | ||||||
| 		dc.w = textw(tags[i]); | 		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) { | 	if(sel) { | ||||||
| 		dc.x += dc.w; | 		dc.x += dc.w; | ||||||
| 		dc.w = textw(sel->name); | 		dc.w = textw(sel->name); | ||||||
| 		drawtext(sel->name, True, True); | 		drawtext(sel->name, istile, True); | ||||||
| 	} | 	} | ||||||
| 	dc.w = textw(stext); | 	dc.w = textw(stext); | ||||||
| 	dc.x = bx + bw - dc.w; | 	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); | 	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0); | ||||||
| 	XFlush(dpy); | 	XFlush(dpy); | ||||||
| @ -47,6 +56,8 @@ void | |||||||
| drawtitle(Client *c) | drawtitle(Client *c) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
|  | 	Bool istile = arrange == dotile; | ||||||
|  | 
 | ||||||
| 	if(c == sel) { | 	if(c == sel) { | ||||||
| 		drawstatus(); | 		drawstatus(); | ||||||
| 		XUnmapWindow(dpy, c->title); | 		XUnmapWindow(dpy, c->title); | ||||||
| @ -64,12 +75,12 @@ drawtitle(Client *c) | |||||||
| 		if(c->tags[i]) { | 		if(c->tags[i]) { | ||||||
| 			dc.x += dc.w; | 			dc.x += dc.w; | ||||||
| 			dc.w = textw(c->tags[i]); | 			dc.w = textw(c->tags[i]); | ||||||
| 			drawtext(c->tags[i], False, True); | 			drawtext(c->tags[i], !istile, True); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	dc.x += dc.w; | 	dc.x += dc.w; | ||||||
| 	dc.w = textw(c->name); | 	dc.w = textw(c->name); | ||||||
| 	drawtext(c->name, False, True); | 	drawtext(c->name, !istile, True); | ||||||
| 	XCopyArea(dpy, dc.drawable, c->title, dc.gc, | 	XCopyArea(dpy, dc.drawable, c->title, dc.gc, | ||||||
| 			0, 0, c->tw, c->th, 0, 0); | 			0, 0, c->tw, c->th, 0, 0); | ||||||
| 	XFlush(dpy); | 	XFlush(dpy); | ||||||
| @ -215,7 +226,7 @@ setfont(const char *fontstr) | |||||||
| 		if (!dc.font.xfont) | 		if (!dc.font.xfont) | ||||||
| 			dc.font.xfont = XLoadQueryFont(dpy, "fixed"); | 			dc.font.xfont = XLoadQueryFont(dpy, "fixed"); | ||||||
| 		if (!dc.font.xfont) | 		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.ascent = dc.font.xfont->ascent; | ||||||
| 		dc.font.descent = dc.font.xfont->descent; | 		dc.font.descent = dc.font.xfont->descent; | ||||||
| 	} | 	} | ||||||
|  | |||||||
							
								
								
									
										36
									
								
								dwm.h
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								dwm.h
									
									
									
									
									
								
							| @ -66,7 +66,7 @@ struct Client { | |||||||
| 	int grav; | 	int grav; | ||||||
| 	unsigned int border; | 	unsigned int border; | ||||||
| 	long flags;  | 	long flags;  | ||||||
| 	Bool floating; | 	Bool dofloat; | ||||||
| 	Window win; | 	Window win; | ||||||
| 	Window title; | 	Window title; | ||||||
| 	Client *next; | 	Client *next; | ||||||
| @ -77,7 +77,7 @@ struct Rule { | |||||||
| 	const char *class; | 	const char *class; | ||||||
| 	const char *instance; | 	const char *instance; | ||||||
| 	char *tags[TLast]; | 	char *tags[TLast]; | ||||||
| 	Bool floating; | 	Bool dofloat; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct Key { | struct Key { | ||||||
| @ -103,6 +103,7 @@ extern DC dc; | |||||||
| extern Client *clients, *sel; | extern Client *clients, *sel; | ||||||
| 
 | 
 | ||||||
| /* client.c */ | /* client.c */ | ||||||
|  | extern void ban(Client *c); | ||||||
| extern void manage(Window w, XWindowAttributes *wa); | extern void manage(Window w, XWindowAttributes *wa); | ||||||
| extern void unmanage(Client *c); | extern void unmanage(Client *c); | ||||||
| extern Client *getclient(Window w); | extern Client *getclient(Window w); | ||||||
| @ -110,14 +111,18 @@ extern void focus(Client *c); | |||||||
| extern void settitle(Client *c); | extern void settitle(Client *c); | ||||||
| extern void resize(Client *c, Bool inc); | extern void resize(Client *c, Bool inc); | ||||||
| extern void setsize(Client *c); | extern void setsize(Client *c); | ||||||
| extern Client *gettitle(Window w); | extern Client *getctitle(Window w); | ||||||
| extern void higher(Client *c); | extern void higher(Client *c); | ||||||
| extern void lower(Client *c); | extern void lower(Client *c); | ||||||
| extern void gravitate(Client *c, Bool invert); | extern void gravitate(Client *c, Bool invert); | ||||||
| extern void ban(Client *c); | extern void zoom(Arg *arg); | ||||||
| extern Client *getnext(Client *c); | extern void maximize(Arg *arg); | ||||||
|  | extern void focusprev(Arg *arg); | ||||||
|  | extern void focusnext(Arg *arg); | ||||||
|  | extern void killclient(Arg *arg); | ||||||
| 
 | 
 | ||||||
| /* draw.c */ | /* draw.c */ | ||||||
|  | extern void drawall(); | ||||||
| extern void drawstatus(); | extern void drawstatus(); | ||||||
| extern void drawtitle(Client *c); | extern void drawtitle(Client *c); | ||||||
| extern void drawtext(const char *text, Bool invert, Bool border); | 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 textw(char *text); | ||||||
| extern unsigned int texth(void); | extern unsigned int texth(void); | ||||||
| 
 | 
 | ||||||
| /* key.c */ | /* event.c */ | ||||||
| extern void grabkeys(); | extern void grabkeys(); | ||||||
| extern void keypress(XEvent *e); |  | ||||||
| 
 | 
 | ||||||
| /* main.c */ | /* 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 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 */ | /* tag.c */ | ||||||
| extern void floating(Arg *arg); | extern Client *getnext(Client *c); | ||||||
| extern void tiling(Arg *arg); | extern void settags(Client *c); | ||||||
|  | extern void dofloat(Arg *arg); | ||||||
|  | extern void dotile(Arg *arg); | ||||||
| extern void view(Arg *arg); | extern void view(Arg *arg); | ||||||
|  | extern void appendtag(Arg *arg); | ||||||
|  | extern void replacetag(Arg *arg); | ||||||
| 
 | 
 | ||||||
| /* util.c */ | /* util.c */ | ||||||
| extern void error(const char *errstr, ...); | extern void eprint(const char *errstr, ...); | ||||||
| extern void *emallocz(unsigned int size); | extern void *emallocz(unsigned int size); | ||||||
| extern void spawn(Arg *arg); | extern void spawn(Arg *arg); | ||||||
|  | |||||||
							
								
								
									
										89
									
								
								event.c
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								event.c
									
									
									
									
									
								
							| @ -16,6 +16,44 @@ | |||||||
| #define ButtonMask      (ButtonPressMask | ButtonReleaseMask) | #define ButtonMask      (ButtonPressMask | ButtonReleaseMask) | ||||||
| #define MouseMask       (ButtonMask | PointerMotionMask) | #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 */ | /* local functions */ | ||||||
| static void buttonpress(XEvent *e); | static void buttonpress(XEvent *e); | ||||||
| static void configurerequest(XEvent *e); | static void configurerequest(XEvent *e); | ||||||
| @ -23,6 +61,7 @@ static void destroynotify(XEvent *e); | |||||||
| static void enternotify(XEvent *e); | static void enternotify(XEvent *e); | ||||||
| static void leavenotify(XEvent *e); | static void leavenotify(XEvent *e); | ||||||
| static void expose(XEvent *e); | static void expose(XEvent *e); | ||||||
|  | static void keypress(XEvent *e); | ||||||
| static void maprequest(XEvent *e); | static void maprequest(XEvent *e); | ||||||
| static void propertynotify(XEvent *e); | static void propertynotify(XEvent *e); | ||||||
| static void unmapnotify(XEvent *e); | static void unmapnotify(XEvent *e); | ||||||
| @ -40,8 +79,40 @@ void (*handler[LASTEvent]) (XEvent *) = { | |||||||
| 	[UnmapNotify] = unmapnotify | 	[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 | 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; | 	XEvent ev; | ||||||
| 	int ocx, ocy; | 	int ocx, ocy; | ||||||
| @ -75,7 +146,7 @@ mresize(Client *c) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| mmove(Client *c) | movemouse(Client *c) | ||||||
| { | { | ||||||
| 	XEvent ev; | 	XEvent ev; | ||||||
| 	int x1, y1, ocx, ocy, di; | 	int x1, y1, ocx, ocy, di; | ||||||
| @ -117,7 +188,7 @@ buttonpress(XEvent *e) | |||||||
| 	Client *c; | 	Client *c; | ||||||
| 
 | 
 | ||||||
| 	if(barwin == ev->window) { | 	if(barwin == ev->window) { | ||||||
| 		x = (arrange == floating) ? textw("~") : 0; | 		x = (arrange == dofloat) ? textw("~") : 0; | ||||||
| 		for(a.i = 0; a.i < TLast; a.i++) { | 		for(a.i = 0; a.i < TLast; a.i++) { | ||||||
| 			x += textw(tags[a.i]); | 			x += textw(tags[a.i]); | ||||||
| 			if(ev->x < x) { | 			if(ev->x < x) { | ||||||
| @ -127,20 +198,20 @@ buttonpress(XEvent *e) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else if((c = getclient(ev->window))) { | 	else if((c = getclient(ev->window))) { | ||||||
| 		if(arrange == tiling && !c->floating) | 		if(arrange == dotile && !c->dofloat) | ||||||
| 			return; | 			return; | ||||||
| 		higher(c); | 		higher(c); | ||||||
| 		switch(ev->button) { | 		switch(ev->button) { | ||||||
| 		default: | 		default: | ||||||
| 			break; | 			break; | ||||||
| 		case Button1: | 		case Button1: | ||||||
| 			mmove(c); | 			movemouse(c); | ||||||
| 			break; | 			break; | ||||||
| 		case Button2: | 		case Button2: | ||||||
| 			lower(c); | 			lower(c); | ||||||
| 			break; | 			break; | ||||||
| 		case Button3: | 		case Button3: | ||||||
| 			mresize(c); | 			resizemouse(c); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -226,7 +297,7 @@ expose(XEvent *e) | |||||||
| 	if(ev->count == 0) { | 	if(ev->count == 0) { | ||||||
| 		if(barwin == ev->window) | 		if(barwin == ev->window) | ||||||
| 			drawstatus(); | 			drawstatus(); | ||||||
| 		else if((c = gettitle(ev->window))) | 		else if((c = getctitle(ev->window))) | ||||||
| 			drawtitle(c); | 			drawtitle(c); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -262,14 +333,14 @@ propertynotify(XEvent *e) | |||||||
| 
 | 
 | ||||||
| 	if((c = getclient(ev->window))) { | 	if((c = getclient(ev->window))) { | ||||||
| 		if(ev->atom == wm_atom[WMProtocols]) { | 		if(ev->atom == wm_atom[WMProtocols]) { | ||||||
| 			c->proto = proto(c->win); | 			c->proto = getproto(c->win); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		switch (ev->atom) { | 		switch (ev->atom) { | ||||||
| 			default: break; | 			default: break; | ||||||
| 			case XA_WM_TRANSIENT_FOR: | 			case XA_WM_TRANSIENT_FOR: | ||||||
| 				XGetTransientForHint(dpy, c->win, &trans); | 				XGetTransientForHint(dpy, c->win, &trans); | ||||||
| 				if(!c->floating && (c->floating = (trans != 0))) | 				if(!c->dofloat && (c->dofloat = (trans != 0))) | ||||||
| 					arrange(NULL); | 					arrange(NULL); | ||||||
| 				break; | 				break; | ||||||
| 			case XA_WM_NORMAL_HINTS: | 			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 *clients = NULL; | ||||||
| Client *sel = NULL; | Client *sel = NULL; | ||||||
| 
 | 
 | ||||||
| static Bool other_wm_running; | static Bool otherwm; | ||||||
| static const char version[] = | static const char version[] = | ||||||
| 	"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; | 	"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; | ||||||
| static int (*x_xerror) (Display *, XErrorEvent *); | static int (*xerrorxlib)(Display *, XErrorEvent *); | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| usage() {	error("usage: dwm [-v]\n"); } | usage() {	eprint("usage: dwm [-v]\n"); } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| scan_wins() | scan() | ||||||
| { | { | ||||||
| 	unsigned int i, num; | 	unsigned int i, num; | ||||||
| 	Window *wins; | 	Window *wins; | ||||||
| @ -73,6 +73,22 @@ scan_wins() | |||||||
| 		XFree(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 | static int | ||||||
| win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) | 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 | int | ||||||
| proto(Window w) | getproto(Window w) | ||||||
| { | { | ||||||
| 	unsigned char *protocols; | 	unsigned char *protocols; | ||||||
| 	long res; | 	long res; | ||||||
| @ -128,6 +144,17 @@ sendevent(Window w, Atom a, long value) | |||||||
| 	XFlush(dpy); | 	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 |  * There's no way to check accesses to destroyed windows, thus | ||||||
|  * those cases are ignored (especially on UnmapNotify's). |  * those cases are ignored (especially on UnmapNotify's). | ||||||
| @ -135,52 +162,25 @@ sendevent(Window w, Atom a, long value) | |||||||
|  * calls exit(). |  * calls exit(). | ||||||
|  */ |  */ | ||||||
| int | int | ||||||
| xerror(Display *dpy, XErrorEvent *error) | xerror(Display *dpy, XErrorEvent *ee) | ||||||
| { | { | ||||||
| 	if(error->error_code == BadWindow | 	if(ee->error_code == BadWindow | ||||||
| 			|| (error->request_code == X_SetInputFocus | 			|| (ee->request_code == X_SetInputFocus | ||||||
| 				&& error->error_code == BadMatch) | 				&& ee->error_code == BadMatch) | ||||||
| 			|| (error->request_code == X_PolyText8 | 			|| (ee->request_code == X_PolyText8 | ||||||
| 				&& error->error_code == BadDrawable) | 				&& ee->error_code == BadDrawable) | ||||||
| 			|| (error->request_code == X_PolyFillRectangle | 			|| (ee->request_code == X_PolyFillRectangle | ||||||
| 				&& error->error_code == BadDrawable) | 				&& ee->error_code == BadDrawable) | ||||||
| 			|| (error->request_code == X_PolySegment | 			|| (ee->request_code == X_PolySegment | ||||||
| 				&& error->error_code == BadDrawable) | 				&& ee->error_code == BadDrawable) | ||||||
| 			|| (error->request_code == X_ConfigureWindow | 			|| (ee->request_code == X_ConfigureWindow | ||||||
| 				&& error->error_code == BadMatch) | 				&& ee->error_code == BadMatch) | ||||||
| 			|| (error->request_code == X_GrabKey | 			|| (ee->request_code == X_GrabKey | ||||||
| 				&& error->error_code == BadAccess)) | 				&& ee->error_code == BadAccess)) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", | 	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", | ||||||
| 			error->request_code, error->error_code); | 			ee->request_code, ee->error_code); | ||||||
| 	return x_xerror(dpy, error); /* may call exit() */ | 	return xerrorxlib(dpy, ee); /* 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; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int | ||||||
| @ -208,23 +208,23 @@ main(int argc, char *argv[]) | |||||||
| 
 | 
 | ||||||
| 	dpy = XOpenDisplay(0); | 	dpy = XOpenDisplay(0); | ||||||
| 	if(!dpy) | 	if(!dpy) | ||||||
| 		error("dwm: cannot connect X server\n"); | 		eprint("dwm: cannot connect X server\n"); | ||||||
| 
 | 
 | ||||||
| 	screen = DefaultScreen(dpy); | 	screen = DefaultScreen(dpy); | ||||||
| 	root = RootWindow(dpy, screen); | 	root = RootWindow(dpy, screen); | ||||||
| 
 | 
 | ||||||
| 	/* check if another WM is already running */ | 	/* check if another WM is already running */ | ||||||
| 	other_wm_running = False; | 	otherwm = False; | ||||||
| 	XSetErrorHandler(startup_xerror); | 	XSetErrorHandler(xerrorstart); | ||||||
| 	/* this causes an error if some other WM is running */ | 	/* this causes an error if some other WM is running */ | ||||||
| 	XSelectInput(dpy, root, SubstructureRedirectMask); | 	XSelectInput(dpy, root, SubstructureRedirectMask); | ||||||
| 	XFlush(dpy); | 	XFlush(dpy); | ||||||
| 
 | 
 | ||||||
| 	if(other_wm_running) | 	if(otherwm) | ||||||
| 		error("dwm: another window manager is already running\n"); | 		eprint("dwm: another window manager is already running\n"); | ||||||
| 
 | 
 | ||||||
| 	XSetErrorHandler(0); | 	XSetErrorHandler(0); | ||||||
| 	x_xerror = XSetErrorHandler(xerror); | 	xerrorxlib = XSetErrorHandler(xerror); | ||||||
| 
 | 
 | ||||||
| 	/* init atoms */ | 	/* init atoms */ | ||||||
| 	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | 	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | ||||||
| @ -278,7 +278,7 @@ main(int argc, char *argv[]) | |||||||
| 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); | 	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); | ||||||
| 
 | 
 | ||||||
| 	strcpy(stext, "dwm-"VERSION); | 	strcpy(stext, "dwm-"VERSION); | ||||||
| 	scan_wins(); | 	scan(); | ||||||
| 
 | 
 | ||||||
| 	/* main event loop, reads status text from stdin as well */ | 	/* main event loop, reads status text from stdin as well */ | ||||||
| Mainloop: | Mainloop: | ||||||
| @ -292,7 +292,7 @@ Mainloop: | |||||||
| 		if(i == -1 && errno == EINTR) | 		if(i == -1 && errno == EINTR) | ||||||
| 			continue; | 			continue; | ||||||
| 		if(i < 0) | 		if(i < 0) | ||||||
| 			error("select failed\n"); | 			eprint("select failed\n"); | ||||||
| 		else if(i > 0) { | 		else if(i > 0) { | ||||||
| 			if(FD_ISSET(ConnectionNumber(dpy), &rd)) { | 			if(FD_ISSET(ConnectionNumber(dpy), &rd)) { | ||||||
| 				while(XPending(dpy)) { | 				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); | ||||||
|  | } | ||||||
|  | 
 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user