diff -ru evilwm-0.99.25-orig/README evilwm-0.99.25/README
--- evilwm-0.99.25-orig/README	2006-02-13 13:06:28.000000000 +0000
+++ evilwm-0.99.25/README	2007-03-05 21:08:07.000000000 +0000
@@ -65,8 +65,10 @@
 H, J, K, L	Move window left, down, up or right (16 pixels).
 		Holding Shift resizes the window instead.
 Y, U, B, N	Move window to top-left, top-right, bottom-left or
-		bottom-right of screen.
+		bottom-right of screen.  Holding Shift resizes the
+		window instead.
 I		Show information about current window.
+Minus		Maximise current window horizontally (toggle).
 Equals		Maximise current window vertically (toggle).
 X		Maximise current window (toggle).
 
diff -ru evilwm-0.99.25-orig/events.c evilwm-0.99.25/events.c
--- evilwm-0.99.25-orig/events.c	2006-04-26 19:53:10.000000000 +0100
+++ evilwm-0.99.25/events.c	2007-03-06 10:07:14.000000000 +0000
@@ -103,20 +103,36 @@
 			}
 			goto move_client;
 		case KEY_TOPLEFT:
+			if (e->state & altmask) {
+				maximise_client(c, MAXIMISE_TOPLEFT);
+				break;
+			}
 			c->x = c->border;
 			c->y = c->border;
 			goto move_client;
 		case KEY_TOPRIGHT:
+			if (e->state & altmask) {
+				maximise_client(c, MAXIMISE_TOPRIGHT);
+				break;
+			}
 			c->x = DisplayWidth(dpy, c->screen->screen)
 				- c->width-c->border;
 			c->y = c->border;
 			goto move_client;
 		case KEY_BOTTOMLEFT:
+			if (e->state & altmask) {
+				maximise_client(c, MAXIMISE_BOTTOMLEFT);
+				break;
+			}
 			c->x = c->border;
 			c->y = DisplayHeight(dpy, c->screen->screen)
 				- c->height-c->border;
 			goto move_client;
 		case KEY_BOTTOMRIGHT:
+			if (e->state & altmask) {
+				maximise_client(c, MAXIMISE_BOTTOMRIGHT);
+				break;
+			}
 			c->x = DisplayWidth(dpy, c->screen->screen)
 				- c->width-c->border;
 			c->y = DisplayHeight(dpy, c->screen->screen)
@@ -134,6 +150,9 @@
 		case KEY_MAX:
 			maximise_client(c, MAXIMISE_HORZ|MAXIMISE_VERT);
 			break;
+		case KEY_MAXHORZ:
+			maximise_client(c, MAXIMISE_HORZ);
+			break;
 		case KEY_MAXVERT:
 			maximise_client(c, MAXIMISE_VERT);
 			break;
diff -ru evilwm-0.99.25-orig/evilwm.1 evilwm-0.99.25/evilwm.1
--- evilwm-0.99.25-orig/evilwm.1	2006-02-13 11:39:38.000000000 +0000
+++ evilwm-0.99.25/evilwm.1	2007-03-05 21:07:49.000000000 +0000
@@ -67,9 +67,11 @@
 window instead.
 .IP "Y, U, B, N"
 Move window to top-left, top-right, bottom-left or
-bottom-right of screen.
+bottom-right of screen.  Holding Shift resizes the window instead.
 .IP I
 Show information about current window.
+.IP Minus
+Maximise current window horizontally (toggle).
 .IP Equals
 Maximise current window vertically (toggle).
 .IP X
diff -ru evilwm-0.99.25-orig/evilwm.h evilwm-0.99.25/evilwm.h
--- evilwm-0.99.25-orig/evilwm.h	2006-04-26 19:53:10.000000000 +0100
+++ evilwm-0.99.25/evilwm.h	2007-03-06 10:09:10.000000000 +0000
@@ -51,6 +51,10 @@
 
 #define MAXIMISE_HORZ        (1<<0)
 #define MAXIMISE_VERT        (1<<1)
+#define MAXIMISE_TOPLEFT     (1<<2)
+#define MAXIMISE_TOPRIGHT    (1<<3)
+#define MAXIMISE_BOTTOMLEFT  (1<<4)
+#define MAXIMISE_BOTTOMRIGHT (1<<5)
 
 /* some coding shorthand */
 
