diff options
| -rw-r--r-- | Makefile | 24 | ||||
| -rw-r--r-- | README | 25 | ||||
| -rw-r--r-- | client.c | 55 | ||||
| -rw-r--r-- | config.mk | 8 | ||||
| -rw-r--r-- | draw.c | 73 | ||||
| -rw-r--r-- | dwm.1 (renamed from gridwm.1) | 0 | ||||
| -rw-r--r-- | dwm.html | 77 | ||||
| -rw-r--r-- | kb.c | 5 | ||||
| -rw-r--r-- | logo.png | bin | 0 -> 387 bytes | |||
| -rw-r--r-- | util.c | 2 | ||||
| -rw-r--r-- | wm.c | 23 | ||||
| -rw-r--r-- | wm.h | 17 | 
12 files changed, 194 insertions, 115 deletions
| @@ -1,18 +1,18 @@ -# gridwm - grid window manager +# dwm - dynamic window manager  #   (C)opyright MMVI Anselm R. Garbe  include config.mk  SRC = client.c draw.c event.c kb.c mouse.c util.c wm.c  OBJ = ${SRC:.c=.o} -MAN1 = gridwm.1  -BIN = gridwm +MAN1 = dwm.1  +BIN = dwm -all: config gridwm +all: config dwm  	@echo finished  config: -	@echo gridwm build options: +	@echo dwm build options:  	@echo "LIBS     = ${LIBS}"  	@echo "CFLAGS   = ${CFLAGS}"  	@echo "LDFLAGS  = ${LDFLAGS}" @@ -24,19 +24,19 @@ config:  ${OBJ}: wm.h -gridwm: ${OBJ} +dwm: ${OBJ}  	@echo LD $@  	@${CC} -o $@ ${OBJ} ${LDFLAGS}  clean: -	rm -f gridwm *.o core +	rm -f dwm *.o core  dist: clean -	mkdir -p gridwm-${VERSION} -	cp -R Makefile README LICENSE config.mk *.h *.c ${MAN} gridwm-${VERSION} -	tar -cf gridwm-${VERSION}.tar gridwm-${VERSION} -	gzip gridwm-${VERSION}.tar -	rm -rf gridwm-${VERSION} +	mkdir -p dwm-${VERSION} +	cp -R Makefile README LICENSE config.mk *.h *.c ${MAN} dwm-${VERSION} +	tar -cf dwm-${VERSION}.tar dwm-${VERSION} +	gzip dwm-${VERSION}.tar +	rm -rf dwm-${VERSION}  install: all  	@mkdir -p ${DESTDIR}${PREFIX}/bin @@ -1,41 +1,40 @@ -gridwm +dwm  ------ -gridwm is an extremly fast, small, and automatic X11 window manager.  It -arranges all windows in a grid. +dwm is an extremly fast, small, and dynamic X11 window manager.  Requirements  ------------ -In order to build gridwm you need the Xlib header files. +In order to build dwm you need the Xlib header files.  Installation  ------------ -Edit config.mk to match your local setup. gridwm is installed into +Edit config.mk to match your local setup. dwm is installed into  the /usr/local namespace by default. -Afterwards enter the following command to build and install gridwm (if +Afterwards enter the following command to build and install dwm (if  necessary as root):      make clean install -Running gridwm +Running dwm  -------------- -Add the following line to your .xinitrc to start gridwm using startx: +Add the following line to your .xinitrc to start dwm using startx: -    exec gridwm +    exec dwm -In order to connect gridwm to a specific display, make sure that +In order to connect dwm to a specific display, make sure that  the DISPLAY environment variable is set correctly, e.g.: -    DISPLAY=foo.bar:1 exec gridwm +    DISPLAY=foo.bar:1 exec dwm -This will start gridwm on display :1 of the host foo.bar. +This will start dwm on display :1 of the host foo.bar.  Configuration  ------------- -The configuration of gridwm is done by customizing the wm.h source file. To +The configuration of dwm is done by customizing the wm.h source file. To  customize the key bindings edit kb.c. @@ -11,7 +11,9 @@  #include "wm.h" -void (*arrange)(void *aux); +static void floating(void); +static void tiling(void); +static void (*arrange)(void) = tiling;  void  max(void *aux) @@ -26,25 +28,23 @@ max(void *aux)  	discard_events(EnterWindowMask);  } -void -floating(void *aux) +static void +floating(void)  {  	Client *c; -	arrange = floating;  	for(c = stack; c; c = c->snext)  		resize(c);  	discard_events(EnterWindowMask);  } -void -grid(void *aux) +static void +tiling(void)  {  	Client *c;  	int n, cols, rows, gw, gh, i, j;      float rt, fd; -	arrange = grid;  	if(!clients)  		return;  	for(n = 0, c = clients; c; c = c->next, n++); @@ -76,6 +76,17 @@ grid(void *aux)  }  void +toggle(void *aux) +{ +	if(arrange == floating) +		arrange = tiling; +	else +		arrange = floating; +	arrange(); +} + + +void  sel(void *aux)  {  	const char *arg = aux; @@ -114,8 +125,8 @@ resize_title(Client *c)  	c->tw = 0;  	for(i = 0; i < TLast; i++)  		if(c->tags[i]) -			c->tw += textw(&brush.font, c->tags[i]) + brush.font.height; -	c->tw += textw(&brush.font, c->name) + brush.font.height; +			c->tw += textw(&dc.font, c->tags[i]) + dc.font.height; +	c->tw += textw(&dc.font, c->name) + dc.font.height;  	if(c->tw > c->w)  		c->tw = c->w + 2;  	c->tx = c->x + c->w - c->tw + 2; @@ -240,7 +251,7 @@ manage(Window w, XWindowAttributes *wa)  	c->border = 1;  	update_size(c);  	XSetWindowBorderWidth(dpy, c->win, 1); -	XSetWindowBorder(dpy, c->win, brush.border); +	XSetWindowBorder(dpy, c->win, dc.border);  	XSelectInput(dpy, c->win,  			StructureNotifyMask | PropertyChangeMask | EnterWindowMask);  	XGetTransientForHint(dpy, c->win, &c->trans); @@ -266,7 +277,7 @@ manage(Window w, XWindowAttributes *wa)  			GrabModeAsync, GrabModeSync, None, None);  	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,  			GrabModeAsync, GrabModeSync, None, None); -	arrange(NULL); +	arrange();  	focus(c);  } @@ -385,7 +396,7 @@ unmanage(Client *c)  	XFlush(dpy);  	XSetErrorHandler(error_handler);  	XUngrabServer(dpy); -	arrange(NULL); +	arrange();  	if(stack)  		focus(stack);  } @@ -417,21 +428,21 @@ draw_client(Client *c)  	if(c == stack)  		return; -	brush.x = brush.y = 0; -	brush.h = c->th; +	dc.x = dc.y = 0; +	dc.h = c->th; -	brush.w = 0; +	dc.w = 0;  	for(i = 0; i < TLast; i++) {  		if(c->tags[i]) { -			brush.x += brush.w; -			brush.w = textw(&brush.font, c->tags[i]) + brush.font.height; -			draw(&brush, True, c->tags[i]); +			dc.x += dc.w; +			dc.w = textw(&dc.font, c->tags[i]) + dc.font.height; +			draw(True, c->tags[i]);  		}  	} -	brush.x += brush.w; -	brush.w = textw(&brush.font, c->name) + brush.font.height; -	draw(&brush, True, c->name); -	XCopyArea(dpy, brush.drawable, c->title, brush.gc, +	dc.x += dc.w; +	dc.w = textw(&dc.font, c->name) + dc.font.height; +	draw(True, c->name); +	XCopyArea(dpy, dc.drawable, c->title, dc.gc,  			0, 0, c->tw, c->th, 0, 0);  	XFlush(dpy);  } @@ -14,14 +14,10 @@ VERSION = 0.0  LIBS = -L${PREFIX}/lib -L/usr/lib -lc -lm -L${X11LIB} -lX11  # Linux/BSD -CFLAGS = -Os -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \ +CFLAGS = -g -Wall -O2 -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \  	-DVERSION=\"${VERSION}\" -LDFLAGS = ${LIBS} -#CFLAGS  += -W -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wcast-qual -Wshadow -Waggregate-return -Wnested-externs -Winline -Wwrite-strings -Wundef -Wsign-compare -Wmissing-prototypes -Wredundant-decls +LDFLAGS = -g ${LIBS} -#CFLAGS = -g -Wall -O2 -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \ -#	-DVERSION=\"${VERSION}\" -#LDFLAGS = -g ${LIBS}  # Solaris  #CFLAGS = -fast -xtarget=ultra ${INCLUDES} -DVERSION=\"${VERSION}\" @@ -11,39 +11,39 @@  #include "wm.h"  static void -drawborder(Brush *b) +drawborder(void)  {  	XPoint points[5]; -	XSetLineAttributes(dpy, b->gc, 1, LineSolid, CapButt, JoinMiter); -	XSetForeground(dpy, b->gc, b->border); -	points[0].x = b->x; -	points[0].y = b->y; -	points[1].x = b->w - 1; +	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); +	XSetForeground(dpy, dc.gc, dc.border); +	points[0].x = dc.x; +	points[0].y = dc.y; +	points[1].x = dc.w - 1;  	points[1].y = 0;  	points[2].x = 0; -	points[2].y = b->h - 1; -	points[3].x = -(b->w - 1); +	points[2].y = dc.h - 1; +	points[3].x = -(dc.w - 1);  	points[3].y = 0;  	points[4].x = 0; -	points[4].y = -(b->h - 1); -	XDrawLines(dpy, b->drawable, b->gc, points, 5, CoordModePrevious); +	points[4].y = -(dc.h - 1); +	XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);  }  void -draw(Brush *b, Bool border, const char *text) +draw(Bool border, const char *text)  {  	int x, y, w, h;  	unsigned int len;  	static char buf[256];  	XGCValues gcv; -	XRectangle r = { b->x, b->y, b->w, b->h }; +	XRectangle r = { dc.x, dc.y, dc.w, dc.h }; -	XSetForeground(dpy, b->gc, b->bg); -	XFillRectangles(dpy, b->drawable, b->gc, &r, 1); +	XSetForeground(dpy, dc.gc, dc.bg); +	XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);  	w = 0;  	if(border) -		drawborder(b); +		drawborder();  	if(!text)  		return; @@ -54,33 +54,33 @@ draw(Brush *b, Bool border, const char *text)  	memcpy(buf, text, len);  	buf[len] = 0; -	h = b->font.ascent + b->font.descent; -	y = b->y + (b->h / 2) - (h / 2) + b->font.ascent; -	x = b->x + (h / 2); +	h = dc.font.ascent + dc.font.descent; +	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; +	x = dc.x + (h / 2);  	/* shorten text if necessary */ -	while(len && (w = textnw(&b->font, buf, len)) > b->w - h) +	while(len && (w = textnw(&dc.font, buf, len)) > dc.w - h)  		buf[--len] = 0; -	if(w > b->w) +	if(w > dc.w)  		return; /* too long */ -	gcv.foreground = b->fg; -	gcv.background = b->bg; -	if(b->font.set) { -		XChangeGC(dpy, b->gc, GCForeground | GCBackground, &gcv); -		XmbDrawImageString(dpy, b->drawable, b->font.set, b->gc, +	gcv.foreground = dc.fg; +	gcv.background = dc.bg; +	if(dc.font.set) { +		XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv); +		XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc,  				x, y, buf, len);  	}  	else { -		gcv.font = b->font.xfont->fid; -		XChangeGC(dpy, b->gc, GCForeground | GCBackground | GCFont, &gcv); -		XDrawImageString(dpy, b->drawable, b->gc, x, y, buf, len); +		gcv.font = dc.font.xfont->fid; +		XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv); +		XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len);  	}  }  static unsigned long -xloadcolors(Colormap cmap, const char *colstr) +xinitcolors(Colormap cmap, const char *colstr)  {  	XColor color;  	XAllocNamedColor(dpy, cmap, colstr, &color, &color); @@ -88,13 +88,12 @@ xloadcolors(Colormap cmap, const char *colstr)  }  void -loadcolors(int scr, Brush *b, -		const char *bg, const char *fg, const char *border) +initcolors(const char *bg, const char *fg, const char *border)  { -	Colormap cmap = DefaultColormap(dpy, scr); -	b->bg = xloadcolors(cmap, bg); -	b->fg = xloadcolors(cmap, fg); -	b->border = xloadcolors(cmap, border); +	Colormap cmap = DefaultColormap(dpy, screen); +	dc.bg = xinitcolors(cmap, bg); +	dc.fg = xinitcolors(cmap, fg); +	dc.border = xinitcolors(cmap, border);  }  unsigned int @@ -121,7 +120,7 @@ texth(Fnt *font)  }  void -loadfont(Fnt *font, const char *fontstr) +initfont(Fnt *font, const char *fontstr)  {  	char **missing, *def;  	int i, n; @@ -164,7 +163,7 @@ loadfont(Fnt *font, const char *fontstr)  		if (!font->xfont)  			font->xfont = XLoadQueryFont(dpy, "fixed");  		if (!font->xfont) -			error("error, cannot load 'fixed' font\n"); +			error("error, cannot init 'fixed' font\n");  		font->ascent = font->xfont->ascent;  		font->descent = font->xfont->descent;  	} diff --git a/dwm.html b/dwm.html new file mode 100644 index 0000000..b617c8c --- /dev/null +++ b/dwm.html @@ -0,0 +1,77 @@ +<html> +	<head> +		<title>dwm - dynamic window manager</title> +		<meta name="author" content="Anselm R. Garbe"> +		<meta name="generator" content="ed"> +		<meta name="copyright" content="(C)opyright 2006 by Anselm R. Garbe"> +		<style type="text/css"> +			body { +				color: #000000; +				font-family: sans-serif; +			} +		</style> +	</head> +	<body> +		<center> +			<img src="logo.png"/><br /> +			<h3>dynamic window manager</h3> +		<center> +		<h2>Description</h3> +		<p> +		dwm is a dynamic window manager for X11. +		</p> +		<h2>Differences to wmii</h2	 +		<p> +		In contrast to wmii, dwm is only a window manager, and nothing else. +		Hence, it is much smaller, faster and simpler. dwm does +		<b>not</b> include following features wmii provides: +		</p> +		<ul> +			<li>9P support</li> +			<li>status bar</li> +			<li>menu</li> +			<li>editable tagbars</li> +			<li>shell-based config/control file</li> +			<li>small tools (selection printer, mouse warper)</li> +		</ul> +		<p> +		dwm is only a single binary, it's source code is intended to never +		exceed 2000 SLOC. +		</p> +		<p> +		dwm is customized through editing its source code, that makes it +		extremely fast and secure - it does not process any input data which +		hasn't been known at compile time, except window title names. +		</p> +		<p> +		dwm is based on tagging and dynamic window management (however simpler +		than wmii or larswm). +		</p> +		<p> +		dwm don't distinguishes between layers, there is no floating or managed +		layer. Wether the clients of currently selected tag are managed or not +		managed, you can re-arrange all clients on the fly. Popup- and +		fixed-size windows are treated unmanaged.  +		</p> +		<p> +		dwm uses 1-pixel borders to provide the maximum of screen real +		estate to clients. Small titlebars are only drawn in front of unfocused +		clients. +		</p> +		<p> +		garbeam <b>don't</b> wants any feedback to dwm. If you ask for support, +		feature requests or if you report bugs, they will be <b>ignored</b> +		with a high chance. dwm is only intended to fit garbeam's needs, +		however you are free to download and distribute/relicense it, with the +		conditions of the <a href="http://wmii.de/cgi-bin/hgwebdir.cgi/dwm?f=f10eb1139362;file=LICENSE;style=raw">MIT/X Consortium license</a>. +		</p> +		<h2>Development</h2> +		<p> +		dwm is actively developed in parallel to wmii. You can <a href="http://wmii.de/cgi-bin/hgwebdir.cgi/dwm">browse</a> its source code repository or get a copy using <a href="http://www.selenic.com/mercurial/">Mercurial</a> with following command: +		</p> +		<p> +		<em>hg clone http://wmii.de/cgi-bin/hgwebdir.cgi/dwm</em> +		</p> +		<p>--Anselm</p> +	</body> +</html> @@ -13,13 +13,14 @@ const char *term[] = {  	"aterm", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",  	"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL  }; +const char *browse[] = { "firefox", NULL };  static Key key[] = {  	{ Mod1Mask, XK_Return, (void (*)(void *))spawn, term }, +	{ Mod1Mask, XK_w, (void (*)(void *))spawn, browse },  	{ Mod1Mask, XK_k, sel, "prev" },   	{ Mod1Mask, XK_j, sel, "next" },  -	{ Mod1Mask, XK_g, grid, NULL },  -	{ Mod1Mask, XK_f, floating, NULL },  +	{ Mod1Mask, XK_space, toggle, NULL },   	{ Mod1Mask, XK_m, max, NULL },   	{ Mod1Mask | ShiftMask, XK_c, ckill, NULL },   	{ Mod1Mask | ShiftMask, XK_q, quit, NULL }, diff --git a/logo.png b/logo.pngBinary files differ new file mode 100644 index 0000000..ebfc8ed --- /dev/null +++ b/logo.png @@ -85,7 +85,7 @@ spawn(char *argv[])  				close(ConnectionNumber(dpy));  			setsid();  			execvp(argv[0], argv); -			fprintf(stderr, "gridwm: execvp %s", argv[0]); +			fprintf(stderr, "dwm: execvp %s", argv[0]);  			perror(" failed");  		}  		exit (0); @@ -37,17 +37,17 @@ char stext[1024];  int tsel = Tdev; /* default tag */  int screen, sx, sy, sw, sh, th; -Brush brush = {0}; +DC dc = {0};  Client *clients = NULL;  Client *stack = NULL;  static Bool other_wm_running;  static const char version[] = -	"gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; +	"dwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";  static int (*x_error_handler) (Display *, XErrorEvent *);  static void -usage() {	error("usage: gridwm [-v]\n"); } +usage() {	error("usage: dwm [-v]\n"); }  static void  scan_wins() @@ -149,7 +149,7 @@ error_handler(Display *dpy, XErrorEvent *error)  			|| (error->request_code == X_GrabKey  				&& error->error_code == BadAccess))  		return 0; -	fprintf(stderr, "gridwm: fatal error: request code=%d, error code=%d\n", +	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",  			error->request_code, error->error_code);  	return x_error_handler(dpy, error); /* may call exit() */  } @@ -203,7 +203,7 @@ main(int argc, char *argv[])  	dpy = XOpenDisplay(0);  	if(!dpy) -		error("gridwm: cannot connect X server\n"); +		error("dwm: cannot connect X server\n");  	screen = DefaultScreen(dpy);  	root = RootWindow(dpy, screen); @@ -216,7 +216,7 @@ main(int argc, char *argv[])  	XFlush(dpy);  	if(other_wm_running) -		error("gridwm: another window manager is already running\n"); +		error("dwm: another window manager is already running\n");  	sx = sy = 0;  	sw = DisplayWidth(dpy, screen); @@ -244,20 +244,19 @@ main(int argc, char *argv[])  	update_keys();  	/* style */ -	loadcolors(screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR); -	loadfont(&brush.font, FONT); +	initcolors(BGCOLOR, FGCOLOR, BORDERCOLOR); +	initfont(&dc.font, FONT); -	th = texth(&brush.font); +	th = texth(&dc.font); -	brush.drawable = XCreatePixmap(dpy, root, sw, th, DefaultDepth(dpy, screen)); -	brush.gc = XCreateGC(dpy, root, 0, 0); +	dc.drawable = XCreatePixmap(dpy, root, sw, th, DefaultDepth(dpy, screen)); +	dc.gc = XCreateGC(dpy, root, 0, 0);  	wa.event_mask = SubstructureRedirectMask | EnterWindowMask \  					| LeaveWindowMask;  	wa.cursor = cursor[CurNormal];  	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); -	arrange = grid;  	scan_wins();  	while(running) { @@ -19,7 +19,7 @@ enum { Tscratch, Tdev, Tirc, Twww, Twork, TLast };  /********** CUSTOMIZE **********/ -typedef struct Brush Brush; +typedef struct DC DC;  typedef struct Client Client;  typedef struct Fnt Fnt;  typedef struct Key Key; @@ -39,7 +39,7 @@ struct Fnt {  	int height;  }; -struct Brush { +struct DC { /* draw context */  	GC gc;  	Drawable drawable;  	int x, y, w, h; @@ -79,12 +79,11 @@ extern Atom wm_atom[WMLast], net_atom[NetLast];  extern Cursor cursor[CurLast];  extern Bool running, issel;  extern void (*handler[LASTEvent]) (XEvent *); -extern void (*arrange)(void *aux);  extern int tsel, screen, sx, sy, sw, sh, th;  extern char stext[1024], *tags[TLast]; -extern Brush brush; +extern DC dc;  extern Client *clients, *stack;  /* client.c */ @@ -102,15 +101,13 @@ 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 grid(void *aux); +extern void toggle(void *aux);  extern void gravitate(Client *c, Bool invert);  /* draw.c */ -extern void draw(Brush *b, Bool border, const char *text); -extern void loadcolors(int scr, Brush *b, -		const char *bg, const char *fg, const char *bo); -extern void loadfont(Fnt *font, const char *fontstr); +extern void draw(Bool border, const char *text); +extern void initcolors(const char *bg, const char *fg, const char *bo); +extern void initfont(Fnt *font, const char *fontstr);  extern unsigned int textnw(Fnt *font, char *text, unsigned int len);  extern unsigned int textw(Fnt *font, char *text);  extern unsigned int texth(Fnt *font); | 
