diff --git a/patches/sowm-handlebar.patch b/patches/sowm-handlebar.patch
new file mode 100644
index 0000000..269f881
--- /dev/null
+++ b/patches/sowm-handlebar.patch
@@ -0,0 +1,173 @@
+diff --git a/config.def.h b/config.def.h
+index aaaf38d..bcf49d8 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,6 +3,9 @@
+ 
+ #define MOD Mod4Mask
+ 
++const int handle_bar_thickness = 20;
++const char *handlebar_colour   = "#ffffff";
++
+ const char* menu[]    = {"dmenu_run",      0};
+ const char* term[]    = {"st",             0};
+ const char* scrot[]   = {"scr",            0};
+diff --git a/sowm.c b/sowm.c
+index bc14c4e..abe94a4 100644
+--- a/sowm.c
++++ b/sowm.c
+@@ -54,6 +54,9 @@ static unsigned int ww, wh;
+ static Display      *d;
+ static XButtonEvent mouse;
+ 
++static Window hb = (Window)NULL;
++static XColor hbc;
++
+ static void (*events[LASTEvent])(XEvent *e) = {
+     [ButtonPress]      = button_press,
+     [ButtonRelease]    = button_release,
+@@ -75,8 +78,36 @@ static void (*events[LASTEvent])(XEvent *e) = {
+     XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \
+                  &(unsigned int){0}, &(unsigned int){0})
+ 
++void configure_hb_for_window(Window w) {
++    XWindowAttributes wa;
++    XGetWindowAttributes(d, w, &wa);
++    if (hb == (Window)NULL) {
++        int s = DefaultScreen(d);
++        hb = XCreateSimpleWindow(d, RootWindow(d, s),
++                                 wa.x, wa.y - handle_bar_thickness,
++                                 wa.width + 2*wa.border_width, handle_bar_thickness,
++                                 0,
++                                 hbc.pixel, hbc.pixel);
++        XMapWindow(d, hb);
++        XGrabButton(d, AnyButton, AnyModifier, hb, True,
++                    ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
++                    GrabModeAsync, GrabModeAsync, 0, 0);
++    } else
++        XMoveResizeWindow(d, hb, wa.x, wa.y - handle_bar_thickness,
++                          wa.width, handle_bar_thickness);
++    XRaiseWindow(d, hb);
++}
++
++void destroy_hb(void) {
++    if (hb == (Window)NULL) return;
++    XUnmapWindow(d, hb);
++    XDestroyWindow(d, hb);
++    hb = (Window)NULL;
++}
++
+ void win_focus(client *c) {
+     cur = c;
++    configure_hb_for_window(c->w);
+     XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
+ }
+ 
+@@ -93,7 +124,22 @@ void notify_enter(XEvent *e) {
+ }
+ 
+ void notify_motion(XEvent *e) {
+-    if (!mouse.subwindow || cur->f) return;
++    if (e->xmotion.window == hb) {
++        while(XCheckTypedEvent(d, MotionNotify, e));
++
++        int xd = e->xbutton.x_root - mouse.x_root;
++        int yd = e->xbutton.y_root - mouse.y_root;
++
++        XMoveResizeWindow(d, cur->w,
++            wx + (mouse.button == 1 ? xd : 0),
++            wy + (mouse.button == 1 ? yd : 0),
++            ww + (mouse.button == 3 ? xd : 0),
++            wh + (mouse.button == 3 ? yd : 0));
++
++        configure_hb_for_window(cur->w);
++    }
++
++    if (!mouse.subwindow || mouse.subwindow == hb || cur->f) return;
+ 
+     while(XCheckTypedEvent(d, MotionNotify, e));
+ 
+@@ -105,6 +151,8 @@ void notify_motion(XEvent *e) {
+         wy + (mouse.button == 1 ? yd : 0),
+         ww + (mouse.button == 3 ? xd : 0),
+         wh + (mouse.button == 3 ? yd : 0));
++
++    if (mouse.subwindow == cur->w) configure_hb_for_window(cur->w);
+ }
+ 
+ void key_press(XEvent *e) {
+@@ -116,6 +164,13 @@ void key_press(XEvent *e) {
+ }
+ 
+ void button_press(XEvent *e) {
++    if (e->xbutton.window == hb) {
++        mouse = e->xbutton;
++        win_size(cur->w, &wx, &wy, &ww, &wh);
++        XRaiseWindow(d, cur->w);
++        return;
++    }
++
+     if (!e->xbutton.subwindow) return;
+ 
+     win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh);
+@@ -154,6 +209,8 @@ void win_del(Window w) {
+ 
+     for win if (c->w == w) x = c;
+ 
++    if ( x == cur ) destroy_hb();
++
+     if (!list || !x)  return;
+     if (x->prev == x) list = 0;
+     if (list == x)    list = x->next;
+@@ -174,6 +231,8 @@ void win_center() {
+     win_size(cur->w, &(int){0}, &(int){0}, &ww, &wh);
+ 
+     XMoveWindow(d, cur->w, (sw - ww) / 2, (sh - wh) / 2);
++
++    configure_hb_for_window(cur->w);
+ }
+ 
+ void win_fs() {
+@@ -182,9 +241,11 @@ void win_fs() {
+     if ((cur->f = cur->f ? 0 : 1)) {
+         win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh);
+         XMoveResizeWindow(d, cur->w, 0, 0, sw, sh);
+-
+-    } else
++        destroy_hb();
++    } else {
+         XMoveResizeWindow(d, cur->w, cur->wx, cur->wy, cur->ww, cur->wh);
++        configure_hb_for_window(cur->w);
++    }
+ }
+ 
+ void win_to_ws(const Arg arg) {
+@@ -201,6 +262,8 @@ void win_to_ws(const Arg arg) {
+     XUnmapWindow(d, cur->w);
+     ws_save(tmp);
+ 
++    destroy_hb();
++
+     if (list) win_focus(list);
+ }
+ 
+@@ -227,6 +290,8 @@ void ws_go(const Arg arg) {
+ 
+     ws_sel(arg.i);
+ 
++    destroy_hb();
++
+     if (list) win_focus(list); else cur = 0;
+ }
+ 
+@@ -290,6 +355,10 @@ int main(void) {
+             ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
+             GrabModeAsync, GrabModeAsync, 0, 0);
+ 
++    Colormap cm = DefaultColormap(d, s);
++    XParseColor(d, cm, handlebar_colour, &hbc);
++    XAllocColor(d, cm, &hbc);
++
+     while (1 && !XNextEvent(d, &ev))
+         if (events[ev.type]) events[ev.type](&ev);
+ }