diff --git a/config.def.h b/config.def.h
index 1bd0c3b..81f2d32 100644
--- a/config.def.h
+++ b/config.def.h
@@ -5,6 +5,9 @@
 static const unsigned int borderpx  = 1;        /* border pixel of windows */
 static const unsigned int snap      = 32;       /* snap pixel */
 static const unsigned int gappx     = 0;        /* gaps between windows */
+static const int rainbow_border     = 0;        /* 1 = animated rainbow border on focused window */
+static const int rainbow_interval   = 50;       /* ms between animation frames */
+static const float rainbow_step     = 3.0;      /* hue degrees to shift per frame */
 static const int showbar            = 1;        /* 0 means no bar */
 static const int topbar             = 1;        /* 0 means bottom bar */
 static const char *fonts[]          = { "monospace:size=10" };
@@ -88,6 +91,7 @@ static const Key keys[] = {
 	{ MODKEY,                       XK_minus,  setgaps,        {.i = -5 } },
 	{ MODKEY,                       XK_equal,  setgaps,        {.i = +5 } },
 	{ MODKEY|ShiftMask,             XK_minus,  setgaps,        {.i = 0 } },
+	{ MODKEY,                       XK_F5,     togglerainbow,  {0} },
 	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
 	{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
 	{ MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
diff --git a/config.mk b/config.mk
index 982dc21..433e544 100644
--- a/config.mk
+++ b/config.mk
@@ -23,13 +23,13 @@ FREETYPEINC = /usr/include/freetype2
 
 # includes and libs
 INCS = -I${X11INC} -I${FREETYPEINC}
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lm
 
 # flags
 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
 #CFLAGS   = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
-CFLAGS   = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
-LDFLAGS  = ${LIBS}
+CFLAGS   = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os -fstack-protector-strong -D_FORTIFY_SOURCE=2 -fPIE ${INCS} ${CPPFLAGS}
+LDFLAGS  = -pie -Wl,-z,relro,-z,now ${LIBS}
 
 # Solaris
 #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
diff --git a/dwm.c b/dwm.c
index b4e350f..34fe9a5 100644
--- a/dwm.c
+++ b/dwm.c
@@ -23,12 +23,15 @@
 #include <dirent.h>
 #include <errno.h>
 #include <locale.h>
+#include <math.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/select.h>
+#include <sys/time.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <X11/cursorfont.h>
@@ -167,6 +170,8 @@ static void detachstack(Client *c);
 static Monitor *dirtomon(int dir);
 static void drawbar(Monitor *m);
 static void drawbars(void);
+static void drawrainbowborder(Client *c);
+static unsigned long hsvtorgb(float h, float s, float v);
 static void enternotify(XEvent *e);
 static void expose(XEvent *e);
 static void focus(Client *c);
@@ -218,6 +223,7 @@ static void tagmon(const Arg *arg);
 static void tile(Monitor *m);
 static void togglebar(const Arg *arg);
 static void togglefloating(const Arg *arg);
+static void togglerainbow(const Arg *arg);
 static void toggletag(const Arg *arg);
 static void toggleview(const Arg *arg);
 static void unfocus(Client *c, int setfocus);
@@ -278,6 +284,10 @@ static Drw *drw;
 static Monitor *mons, *selmon;
 static Window root, wmcheckwin;
 
+/* rainbow border state */
+static float rainbow_hue = 0;
+static int rainbow_enabled;
+
 /* configuration, allows nested code to access above variables */
 #include "config.h"
 
@@ -374,7 +384,7 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
 			*h -= c->baseh;
 		}
 		/* adjust for aspect limits */
-		if (c->mina > 0 && c->maxa > 0) {
+		if (c->mina > 0 && c->maxa > 0 && *w > 0 && *h > 0) {
 			if (c->maxa < (float)*w / *h)
 				*w = *h * c->maxa + 0.5;
 			else if (c->mina < (float)*h / *w)
@@ -630,7 +640,7 @@ configurerequest(XEvent *e)
 	if ((c = wintoclient(ev->window))) {
 		if (ev->value_mask & CWBorderWidth)
 			c->bw = ev->border_width;
-		else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
+		else if (c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
 			m = c->mon;
 			if (ev->value_mask & CWX) {
 				c->oldx = c->x;
@@ -829,6 +839,37 @@ drawbars(void)
 		drawbar(m);
 }
 
+unsigned long
+hsvtorgb(float h, float s, float v)
+{
+	float c = v * s;
+	float x = c * (1.0f - fabsf(fmodf(h / 60.0f, 2.0f) - 1.0f));
+	float m = v - c;
+	float r, g, b;
+
+	if (h < 60)       { r = c; g = x; b = 0; }
+	else if (h < 120)  { r = x; g = c; b = 0; }
+	else if (h < 180)  { r = 0; g = c; b = x; }
+	else if (h < 240)  { r = 0; g = x; b = c; }
+	else if (h < 300)  { r = x; g = 0; b = c; }
+	else               { r = c; g = 0; b = x; }
+
+	unsigned char R = (unsigned char)((r + m) * 255);
+	unsigned char G = (unsigned char)((g + m) * 255);
+	unsigned char B = (unsigned char)((b + m) * 255);
+
+	return (R << 16) | (G << 8) | B;
+}
+
+void
+drawrainbowborder(Client *c)
+{
+	if (!c || c->isfullscreen || !c->bw)
+		return;
+
+	XSetWindowBorder(dpy, c->win, hsvtorgb(rainbow_hue, 1.0f, 1.0f));
+}
+
 void
 enternotify(XEvent *e)
 {
@@ -873,7 +914,10 @@ focus(Client *c)
 		detachstack(c);
 		attachstack(c);
 		grabbuttons(c, 1);
-		XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
+		if (rainbow_enabled)
+			drawrainbowborder(c);
+		else
+			XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
 		setfocus(c);
 	} else {
 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
@@ -1025,7 +1069,7 @@ getstate(Window w)
 		&real, &format, &n, &extra, (unsigned char **)&p) != Success)
 		return -1;
 	if (n != 0)
-		result = *p;
+		result = *(long *)p;
 	XFree(p);
 	return result;
 }
@@ -1056,7 +1100,7 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size)
 void
 grabbuttons(Client *c, int focused)
 {
-	updatenumlockmask();
+	/* numlockmask is updated by grabkeys() on MappingNotify */
 	{
 		unsigned int i, j;
 		unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
@@ -1290,8 +1334,10 @@ movemouse(const Arg *arg)
 	if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
 		None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
 		return;
-	if (!getrootptr(&x, &y))
+	if (!getrootptr(&x, &y)) {
+		XUngrabPointer(dpy, CurrentTime);
 		return;
+	}
 	do {
 		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
 		switch(ev.type) {
@@ -1423,7 +1469,6 @@ resizeclient(Client *c, int x, int y, int w, int h)
 	wc.border_width = c->bw;
 	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
 	configure(c);
-	XSync(dpy, False);
 }
 
 void
@@ -1512,11 +1557,41 @@ void
 run(void)
 {
 	XEvent ev;
+	int xfd;
+	fd_set rfds;
+	struct timeval tv, now;
+	long long now_ms, last_rainbow_ms = 0;
+
 	/* main event loop */
 	XSync(dpy, False);
-	while (running && !XNextEvent(dpy, &ev))
-		if (handler[ev.type])
-			handler[ev.type](&ev); /* call handler */
+	xfd = ConnectionNumber(dpy);
+
+	while (running) {
+		FD_ZERO(&rfds);
+		FD_SET(xfd, &rfds);
+		tv.tv_sec = 0;
+		tv.tv_usec = rainbow_enabled ? (rainbow_interval * 1000L) : 200000L;
+
+		if (select(xfd + 1, &rfds, NULL, NULL, &tv) > 0) {
+			while (XPending(dpy)) {
+				XNextEvent(dpy, &ev);
+				if (handler[ev.type])
+					handler[ev.type](&ev);
+			}
+		}
+
+		if (rainbow_enabled) {
+			gettimeofday(&now, NULL);
+			now_ms = now.tv_sec * 1000LL + now.tv_usec / 1000;
+			if (now_ms - last_rainbow_ms >= rainbow_interval) {
+				last_rainbow_ms = now_ms;
+				rainbow_hue = fmodf(rainbow_hue + rainbow_step, 360.0f);
+				if (selmon && selmon->sel)
+					drawrainbowborder(selmon->sel);
+				XFlush(dpy);
+			}
+		}
+	}
 }
 
 void
@@ -1577,7 +1652,7 @@ sendevent(Client *c, Atom proto)
 	int n;
 	Atom *protocols;
 	int exists = 0;
-	XEvent ev;
+	XEvent ev = {0};
 
 	if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
 		while (!exists && n--)
@@ -1683,6 +1758,8 @@ setup(void)
 	Atom utf8string;
 	struct sigaction sa;
 
+	rainbow_enabled = rainbow_border;
+
 	/* do not transform children into zombies when they terminate */
 	sigemptyset(&sa.sa_mask);
 	sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART;
@@ -1801,10 +1878,13 @@ void
 spawn(const Arg *arg)
 {
 	struct sigaction sa;
+	pid_t pid;
 
-	if (arg->v == dmenucmd)
-		dmenumon[0] = '0' + selmon->num;
-	if (fork() == 0) {
+	if ((pid = fork()) < 0) {
+		fprintf(stderr, "dwm: fork failed: %s\n", strerror(errno));
+		return;
+	}
+	if (pid == 0) {
 		if (dpy)
 			close(ConnectionNumber(dpy));
 		setsid();
@@ -1888,6 +1968,14 @@ togglefloating(const Arg *arg)
 	arrange(selmon);
 }
 
+void
+togglerainbow(const Arg *arg)
+{
+	rainbow_enabled = !rainbow_enabled;
+	if (!rainbow_enabled && selmon && selmon->sel)
+		XSetWindowBorder(dpy, selmon->sel->win, scheme[SchemeSel][ColBorder].pixel);
+}
+
 void
 toggletag(const Arg *arg)
 {
