dwm-meillo

changeset 75:f08271b7cb20

rearranged several stuff
author Anselm R. Garbe <garbeam@wmii.de>
date Sat, 15 Jul 2006 16:30:50 +0200
parents 5370ef170cc9
children 4bd49f404f10
files Makefile client.c draw.c dwm.h event.c main.c tag.c util.c
diffstat 10 files changed, 442 insertions(+), 444 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Fri Jul 14 22:54:09 2006 +0200
     1.2 +++ b/Makefile	Sat Jul 15 16:30:50 2006 +0200
     1.3 @@ -3,7 +3,7 @@
     1.4  
     1.5  include config.mk
     1.6  
     1.7 -SRC = client.c draw.c event.c key.c main.c screen.c util.c
     1.8 +SRC = client.c draw.c event.c main.c tag.c util.c
     1.9  OBJ = ${SRC:.c=.o}
    1.10  MAN1 = dwm.1 
    1.11  BIN = dwm
     2.1 --- a/client.c	Fri Jul 14 22:54:09 2006 +0200
     2.2 +++ b/client.c	Sat Jul 15 16:30:50 2006 +0200
     2.3 @@ -11,18 +11,6 @@
     2.4  
     2.5  #include "dwm.h"
     2.6  
     2.7 -static Rule rule[] = {
     2.8 -	/* class			instance	tags						floating */
     2.9 -	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
    2.10 -};
    2.11 -
    2.12 -Client *
    2.13 -getnext(Client *c)
    2.14 -{
    2.15 -	for(; c && !c->tags[tsel]; c = c->next);
    2.16 -	return c;
    2.17 -}
    2.18 -
    2.19  void
    2.20  ban(Client *c)
    2.21  {
    2.22 @@ -31,7 +19,7 @@
    2.23  }
    2.24  
    2.25  static void
    2.26 -resize_title(Client *c)
    2.27 +resizetitle(Client *c)
    2.28  {
    2.29  	int i;
    2.30  
    2.31 @@ -72,7 +60,7 @@
    2.32  		}
    2.33  	}
    2.34  	XFree(name.value);
    2.35 -	resize_title(c);
    2.36 +	resizetitle(c);
    2.37  }
    2.38  
    2.39  void
    2.40 @@ -143,42 +131,6 @@
    2.41  	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
    2.42  }
    2.43  
    2.44 -static void
    2.45 -init_tags(Client *c)
    2.46 -{
    2.47 -	XClassHint ch;
    2.48 -	static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
    2.49 -	unsigned int i, j;
    2.50 -	Bool matched = False;
    2.51 -
    2.52 -	if(!len) {
    2.53 -		c->tags[tsel] = tags[tsel];
    2.54 -		return;
    2.55 -	}
    2.56 -
    2.57 -	if(XGetClassHint(dpy, c->win, &ch)) {
    2.58 -		if(ch.res_class && ch.res_name) {
    2.59 -			for(i = 0; i < len; i++)
    2.60 -				if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
    2.61 -					&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
    2.62 -				{
    2.63 -					for(j = 0; j < TLast; j++)
    2.64 -						c->tags[j] = rule[i].tags[j];
    2.65 -					c->floating = rule[i].floating;
    2.66 -					matched = True;
    2.67 -					break;
    2.68 -				}
    2.69 -		}
    2.70 -		if(ch.res_class)
    2.71 -			XFree(ch.res_class);
    2.72 -		if(ch.res_name)
    2.73 -			XFree(ch.res_name);
    2.74 -	}
    2.75 -
    2.76 -	if(!matched)
    2.77 -		c->tags[tsel] = tags[tsel];
    2.78 -}
    2.79 -
    2.80  void
    2.81  manage(Window w, XWindowAttributes *wa)
    2.82  {
    2.83 @@ -196,7 +148,7 @@
    2.84  	c->h = wa->height;
    2.85  	c->th = bh;
    2.86  	c->border = 1;
    2.87 -	c->proto = proto(c->win);
    2.88 +	c->proto = getproto(c->win);
    2.89  	setsize(c);
    2.90  	XSelectInput(dpy, c->win,
    2.91  			StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
    2.92 @@ -211,7 +163,7 @@
    2.93  			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
    2.94  
    2.95  	settitle(c);
    2.96 -	init_tags(c);
    2.97 +	settags(c);
    2.98  
    2.99  	for(l = &clients; *l; l = &(*l)->next);
   2.100  	c->next = *l; /* *l == nil */
   2.101 @@ -224,8 +176,8 @@
   2.102  	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
   2.103  			GrabModeAsync, GrabModeSync, None, None);
   2.104  
   2.105 -	if(!c->floating)
   2.106 -		c->floating = trans
   2.107 +	if(!c->dofloat)
   2.108 +		c->dofloat = trans
   2.109  			|| ((c->maxw == c->minw) && (c->maxh == c->minh));
   2.110  
   2.111  	arrange(NULL);
   2.112 @@ -321,7 +273,7 @@
   2.113  		c->w = c->maxw;
   2.114  	if(c->maxh && c->h > c->maxh)
   2.115  		c->h = c->maxh;
   2.116 -	resize_title(c);
   2.117 +	resizetitle(c);
   2.118  	XSetWindowBorderWidth(dpy, c->win, 1);
   2.119  	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
   2.120  	e.type = ConfigureNotify;
   2.121 @@ -339,7 +291,7 @@
   2.122  }
   2.123  
   2.124  static int
   2.125 -dummy_xerror(Display *dsply, XErrorEvent *err)
   2.126 +xerrordummy(Display *dsply, XErrorEvent *ee)
   2.127  {
   2.128  	return 0;
   2.129  }
   2.130 @@ -350,7 +302,7 @@
   2.131  	Client **l;
   2.132  
   2.133  	XGrabServer(dpy);
   2.134 -	XSetErrorHandler(dummy_xerror);
   2.135 +	XSetErrorHandler(xerrordummy);
   2.136  
   2.137  	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
   2.138  	XDestroyWindow(dpy, c->title);
   2.139 @@ -374,7 +326,7 @@
   2.140  }
   2.141  
   2.142  Client *
   2.143 -gettitle(Window w)
   2.144 +getctitle(Window w)
   2.145  {
   2.146  	Client *c;
   2.147  	for(c = clients; c; c = c->next)
   2.148 @@ -392,3 +344,80 @@
   2.149  			return c;
   2.150  	return NULL;
   2.151  }
   2.152 +
   2.153 +void
   2.154 +zoom(Arg *arg)
   2.155 +{
   2.156 +	Client **l, *c;
   2.157 +
   2.158 +	if(!sel)
   2.159 +		return;
   2.160 +
   2.161 +	if(sel == getnext(clients) && sel->next)  {
   2.162 +		if((c = getnext(sel->next)))
   2.163 +			sel = c;
   2.164 +	}
   2.165 +
   2.166 +	for(l = &clients; *l && *l != sel; l = &(*l)->next);
   2.167 +	*l = sel->next;
   2.168 +
   2.169 +	sel->next = clients; /* pop */
   2.170 +	clients = sel;
   2.171 +	arrange(NULL);
   2.172 +	focus(sel);
   2.173 +}
   2.174 +
   2.175 +void
   2.176 +maximize(Arg *arg)
   2.177 +{
   2.178 +	if(!sel)
   2.179 +		return;
   2.180 +	sel->x = sx;
   2.181 +	sel->y = sy + bh;
   2.182 +	sel->w = sw - 2 * sel->border;
   2.183 +	sel->h = sh - 2 * sel->border - bh;
   2.184 +	higher(sel);
   2.185 +	resize(sel, False);
   2.186 +}
   2.187 +
   2.188 +void
   2.189 +focusprev(Arg *arg)
   2.190 +{
   2.191 +	Client *c;
   2.192 +
   2.193 +	if(!sel)
   2.194 +		return;
   2.195 +
   2.196 +	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
   2.197 +		higher(c);
   2.198 +		focus(c);
   2.199 +	}
   2.200 +}
   2.201 +
   2.202 +void
   2.203 +focusnext(Arg *arg)
   2.204 +{
   2.205 +	Client *c;
   2.206 +   
   2.207 +	if(!sel)
   2.208 +		return;
   2.209 +
   2.210 +	if(!(c = getnext(sel->next)))
   2.211 +		c = getnext(clients);
   2.212 +	if(c) {
   2.213 +		higher(c);
   2.214 +		c->revert = sel;
   2.215 +		focus(c);
   2.216 +	}
   2.217 +}
   2.218 +
   2.219 +void
   2.220 +killclient(Arg *arg)
   2.221 +{
   2.222 +	if(!sel)
   2.223 +		return;
   2.224 +	if(sel->proto & WM_PROTOCOL_DELWIN)
   2.225 +		sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
   2.226 +	else
   2.227 +		XKillClient(dpy, sel->win);
   2.228 +}
     3.1 --- a/draw.c	Fri Jul 14 22:54:09 2006 +0200
     3.2 +++ b/draw.c	Sat Jul 15 16:30:50 2006 +0200
     3.3 @@ -11,33 +11,42 @@
     3.4  #include "dwm.h"
     3.5  
     3.6  void
     3.7 +drawall()
     3.8 +{
     3.9 +	Client *c;
    3.10 +
    3.11 +	for(c = clients; c; c = getnext(c->next))
    3.12 +		drawtitle(c);
    3.13 +	drawstatus();
    3.14 +}
    3.15 +
    3.16 +void
    3.17  drawstatus()
    3.18  {
    3.19  	int i;
    3.20 +	Bool istile = arrange == dotile;
    3.21  
    3.22  	dc.x = dc.y = 0;
    3.23  	dc.w = bw;
    3.24 -	drawtext(NULL, False, False);
    3.25 +	drawtext(NULL, !istile, False);
    3.26  
    3.27 -	if(arrange == floating) {
    3.28 -		dc.w = textw("~");
    3.29 -		drawtext("~", False, False);
    3.30 -	}
    3.31 -	else
    3.32 -		dc.w = 0;
    3.33 +	dc.w = 0;
    3.34  	for(i = 0; i < TLast; i++) {
    3.35  		dc.x += dc.w;
    3.36  		dc.w = textw(tags[i]);
    3.37 -		drawtext(tags[i], i == tsel, True);
    3.38 +		if(istile)
    3.39 +			drawtext(tags[i], (i == tsel), True);
    3.40 +		else
    3.41 +			drawtext(tags[i], (i != tsel), True);
    3.42  	}
    3.43  	if(sel) {
    3.44  		dc.x += dc.w;
    3.45  		dc.w = textw(sel->name);
    3.46 -		drawtext(sel->name, True, True);
    3.47 +		drawtext(sel->name, istile, True);
    3.48  	}
    3.49  	dc.w = textw(stext);
    3.50  	dc.x = bx + bw - dc.w;
    3.51 -	drawtext(stext, False, False);
    3.52 +	drawtext(stext, !istile, False);
    3.53  
    3.54  	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
    3.55  	XFlush(dpy);
    3.56 @@ -47,6 +56,8 @@
    3.57  drawtitle(Client *c)
    3.58  {
    3.59  	int i;
    3.60 +	Bool istile = arrange == dotile;
    3.61 +
    3.62  	if(c == sel) {
    3.63  		drawstatus();
    3.64  		XUnmapWindow(dpy, c->title);
    3.65 @@ -64,12 +75,12 @@
    3.66  		if(c->tags[i]) {
    3.67  			dc.x += dc.w;
    3.68  			dc.w = textw(c->tags[i]);
    3.69 -			drawtext(c->tags[i], False, True);
    3.70 +			drawtext(c->tags[i], !istile, True);
    3.71  		}
    3.72  	}
    3.73  	dc.x += dc.w;
    3.74  	dc.w = textw(c->name);
    3.75 -	drawtext(c->name, False, True);
    3.76 +	drawtext(c->name, !istile, True);
    3.77  	XCopyArea(dpy, dc.drawable, c->title, dc.gc,
    3.78  			0, 0, c->tw, c->th, 0, 0);
    3.79  	XFlush(dpy);
    3.80 @@ -215,7 +226,7 @@
    3.81  		if (!dc.font.xfont)
    3.82  			dc.font.xfont = XLoadQueryFont(dpy, "fixed");
    3.83  		if (!dc.font.xfont)
    3.84 -			error("error, cannot init 'fixed' font\n");
    3.85 +			eprint("error, cannot init 'fixed' font\n");
    3.86  		dc.font.ascent = dc.font.xfont->ascent;
    3.87  		dc.font.descent = dc.font.xfont->descent;
    3.88  	}
     4.1 --- a/dwm.h	Fri Jul 14 22:54:09 2006 +0200
     4.2 +++ b/dwm.h	Sat Jul 15 16:30:50 2006 +0200
     4.3 @@ -66,7 +66,7 @@
     4.4  	int grav;
     4.5  	unsigned int border;
     4.6  	long flags; 
     4.7 -	Bool floating;
     4.8 +	Bool dofloat;
     4.9  	Window win;
    4.10  	Window title;
    4.11  	Client *next;
    4.12 @@ -77,7 +77,7 @@
    4.13  	const char *class;
    4.14  	const char *instance;
    4.15  	char *tags[TLast];
    4.16 -	Bool floating;
    4.17 +	Bool dofloat;
    4.18  };
    4.19  
    4.20  struct Key {
    4.21 @@ -103,6 +103,7 @@
    4.22  extern Client *clients, *sel;
    4.23  
    4.24  /* client.c */
    4.25 +extern void ban(Client *c);
    4.26  extern void manage(Window w, XWindowAttributes *wa);
    4.27  extern void unmanage(Client *c);
    4.28  extern Client *getclient(Window w);
    4.29 @@ -110,14 +111,18 @@
    4.30  extern void settitle(Client *c);
    4.31  extern void resize(Client *c, Bool inc);
    4.32  extern void setsize(Client *c);
    4.33 -extern Client *gettitle(Window w);
    4.34 +extern Client *getctitle(Window w);
    4.35  extern void higher(Client *c);
    4.36  extern void lower(Client *c);
    4.37  extern void gravitate(Client *c, Bool invert);
    4.38 -extern void ban(Client *c);
    4.39 -extern Client *getnext(Client *c);
    4.40 +extern void zoom(Arg *arg);
    4.41 +extern void maximize(Arg *arg);
    4.42 +extern void focusprev(Arg *arg);
    4.43 +extern void focusnext(Arg *arg);
    4.44 +extern void killclient(Arg *arg);
    4.45  
    4.46  /* draw.c */
    4.47 +extern void drawall();
    4.48  extern void drawstatus();
    4.49  extern void drawtitle(Client *c);
    4.50  extern void drawtext(const char *text, Bool invert, Bool border);
    4.51 @@ -127,22 +132,25 @@
    4.52  extern unsigned int textw(char *text);
    4.53  extern unsigned int texth(void);
    4.54  
    4.55 -/* key.c */
    4.56 +/* event.c */
    4.57  extern void grabkeys();
    4.58 -extern void keypress(XEvent *e);
    4.59  
    4.60  /* main.c */
    4.61 -extern int xerror(Display *dsply, XErrorEvent *e);
    4.62 +extern void quit(Arg *arg);
    4.63 +extern int xerror(Display *dsply, XErrorEvent *ee);
    4.64  extern void sendevent(Window w, Atom a, long value);
    4.65 -extern int proto(Window w);
    4.66 -extern void quit(Arg *arg);
    4.67 +extern int getproto(Window w);
    4.68  
    4.69 -/* screen.c */
    4.70 -extern void floating(Arg *arg);
    4.71 -extern void tiling(Arg *arg);
    4.72 +/* tag.c */
    4.73 +extern Client *getnext(Client *c);
    4.74 +extern void settags(Client *c);
    4.75 +extern void dofloat(Arg *arg);
    4.76 +extern void dotile(Arg *arg);
    4.77  extern void view(Arg *arg);
    4.78 +extern void appendtag(Arg *arg);
    4.79 +extern void replacetag(Arg *arg);
    4.80  
    4.81  /* util.c */
    4.82 -extern void error(const char *errstr, ...);
    4.83 +extern void eprint(const char *errstr, ...);
    4.84  extern void *emallocz(unsigned int size);
    4.85  extern void spawn(Arg *arg);
     5.1 --- a/event.c	Fri Jul 14 22:54:09 2006 +0200
     5.2 +++ b/event.c	Sat Jul 15 16:30:50 2006 +0200
     5.3 @@ -16,6 +16,44 @@
     5.4  #define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
     5.5  #define MouseMask       (ButtonMask | PointerMotionMask)
     5.6  
     5.7 +/********** CUSTOMIZE **********/
     5.8 +
     5.9 +const char *term[] = { 
    5.10 +	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
    5.11 +	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
    5.12 +};
    5.13 +const char *browse[] = { "firefox", NULL };
    5.14 +const char *xlock[] = { "xlock", NULL };
    5.15 +
    5.16 +Key key[] = {
    5.17 +	/* modifier				key			function	arguments */
    5.18 +	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } },
    5.19 +	{ Mod1Mask,				XK_k,		focusprev,		{ 0 } },
    5.20 +	{ Mod1Mask,				XK_j,		focusnext,		{ 0 } }, 
    5.21 +	{ Mod1Mask,				XK_m,		maximize,		{ 0 } }, 
    5.22 +	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } }, 
    5.23 +	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } }, 
    5.24 +	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } }, 
    5.25 +	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } }, 
    5.26 +	{ Mod1Mask,				XK_space,	dotile,		{ 0 } }, 
    5.27 +	{ Mod1Mask|ShiftMask,	XK_space,	dofloat,	{ 0 } }, 
    5.28 +	{ Mod1Mask|ShiftMask,	XK_0,		replacetag,		{ .i = Tscratch } }, 
    5.29 +	{ Mod1Mask|ShiftMask,	XK_1,		replacetag,		{ .i = Tdev } }, 
    5.30 +	{ Mod1Mask|ShiftMask,	XK_2,		replacetag,		{ .i = Twww } }, 
    5.31 +	{ Mod1Mask|ShiftMask,	XK_3,		replacetag,		{ .i = Twork } }, 
    5.32 +	{ Mod1Mask|ShiftMask,	XK_c,		killclient,		{ 0 } }, 
    5.33 +	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } },
    5.34 +	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } },
    5.35 +	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } },
    5.36 +	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } },
    5.37 +	{ ControlMask,			XK_0,		appendtag,	{ .i = Tscratch } }, 
    5.38 +	{ ControlMask,			XK_1,		appendtag,	{ .i = Tdev } }, 
    5.39 +	{ ControlMask,			XK_2,		appendtag,	{ .i = Twww } }, 
    5.40 +	{ ControlMask,			XK_3,		appendtag,	{ .i = Twork } }, 
    5.41 +};
    5.42 +
    5.43 +/********** CUSTOMIZE **********/
    5.44 +
    5.45  /* local functions */
    5.46  static void buttonpress(XEvent *e);
    5.47  static void configurerequest(XEvent *e);
    5.48 @@ -23,6 +61,7 @@
    5.49  static void enternotify(XEvent *e);
    5.50  static void leavenotify(XEvent *e);
    5.51  static void expose(XEvent *e);
    5.52 +static void keypress(XEvent *e);
    5.53  static void maprequest(XEvent *e);
    5.54  static void propertynotify(XEvent *e);
    5.55  static void unmapnotify(XEvent *e);
    5.56 @@ -40,8 +79,40 @@
    5.57  	[UnmapNotify] = unmapnotify
    5.58  };
    5.59  
    5.60 +void
    5.61 +grabkeys()
    5.62 +{
    5.63 +	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
    5.64 +	unsigned int i;
    5.65 +	KeyCode code;
    5.66 +
    5.67 +	for(i = 0; i < len; i++) {
    5.68 +		code = XKeysymToKeycode(dpy, key[i].keysym);
    5.69 +		XUngrabKey(dpy, code, key[i].mod, root);
    5.70 +		XGrabKey(dpy, code, key[i].mod, root, True,
    5.71 +				GrabModeAsync, GrabModeAsync);
    5.72 +	}
    5.73 +}
    5.74 +
    5.75  static void
    5.76 -mresize(Client *c)
    5.77 +keypress(XEvent *e)
    5.78 +{
    5.79 +	XKeyEvent *ev = &e->xkey;
    5.80 +	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
    5.81 +	unsigned int i;
    5.82 +	KeySym keysym;
    5.83 +
    5.84 +	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
    5.85 +	for(i = 0; i < len; i++)
    5.86 +		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
    5.87 +			if(key[i].func)
    5.88 +				key[i].func(&key[i].arg);
    5.89 +			return;
    5.90 +		}
    5.91 +}
    5.92 +
    5.93 +static void
    5.94 +resizemouse(Client *c)
    5.95  {
    5.96  	XEvent ev;
    5.97  	int ocx, ocy;
    5.98 @@ -75,7 +146,7 @@
    5.99  }
   5.100  
   5.101  static void
   5.102 -mmove(Client *c)
   5.103 +movemouse(Client *c)
   5.104  {
   5.105  	XEvent ev;
   5.106  	int x1, y1, ocx, ocy, di;
   5.107 @@ -117,7 +188,7 @@
   5.108  	Client *c;
   5.109  
   5.110  	if(barwin == ev->window) {
   5.111 -		x = (arrange == floating) ? textw("~") : 0;
   5.112 +		x = (arrange == dofloat) ? textw("~") : 0;
   5.113  		for(a.i = 0; a.i < TLast; a.i++) {
   5.114  			x += textw(tags[a.i]);
   5.115  			if(ev->x < x) {
   5.116 @@ -127,20 +198,20 @@
   5.117  		}
   5.118  	}
   5.119  	else if((c = getclient(ev->window))) {
   5.120 -		if(arrange == tiling && !c->floating)
   5.121 +		if(arrange == dotile && !c->dofloat)
   5.122  			return;
   5.123  		higher(c);
   5.124  		switch(ev->button) {
   5.125  		default:
   5.126  			break;
   5.127  		case Button1:
   5.128 -			mmove(c);
   5.129 +			movemouse(c);
   5.130  			break;
   5.131  		case Button2:
   5.132  			lower(c);
   5.133  			break;
   5.134  		case Button3:
   5.135 -			mresize(c);
   5.136 +			resizemouse(c);
   5.137  			break;
   5.138  		}
   5.139  	}
   5.140 @@ -226,7 +297,7 @@
   5.141  	if(ev->count == 0) {
   5.142  		if(barwin == ev->window)
   5.143  			drawstatus();
   5.144 -		else if((c = gettitle(ev->window)))
   5.145 +		else if((c = getctitle(ev->window)))
   5.146  			drawtitle(c);
   5.147  	}
   5.148  }
   5.149 @@ -262,14 +333,14 @@
   5.150  
   5.151  	if((c = getclient(ev->window))) {
   5.152  		if(ev->atom == wm_atom[WMProtocols]) {
   5.153 -			c->proto = proto(c->win);
   5.154 +			c->proto = getproto(c->win);
   5.155  			return;
   5.156  		}
   5.157  		switch (ev->atom) {
   5.158  			default: break;
   5.159  			case XA_WM_TRANSIENT_FOR:
   5.160  				XGetTransientForHint(dpy, c->win, &trans);
   5.161 -				if(!c->floating && (c->floating = (trans != 0)))
   5.162 +				if(!c->dofloat && (c->dofloat = (trans != 0)))
   5.163  					arrange(NULL);
   5.164  				break;
   5.165  			case XA_WM_NORMAL_HINTS:
     6.1 --- a/key.c	Fri Jul 14 22:54:09 2006 +0200
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,192 +0,0 @@
     6.4 -/*
     6.5 - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     6.6 - * See LICENSE file for license details.
     6.7 - */
     6.8 -
     6.9 -#include <fcntl.h>
    6.10 -#include <stdio.h>
    6.11 -#include <stdlib.h>
    6.12 -#include <string.h>
    6.13 -#include <unistd.h>
    6.14 -#include <X11/keysym.h>
    6.15 -#include <X11/Xatom.h>
    6.16 -
    6.17 -#include "dwm.h"
    6.18 -
    6.19 -static void ckill(Arg *arg);
    6.20 -static void nextc(Arg *arg);
    6.21 -static void prevc(Arg *arg);
    6.22 -static void max(Arg *arg);
    6.23 -static void ttrunc(Arg *arg);
    6.24 -static void tappend(Arg *arg);
    6.25 -static void zoom(Arg *arg);
    6.26 -
    6.27 -/********** CUSTOMIZE **********/
    6.28 -
    6.29 -const char *term[] = { 
    6.30 -	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
    6.31 -	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
    6.32 -};
    6.33 -const char *browse[] = { "firefox", NULL };
    6.34 -const char *xlock[] = { "xlock", NULL };
    6.35 -
    6.36 -Key key[] = {
    6.37 -	/* modifier				key			function	arguments */
    6.38 -	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } },
    6.39 -	{ Mod1Mask,				XK_k,		prevc,		{ 0 } },
    6.40 -	{ Mod1Mask,				XK_j,		nextc,		{ 0 } }, 
    6.41 -	{ Mod1Mask,				XK_m,		max,		{ 0 } }, 
    6.42 -	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } }, 
    6.43 -	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } }, 
    6.44 -	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } }, 
    6.45 -	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } }, 
    6.46 -	{ Mod1Mask,				XK_space,	tiling,		{ 0 } }, 
    6.47 -	{ Mod1Mask|ShiftMask,	XK_space,	floating,	{ 0 } }, 
    6.48 -	{ Mod1Mask|ShiftMask,	XK_0,		ttrunc,		{ .i = Tscratch } }, 
    6.49 -	{ Mod1Mask|ShiftMask,	XK_1,		ttrunc,		{ .i = Tdev } }, 
    6.50 -	{ Mod1Mask|ShiftMask,	XK_2,		ttrunc,		{ .i = Twww } }, 
    6.51 -	{ Mod1Mask|ShiftMask,	XK_3,		ttrunc,		{ .i = Twork } }, 
    6.52 -	{ Mod1Mask|ShiftMask,	XK_c,		ckill,		{ 0 } }, 
    6.53 -	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } },
    6.54 -	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } },
    6.55 -	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } },
    6.56 -	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } },
    6.57 -	{ ControlMask,			XK_0,		tappend,	{ .i = Tscratch } }, 
    6.58 -	{ ControlMask,			XK_1,		tappend,	{ .i = Tdev } }, 
    6.59 -	{ ControlMask,			XK_2,		tappend,	{ .i = Twww } }, 
    6.60 -	{ ControlMask,			XK_3,		tappend,	{ .i = Twork } }, 
    6.61 -};
    6.62 -
    6.63 -/********** CUSTOMIZE **********/
    6.64 -
    6.65 -void
    6.66 -grabkeys()
    6.67 -{
    6.68 -	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
    6.69 -	unsigned int i;
    6.70 -	KeyCode code;
    6.71 -
    6.72 -	for(i = 0; i < len; i++) {
    6.73 -		code = XKeysymToKeycode(dpy, key[i].keysym);
    6.74 -		XUngrabKey(dpy, code, key[i].mod, root);
    6.75 -		XGrabKey(dpy, code, key[i].mod, root, True,
    6.76 -				GrabModeAsync, GrabModeAsync);
    6.77 -	}
    6.78 -}
    6.79 -
    6.80 -void
    6.81 -keypress(XEvent *e)
    6.82 -{
    6.83 -	XKeyEvent *ev = &e->xkey;
    6.84 -	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
    6.85 -	unsigned int i;
    6.86 -	KeySym keysym;
    6.87 -
    6.88 -	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
    6.89 -	for(i = 0; i < len; i++)
    6.90 -		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
    6.91 -			if(key[i].func)
    6.92 -				key[i].func(&key[i].arg);
    6.93 -			return;
    6.94 -		}
    6.95 -}
    6.96 -
    6.97 -static void
    6.98 -zoom(Arg *arg)
    6.99 -{
   6.100 -	Client **l, *c;
   6.101 -
   6.102 -	if(!sel)
   6.103 -		return;
   6.104 -
   6.105 -	if(sel == getnext(clients) && sel->next)  {
   6.106 -		if((c = getnext(sel->next)))
   6.107 -			sel = c;
   6.108 -	}
   6.109 -
   6.110 -	for(l = &clients; *l && *l != sel; l = &(*l)->next);
   6.111 -	*l = sel->next;
   6.112 -
   6.113 -	sel->next = clients; /* pop */
   6.114 -	clients = sel;
   6.115 -	arrange(NULL);
   6.116 -	focus(sel);
   6.117 -}
   6.118 -
   6.119 -static void
   6.120 -max(Arg *arg)
   6.121 -{
   6.122 -	if(!sel)
   6.123 -		return;
   6.124 -	sel->x = sx;
   6.125 -	sel->y = sy + bh;
   6.126 -	sel->w = sw - 2 * sel->border;
   6.127 -	sel->h = sh - 2 * sel->border - bh;
   6.128 -	higher(sel);
   6.129 -	resize(sel, False);
   6.130 -}
   6.131 -
   6.132 -static void
   6.133 -tappend(Arg *arg)
   6.134 -{
   6.135 -	if(!sel)
   6.136 -		return;
   6.137 -
   6.138 -	sel->tags[arg->i] = tags[arg->i];
   6.139 -	arrange(NULL);
   6.140 -}
   6.141 -
   6.142 -static void
   6.143 -ttrunc(Arg *arg)
   6.144 -{
   6.145 -	int i;
   6.146 -	if(!sel)
   6.147 -		return;
   6.148 -
   6.149 -	for(i = 0; i < TLast; i++)
   6.150 -		sel->tags[i] = NULL;
   6.151 -	tappend(arg);
   6.152 -}
   6.153 -
   6.154 -static void
   6.155 -prevc(Arg *arg)
   6.156 -{
   6.157 -	Client *c;
   6.158 -
   6.159 -	if(!sel)
   6.160 -		return;
   6.161 -
   6.162 -	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
   6.163 -		higher(c);
   6.164 -		focus(c);
   6.165 -	}
   6.166 -}
   6.167 -
   6.168 -static void
   6.169 -nextc(Arg *arg)
   6.170 -{
   6.171 -	Client *c;
   6.172 -   
   6.173 -	if(!sel)
   6.174 -		return;
   6.175 -
   6.176 -	if(!(c = getnext(sel->next)))
   6.177 -		c = getnext(clients);
   6.178 -	if(c) {
   6.179 -		higher(c);
   6.180 -		c->revert = sel;
   6.181 -		focus(c);
   6.182 -	}
   6.183 -}
   6.184 -
   6.185 -static void
   6.186 -ckill(Arg *arg)
   6.187 -{
   6.188 -	if(!sel)
   6.189 -		return;
   6.190 -	if(sel->proto & WM_PROTOCOL_DELWIN)
   6.191 -		sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
   6.192 -	else
   6.193 -		XKillClient(dpy, sel->win);
   6.194 -}
   6.195 -
     7.1 --- a/main.c	Fri Jul 14 22:54:09 2006 +0200
     7.2 +++ b/main.c	Sat Jul 15 16:30:50 2006 +0200
     7.3 @@ -43,16 +43,16 @@
     7.4  Client *clients = NULL;
     7.5  Client *sel = NULL;
     7.6  
     7.7 -static Bool other_wm_running;
     7.8 +static Bool otherwm;
     7.9  static const char version[] =
    7.10  	"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
    7.11 -static int (*x_xerror) (Display *, XErrorEvent *);
    7.12 +static int (*xerrorxlib)(Display *, XErrorEvent *);
    7.13  
    7.14  static void
    7.15 -usage() {	error("usage: dwm [-v]\n"); }
    7.16 +usage() {	eprint("usage: dwm [-v]\n"); }
    7.17  
    7.18  static void
    7.19 -scan_wins()
    7.20 +scan()
    7.21  {
    7.22  	unsigned int i, num;
    7.23  	Window *wins;
    7.24 @@ -73,6 +73,22 @@
    7.25  		XFree(wins);
    7.26  }
    7.27  
    7.28 +static void
    7.29 +cleanup()
    7.30 +{
    7.31 +	while(sel) {
    7.32 +		resize(sel, True);
    7.33 +		unmanage(sel);
    7.34 +	}
    7.35 +	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
    7.36 +}
    7.37 +
    7.38 +void
    7.39 +quit(Arg *arg)
    7.40 +{
    7.41 +	running = False;
    7.42 +}
    7.43 +
    7.44  static int
    7.45  win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
    7.46  {
    7.47 @@ -94,7 +110,7 @@
    7.48  }
    7.49  
    7.50  int
    7.51 -proto(Window w)
    7.52 +getproto(Window w)
    7.53  {
    7.54  	unsigned char *protocols;
    7.55  	long res;
    7.56 @@ -129,58 +145,42 @@
    7.57  }
    7.58  
    7.59  /*
    7.60 + * Startup Error handler to check if another window manager
    7.61 + * is already running.
    7.62 + */
    7.63 +static int
    7.64 +xerrorstart(Display *dsply, XErrorEvent *ee)
    7.65 +{
    7.66 +	otherwm = True;
    7.67 +	return -1;
    7.68 +}
    7.69 +
    7.70 +/*
    7.71   * There's no way to check accesses to destroyed windows, thus
    7.72   * those cases are ignored (especially on UnmapNotify's).
    7.73   * Other types of errors call Xlib's default error handler, which
    7.74   * calls exit().
    7.75   */
    7.76  int
    7.77 -xerror(Display *dpy, XErrorEvent *error)
    7.78 +xerror(Display *dpy, XErrorEvent *ee)
    7.79  {
    7.80 -	if(error->error_code == BadWindow
    7.81 -			|| (error->request_code == X_SetInputFocus
    7.82 -				&& error->error_code == BadMatch)
    7.83 -			|| (error->request_code == X_PolyText8
    7.84 -				&& error->error_code == BadDrawable)
    7.85 -			|| (error->request_code == X_PolyFillRectangle
    7.86 -				&& error->error_code == BadDrawable)
    7.87 -			|| (error->request_code == X_PolySegment
    7.88 -				&& error->error_code == BadDrawable)
    7.89 -			|| (error->request_code == X_ConfigureWindow
    7.90 -				&& error->error_code == BadMatch)
    7.91 -			|| (error->request_code == X_GrabKey
    7.92 -				&& error->error_code == BadAccess))
    7.93 +	if(ee->error_code == BadWindow
    7.94 +			|| (ee->request_code == X_SetInputFocus
    7.95 +				&& ee->error_code == BadMatch)
    7.96 +			|| (ee->request_code == X_PolyText8
    7.97 +				&& ee->error_code == BadDrawable)
    7.98 +			|| (ee->request_code == X_PolyFillRectangle
    7.99 +				&& ee->error_code == BadDrawable)
   7.100 +			|| (ee->request_code == X_PolySegment
   7.101 +				&& ee->error_code == BadDrawable)
   7.102 +			|| (ee->request_code == X_ConfigureWindow
   7.103 +				&& ee->error_code == BadMatch)
   7.104 +			|| (ee->request_code == X_GrabKey
   7.105 +				&& ee->error_code == BadAccess))
   7.106  		return 0;
   7.107  	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
   7.108 -			error->request_code, error->error_code);
   7.109 -	return x_xerror(dpy, error); /* may call exit() */
   7.110 -}
   7.111 -
   7.112 -/*
   7.113 - * Startup Error handler to check if another window manager
   7.114 - * is already running.
   7.115 - */
   7.116 -static int
   7.117 -startup_xerror(Display *dpy, XErrorEvent *error)
   7.118 -{
   7.119 -	other_wm_running = True;
   7.120 -	return -1;
   7.121 -}
   7.122 -
   7.123 -static void
   7.124 -cleanup()
   7.125 -{
   7.126 -	while(sel) {
   7.127 -		resize(sel, True);
   7.128 -		unmanage(sel);
   7.129 -	}
   7.130 -	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
   7.131 -}
   7.132 -
   7.133 -void
   7.134 -quit(Arg *arg)
   7.135 -{
   7.136 -	running = False;
   7.137 +			ee->request_code, ee->error_code);
   7.138 +	return xerrorxlib(dpy, ee); /* may call exit() */
   7.139  }
   7.140  
   7.141  int
   7.142 @@ -208,23 +208,23 @@
   7.143  
   7.144  	dpy = XOpenDisplay(0);
   7.145  	if(!dpy)
   7.146 -		error("dwm: cannot connect X server\n");
   7.147 +		eprint("dwm: cannot connect X server\n");
   7.148  
   7.149  	screen = DefaultScreen(dpy);
   7.150  	root = RootWindow(dpy, screen);
   7.151  
   7.152  	/* check if another WM is already running */
   7.153 -	other_wm_running = False;
   7.154 -	XSetErrorHandler(startup_xerror);
   7.155 +	otherwm = False;
   7.156 +	XSetErrorHandler(xerrorstart);
   7.157  	/* this causes an error if some other WM is running */
   7.158  	XSelectInput(dpy, root, SubstructureRedirectMask);
   7.159  	XFlush(dpy);
   7.160  
   7.161 -	if(other_wm_running)
   7.162 -		error("dwm: another window manager is already running\n");
   7.163 +	if(otherwm)
   7.164 +		eprint("dwm: another window manager is already running\n");
   7.165  
   7.166  	XSetErrorHandler(0);
   7.167 -	x_xerror = XSetErrorHandler(xerror);
   7.168 +	xerrorxlib = XSetErrorHandler(xerror);
   7.169  
   7.170  	/* init atoms */
   7.171  	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
   7.172 @@ -278,7 +278,7 @@
   7.173  	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
   7.174  
   7.175  	strcpy(stext, "dwm-"VERSION);
   7.176 -	scan_wins();
   7.177 +	scan();
   7.178  
   7.179  	/* main event loop, reads status text from stdin as well */
   7.180  Mainloop:
   7.181 @@ -292,7 +292,7 @@
   7.182  		if(i == -1 && errno == EINTR)
   7.183  			continue;
   7.184  		if(i < 0)
   7.185 -			error("select failed\n");
   7.186 +			eprint("select failed\n");
   7.187  		else if(i > 0) {
   7.188  			if(FD_ISSET(ConnectionNumber(dpy), &rd)) {
   7.189  				while(XPending(dpy)) {
     8.1 --- a/screen.c	Fri Jul 14 22:54:09 2006 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,100 +0,0 @@
     8.4 -/*
     8.5 - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     8.6 - * See LICENSE file for license details.
     8.7 - */
     8.8 -
     8.9 -#include "dwm.h"
    8.10 -
    8.11 -void (*arrange)(Arg *) = tiling;
    8.12 -
    8.13 -void
    8.14 -view(Arg *arg)
    8.15 -{
    8.16 -	Client *c;
    8.17 -
    8.18 -	tsel = arg->i;
    8.19 -	arrange(NULL);
    8.20 -
    8.21 -	for(c = clients; c; c = getnext(c->next))
    8.22 -		drawtitle(c);
    8.23 -	drawstatus();
    8.24 -}
    8.25 -
    8.26 -void
    8.27 -floating(Arg *arg)
    8.28 -{
    8.29 -	Client *c;
    8.30 -
    8.31 -	arrange = floating;
    8.32 -	for(c = clients; c; c = c->next) {
    8.33 -		if(c->tags[tsel])
    8.34 -			resize(c, True);
    8.35 -		else
    8.36 -			ban(c);
    8.37 -	}
    8.38 -	if(sel && !sel->tags[tsel]) {
    8.39 -		if((sel = getnext(clients))) {
    8.40 -			higher(sel);
    8.41 -			focus(sel);
    8.42 -		}
    8.43 -	}
    8.44 -	drawstatus();
    8.45 -}
    8.46 -
    8.47 -void
    8.48 -tiling(Arg *arg)
    8.49 -{
    8.50 -	Client *c;
    8.51 -	int n, i, w, h;
    8.52 -
    8.53 -	w = sw - mw;
    8.54 -	arrange = tiling;
    8.55 -	for(n = 0, c = clients; c; c = c->next)
    8.56 -		if(c->tags[tsel] && !c->floating)
    8.57 -			n++;
    8.58 -
    8.59 -	if(n > 1)
    8.60 -		h = (sh - bh) / (n - 1);
    8.61 -	else
    8.62 -		h = sh - bh;
    8.63 -
    8.64 -	for(i = 0, c = clients; c; c = c->next) {
    8.65 -		if(c->tags[tsel]) {
    8.66 -			if(c->floating) {
    8.67 -				higher(c);
    8.68 -				resize(c, True);
    8.69 -				continue;
    8.70 -			}
    8.71 -			if(n == 1) {
    8.72 -				c->x = sx;
    8.73 -				c->y = sy + bh;
    8.74 -				c->w = sw - 2 * c->border;
    8.75 -				c->h = sh - 2 * c->border - bh;
    8.76 -			}
    8.77 -			else if(i == 0) {
    8.78 -				c->x = sx;
    8.79 -				c->y = sy + bh;
    8.80 -				c->w = mw - 2 * c->border;
    8.81 -				c->h = sh - 2 * c->border - bh;
    8.82 -			}
    8.83 -			else {
    8.84 -				c->x = sx + mw;
    8.85 -				c->y = sy + (i - 1) * h + bh;
    8.86 -				c->w = w - 2 * c->border;
    8.87 -				c->h = h - 2 * c->border;
    8.88 -			}
    8.89 -			resize(c, False);
    8.90 -			i++;
    8.91 -		}
    8.92 -		else
    8.93 -			ban(c);
    8.94 -	}
    8.95 -	if(!sel || (sel && !sel->tags[tsel])) {
    8.96 -		if((sel = getnext(clients))) {
    8.97 -			higher(sel);
    8.98 -			focus(sel);
    8.99 -		}
   8.100 -	}
   8.101 -	drawstatus();
   8.102 -}
   8.103 -
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tag.c	Sat Jul 15 16:30:50 2006 +0200
     9.3 @@ -0,0 +1,171 @@
     9.4 +/*
     9.5 + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     9.6 + * See LICENSE file for license details.
     9.7 + */
     9.8 +
     9.9 +#include <stdlib.h>
    9.10 +#include <stdio.h>
    9.11 +#include <string.h>
    9.12 +#include <X11/Xatom.h>
    9.13 +#include <X11/Xutil.h>
    9.14 +
    9.15 +#include "dwm.h"
    9.16 +
    9.17 +static Rule rule[] = {
    9.18 +	/* class			instance	tags						dofloat */
    9.19 +	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
    9.20 +};
    9.21 +
    9.22 +void (*arrange)(Arg *) = dotile;
    9.23 +
    9.24 +Client *
    9.25 +getnext(Client *c)
    9.26 +{
    9.27 +	for(; c && !c->tags[tsel]; c = c->next);
    9.28 +	return c;
    9.29 +}
    9.30 +
    9.31 +void
    9.32 +settags(Client *c)
    9.33 +{
    9.34 +	XClassHint ch;
    9.35 +	static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
    9.36 +	unsigned int i, j;
    9.37 +	Bool matched = False;
    9.38 +
    9.39 +	if(!len) {
    9.40 +		c->tags[tsel] = tags[tsel];
    9.41 +		return;
    9.42 +	}
    9.43 +
    9.44 +	if(XGetClassHint(dpy, c->win, &ch)) {
    9.45 +		if(ch.res_class && ch.res_name) {
    9.46 +			for(i = 0; i < len; i++)
    9.47 +				if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
    9.48 +					&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
    9.49 +				{
    9.50 +					for(j = 0; j < TLast; j++)
    9.51 +						c->tags[j] = rule[i].tags[j];
    9.52 +					c->dofloat = rule[i].dofloat;
    9.53 +					matched = True;
    9.54 +					break;
    9.55 +				}
    9.56 +		}
    9.57 +		if(ch.res_class)
    9.58 +			XFree(ch.res_class);
    9.59 +		if(ch.res_name)
    9.60 +			XFree(ch.res_name);
    9.61 +	}
    9.62 +
    9.63 +	if(!matched)
    9.64 +		c->tags[tsel] = tags[tsel];
    9.65 +}
    9.66 +
    9.67 +void
    9.68 +view(Arg *arg)
    9.69 +{
    9.70 +	tsel = arg->i;
    9.71 +	arrange(NULL);
    9.72 +	drawall();
    9.73 +}
    9.74 +
    9.75 +void
    9.76 +dofloat(Arg *arg)
    9.77 +{
    9.78 +	Client *c;
    9.79 +
    9.80 +	arrange = dofloat;
    9.81 +	for(c = clients; c; c = c->next) {
    9.82 +		if(c->tags[tsel])
    9.83 +			resize(c, True);
    9.84 +		else
    9.85 +			ban(c);
    9.86 +	}
    9.87 +	if(sel && !sel->tags[tsel]) {
    9.88 +		if((sel = getnext(clients))) {
    9.89 +			higher(sel);
    9.90 +			focus(sel);
    9.91 +		}
    9.92 +	}
    9.93 +	drawall();
    9.94 +}
    9.95 +
    9.96 +void
    9.97 +dotile(Arg *arg)
    9.98 +{
    9.99 +	Client *c;
   9.100 +	int n, i, w, h;
   9.101 +
   9.102 +	w = sw - mw;
   9.103 +	arrange = dotile;
   9.104 +	for(n = 0, c = clients; c; c = c->next)
   9.105 +		if(c->tags[tsel] && !c->dofloat)
   9.106 +			n++;
   9.107 +
   9.108 +	if(n > 1)
   9.109 +		h = (sh - bh) / (n - 1);
   9.110 +	else
   9.111 +		h = sh - bh;
   9.112 +
   9.113 +	for(i = 0, c = clients; c; c = c->next) {
   9.114 +		if(c->tags[tsel]) {
   9.115 +			if(c->dofloat) {
   9.116 +				higher(c);
   9.117 +				resize(c, True);
   9.118 +				continue;
   9.119 +			}
   9.120 +			if(n == 1) {
   9.121 +				c->x = sx;
   9.122 +				c->y = sy + bh;
   9.123 +				c->w = sw - 2 * c->border;
   9.124 +				c->h = sh - 2 * c->border - bh;
   9.125 +			}
   9.126 +			else if(i == 0) {
   9.127 +				c->x = sx;
   9.128 +				c->y = sy + bh;
   9.129 +				c->w = mw - 2 * c->border;
   9.130 +				c->h = sh - 2 * c->border - bh;
   9.131 +			}
   9.132 +			else {
   9.133 +				c->x = sx + mw;
   9.134 +				c->y = sy + (i - 1) * h + bh;
   9.135 +				c->w = w - 2 * c->border;
   9.136 +				c->h = h - 2 * c->border;
   9.137 +			}
   9.138 +			resize(c, False);
   9.139 +			i++;
   9.140 +		}
   9.141 +		else
   9.142 +			ban(c);
   9.143 +	}
   9.144 +	if(!sel || (sel && !sel->tags[tsel])) {
   9.145 +		if((sel = getnext(clients))) {
   9.146 +			higher(sel);
   9.147 +			focus(sel);
   9.148 +		}
   9.149 +	}
   9.150 +	drawall();
   9.151 +}
   9.152 +
   9.153 +void
   9.154 +appendtag(Arg *arg)
   9.155 +{
   9.156 +	if(!sel)
   9.157 +		return;
   9.158 +
   9.159 +	sel->tags[arg->i] = tags[arg->i];
   9.160 +	arrange(NULL);
   9.161 +}
   9.162 +
   9.163 +void
   9.164 +replacetag(Arg *arg)
   9.165 +{
   9.166 +	int i;
   9.167 +	if(!sel)
   9.168 +		return;
   9.169 +
   9.170 +	for(i = 0; i < TLast; i++)
   9.171 +		sel->tags[i] = NULL;
   9.172 +	appendtag(arg);
   9.173 +}
   9.174 +
    10.1 --- a/util.c	Fri Jul 14 22:54:09 2006 +0200
    10.2 +++ b/util.c	Sat Jul 15 16:30:50 2006 +0200
    10.3 @@ -13,7 +13,7 @@
    10.4  #include "dwm.h"
    10.5  
    10.6  void
    10.7 -error(const char *errstr, ...) {
    10.8 +eprint(const char *errstr, ...) {
    10.9  	va_list ap;
   10.10  	va_start(ap, errstr);
   10.11  	vfprintf(stderr, errstr, ap);