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