diff --git a/config.def.h b/config.def.h
--- a/config.def.h
+++ b/config.def.h
@@ -78,6 +78,15 @@
 	{ MODKEY,                       XK_period, focusmon,       {.i = +1 } },
 	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
 	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
+    { MODKEY|ControlMask,           XK_l,      togglehorizontalmax, {.i = +1} }, // Only maximize to the right
+    { MODKEY|ControlMask|ShiftMask, XK_l,      togglehorizontalmax, {.i =  0} }, // Maximize both left and right
+    { MODKEY|ControlMask,           XK_g,      togglehorizontalmax, {.i = -1} }, // Only maximize to the left
+    { MODKEY|ControlMask,           XK_r,      toggleverticalmax,   {.i = +1} },
+    { MODKEY|ControlMask|ShiftMask, XK_r,      toggleverticalmax,   {.i =  0} },
+    { MODKEY|ControlMask,           XK_c,      toggleverticalmax,   {.i = -1} },
+    { MODKEY|ControlMask,           XK_m,      togglemaximize,      {.i = +1} }, // Force maximize
+    { MODKEY|ControlMask|ShiftMask, XK_m,      togglemaximize,      {.i =  0} }, // Toggle maximize
+    { MODKEY|ControlMask,           XK_n,      togglemaximize,      {.i = -1} }, // Remove all maximization
 	TAGKEYS(                        XK_1,                      0)
 	TAGKEYS(                        XK_2,                      1)
 	TAGKEYS(                        XK_3,                      2)
diff --git a/dwm.c b/dwm.c
--- a/dwm.c
+++ b/dwm.c
@@ -91,7 +91,9 @@
 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
 	int bw, oldbw;
 	unsigned int tags;
-	Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+	unsigned char maxmask;
+	int maxx1, maxy1, maxx2, maxy2;
+	Bool wasfloating, isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
 	Client *next;
 	Client *snext;
 	Monitor *mon;
@@ -1158,6 +1160,8 @@
 	updatewmhints(c);
 	XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
 	grabbuttons(c, False);
+	c->wasfloating = False;
+	c->maxmask = 0;
 	if(!c->isfloating)
 		c->isfloating = c->oldstate = trans != None || c->isfixed;
 	if(c->isfloating)
@@ -1367,6 +1371,7 @@
 	c->oldy = c->y; c->y = wc.y = y;
 	c->oldw = c->w; c->w = wc.width = w;
 	c->oldh = c->h; c->h = wc.height = h;
+	c->maxmask = 0;
 	wc.border_width = c->bw;
 	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
 	configure(c);
diff --git a/maximize.c b/maximize.c
new file mode 100644
--- /dev/null
+++ b/maximize.c
@@ -0,0 +1,114 @@
+#define MAX_LEFT  (1 << 0)
+#define MAX_RIGHT (1 << 2)
+#define MAX_UP    (1 << 4)
+#define MAX_DOWN  (1 << 6)
+
+#define IS_SET(q, w) ((q & w) != 0)
+#define IS_FORCED(q, w) IS_SET((q << 1), w)
+#ifndef MAX
+#define MAX(a,b) (a > b ? a : b)
+#endif
+
+int
+new_value(unsigned char mask, unsigned char curmask,
+		  unsigned char *newmask, unsigned char key,
+		  int *reset_value, int new_reset_value,
+		  int max_value, int old_value) {
+	if (IS_SET(key, mask) ||
+			(IS_SET(key, curmask) && (!IS_SET(key, mask) && IS_FORCED(key, mask))) ||
+			(!IS_SET(key, curmask) && (IS_SET(key, mask) && IS_FORCED(key, mask)))) {
+
+		if (IS_SET(key, mask) && (!IS_SET(key,curmask) || IS_FORCED(key,mask)))
+		{
+			if (!IS_SET(key, curmask))
+			    *reset_value = new_reset_value;
+			*newmask |= key;
+			return max_value;
+		} else if ((IS_SET(key,curmask) && IS_SET(key, mask)) ||
+				   (!IS_SET(key, mask) && IS_FORCED(key, mask))) {
+			*newmask &= ~key;
+			return *reset_value;
+		} else {
+			*newmask &= ~key;
+			return old_value;
+		}
+	} else
+		return new_reset_value;
+}
+
+void
+maximize(unsigned char mask) {
+	XEvent ev;
+	int nx1, ny1, nx2, ny2;
+	unsigned char curmask;
+	unsigned char newmask;
+
+	if(!selmon->sel || selmon->sel->isfixed)
+		return;
+	XRaiseWindow(dpy, selmon->sel->win);
+	newmask = curmask = selmon->sel->maxmask;
+
+	if (curmask == 0) {
+		if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating)
+			selmon->sel->wasfloating = True;
+		else {
+			togglefloating(NULL);
+			selmon->sel->wasfloating = False;
+		}
+	}
+
+	nx1 = new_value(mask, curmask, &newmask,
+					MAX_LEFT, &selmon->sel->maxx1,
+							  selmon->sel->x,
+							  selmon->wx,
+							  selmon->sel->oldx);
+	nx2 = new_value(mask, curmask, &newmask,
+					MAX_RIGHT, &selmon->sel->maxx2,
+							   selmon->sel->x + selmon->sel->w,
+							   selmon->wx + selmon->ww - 2*borderpx,
+							   selmon->sel->oldw + selmon->sel->x);
+	ny1 = new_value(mask, curmask, &newmask,
+					MAX_UP, &selmon->sel->maxy1,
+							selmon->sel->y,
+							selmon->wy,
+							selmon->sel->oldy);
+	ny2 = new_value(mask, curmask, &newmask,
+					MAX_DOWN, &selmon->sel->maxy2,
+							  selmon->sel->y + selmon->sel->h,
+							  selmon->wy + selmon->wh - 2*borderpx,
+							  selmon->sel->oldh + selmon->sel->y);
+
+
+	resizeclient(selmon->sel, nx1, ny1, MAX(nx2-nx1, 32), MAX(ny2-ny1, 32));
+
+	if ((newmask == 0) && (!selmon->sel->wasfloating))
+		togglefloating(NULL);
+	selmon->sel->maxmask = newmask;
+	drawbar(selmon);
+	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+}
+
+#define MAXIMIZE       (MAX_LEFT | MAX_RIGHT | MAX_UP | MAX_DOWN)
+#define UNMAXIMIZE     (MAXIMIZE << 1) // Force all directions to 0
+#define FORCE_MAXIMIZE ~0 //(MAXIMIZE | (MAXIMIZE << 1))
+
+void
+togglemaximize(const Arg *arg) {
+	if (arg->i > 0) maximize(FORCE_MAXIMIZE);
+	else if (arg->i < 0) maximize(UNMAXIMIZE);
+	else maximize(MAXIMIZE);
+}
+
+void
+toggleverticalmax(const Arg *arg) {
+	if (arg->i < 0) maximize(MAX_DOWN);
+	else if (arg->i > 0) maximize(MAX_UP);
+	else maximize(MAX_DOWN | MAX_UP);
+}
+
+void
+togglehorizontalmax(const Arg *arg) {
+	if (arg->i < 0) maximize(MAX_LEFT);
+	else if (arg->i > 0) maximize(MAX_RIGHT);
+	else maximize(MAX_LEFT | MAX_RIGHT);
+}