@@ -124,6 +128,7 @@
 	int             x, y, width, height;
 	int             border;
 	int             oldx, oldy, oldw, oldh;  /* used when maximising */
+	int		restore;
 
 	int             min_width, min_height;
 	int             max_width, max_height;
diff -ru evilwm-0.99.25-orig/keymap.h evilwm-0.99.25/keymap.h
--- evilwm-0.99.25-orig/keymap.h	2006-02-22 12:38:57.000000000 +0000
+++ evilwm-0.99.25/keymap.h	2007-03-05 21:05:33.000000000 +0000
@@ -14,6 +14,7 @@
 #define KEY_LOWER	XK_Insert
 #define KEY_ALTLOWER	XK_KP_Insert
 #define KEY_INFO	XK_i
+#define KEY_MAXHORZ	XK_minus
 #define KEY_MAXVERT	XK_equal
 #define KEY_MAX		XK_x
 #ifdef VWM
diff -ru evilwm-0.99.25-orig/new.c evilwm-0.99.25/new.c
--- evilwm-0.99.25-orig/new.c	2006-04-25 19:08:33.000000000 +0100
+++ evilwm-0.99.25/new.c	2007-03-06 09:43:20.000000000 +0000
@@ -208,7 +208,8 @@
 	XGetWindowAttributes(dpy, c->window, &attr);
 	LOG_XDEBUG("\t(%s) %dx%d+%d+%d, bw = %d\n", map_state_string(attr.map_state), attr.width, attr.height, attr.x, attr.y, attr.border_width);
 	c->old_border = attr.border_width;
-	c->oldw = c->oldh = 0;
+	c->oldx = c->oldy = c->oldw = c->oldh = 0;
+	c->restore = 0;
 #ifdef COLOURMAP
 	c->cmap = attr.colormap;
 #endif
diff -ru evilwm-0.99.25-orig/screen.c evilwm-0.99.25/screen.c
--- evilwm-0.99.25-orig/screen.c	2006-04-26 19:53:10.000000000 +0100
+++ evilwm-0.99.25/screen.c	2007-03-06 10:03:00.000000000 +0000
@@ -32,7 +32,8 @@
 	if (!info_window)
 		return;
 	snprintf(buf, sizeof(buf), "%dx%d+%d+%d", (c->width-c->base_width)/width_inc,
-		(c->height-c->base_height)/height_inc, c->x, c->y);
+		(c->height-c->base_height)/height_inc,
+		c->x - c->border, c->y - c->border);
 	iwinw = XTextWidth(font, buf, strlen(buf)) + 2;
 	iwinh = font->max_bounds.ascent + font->max_bounds.descent;
 	XFetchName(dpy, c->window, &name);
@@ -83,7 +84,8 @@
 
 #ifndef INFOBANNER_MOVERESIZE
 	snprintf(buf, sizeof(buf), "%dx%d+%d+%d", (c->width-c->base_width)/width_inc,
-			(c->height-c->base_height)/height_inc, c->x, c->y);
+			(c->height-c->base_height)/height_inc,
+			c->x - c->border, c->y - c->border);
 	XDrawString(dpy, c->screen->root, c->screen->invert_gc,
 		c->x + c->width - XTextWidth(font, buf, strlen(buf)) - SPACE,
 		c->y + c->height - SPACE,
@@ -101,8 +103,8 @@
 	if (c->min_height && c->height < c->min_height) c->height = c->min_height;
 	if (c->max_width && c->width > c->max_width) c->width = c->max_width;
 	if (c->max_height && c->height > c->max_height) c->height = c->max_height;
-	c->x = (x1 <= x2) ? x1 : x1 - c->width;
-	c->y = (y1 <= y2) ? y1 : y1 - c->height;
+	c->x = (x1 <= x2) ? x1 : x1 - c->width - c->border;
+	c->y = (y1 <= y2) ? y1 : y1 - c->height - c->border;
 }
 
 #ifdef MOUSE
