dwm-meillo

changeset 50:148f25ed0ad7

several other additions/fixes, dwm is quite usable already
author Anselm R. Garbe <garbeam@wmii.de>
date Thu, 13 Jul 2006 18:21:38 +0200
parents 466591c2f967
children 035617ee18d1
files client.c dev.c dwm.h main.c
diffstat 4 files changed, 164 insertions(+), 110 deletions(-) [+]
line diff
     1.1 --- a/client.c	Thu Jul 13 17:09:35 2006 +0200
     1.2 +++ b/client.c	Thu Jul 13 18:21:38 2006 +0200
     1.3 @@ -13,60 +13,105 @@
     1.4  
     1.5  static void (*arrange)(Arg *) = floating;
     1.6  
     1.7 +static void
     1.8 +center(Client *c)
     1.9 +{
    1.10 +	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
    1.11 +}
    1.12 +
    1.13  static Client *
    1.14  next(Client *c)
    1.15  {
    1.16 -	for(c = c->next; c && !c->tags[tsel]; c = c->next);
    1.17 +	for(; c && !c->tags[tsel]; c = c->next);
    1.18  	return c;
    1.19  }
    1.20  
    1.21 -static Client *
    1.22 -prev(Client *c)
    1.23 +void
    1.24 +zoom(Arg *arg)
    1.25  {
    1.26 -	for(c = c->prev; c && !c->tags[tsel]; c = c->prev);
    1.27 -	return c;
    1.28 +	Client **l;
    1.29 +
    1.30 +	if(!sel)
    1.31 +		return;
    1.32 +
    1.33 +	for(l = &clients; *l && *l != sel; l = &(*l)->next);
    1.34 +	*l = sel->next;
    1.35 +
    1.36 +	sel->next = clients; /* pop */
    1.37 +	clients = sel;
    1.38 +	arrange(NULL);
    1.39 +	center(sel);
    1.40 +	focus(sel);
    1.41  }
    1.42  
    1.43  void
    1.44  max(Arg *arg)
    1.45  {
    1.46 -	if(!csel)
    1.47 +	if(!sel)
    1.48  		return;
    1.49 -	csel->x = sx;
    1.50 -	csel->y = sy;
    1.51 -	csel->w = sw - 2 * csel->border;
    1.52 -	csel->h = sh - 2 * csel->border;
    1.53 -	craise(csel);
    1.54 -	resize(csel);
    1.55 +	sel->x = sx;
    1.56 +	sel->y = sy;
    1.57 +	sel->w = sw - 2 * sel->border;
    1.58 +	sel->h = sh - 2 * sel->border;
    1.59 +	craise(sel);
    1.60 +	resize(sel);
    1.61  	discard_events(EnterWindowMask);
    1.62  }
    1.63  
    1.64  void
    1.65 +view(Arg *arg)
    1.66 +{
    1.67 +	tsel = arg->i;
    1.68 +	arrange(NULL);
    1.69 +}
    1.70 +
    1.71 +void
    1.72  tag(Arg *arg)
    1.73  {
    1.74 -	if(!csel)
    1.75 +	int i, n;
    1.76 +	if(!sel)
    1.77  		return;
    1.78  
    1.79 -	if(arg->i == tsel)
    1.80 -		return;
    1.81 +	if(arg->i == tsel) {
    1.82 +		for(n = i = 0; i < TLast; i++)
    1.83 +			if(sel->tags[i])
    1.84 +				n++;
    1.85 +		if(n < 2)
    1.86 +			return;
    1.87 +	}
    1.88  
    1.89 -	if(csel->tags[arg->i])
    1.90 -		csel->tags[arg->i] = NULL; /* toggle tag */
    1.91 +	if(sel->tags[arg->i])
    1.92 +		sel->tags[arg->i] = NULL; /* toggle tag */
    1.93  	else
    1.94 -		csel->tags[arg->i] = tags[arg->i];
    1.95 +		sel->tags[arg->i] = tags[arg->i];
    1.96  	arrange(NULL);
    1.97  }
    1.98  
    1.99 +static void
   1.100 +ban_client(Client *c)
   1.101 +{
   1.102 +	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
   1.103 +	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
   1.104 +}
   1.105 +
   1.106  void
   1.107  floating(Arg *arg)
   1.108  {
   1.109  	Client *c;
   1.110  
   1.111  	arrange = floating;
   1.112 -	if(!csel)
   1.113 -		return;
   1.114 -	for(c = csel; c; c = next(c))
   1.115 -		resize(c);
   1.116 +	for(c = clients; c; c = c->next) {
   1.117 +		if(c->tags[tsel])
   1.118 +			resize(c);
   1.119 +		else
   1.120 +			ban_client(c);
   1.121 +	}
   1.122 +	if(sel && !sel->tags[tsel]) {
   1.123 +		if((sel = next(clients))) {
   1.124 +			craise(sel);
   1.125 +			focus(sel);
   1.126 +		}
   1.127 +	}
   1.128  	discard_events(EnterWindowMask);
   1.129  }
   1.130  
   1.131 @@ -78,31 +123,43 @@
   1.132      float rt, fd;
   1.133  
   1.134  	arrange = tiling;
   1.135 -	if(!csel)
   1.136 -		return;
   1.137 -	for(n = 0, c = csel; c; c = next(c), n++);
   1.138 -	rt = sqrt(n);
   1.139 -	if(modff(rt, &fd) < 0.5)
   1.140 -		rows = floor(rt);
   1.141 +	for(n = 0, c = clients; c; c = next(c->next), n++);
   1.142 +	if(n) {
   1.143 +		rt = sqrt(n);
   1.144 +		if(modff(rt, &fd) < 0.5)
   1.145 +			rows = floor(rt);
   1.146 +		else
   1.147 +			rows = ceil(rt);
   1.148 +		if(rows * rows < n)
   1.149 +			cols = rows + 1;
   1.150 +		else
   1.151 +			cols = rows;
   1.152 +
   1.153 +		gw = (sw - 2)  / cols;
   1.154 +		gh = (sh - 2) / rows;
   1.155 +	}
   1.156  	else
   1.157 -		rows = ceil(rt);
   1.158 -	if(rows * rows < n)
   1.159 -		cols = rows + 1;
   1.160 -	else
   1.161 -		cols = rows;
   1.162 +		cols = rows = gw = gh = 0;
   1.163  
   1.164 -	gw = (sw - 2)  / cols;
   1.165 -	gh = (sh - 2) / rows;
   1.166 -
   1.167 -	for(i = j = 0, c = csel; c; c = next(c)) {
   1.168 -		c->x = i * gw;
   1.169 -		c->y = j * gh;
   1.170 -		c->w = gw;
   1.171 -		c->h = gh;
   1.172 -		resize(c);
   1.173 -		if(++i == cols) {
   1.174 -			j++;
   1.175 -			i = 0;
   1.176 +	for(i = j = 0, c = clients; c; c = c->next) {
   1.177 +		if(c->tags[tsel]) {
   1.178 +			c->x = i * gw;
   1.179 +			c->y = j * gh;
   1.180 +			c->w = gw;
   1.181 +			c->h = gh;
   1.182 +			resize(c);
   1.183 +			if(++i == cols) {
   1.184 +				j++;
   1.185 +				i = 0;
   1.186 +			}
   1.187 +		}
   1.188 +		else
   1.189 +			ban_client(c);
   1.190 +	}
   1.191 +	if(sel && !sel->tags[tsel]) {
   1.192 +		if((sel = next(clients))) {
   1.193 +			craise(sel);
   1.194 +			focus(sel);
   1.195  		}
   1.196  	}
   1.197  	discard_events(EnterWindowMask);
   1.198 @@ -113,14 +170,12 @@
   1.199  {
   1.200  	Client *c;
   1.201  
   1.202 -	if(!csel)
   1.203 +	if(!sel)
   1.204  		return;
   1.205  
   1.206 -	if(!(c = prev(csel)))
   1.207 -		c = prev(cend);
   1.208 -	if(c) {
   1.209 +	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
   1.210  		craise(c);
   1.211 -		XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
   1.212 +		center(c);
   1.213  		focus(c);
   1.214  	}
   1.215  }
   1.216 @@ -130,15 +185,15 @@
   1.217  {
   1.218  	Client *c;
   1.219     
   1.220 -	if(!csel)
   1.221 +	if(!sel)
   1.222  		return;
   1.223  
   1.224 -	if(!(c = next(csel)))
   1.225 -		c = next(cstart);
   1.226 -
   1.227 +	if(!(c = next(sel->next)))
   1.228 +		c = next(clients);
   1.229  	if(c) {
   1.230  		craise(c);
   1.231 -		XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
   1.232 +		center(c);
   1.233 +		c->revert = sel;
   1.234  		focus(c);
   1.235  	}
   1.236  }
   1.237 @@ -146,14 +201,12 @@
   1.238  void
   1.239  ckill(Arg *arg)
   1.240  {
   1.241 -	Client *c = csel;
   1.242 -
   1.243 -	if(!c)
   1.244 +	if(!sel)
   1.245  		return;
   1.246 -	if(c->proto & WM_PROTOCOL_DELWIN)
   1.247 -		send_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
   1.248 +	if(sel->proto & WM_PROTOCOL_DELWIN)
   1.249 +		send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
   1.250  	else
   1.251 -		XKillClient(dpy, c->win);
   1.252 +		XKillClient(dpy, sel->win);
   1.253  }
   1.254  
   1.255  static void
   1.256 @@ -256,12 +309,12 @@
   1.257  void
   1.258  focus(Client *c)
   1.259  {
   1.260 -	if(csel && csel != c) {
   1.261 -		XSetWindowBorder(dpy, csel->win, dc.bg);
   1.262 -		XMapWindow(dpy, csel->title);
   1.263 -		draw_client(csel);
   1.264 +	if(sel && sel != c) {
   1.265 +		XSetWindowBorder(dpy, sel->win, dc.bg);
   1.266 +		XMapWindow(dpy, sel->title);
   1.267 +		draw_client(sel);
   1.268  	}
   1.269 -	csel = c;
   1.270 +	sel = c;
   1.271  	XUnmapWindow(dpy, c->title);
   1.272  	XSetWindowBorder(dpy, c->win, dc.fg);
   1.273  	draw_client(c);
   1.274 @@ -273,7 +326,7 @@
   1.275  void
   1.276  manage(Window w, XWindowAttributes *wa)
   1.277  {
   1.278 -	Client *c;
   1.279 +	Client *c, **l;
   1.280  	XSetWindowAttributes twa;
   1.281  
   1.282  	c = emallocz(sizeof(Client));
   1.283 @@ -284,6 +337,7 @@
   1.284  	c->h = wa->height;
   1.285  	c->th = th;
   1.286  	c->border = 1;
   1.287 +	c->proto = win_proto(c->win);
   1.288  	update_size(c);
   1.289  	XSelectInput(dpy, c->win,
   1.290  			StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
   1.291 @@ -300,13 +354,9 @@
   1.292  
   1.293  	update_name(c);
   1.294  
   1.295 -	if(!cstart)
   1.296 -		cstart = cend = c;
   1.297 -	else {
   1.298 -		cend->next = c;
   1.299 -		c->prev = cend;
   1.300 -		cend = c;
   1.301 -	}
   1.302 +	for(l = &clients; *l; l = &(*l)->next);
   1.303 +	c->next = *l; /* *l == nil */
   1.304 +	*l = c;
   1.305  
   1.306  	XSetWindowBorderWidth(dpy, c->win, 1);
   1.307  	XMapRaised(dpy, c->win);
   1.308 @@ -318,7 +368,7 @@
   1.309  	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
   1.310  			GrabModeAsync, GrabModeSync, None, None);
   1.311  	arrange(NULL);
   1.312 -	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
   1.313 +	center(c);
   1.314  	focus(c);
   1.315  }
   1.316  
   1.317 @@ -420,26 +470,21 @@
   1.318  void
   1.319  unmanage(Client *c)
   1.320  {
   1.321 +	Client **l;
   1.322 +
   1.323  	XGrabServer(dpy);
   1.324  	XSetErrorHandler(dummy_error_handler);
   1.325  
   1.326  	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
   1.327  	XDestroyWindow(dpy, c->title);
   1.328  
   1.329 -	if(c->prev) {
   1.330 -		c->prev->next = c->next;
   1.331 -		if(csel == c)
   1.332 -			csel = c->prev;
   1.333 -	}
   1.334 -	if(c->next) {
   1.335 -		c->next->prev = c->prev;
   1.336 -		if(csel == c)
   1.337 -			csel = c->next;
   1.338 -	}
   1.339 -	if(cstart == c)
   1.340 -		cstart = c->next;
   1.341 -	if(cend == c)
   1.342 -		cend = c->prev;
   1.343 +	for(l = &clients; *l && *l != c; l = &(*l)->next);
   1.344 +	*l = c->next;
   1.345 +	for(l = &clients; *l; l = &(*l)->next)
   1.346 +		if((*l)->revert == c)
   1.347 +			(*l)->revert = NULL;
   1.348 +	if(sel == c)
   1.349 +		sel = sel->revert ? sel->revert : clients;
   1.350  
   1.351  	free(c);
   1.352  
   1.353 @@ -447,15 +492,15 @@
   1.354  	XSetErrorHandler(error_handler);
   1.355  	XUngrabServer(dpy);
   1.356  	arrange(NULL);
   1.357 -	if(csel)
   1.358 -		focus(csel);
   1.359 +	if(sel)
   1.360 +		focus(sel);
   1.361  }
   1.362  
   1.363  Client *
   1.364  gettitle(Window w)
   1.365  {
   1.366  	Client *c;
   1.367 -	for(c = cstart; c; c = c->next)
   1.368 +	for(c = clients; c; c = c->next)
   1.369  		if(c->title == w)
   1.370  			return c;
   1.371  	return NULL;
   1.372 @@ -465,7 +510,7 @@
   1.373  getclient(Window w)
   1.374  {
   1.375  	Client *c;
   1.376 -	for(c = cstart; c; c = c->next)
   1.377 +	for(c = clients; c; c = c->next)
   1.378  		if(c->win == w)
   1.379  			return c;
   1.380  	return NULL;
   1.381 @@ -475,7 +520,7 @@
   1.382  draw_client(Client *c)
   1.383  {
   1.384  	int i;
   1.385 -	if(c == csel)
   1.386 +	if(c == sel)
   1.387  		return;
   1.388  
   1.389  	dc.x = dc.y = 0;
     2.1 --- a/dev.c	Thu Jul 13 17:09:35 2006 +0200
     2.2 +++ b/dev.c	Thu Jul 13 18:21:38 2006 +0200
     2.3 @@ -20,19 +20,25 @@
     2.4  const char *xlock[] = { "xlock", NULL };
     2.5  
     2.6  static Key key[] = {
     2.7 -	{ Mod1Mask, XK_Return, spawn, { .argv = term } },
     2.8 +	{ Mod1Mask, XK_Return, zoom, { 0 } },
     2.9 +	{ Mod1Mask, XK_t, spawn, { .argv = term } },
    2.10  	{ Mod1Mask, XK_w, spawn, { .argv = browse } },
    2.11  	{ Mod1Mask, XK_l, spawn, { .argv = xlock } },
    2.12  	{ Mod1Mask, XK_k, prevc, { 0 } },
    2.13  	{ Mod1Mask, XK_j, nextc, { 0 } }, 
    2.14 -	{ Mod1Mask, XK_t, tiling, { 0 } }, 
    2.15 -	{ Mod1Mask, XK_f, floating, { 0 } }, 
    2.16  	{ Mod1Mask, XK_m, max, { 0 } }, 
    2.17 -	{ Mod1Mask, XK_0, tag, { .i = Tscratch } }, 
    2.18 -	{ Mod1Mask, XK_1, tag, { .i = Tdev } }, 
    2.19 -	{ Mod1Mask, XK_2, tag, { .i = Tirc } }, 
    2.20 -	{ Mod1Mask, XK_3, tag, { .i = Twww } }, 
    2.21 -	{ Mod1Mask, XK_4, tag, { .i = Twork } }, 
    2.22 +	{ Mod1Mask, XK_0, view, { .i = Tscratch } }, 
    2.23 +	{ Mod1Mask, XK_1, view, { .i = Tdev } }, 
    2.24 +	{ Mod1Mask, XK_2, view, { .i = Tirc } }, 
    2.25 +	{ Mod1Mask, XK_3, view, { .i = Twww } }, 
    2.26 +	{ Mod1Mask, XK_4, view, { .i = Twork } }, 
    2.27 +	{ Mod1Mask, XK_space, tiling, { 0 } }, 
    2.28 +	{ Mod1Mask | ShiftMask, XK_space, floating, { 0 } }, 
    2.29 +	{ Mod1Mask | ShiftMask, XK_0, tag, { .i = Tscratch } }, 
    2.30 +	{ Mod1Mask | ShiftMask, XK_1, tag, { .i = Tdev } }, 
    2.31 +	{ Mod1Mask | ShiftMask, XK_2, tag, { .i = Tirc } }, 
    2.32 +	{ Mod1Mask | ShiftMask, XK_3, tag, { .i = Twww } }, 
    2.33 +	{ Mod1Mask | ShiftMask, XK_4, tag, { .i = Twork } }, 
    2.34  	{ Mod1Mask | ShiftMask, XK_c, ckill, { 0 } }, 
    2.35  	{ Mod1Mask | ShiftMask, XK_q, quit, { 0 } },
    2.36  };
     3.1 --- a/dwm.h	Thu Jul 13 17:09:35 2006 +0200
     3.2 +++ b/dwm.h	Thu Jul 13 18:21:38 2006 +0200
     3.3 @@ -68,7 +68,7 @@
     3.4  	Window trans;
     3.5  	Window title;
     3.6  	Client *next;
     3.7 -	Client *prev;
     3.8 +	Client *revert;
     3.9  };
    3.10  
    3.11  struct Key {
    3.12 @@ -89,7 +89,7 @@
    3.13  extern char stext[1024], *tags[TLast];
    3.14  
    3.15  extern DC dc;
    3.16 -extern Client *cstart, *cend, *csel;
    3.17 +extern Client *clients, *sel;
    3.18  
    3.19  /* client.c */
    3.20  extern void manage(Window w, XWindowAttributes *wa);
    3.21 @@ -109,7 +109,9 @@
    3.22  extern void max(Arg *arg);
    3.23  extern void floating(Arg *arg);
    3.24  extern void tiling(Arg *arg);
    3.25 -void tag(Arg *arg);
    3.26 +extern void tag(Arg *arg);
    3.27 +extern void view(Arg *arg);
    3.28 +extern void zoom(Arg *arg);
    3.29  extern void gravitate(Client *c, Bool invert);
    3.30  
    3.31  /* draw.c */
     4.1 --- a/main.c	Thu Jul 13 17:09:35 2006 +0200
     4.2 +++ b/main.c	Thu Jul 13 18:21:38 2006 +0200
     4.3 @@ -38,9 +38,8 @@
     4.4  int screen, sx, sy, sw, sh, th;
     4.5  
     4.6  DC dc = {0};
     4.7 -Client *cstart = NULL;
     4.8 -Client *cend = NULL;
     4.9 -Client *csel = NULL;
    4.10 +Client *clients = NULL;
    4.11 +Client *sel = NULL;
    4.12  
    4.13  static Bool other_wm_running;
    4.14  static const char version[] =
    4.15 @@ -169,8 +168,10 @@
    4.16  static void
    4.17  cleanup()
    4.18  {
    4.19 -	while(csel)
    4.20 -		unmanage(csel);
    4.21 +	while(sel) {
    4.22 +		resize(sel);
    4.23 +		unmanage(sel);
    4.24 +	}
    4.25  	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
    4.26  }
    4.27