aewl

changeset 73:c2ddb9dbbd10

rearranged
author Anselm R. Garbe <garbeam@wmii.de>
date Fri, 14 Jul 2006 22:33:38 +0200
parents d0eb0bb63c40
children 5370ef170cc9
files Makefile client.c draw.c dwm.h event.c key.c main.c screen.c
diffstat 10 files changed, 461 insertions(+), 464 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Fri Jul 14 18:59:25 2006 +0200
     1.2 +++ b/Makefile	Fri Jul 14 22:33:38 2006 +0200
     1.3 @@ -3,7 +3,7 @@
     1.4  
     1.5  include config.mk
     1.6  
     1.7 -SRC = bar.c client.c dev.c draw.c event.c main.c util.c
     1.8 +SRC = client.c draw.c event.c key.c main.c screen.c util.c
     1.9  OBJ = ${SRC:.c=.o}
    1.10  MAN1 = dwm.1 
    1.11  BIN = dwm
     2.1 --- a/bar.c	Fri Jul 14 18:59:25 2006 +0200
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,54 +0,0 @@
     2.4 -/*
     2.5 - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     2.6 - * See LICENSE file for license details.
     2.7 - */
     2.8 -
     2.9 -#include "dwm.h"
    2.10 -
    2.11 -void
    2.12 -barclick(XButtonPressedEvent *e)
    2.13 -{
    2.14 -	int x = 0;
    2.15 -	Arg a;
    2.16 -	for(a.i = 0; a.i < TLast; a.i++) {
    2.17 -		x += textw(tags[a.i]) + dc.font.height;
    2.18 -		if(e->x < x) {
    2.19 -			view(&a);
    2.20 -			return;
    2.21 -		}
    2.22 -	}
    2.23 -}
    2.24 -
    2.25 -void
    2.26 -draw_bar()
    2.27 -{
    2.28 -	int i, modw;
    2.29 -	char *mode = arrange == tiling ? "#" : "~";
    2.30 -
    2.31 -	dc.x = dc.y = 0;
    2.32 -	dc.w = bw;
    2.33 -	drawtext(NULL, False, False);
    2.34 -
    2.35 -	modw = textw(mode) + dc.font.height;
    2.36 -	dc.w = 0;
    2.37 -	for(i = 0; i < TLast; i++) {
    2.38 -		dc.x += dc.w;
    2.39 -		dc.w = textw(tags[i]) + dc.font.height;
    2.40 -		drawtext(tags[i], i == tsel, True);
    2.41 -	}
    2.42 -	if(sel) {
    2.43 -		dc.x += dc.w;
    2.44 -		dc.w = textw(sel->name) + dc.font.height;
    2.45 -		drawtext(sel->name, True, True);
    2.46 -	}
    2.47 -	dc.w = textw(stext) + dc.font.height;
    2.48 -	dc.x = bx + bw - dc.w - modw;
    2.49 -	drawtext(stext, False, False);
    2.50 -
    2.51 -	dc.x = bx + bw - modw;
    2.52 -	dc.w = modw;
    2.53 -	drawtext(mode, True, True);
    2.54 -
    2.55 -	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
    2.56 -	XFlush(dpy);
    2.57 -}
     3.1 --- a/client.c	Fri Jul 14 18:59:25 2006 +0200
     3.2 +++ b/client.c	Fri Jul 14 22:33:38 2006 +0200
     3.3 @@ -11,14 +11,12 @@
     3.4  
     3.5  #include "dwm.h"
     3.6  
     3.7 -void (*arrange)(Arg *) = tiling;
     3.8 -
     3.9  static Rule rule[] = {
    3.10  	/* class			instance	tags						floating */
    3.11  	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
    3.12  };
    3.13  
    3.14 -static Client *
    3.15 +Client *
    3.16  next(Client *c)
    3.17  {
    3.18  	for(; c && !c->tags[tsel]; c = c->next);
    3.19 @@ -26,202 +24,12 @@
    3.20  }
    3.21  
    3.22  void
    3.23 -zoom(Arg *arg)
    3.24 -{
    3.25 -	Client **l, *c;
    3.26 -
    3.27 -	if(!sel)
    3.28 -		return;
    3.29 -
    3.30 -	if(sel == next(clients) && sel->next)  {
    3.31 -		if((c = next(sel->next)))
    3.32 -			sel = c;
    3.33 -	}
    3.34 -
    3.35 -	for(l = &clients; *l && *l != sel; l = &(*l)->next);
    3.36 -	*l = sel->next;
    3.37 -
    3.38 -	sel->next = clients; /* pop */
    3.39 -	clients = sel;
    3.40 -	arrange(NULL);
    3.41 -	focus(sel);
    3.42 -}
    3.43 -
    3.44 -void
    3.45 -max(Arg *arg)
    3.46 -{
    3.47 -	if(!sel)
    3.48 -		return;
    3.49 -	sel->x = sx;
    3.50 -	sel->y = sy + bh;
    3.51 -	sel->w = sw - 2 * sel->border;
    3.52 -	sel->h = sh - 2 * sel->border - bh;
    3.53 -	craise(sel);
    3.54 -	resize(sel, False);
    3.55 -}
    3.56 -
    3.57 -void
    3.58 -view(Arg *arg)
    3.59 -{
    3.60 -	Client *c;
    3.61 -
    3.62 -	tsel = arg->i;
    3.63 -	arrange(NULL);
    3.64 -
    3.65 -	for(c = clients; c; c = next(c->next))
    3.66 -		draw_client(c);
    3.67 -	draw_bar();
    3.68 -}
    3.69 -
    3.70 -void
    3.71 -tappend(Arg *arg)
    3.72 -{
    3.73 -	if(!sel)
    3.74 -		return;
    3.75 -
    3.76 -	sel->tags[arg->i] = tags[arg->i];
    3.77 -	arrange(NULL);
    3.78 -}
    3.79 -
    3.80 -void
    3.81 -ttrunc(Arg *arg)
    3.82 -{
    3.83 -	int i;
    3.84 -	if(!sel)
    3.85 -		return;
    3.86 -
    3.87 -	for(i = 0; i < TLast; i++)
    3.88 -		sel->tags[i] = NULL;
    3.89 -	tappend(arg);
    3.90 -}
    3.91 -
    3.92 -static void
    3.93  ban_client(Client *c)
    3.94  {
    3.95  	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
    3.96  	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
    3.97  }
    3.98  
    3.99 -void
   3.100 -floating(Arg *arg)
   3.101 -{
   3.102 -	Client *c;
   3.103 -
   3.104 -	arrange = floating;
   3.105 -	for(c = clients; c; c = c->next) {
   3.106 -		if(c->tags[tsel])
   3.107 -			resize(c, True);
   3.108 -		else
   3.109 -			ban_client(c);
   3.110 -	}
   3.111 -	if(sel && !sel->tags[tsel]) {
   3.112 -		if((sel = next(clients))) {
   3.113 -			craise(sel);
   3.114 -			focus(sel);
   3.115 -		}
   3.116 -	}
   3.117 -	draw_bar();
   3.118 -}
   3.119 -
   3.120 -void
   3.121 -tiling(Arg *arg)
   3.122 -{
   3.123 -	Client *c;
   3.124 -	int n, i, w, h;
   3.125 -
   3.126 -	w = sw - mw;
   3.127 -	arrange = tiling;
   3.128 -	for(n = 0, c = clients; c; c = c->next)
   3.129 -		if(c->tags[tsel] && !c->floating)
   3.130 -			n++;
   3.131 -
   3.132 -	if(n > 1)
   3.133 -		h = (sh - bh) / (n - 1);
   3.134 -	else
   3.135 -		h = sh - bh;
   3.136 -
   3.137 -	for(i = 0, c = clients; c; c = c->next) {
   3.138 -		if(c->tags[tsel]) {
   3.139 -			if(c->floating) {
   3.140 -				craise(c);
   3.141 -				resize(c, True);
   3.142 -				continue;
   3.143 -			}
   3.144 -			if(n == 1) {
   3.145 -				c->x = sx;
   3.146 -				c->y = sy + bh;
   3.147 -				c->w = sw - 2 * c->border;
   3.148 -				c->h = sh - 2 * c->border - bh;
   3.149 -			}
   3.150 -			else if(i == 0) {
   3.151 -				c->x = sx;
   3.152 -				c->y = sy + bh;
   3.153 -				c->w = mw - 2 * c->border;
   3.154 -				c->h = sh - 2 * c->border - bh;
   3.155 -			}
   3.156 -			else {
   3.157 -				c->x = sx + mw;
   3.158 -				c->y = sy + (i - 1) * h + bh;
   3.159 -				c->w = w - 2 * c->border;
   3.160 -				c->h = h - 2 * c->border;
   3.161 -			}
   3.162 -			resize(c, False);
   3.163 -			i++;
   3.164 -		}
   3.165 -		else
   3.166 -			ban_client(c);
   3.167 -	}
   3.168 -	if(!sel || (sel && !sel->tags[tsel])) {
   3.169 -		if((sel = next(clients))) {
   3.170 -			craise(sel);
   3.171 -			focus(sel);
   3.172 -		}
   3.173 -	}
   3.174 -	draw_bar();
   3.175 -}
   3.176 -
   3.177 -void
   3.178 -prevc(Arg *arg)
   3.179 -{
   3.180 -	Client *c;
   3.181 -
   3.182 -	if(!sel)
   3.183 -		return;
   3.184 -
   3.185 -	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
   3.186 -		craise(c);
   3.187 -		focus(c);
   3.188 -	}
   3.189 -}
   3.190 -
   3.191 -void
   3.192 -nextc(Arg *arg)
   3.193 -{
   3.194 -	Client *c;
   3.195 -   
   3.196 -	if(!sel)
   3.197 -		return;
   3.198 -
   3.199 -	if(!(c = next(sel->next)))
   3.200 -		c = next(clients);
   3.201 -	if(c) {
   3.202 -		craise(c);
   3.203 -		c->revert = sel;
   3.204 -		focus(c);
   3.205 -	}
   3.206 -}
   3.207 -
   3.208 -void
   3.209 -ckill(Arg *arg)
   3.210 -{
   3.211 -	if(!sel)
   3.212 -		return;
   3.213 -	if(sel->proto & WM_PROTOCOL_DELWIN)
   3.214 -		send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
   3.215 -	else
   3.216 -		XKillClient(dpy, sel->win);
   3.217 -}
   3.218 -
   3.219  static void
   3.220  resize_title(Client *c)
   3.221  {
   3.222 @@ -230,8 +38,8 @@
   3.223  	c->tw = 0;
   3.224  	for(i = 0; i < TLast; i++)
   3.225  		if(c->tags[i])
   3.226 -			c->tw += textw(c->tags[i]) + dc.font.height;
   3.227 -	c->tw += textw(c->name) + dc.font.height;
   3.228 +			c->tw += textw(c->tags[i]);
   3.229 +	c->tw += textw(c->name);
   3.230  	if(c->tw > c->w)
   3.231  		c->tw = c->w + 2;
   3.232  	c->tx = c->x + c->w - c->tw + 2;
   3.233 @@ -584,35 +392,3 @@
   3.234  			return c;
   3.235  	return NULL;
   3.236  }
   3.237 -
   3.238 -void
   3.239 -draw_client(Client *c)
   3.240 -{
   3.241 -	int i;
   3.242 -	if(c == sel) {
   3.243 -		draw_bar();
   3.244 -		XUnmapWindow(dpy, c->title);
   3.245 -		XSetWindowBorder(dpy, c->win, dc.fg);
   3.246 -		return;
   3.247 -	}
   3.248 -
   3.249 -	XSetWindowBorder(dpy, c->win, dc.bg);
   3.250 -	XMapWindow(dpy, c->title);
   3.251 -
   3.252 -	dc.x = dc.y = 0;
   3.253 -
   3.254 -	dc.w = 0;
   3.255 -	for(i = 0; i < TLast; i++) {
   3.256 -		if(c->tags[i]) {
   3.257 -			dc.x += dc.w;
   3.258 -			dc.w = textw(c->tags[i]) + dc.font.height;
   3.259 -			drawtext(c->tags[i], False, True);
   3.260 -		}
   3.261 -	}
   3.262 -	dc.x += dc.w;
   3.263 -	dc.w = textw(c->name) + dc.font.height;
   3.264 -	drawtext(c->name, False, True);
   3.265 -	XCopyArea(dpy, dc.drawable, c->title, dc.gc,
   3.266 -			0, 0, c->tw, c->th, 0, 0);
   3.267 -	XFlush(dpy);
   3.268 -}
     4.1 --- a/dev.c	Fri Jul 14 18:59:25 2006 +0200
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,151 +0,0 @@
     4.4 -/*
     4.5 - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     4.6 - * See LICENSE file for license details.
     4.7 - */
     4.8 -
     4.9 -#include "dwm.h"
    4.10 -
    4.11 -#include <stdlib.h>
    4.12 -#include <string.h>
    4.13 -#include <unistd.h>
    4.14 -#include <X11/keysym.h>
    4.15 -
    4.16 -/********** CUSTOMIZE **********/
    4.17 -
    4.18 -const char *term[] = { 
    4.19 -	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
    4.20 -	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
    4.21 -};
    4.22 -const char *browse[] = { "firefox", NULL };
    4.23 -const char *xlock[] = { "xlock", NULL };
    4.24 -
    4.25 -static Key key[] = {
    4.26 -	/* modifier				key			function	arguments */
    4.27 -	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } },
    4.28 -	{ Mod1Mask,				XK_k,		prevc,		{ 0 } },
    4.29 -	{ Mod1Mask,				XK_j,		nextc,		{ 0 } }, 
    4.30 -	{ Mod1Mask,				XK_m,		max,		{ 0 } }, 
    4.31 -	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } }, 
    4.32 -	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } }, 
    4.33 -	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } }, 
    4.34 -	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } }, 
    4.35 -	{ Mod1Mask,				XK_space,	tiling,		{ 0 } }, 
    4.36 -	{ Mod1Mask|ShiftMask,	XK_space,	floating,	{ 0 } }, 
    4.37 -	{ Mod1Mask|ShiftMask,	XK_0,		ttrunc,		{ .i = Tscratch } }, 
    4.38 -	{ Mod1Mask|ShiftMask,	XK_1,		ttrunc,		{ .i = Tdev } }, 
    4.39 -	{ Mod1Mask|ShiftMask,	XK_2,		ttrunc,		{ .i = Twww } }, 
    4.40 -	{ Mod1Mask|ShiftMask,	XK_3,		ttrunc,		{ .i = Twork } }, 
    4.41 -	{ Mod1Mask|ShiftMask,	XK_c,		ckill,		{ 0 } }, 
    4.42 -	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } },
    4.43 -	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } },
    4.44 -	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } },
    4.45 -	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } },
    4.46 -	{ ControlMask,			XK_0,		tappend,	{ .i = Tscratch } }, 
    4.47 -	{ ControlMask,			XK_1,		tappend,	{ .i = Tdev } }, 
    4.48 -	{ ControlMask,			XK_2,		tappend,	{ .i = Twww } }, 
    4.49 -	{ ControlMask,			XK_3,		tappend,	{ .i = Twork } }, 
    4.50 -};
    4.51 -
    4.52 -/********** CUSTOMIZE **********/
    4.53 -
    4.54 -void
    4.55 -update_keys(void)
    4.56 -{
    4.57 -	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
    4.58 -	unsigned int i;
    4.59 -	KeyCode code;
    4.60 -
    4.61 -	for(i = 0; i < len; i++) {
    4.62 -		code = XKeysymToKeycode(dpy, key[i].keysym);
    4.63 -		XUngrabKey(dpy, code, key[i].mod, root);
    4.64 -		XGrabKey(dpy, code, key[i].mod, root, True, GrabModeAsync, GrabModeAsync);
    4.65 -	}
    4.66 -}
    4.67 -
    4.68 -void
    4.69 -keypress(XEvent *e)
    4.70 -{
    4.71 -	XKeyEvent *ev = &e->xkey;
    4.72 -	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
    4.73 -	unsigned int i;
    4.74 -	KeySym keysym;
    4.75 -
    4.76 -	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
    4.77 -	for(i = 0; i < len; i++)
    4.78 -		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
    4.79 -			if(key[i].func)
    4.80 -				key[i].func(&key[i].arg);
    4.81 -			return;
    4.82 -		}
    4.83 -}
    4.84 -
    4.85 -#define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
    4.86 -#define MouseMask       (ButtonMask | PointerMotionMask)
    4.87 -
    4.88 -void
    4.89 -mresize(Client *c)
    4.90 -{
    4.91 -	XEvent ev;
    4.92 -	int ocx, ocy;
    4.93 -
    4.94 -	ocx = c->x;
    4.95 -	ocy = c->y;
    4.96 -	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
    4.97 -				None, cursor[CurResize], CurrentTime) != GrabSuccess)
    4.98 -		return;
    4.99 -	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
   4.100 -	for(;;) {
   4.101 -		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
   4.102 -		switch(ev.type) {
   4.103 -		default: break;
   4.104 -		case Expose:
   4.105 -			handler[Expose](&ev);
   4.106 -			break;
   4.107 -		case MotionNotify:
   4.108 -			XFlush(dpy);
   4.109 -			c->w = abs(ocx - ev.xmotion.x);
   4.110 -			c->h = abs(ocy - ev.xmotion.y);
   4.111 -			c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
   4.112 -			c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
   4.113 -			resize(c, True);
   4.114 -			break;
   4.115 -		case ButtonRelease:
   4.116 -			XUngrabPointer(dpy, CurrentTime);
   4.117 -			return;
   4.118 -		}
   4.119 -	}
   4.120 -}
   4.121 -
   4.122 -void
   4.123 -mmove(Client *c)
   4.124 -{
   4.125 -	XEvent ev;
   4.126 -	int x1, y1, ocx, ocy, di;
   4.127 -	unsigned int dui;
   4.128 -	Window dummy;
   4.129 -
   4.130 -	ocx = c->x;
   4.131 -	ocy = c->y;
   4.132 -	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
   4.133 -				None, cursor[CurMove], CurrentTime) != GrabSuccess)
   4.134 -		return;
   4.135 -	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
   4.136 -	for(;;) {
   4.137 -		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
   4.138 -		switch (ev.type) {
   4.139 -		default: break;
   4.140 -		case Expose:
   4.141 -			handler[Expose](&ev);
   4.142 -			break;
   4.143 -		case MotionNotify:
   4.144 -			XFlush(dpy);
   4.145 -			c->x = ocx + (ev.xmotion.x - x1);
   4.146 -			c->y = ocy + (ev.xmotion.y - y1);
   4.147 -			resize(c, False);
   4.148 -			break;
   4.149 -		case ButtonRelease:
   4.150 -			XUngrabPointer(dpy, CurrentTime);
   4.151 -			return;
   4.152 -		}
   4.153 -	}
   4.154 -}
     5.1 --- a/draw.c	Fri Jul 14 18:59:25 2006 +0200
     5.2 +++ b/draw.c	Fri Jul 14 22:33:38 2006 +0200
     5.3 @@ -10,6 +10,71 @@
     5.4  
     5.5  #include "dwm.h"
     5.6  
     5.7 +void
     5.8 +draw_bar()
     5.9 +{
    5.10 +	int i;
    5.11 +
    5.12 +	dc.x = dc.y = 0;
    5.13 +	dc.w = bw;
    5.14 +	drawtext(NULL, False, False);
    5.15 +
    5.16 +	if(arrange == floating) {
    5.17 +		dc.w = textw("~");
    5.18 +		drawtext("~", False, False);
    5.19 +	}
    5.20 +	else
    5.21 +		dc.w = 0;
    5.22 +	for(i = 0; i < TLast; i++) {
    5.23 +		dc.x += dc.w;
    5.24 +		dc.w = textw(tags[i]);
    5.25 +		drawtext(tags[i], i == tsel, True);
    5.26 +	}
    5.27 +	if(sel) {
    5.28 +		dc.x += dc.w;
    5.29 +		dc.w = textw(sel->name);
    5.30 +		drawtext(sel->name, True, True);
    5.31 +	}
    5.32 +	dc.w = textw(stext);
    5.33 +	dc.x = bx + bw - dc.w;
    5.34 +	drawtext(stext, False, False);
    5.35 +
    5.36 +	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
    5.37 +	XFlush(dpy);
    5.38 +}
    5.39 +
    5.40 +void
    5.41 +draw_client(Client *c)
    5.42 +{
    5.43 +	int i;
    5.44 +	if(c == sel) {
    5.45 +		draw_bar();
    5.46 +		XUnmapWindow(dpy, c->title);
    5.47 +		XSetWindowBorder(dpy, c->win, dc.fg);
    5.48 +		return;
    5.49 +	}
    5.50 +
    5.51 +	XSetWindowBorder(dpy, c->win, dc.bg);
    5.52 +	XMapWindow(dpy, c->title);
    5.53 +
    5.54 +	dc.x = dc.y = 0;
    5.55 +
    5.56 +	dc.w = 0;
    5.57 +	for(i = 0; i < TLast; i++) {
    5.58 +		if(c->tags[i]) {
    5.59 +			dc.x += dc.w;
    5.60 +			dc.w = textw(c->tags[i]);
    5.61 +			drawtext(c->tags[i], False, True);
    5.62 +		}
    5.63 +	}
    5.64 +	dc.x += dc.w;
    5.65 +	dc.w = textw(c->name);
    5.66 +	drawtext(c->name, False, True);
    5.67 +	XCopyArea(dpy, dc.drawable, c->title, dc.gc,
    5.68 +			0, 0, c->tw, c->th, 0, 0);
    5.69 +	XFlush(dpy);
    5.70 +}
    5.71 +
    5.72  static void
    5.73  drawborder(void)
    5.74  {
    5.75 @@ -103,7 +168,7 @@
    5.76  unsigned int
    5.77  textw(char *text)
    5.78  {
    5.79 -	return textnw(text, strlen(text));
    5.80 +	return textnw(text, strlen(text)) + dc.font.height;
    5.81  }
    5.82  
    5.83  void
     6.1 --- a/dwm.h	Fri Jul 14 18:59:25 2006 +0200
     6.2 +++ b/dwm.h	Fri Jul 14 22:33:38 2006 +0200
     6.3 @@ -94,6 +94,7 @@
     6.4  extern Bool running, issel;
     6.5  extern void (*handler[LASTEvent])(XEvent *);
     6.6  extern void (*arrange)(Arg *);
     6.7 +extern Key key[];
     6.8  
     6.9  extern int tsel, screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
    6.10  extern char *tags[TLast], stext[1024];
    6.11 @@ -101,35 +102,24 @@
    6.12  extern DC dc;
    6.13  extern Client *clients, *sel;
    6.14  
    6.15 -/* bar.c */
    6.16 -extern void draw_bar();
    6.17 -extern void barclick(XButtonPressedEvent *e);
    6.18 -
    6.19  /* client.c */
    6.20  extern void manage(Window w, XWindowAttributes *wa);
    6.21  extern void unmanage(Client *c);
    6.22  extern Client *getclient(Window w);
    6.23  extern void focus(Client *c);
    6.24  extern void update_name(Client *c);
    6.25 -extern void draw_client(Client *c);
    6.26  extern void resize(Client *c, Bool inc);
    6.27  extern void update_size(Client *c);
    6.28  extern Client *gettitle(Window w);
    6.29  extern void craise(Client *c);
    6.30  extern void lower(Client *c);
    6.31 -extern void ckill(Arg *arg);
    6.32 -extern void nextc(Arg *arg);
    6.33 -extern void prevc(Arg *arg);
    6.34 -extern void max(Arg *arg);
    6.35 -extern void floating(Arg *arg);
    6.36 -extern void tiling(Arg *arg);
    6.37 -extern void ttrunc(Arg *arg);
    6.38 -extern void tappend(Arg *arg);
    6.39 -extern void view(Arg *arg);
    6.40 -extern void zoom(Arg *arg);
    6.41  extern void gravitate(Client *c, Bool invert);
    6.42 +extern void ban_client(Client *c);
    6.43 +extern Client *next(Client *c);
    6.44  
    6.45  /* draw.c */
    6.46 +extern void draw_bar();
    6.47 +extern void draw_client(Client *c);
    6.48  extern void drawtext(const char *text, Bool invert, Bool border);
    6.49  extern unsigned long initcolor(const char *colstr);
    6.50  extern void initfont(const char *fontstr);
    6.51 @@ -137,11 +127,9 @@
    6.52  extern unsigned int textw(char *text);
    6.53  extern unsigned int texth(void);
    6.54  
    6.55 -/* dev.c */
    6.56 -extern void update_keys(void);
    6.57 +/* key.c */
    6.58 +extern void grabkeys();
    6.59  extern void keypress(XEvent *e);
    6.60 -extern void mresize(Client *c);
    6.61 -extern void mmove(Client *c);
    6.62  
    6.63  /* main.c */
    6.64  extern int error_handler(Display *dsply, XErrorEvent *e);
    6.65 @@ -149,6 +137,11 @@
    6.66  extern int win_proto(Window w);
    6.67  extern void quit(Arg *arg);
    6.68  
    6.69 +/* screen.c */
    6.70 +extern void floating(Arg *arg);
    6.71 +extern void tiling(Arg *arg);
    6.72 +extern void view(Arg *arg);
    6.73 +
    6.74  /* util.c */
    6.75  extern void error(const char *errstr, ...);
    6.76  extern void *emallocz(unsigned int size);
     7.1 --- a/event.c	Fri Jul 14 18:59:25 2006 +0200
     7.2 +++ b/event.c	Fri Jul 14 22:33:38 2006 +0200
     7.3 @@ -7,11 +7,15 @@
     7.4  #include <stdio.h>
     7.5  #include <stdlib.h>
     7.6  #include <string.h>
     7.7 +#include <unistd.h>
     7.8  #include <X11/keysym.h>
     7.9  #include <X11/Xatom.h>
    7.10  
    7.11  #include "dwm.h"
    7.12  
    7.13 +#define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
    7.14 +#define MouseMask       (ButtonMask | PointerMotionMask)
    7.15 +
    7.16  /* local functions */
    7.17  static void buttonpress(XEvent *e);
    7.18  static void configurerequest(XEvent *e);
    7.19 @@ -19,7 +23,6 @@
    7.20  static void enternotify(XEvent *e);
    7.21  static void leavenotify(XEvent *e);
    7.22  static void expose(XEvent *e);
    7.23 -static void keymapnotify(XEvent *e);
    7.24  static void maprequest(XEvent *e);
    7.25  static void propertynotify(XEvent *e);
    7.26  static void unmapnotify(XEvent *e);
    7.27 @@ -32,21 +35,100 @@
    7.28  	[LeaveNotify] = leavenotify,
    7.29  	[Expose] = expose,
    7.30  	[KeyPress] = keypress,
    7.31 -	[KeymapNotify] = keymapnotify,
    7.32  	[MapRequest] = maprequest,
    7.33  	[PropertyNotify] = propertynotify,
    7.34  	[UnmapNotify] = unmapnotify
    7.35  };
    7.36  
    7.37  static void
    7.38 +mresize(Client *c)
    7.39 +{
    7.40 +	XEvent ev;
    7.41 +	int ocx, ocy;
    7.42 +
    7.43 +	ocx = c->x;
    7.44 +	ocy = c->y;
    7.45 +	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
    7.46 +				None, cursor[CurResize], CurrentTime) != GrabSuccess)
    7.47 +		return;
    7.48 +	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
    7.49 +	for(;;) {
    7.50 +		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
    7.51 +		switch(ev.type) {
    7.52 +		default: break;
    7.53 +		case Expose:
    7.54 +			handler[Expose](&ev);
    7.55 +			break;
    7.56 +		case MotionNotify:
    7.57 +			XFlush(dpy);
    7.58 +			c->w = abs(ocx - ev.xmotion.x);
    7.59 +			c->h = abs(ocy - ev.xmotion.y);
    7.60 +			c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
    7.61 +			c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
    7.62 +			resize(c, True);
    7.63 +			break;
    7.64 +		case ButtonRelease:
    7.65 +			XUngrabPointer(dpy, CurrentTime);
    7.66 +			return;
    7.67 +		}
    7.68 +	}
    7.69 +}
    7.70 +
    7.71 +static void
    7.72 +mmove(Client *c)
    7.73 +{
    7.74 +	XEvent ev;
    7.75 +	int x1, y1, ocx, ocy, di;
    7.76 +	unsigned int dui;
    7.77 +	Window dummy;
    7.78 +
    7.79 +	ocx = c->x;
    7.80 +	ocy = c->y;
    7.81 +	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
    7.82 +				None, cursor[CurMove], CurrentTime) != GrabSuccess)
    7.83 +		return;
    7.84 +	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
    7.85 +	for(;;) {
    7.86 +		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
    7.87 +		switch (ev.type) {
    7.88 +		default: break;
    7.89 +		case Expose:
    7.90 +			handler[Expose](&ev);
    7.91 +			break;
    7.92 +		case MotionNotify:
    7.93 +			XFlush(dpy);
    7.94 +			c->x = ocx + (ev.xmotion.x - x1);
    7.95 +			c->y = ocy + (ev.xmotion.y - y1);
    7.96 +			resize(c, False);
    7.97 +			break;
    7.98 +		case ButtonRelease:
    7.99 +			XUngrabPointer(dpy, CurrentTime);
   7.100 +			return;
   7.101 +		}
   7.102 +	}
   7.103 +}
   7.104 +
   7.105 +static void
   7.106  buttonpress(XEvent *e)
   7.107  {
   7.108 +	int x;
   7.109 +	Arg a;
   7.110  	XButtonPressedEvent *ev = &e->xbutton;
   7.111  	Client *c;
   7.112  
   7.113 -	if(barwin == ev->window)
   7.114 -		barclick(ev);
   7.115 +	if(barwin == ev->window) {
   7.116 +		x = (arrange == floating) ? textw("~") : 0;
   7.117 +		for(a.i = 0; a.i < TLast; a.i++) {
   7.118 +			x += textw(tags[a.i]);
   7.119 +			if(ev->x < x) {
   7.120 +				view(&a);
   7.121 +				break;
   7.122 +			}
   7.123 +		}
   7.124 +	}
   7.125  	else if((c = getclient(ev->window))) {
   7.126 +		if(arrange == tiling && !c->floating)
   7.127 +			return;
   7.128  		craise(c);
   7.129  		switch(ev->button) {
   7.130  		default:
   7.131 @@ -150,12 +232,6 @@
   7.132  }
   7.133  
   7.134  static void
   7.135 -keymapnotify(XEvent *e)
   7.136 -{
   7.137 -	update_keys();
   7.138 -}
   7.139 -
   7.140 -static void
   7.141  maprequest(XEvent *e)
   7.142  {
   7.143  	XMapRequestEvent *ev = &e->xmaprequest;
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/key.c	Fri Jul 14 22:33:38 2006 +0200
     8.3 @@ -0,0 +1,192 @@
     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 <fcntl.h>
    8.10 +#include <stdio.h>
    8.11 +#include <stdlib.h>
    8.12 +#include <string.h>
    8.13 +#include <unistd.h>
    8.14 +#include <X11/keysym.h>
    8.15 +#include <X11/Xatom.h>
    8.16 +
    8.17 +#include "dwm.h"
    8.18 +
    8.19 +static void ckill(Arg *arg);
    8.20 +static void nextc(Arg *arg);
    8.21 +static void prevc(Arg *arg);
    8.22 +static void max(Arg *arg);
    8.23 +static void ttrunc(Arg *arg);
    8.24 +static void tappend(Arg *arg);
    8.25 +static void zoom(Arg *arg);
    8.26 +
    8.27 +/********** CUSTOMIZE **********/
    8.28 +
    8.29 +const char *term[] = { 
    8.30 +	"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
    8.31 +	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
    8.32 +};
    8.33 +const char *browse[] = { "firefox", NULL };
    8.34 +const char *xlock[] = { "xlock", NULL };
    8.35 +
    8.36 +Key key[] = {
    8.37 +	/* modifier				key			function	arguments */
    8.38 +	{ Mod1Mask,				XK_Return,	zoom,		{ 0 } },
    8.39 +	{ Mod1Mask,				XK_k,		prevc,		{ 0 } },
    8.40 +	{ Mod1Mask,				XK_j,		nextc,		{ 0 } }, 
    8.41 +	{ Mod1Mask,				XK_m,		max,		{ 0 } }, 
    8.42 +	{ Mod1Mask,				XK_0,		view,		{ .i = Tscratch } }, 
    8.43 +	{ Mod1Mask,				XK_1,		view,		{ .i = Tdev } }, 
    8.44 +	{ Mod1Mask,				XK_2,		view,		{ .i = Twww } }, 
    8.45 +	{ Mod1Mask,				XK_3,		view,		{ .i = Twork } }, 
    8.46 +	{ Mod1Mask,				XK_space,	tiling,		{ 0 } }, 
    8.47 +	{ Mod1Mask|ShiftMask,	XK_space,	floating,	{ 0 } }, 
    8.48 +	{ Mod1Mask|ShiftMask,	XK_0,		ttrunc,		{ .i = Tscratch } }, 
    8.49 +	{ Mod1Mask|ShiftMask,	XK_1,		ttrunc,		{ .i = Tdev } }, 
    8.50 +	{ Mod1Mask|ShiftMask,	XK_2,		ttrunc,		{ .i = Twww } }, 
    8.51 +	{ Mod1Mask|ShiftMask,	XK_3,		ttrunc,		{ .i = Twork } }, 
    8.52 +	{ Mod1Mask|ShiftMask,	XK_c,		ckill,		{ 0 } }, 
    8.53 +	{ Mod1Mask|ShiftMask,	XK_q,		quit,		{ 0 } },
    8.54 +	{ Mod1Mask|ShiftMask,	XK_Return,	spawn,		{ .argv = term } },
    8.55 +	{ Mod1Mask|ShiftMask,	XK_w,		spawn,		{ .argv = browse } },
    8.56 +	{ Mod1Mask|ShiftMask,	XK_l,		spawn,		{ .argv = xlock } },
    8.57 +	{ ControlMask,			XK_0,		tappend,	{ .i = Tscratch } }, 
    8.58 +	{ ControlMask,			XK_1,		tappend,	{ .i = Tdev } }, 
    8.59 +	{ ControlMask,			XK_2,		tappend,	{ .i = Twww } }, 
    8.60 +	{ ControlMask,			XK_3,		tappend,	{ .i = Twork } }, 
    8.61 +};
    8.62 +
    8.63 +/********** CUSTOMIZE **********/
    8.64 +
    8.65 +void
    8.66 +grabkeys()
    8.67 +{
    8.68 +	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
    8.69 +	unsigned int i;
    8.70 +	KeyCode code;
    8.71 +
    8.72 +	for(i = 0; i < len; i++) {
    8.73 +		code = XKeysymToKeycode(dpy, key[i].keysym);
    8.74 +		XUngrabKey(dpy, code, key[i].mod, root);
    8.75 +		XGrabKey(dpy, code, key[i].mod, root, True,
    8.76 +				GrabModeAsync, GrabModeAsync);
    8.77 +	}
    8.78 +}
    8.79 +
    8.80 +void
    8.81 +keypress(XEvent *e)
    8.82 +{
    8.83 +	XKeyEvent *ev = &e->xkey;
    8.84 +	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
    8.85 +	unsigned int i;
    8.86 +	KeySym keysym;
    8.87 +
    8.88 +	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
    8.89 +	for(i = 0; i < len; i++)
    8.90 +		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
    8.91 +			if(key[i].func)
    8.92 +				key[i].func(&key[i].arg);
    8.93 +			return;
    8.94 +		}
    8.95 +}
    8.96 +
    8.97 +static void
    8.98 +zoom(Arg *arg)
    8.99 +{
   8.100 +	Client **l, *c;
   8.101 +
   8.102 +	if(!sel)
   8.103 +		return;
   8.104 +
   8.105 +	if(sel == next(clients) && sel->next)  {
   8.106 +		if((c = next(sel->next)))
   8.107 +			sel = c;
   8.108 +	}
   8.109 +
   8.110 +	for(l = &clients; *l && *l != sel; l = &(*l)->next);
   8.111 +	*l = sel->next;
   8.112 +
   8.113 +	sel->next = clients; /* pop */
   8.114 +	clients = sel;
   8.115 +	arrange(NULL);
   8.116 +	focus(sel);
   8.117 +}
   8.118 +
   8.119 +static void
   8.120 +max(Arg *arg)
   8.121 +{
   8.122 +	if(!sel)
   8.123 +		return;
   8.124 +	sel->x = sx;
   8.125 +	sel->y = sy + bh;
   8.126 +	sel->w = sw - 2 * sel->border;
   8.127 +	sel->h = sh - 2 * sel->border - bh;
   8.128 +	craise(sel);
   8.129 +	resize(sel, False);
   8.130 +}
   8.131 +
   8.132 +static void
   8.133 +tappend(Arg *arg)
   8.134 +{
   8.135 +	if(!sel)
   8.136 +		return;
   8.137 +
   8.138 +	sel->tags[arg->i] = tags[arg->i];
   8.139 +	arrange(NULL);
   8.140 +}
   8.141 +
   8.142 +static void
   8.143 +ttrunc(Arg *arg)
   8.144 +{
   8.145 +	int i;
   8.146 +	if(!sel)
   8.147 +		return;
   8.148 +
   8.149 +	for(i = 0; i < TLast; i++)
   8.150 +		sel->tags[i] = NULL;
   8.151 +	tappend(arg);
   8.152 +}
   8.153 +
   8.154 +static void
   8.155 +prevc(Arg *arg)
   8.156 +{
   8.157 +	Client *c;
   8.158 +
   8.159 +	if(!sel)
   8.160 +		return;
   8.161 +
   8.162 +	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
   8.163 +		craise(c);
   8.164 +		focus(c);
   8.165 +	}
   8.166 +}
   8.167 +
   8.168 +static void
   8.169 +nextc(Arg *arg)
   8.170 +{
   8.171 +	Client *c;
   8.172 +   
   8.173 +	if(!sel)
   8.174 +		return;
   8.175 +
   8.176 +	if(!(c = next(sel->next)))
   8.177 +		c = next(clients);
   8.178 +	if(c) {
   8.179 +		craise(c);
   8.180 +		c->revert = sel;
   8.181 +		focus(c);
   8.182 +	}
   8.183 +}
   8.184 +
   8.185 +static void
   8.186 +ckill(Arg *arg)
   8.187 +{
   8.188 +	if(!sel)
   8.189 +		return;
   8.190 +	if(sel->proto & WM_PROTOCOL_DELWIN)
   8.191 +		send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
   8.192 +	else
   8.193 +		XKillClient(dpy, sel->win);
   8.194 +}
   8.195 +
     9.1 --- a/main.c	Fri Jul 14 18:59:25 2006 +0200
     9.2 +++ b/main.c	Fri Jul 14 22:33:38 2006 +0200
     9.3 @@ -239,7 +239,7 @@
     9.4  	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
     9.5  	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
     9.6  
     9.7 -	update_keys();
     9.8 +	grabkeys();
     9.9  
    9.10  	/* style */
    9.11  	dc.bg = initcolor(BGCOLOR);
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/screen.c	Fri Jul 14 22:33:38 2006 +0200
    10.3 @@ -0,0 +1,100 @@
    10.4 +/*
    10.5 + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
    10.6 + * See LICENSE file for license details.
    10.7 + */
    10.8 +
    10.9 +#include "dwm.h"
   10.10 +
   10.11 +void (*arrange)(Arg *) = tiling;
   10.12 +
   10.13 +void
   10.14 +view(Arg *arg)
   10.15 +{
   10.16 +	Client *c;
   10.17 +
   10.18 +	tsel = arg->i;
   10.19 +	arrange(NULL);
   10.20 +
   10.21 +	for(c = clients; c; c = next(c->next))
   10.22 +		draw_client(c);
   10.23 +	draw_bar();
   10.24 +}
   10.25 +
   10.26 +void
   10.27 +floating(Arg *arg)
   10.28 +{
   10.29 +	Client *c;
   10.30 +
   10.31 +	arrange = floating;
   10.32 +	for(c = clients; c; c = c->next) {
   10.33 +		if(c->tags[tsel])
   10.34 +			resize(c, True);
   10.35 +		else
   10.36 +			ban_client(c);
   10.37 +	}
   10.38 +	if(sel && !sel->tags[tsel]) {
   10.39 +		if((sel = next(clients))) {
   10.40 +			craise(sel);
   10.41 +			focus(sel);
   10.42 +		}
   10.43 +	}
   10.44 +	draw_bar();
   10.45 +}
   10.46 +
   10.47 +void
   10.48 +tiling(Arg *arg)
   10.49 +{
   10.50 +	Client *c;
   10.51 +	int n, i, w, h;
   10.52 +
   10.53 +	w = sw - mw;
   10.54 +	arrange = tiling;
   10.55 +	for(n = 0, c = clients; c; c = c->next)
   10.56 +		if(c->tags[tsel] && !c->floating)
   10.57 +			n++;
   10.58 +
   10.59 +	if(n > 1)
   10.60 +		h = (sh - bh) / (n - 1);
   10.61 +	else
   10.62 +		h = sh - bh;
   10.63 +
   10.64 +	for(i = 0, c = clients; c; c = c->next) {
   10.65 +		if(c->tags[tsel]) {
   10.66 +			if(c->floating) {
   10.67 +				craise(c);
   10.68 +				resize(c, True);
   10.69 +				continue;
   10.70 +			}
   10.71 +			if(n == 1) {
   10.72 +				c->x = sx;
   10.73 +				c->y = sy + bh;
   10.74 +				c->w = sw - 2 * c->border;
   10.75 +				c->h = sh - 2 * c->border - bh;
   10.76 +			}
   10.77 +			else if(i == 0) {
   10.78 +				c->x = sx;
   10.79 +				c->y = sy + bh;
   10.80 +				c->w = mw - 2 * c->border;
   10.81 +				c->h = sh - 2 * c->border - bh;
   10.82 +			}
   10.83 +			else {
   10.84 +				c->x = sx + mw;
   10.85 +				c->y = sy + (i - 1) * h + bh;
   10.86 +				c->w = w - 2 * c->border;
   10.87 +				c->h = h - 2 * c->border;
   10.88 +			}
   10.89 +			resize(c, False);
   10.90 +			i++;
   10.91 +		}
   10.92 +		else
   10.93 +			ban_client(c);
   10.94 +	}
   10.95 +	if(!sel || (sel && !sel->tags[tsel])) {
   10.96 +		if((sel = next(clients))) {
   10.97 +			craise(sel);
   10.98 +			focus(sel);
   10.99 +		}
  10.100 +	}
  10.101 +	draw_bar();
  10.102 +}
  10.103 +