@@ -298,31 +300,64 @@
 }
 
 void maximise_client(Client *c, int hv) {
+	/*
+	 * Save/restore window position if requested action is the same as
+	 * previous, allowing one level of "undo".
+	 */
+	if (c->restore == hv) {
+		LOG_DEBUG("Restoring window to %dx%d+%d+%d\n",
+			c->oldw, c->oldh, c->oldx, c->oldy);
+		c->x = c->oldx;
+		c->y = c->oldy;
+		c->width = c->oldw;
+		c->height = c->oldh;
+		c->restore = 0;
+		goto restore;
+	} else {
+		LOG_DEBUG("Saving window geometry %dx%d+%d+%d\n",
+			c->width, c->height, c->x, c->y);
+		c->oldx = c->x;
+		c->oldy = c->y;
+		c->oldw = c->width;
+		c->oldh = c->height;
+		c->restore = hv;
+	}
+	
 	if (hv & MAXIMISE_HORZ) {
-		if (c->oldw) {
-			c->x = c->oldx;
-			c->width = c->oldw;
-			c->oldw = 0;
-		} else {
-			c->oldx = c->x;
-			c->oldw = c->width;
-			c->x = 0;
-			c->width = DisplayWidth(dpy, c->screen->screen);
-		}
+		c->x = c->border;
+		c->width = DisplayWidth(dpy, c->screen->screen)
+			- (2 * c->border);
 	}
 	if (hv & MAXIMISE_VERT) {
-		if (c->oldh) {
-			c->y = c->oldy;
-			c->height = c->oldh;
-			c->oldh = 0;
-		} else {
-			c->oldy = c->y;
-			c->oldh = c->height;
-			c->y = 0;
-			c->height = DisplayHeight(dpy, c->screen->screen);
-		}
+		c->y = c->border;
+		c->height = DisplayHeight(dpy, c->screen->screen)
+			- (2 * c->border);
+	}
+	if (hv & MAXIMISE_TOPLEFT) {
+		c->width += c->x - c->border;
+		c->height += c->y - c->border;
+		c->x = c->border;
+		c->y = c->border;
+	}
+	if (hv & MAXIMISE_TOPRIGHT) {
+		c->width += DisplayWidth(dpy, c->screen->screen)
+				- (c->x + c->width + c->border);
+		c->height += c->y - c->border;
+		c->y = c->border;
+	}
+	if (hv & MAXIMISE_BOTTOMLEFT) {
+		c->width += c->x - c->border;
+		c->height += DisplayHeight(dpy, c->screen->screen)
+				- (c->y + c->height + c->border);
+		c->x = c->border;
+	}
+	if (hv & MAXIMISE_BOTTOMRIGHT) {
+		c->width += DisplayWidth(dpy, c->screen->screen)
+				- (c->x + c->width + c->border);
+		c->height += DisplayHeight(dpy, c->screen->screen)
+				- (c->y + c->height + c->border);
 	}
-	recalculate_sweep(c, c->x, c->y, c->x + c->width, c->y + c->height);
+restore:
 	moveresize(c);
 	discard_enter_events();
 }
@@ -451,7 +486,7 @@
 		KEY_NEW, KEY_KILL,
 		KEY_TOPLEFT, KEY_TOPRIGHT, KEY_BOTTOMLEFT, KEY_BOTTOMRIGHT,
 		KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP,
-		KEY_LOWER, KEY_ALTLOWER, KEY_INFO, KEY_MAXVERT, KEY_MAX,
+		KEY_LOWER, KEY_ALTLOWER, KEY_INFO, KEY_MAXHORZ, KEY_MAXVERT, KEY_MAX,
 #ifdef VWM
 		KEY_FIX, KEY_PREVDESK, KEY_NEXTDESK,
 		XK_1, XK_2, XK_3, XK_4, XK_5, XK_6, XK_7, XK_8,
@@ -459,7 +494,10 @@
 		0
 	};
 	KeySym alt_keys_to_grab[] = {
-		KEY_KILL, KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0
+		KEY_KILL,
+		KEY_TOPLEFT, KEY_TOPRIGHT, KEY_BOTTOMLEFT, KEY_BOTTOMRIGHT,
+		KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP,
+		0
 	};
 
 	/* Release any previous grabs */
