diff options
| author | Anselm R. Garbe <garbeam@wmii.de> | 2006-07-13 18:21:38 +0200 | 
|---|---|---|
| committer | Anselm R. Garbe <garbeam@wmii.de> | 2006-07-13 18:21:38 +0200 | 
| commit | efa7e514012865fcb3e9ea6e7d5b5c87d84353e5 (patch) | |
| tree | 0de62a03a41d3c374abaad67146b9caf3c854615 | |
| parent | c47da143bdf5b4e3924a411f42648d4b3e86ff00 (diff) | |
several other additions/fixes, dwm is quite usable already
| -rw-r--r-- | client.c | 233 | ||||
| -rw-r--r-- | dev.c | 22 | ||||
| -rw-r--r-- | dwm.h | 8 | ||||
| -rw-r--r-- | main.c | 11 | 
4 files changed, 164 insertions, 110 deletions
| @@ -13,60 +13,105 @@  static void (*arrange)(Arg *) = floating; +static void +center(Client *c) +{ +	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); +} +  static Client *  next(Client *c)  { -	for(c = c->next; c && !c->tags[tsel]; c = c->next); +	for(; c && !c->tags[tsel]; c = c->next);  	return c;  } -static Client * -prev(Client *c) +void +zoom(Arg *arg)  { -	for(c = c->prev; c && !c->tags[tsel]; c = c->prev); -	return c; +	Client **l; + +	if(!sel) +		return; + +	for(l = &clients; *l && *l != sel; l = &(*l)->next); +	*l = sel->next; + +	sel->next = clients; /* pop */ +	clients = sel; +	arrange(NULL); +	center(sel); +	focus(sel);  }  void  max(Arg *arg)  { -	if(!csel) +	if(!sel)  		return; -	csel->x = sx; -	csel->y = sy; -	csel->w = sw - 2 * csel->border; -	csel->h = sh - 2 * csel->border; -	craise(csel); -	resize(csel); +	sel->x = sx; +	sel->y = sy; +	sel->w = sw - 2 * sel->border; +	sel->h = sh - 2 * sel->border; +	craise(sel); +	resize(sel);  	discard_events(EnterWindowMask);  }  void +view(Arg *arg) +{ +	tsel = arg->i; +	arrange(NULL); +} + +void  tag(Arg *arg)  { -	if(!csel) +	int i, n; +	if(!sel)  		return; -	if(arg->i == tsel) -		return; +	if(arg->i == tsel) { +		for(n = i = 0; i < TLast; i++) +			if(sel->tags[i]) +				n++; +		if(n < 2) +			return; +	} -	if(csel->tags[arg->i]) -		csel->tags[arg->i] = NULL; /* toggle tag */ +	if(sel->tags[arg->i]) +		sel->tags[arg->i] = NULL; /* toggle tag */  	else -		csel->tags[arg->i] = tags[arg->i]; +		sel->tags[arg->i] = tags[arg->i];  	arrange(NULL);  } +static void +ban_client(Client *c) +{ +	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); +	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); +} +  void  floating(Arg *arg)  {  	Client *c;  	arrange = floating; -	if(!csel) -		return; -	for(c = csel; c; c = next(c)) -		resize(c); +	for(c = clients; c; c = c->next) { +		if(c->tags[tsel]) +			resize(c); +		else +			ban_client(c); +	} +	if(sel && !sel->tags[tsel]) { +		if((sel = next(clients))) { +			craise(sel); +			focus(sel); +		} +	}  	discard_events(EnterWindowMask);  } @@ -78,31 +123,43 @@ tiling(Arg *arg)      float rt, fd;  	arrange = tiling; -	if(!csel) -		return; -	for(n = 0, c = csel; c; c = next(c), n++); -	rt = sqrt(n); -	if(modff(rt, &fd) < 0.5) -		rows = floor(rt); -	else -		rows = ceil(rt); -	if(rows * rows < n) -		cols = rows + 1; -	else -		cols = rows; +	for(n = 0, c = clients; c; c = next(c->next), n++); +	if(n) { +		rt = sqrt(n); +		if(modff(rt, &fd) < 0.5) +			rows = floor(rt); +		else +			rows = ceil(rt); +		if(rows * rows < n) +			cols = rows + 1; +		else +			cols = rows; -	gw = (sw - 2)  / cols; -	gh = (sh - 2) / rows; +		gw = (sw - 2)  / cols; +		gh = (sh - 2) / rows; +	} +	else +		cols = rows = gw = gh = 0; -	for(i = j = 0, c = csel; c; c = next(c)) { -		c->x = i * gw; -		c->y = j * gh; -		c->w = gw; -		c->h = gh; -		resize(c); -		if(++i == cols) { -			j++; -			i = 0; +	for(i = j = 0, c = clients; c; c = c->next) { +		if(c->tags[tsel]) { +			c->x = i * gw; +			c->y = j * gh; +			c->w = gw; +			c->h = gh; +			resize(c); +			if(++i == cols) { +				j++; +				i = 0; +			} +		} +		else +			ban_client(c); +	} +	if(sel && !sel->tags[tsel]) { +		if((sel = next(clients))) { +			craise(sel); +			focus(sel);  		}  	}  	discard_events(EnterWindowMask); @@ -113,14 +170,12 @@ prevc(Arg *arg)  {  	Client *c; -	if(!csel) +	if(!sel)  		return; -	if(!(c = prev(csel))) -		c = prev(cend); -	if(c) { +	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {  		craise(c); -		XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); +		center(c);  		focus(c);  	}  } @@ -130,15 +185,15 @@ nextc(Arg *arg)  {  	Client *c; -	if(!csel) +	if(!sel)  		return; -	if(!(c = next(csel))) -		c = next(cstart); - +	if(!(c = next(sel->next))) +		c = next(clients);  	if(c) {  		craise(c); -		XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); +		center(c); +		c->revert = sel;  		focus(c);  	}  } @@ -146,14 +201,12 @@ nextc(Arg *arg)  void  ckill(Arg *arg)  { -	Client *c = csel; - -	if(!c) +	if(!sel)  		return; -	if(c->proto & WM_PROTOCOL_DELWIN) -		send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]); +	if(sel->proto & WM_PROTOCOL_DELWIN) +		send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);  	else -		XKillClient(dpy, c->win); +		XKillClient(dpy, sel->win);  }  static void @@ -256,12 +309,12 @@ lower(Client *c)  void  focus(Client *c)  { -	if(csel && csel != c) { -		XSetWindowBorder(dpy, csel->win, dc.bg); -		XMapWindow(dpy, csel->title); -		draw_client(csel); +	if(sel && sel != c) { +		XSetWindowBorder(dpy, sel->win, dc.bg); +		XMapWindow(dpy, sel->title); +		draw_client(sel);  	} -	csel = c; +	sel = c;  	XUnmapWindow(dpy, c->title);  	XSetWindowBorder(dpy, c->win, dc.fg);  	draw_client(c); @@ -273,7 +326,7 @@ focus(Client *c)  void  manage(Window w, XWindowAttributes *wa)  { -	Client *c; +	Client *c, **l;  	XSetWindowAttributes twa;  	c = emallocz(sizeof(Client)); @@ -284,6 +337,7 @@ manage(Window w, XWindowAttributes *wa)  	c->h = wa->height;  	c->th = th;  	c->border = 1; +	c->proto = win_proto(c->win);  	update_size(c);  	XSelectInput(dpy, c->win,  			StructureNotifyMask | PropertyChangeMask | EnterWindowMask); @@ -300,13 +354,9 @@ manage(Window w, XWindowAttributes *wa)  	update_name(c); -	if(!cstart) -		cstart = cend = c; -	else { -		cend->next = c; -		c->prev = cend; -		cend = c; -	} +	for(l = &clients; *l; l = &(*l)->next); +	c->next = *l; /* *l == nil */ +	*l = c;  	XSetWindowBorderWidth(dpy, c->win, 1);  	XMapRaised(dpy, c->win); @@ -318,7 +368,7 @@ manage(Window w, XWindowAttributes *wa)  	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,  			GrabModeAsync, GrabModeSync, None, None);  	arrange(NULL); -	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); +	center(c);  	focus(c);  } @@ -420,26 +470,21 @@ 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); -	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; +	for(l = &clients; *l && *l != c; l = &(*l)->next); +	*l = c->next; +	for(l = &clients; *l; l = &(*l)->next) +		if((*l)->revert == c) +			(*l)->revert = NULL; +	if(sel == c) +		sel = sel->revert ? sel->revert : clients;  	free(c); @@ -447,15 +492,15 @@ unmanage(Client *c)  	XSetErrorHandler(error_handler);  	XUngrabServer(dpy);  	arrange(NULL); -	if(csel) -		focus(csel); +	if(sel) +		focus(sel);  }  Client *  gettitle(Window w)  {  	Client *c; -	for(c = cstart; c; c = c->next) +	for(c = clients; c; c = c->next)  		if(c->title == w)  			return c;  	return NULL; @@ -465,7 +510,7 @@ Client *  getclient(Window w)  {  	Client *c; -	for(c = cstart; c; c = c->next) +	for(c = clients; c; c = c->next)  		if(c->win == w)  			return c;  	return NULL; @@ -475,7 +520,7 @@ void  draw_client(Client *c)  {  	int i; -	if(c == csel) +	if(c == sel)  		return;  	dc.x = dc.y = 0; @@ -20,19 +20,25 @@ const char *browse[] = { "firefox", NULL };  const char *xlock[] = { "xlock", NULL };  static Key key[] = { -	{ Mod1Mask, XK_Return, spawn, { .argv = term } }, +	{ Mod1Mask, XK_Return, zoom, { 0 } }, +	{ Mod1Mask, XK_t, 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, XK_0, view, { .i = Tscratch } },  +	{ Mod1Mask, XK_1, view, { .i = Tdev } },  +	{ Mod1Mask, XK_2, view, { .i = Tirc } },  +	{ Mod1Mask, XK_3, view, { .i = Twww } },  +	{ Mod1Mask, XK_4, view, { .i = Twork } },  +	{ Mod1Mask, XK_space, tiling, { 0 } },  +	{ Mod1Mask | ShiftMask, XK_space, floating, { 0 } },  +	{ Mod1Mask | ShiftMask, XK_0, tag, { .i = Tscratch } },  +	{ Mod1Mask | ShiftMask, XK_1, tag, { .i = Tdev } },  +	{ Mod1Mask | ShiftMask, XK_2, tag, { .i = Tirc } },  +	{ Mod1Mask | ShiftMask, XK_3, tag, { .i = Twww } },  +	{ Mod1Mask | ShiftMask, XK_4, tag, { .i = Twork } },   	{ Mod1Mask | ShiftMask, XK_c, ckill, { 0 } },   	{ Mod1Mask | ShiftMask, XK_q, quit, { 0 } },  }; @@ -68,7 +68,7 @@ struct Client {  	Window trans;  	Window title;  	Client *next; -	Client *prev; +	Client *revert;  };  struct Key { @@ -89,7 +89,7 @@ extern int tsel, screen, sx, sy, sw, sh, th;  extern char stext[1024], *tags[TLast];  extern DC dc; -extern Client *cstart, *cend, *csel; +extern Client *clients, *sel;  /* client.c */  extern void manage(Window w, XWindowAttributes *wa); @@ -109,7 +109,9 @@ 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 tag(Arg *arg); +extern void view(Arg *arg); +extern void zoom(Arg *arg);  extern void gravitate(Client *c, Bool invert);  /* draw.c */ @@ -38,9 +38,8 @@ int tsel = Tdev; /* default tag */  int screen, sx, sy, sw, sh, th;  DC dc = {0}; -Client *cstart = NULL; -Client *cend = NULL; -Client *csel = NULL; +Client *clients = NULL; +Client *sel = NULL;  static Bool other_wm_running;  static const char version[] = @@ -169,8 +168,10 @@ startup_error_handler(Display *dpy, XErrorEvent *error)  static void  cleanup()  { -	while(csel) -		unmanage(csel); +	while(sel) { +		resize(sel); +		unmanage(sel); +	}  	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);  } | 
