commit 4f1816175884e0dcdb6cea60baf43eeecd122a22
parent 087e2767361e60a143b3f00cbe7a7486b032af4a
Author: Dylan Araps <dylan.araps@gmail.com>
Date:   Thu, 23 Jan 2020 02:37:32 +0200
docs: update
Diffstat:
12 files changed, 1 insertion(+), 948 deletions(-)
diff --git a/README.md b/README.md
@@ -9,7 +9,7 @@ An itsy bitsy floating window manager (*220~ sloc / 24kb compiled!*).
 - Window centering.
 - Mix of mouse and keyboard workflow.
 - Focus with cursor.
-- Rounded corners (*[through patch](https://github.com/dylanaraps/sowm/blob/master/patches/sowm-rounded-corners.patch)*)
+- Rounded corners (*[through patch](https://github.com/dylanaraps/sowm-patches)*)
 
 <a href="https://user-images.githubusercontent.com/6799467/66687814-8cd9f800-ec73-11e9-97b8-6ae77876bd1b.jpg"><img src="https://user-images.githubusercontent.com/6799467/66687814-8cd9f800-ec73-11e9-97b8-6ae77876bd1b.jpg" width="43%" align="right"></a>
 
diff --git a/patches/.sowm-wheelresize.patch.swp b/patches/.sowm-wheelresize.patch.swp
Binary files differ.
diff --git a/patches/sowm-2bswm-style.patch b/patches/sowm-2bswm-style.patch
@@ -1,76 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index cae2009..f787cbd 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -26,6 +26,20 @@ static struct key keys[] = {
-     {MOD, XK_p,      run, {.com = scrot}},
-     {MOD, XK_Return, run, {.com = term}},
- 
-+		/*
-+		 * 2bswm-patch.
-+		 * .i => Increment/Decrement size
-+		 * .com => {(move/resize), (direction)}
-+		 */
-+		{MOD,           XK_h,      move,  {.com=(char*[]){"move", "left"}, .i=10}},
-+		{MOD,           XK_j,      move,  {.com=(char*[]){"move", "down"}, .i=10}},
-+		{MOD,           XK_k,      move,  {.com=(char*[]){"move", "up"}, .i=10}},
-+		{MOD,           XK_l,      move,  {.com=(char*[]){"move", "right"}, .i=10}},
-+		{MOD|ShiftMask, XK_h,      move,  {.com=(char*[]){"resize", "left"}, .i=10}},
-+		{MOD|ShiftMask, XK_j,      move,  {.com=(char*[]){"resize", "down"}, .i=10}},
-+		{MOD|ShiftMask, XK_k,      move,  {.com=(char*[]){"resize", "up"}, .i=10}},
-+		{MOD|ShiftMask, XK_l,      move,  {.com=(char*[]){"resize", "right"}, .i=10}},
-+
-     {0,   XF86XK_AudioLowerVolume,  run, {.com = voldown}},
-     {0,   XF86XK_AudioRaiseVolume,  run, {.com = volup}},
-     {0,   XF86XK_AudioMute,         run, {.com = volmute}},
-diff --git a/sowm.c b/sowm.c
-index 90ae3bc..7c76571 100644
---- a/sowm.c
-+++ b/sowm.c
-@@ -8,7 +8,7 @@
- #include <signal.h>
- #include <unistd.h>
- 
--typedef union {
-+typedef struct {
-     const char** com;
-     const int i;
-     const Window w;
-@@ -46,6 +46,8 @@ static void win_prev();
- static void win_next();
- static void win_to_ws(const Arg arg);
- static void ws_go(const Arg arg);
-+static void apply(int x, int y, int w, int h);
-+static void move(const Arg arg);
- static int  xerror() { return 0;}
- 
- static client       *list = {0}, *ws_list[10] = {0}, *cur;
-@@ -80,6 +82,28 @@ static void (*events[LASTEvent])(XEvent *e) = {
- #define mod_clean(mask) (mask & ~(numlock|LockMask) & \
-         (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
- 
-+void apply(int x, int y, int w, int h) {
-+    win_size(cur->w, &wx, &wy, &ww, &wh);
-+    XMoveResizeWindow(d, cur->w,
-+        wx + x, wy + y,
-+        ww + w, wh + h);
-+}
-+
-+void move(const Arg arg) {
-+	 if(arg.com[1]=="left") {
-+        apply((arg.com[0]=="resize")?0:-arg.i, 0, (arg.com[0]=="resize")?-arg.i:0, 0);
-+    }
-+    else if(arg.com[1]=="right"){
-+        apply((arg.com[0]=="resize")?0:arg.i, 0, (arg.com[0]=="resize")?arg.i:0, 0);
-+    }
-+    else if(arg.com[1]=="up"){
-+        apply(0, (arg.com[0]=="resize")?0:-arg.i, 0, (arg.com[0]=="resize")?-arg.i:0);
-+    }
-+    else if(arg.com[1]=="down"){
-+        apply(0, (arg.com[0]=="resize")?0:arg.i, 0, (arg.com[0]=="resize")?arg.i:0);
-+    }
-+}
-+
- void win_focus(client *c) {
-     cur = c;
-     XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
diff --git a/patches/sowm-almost-tags-0.3.diff b/patches/sowm-almost-tags-0.3.diff
@@ -1,132 +0,0 @@
-diff -up a/config.def.h b/config.def.h
---- a/config.def.h	2019-10-17 19:48:23.000000000 +0300
-+++ b/config.def.h	2019-10-20 15:12:05.510971991 +0300
-@@ -32,16 +32,29 @@ static struct key keys[] = {
- 
-     {MOD,           XK_1, ws_go,     {.i = 1}},
-     {MOD|ShiftMask, XK_1, win_to_ws, {.i = 1}},
-+    {MOD|ControlMask,XK_1,ws_toggle, {.i = 1}},
-+
-     {MOD,           XK_2, ws_go,     {.i = 2}},
-     {MOD|ShiftMask, XK_2, win_to_ws, {.i = 2}},
-+    {MOD|ControlMask,XK_2,ws_toggle, {.i = 2}},
-+
-     {MOD,           XK_3, ws_go,     {.i = 3}},
-     {MOD|ShiftMask, XK_3, win_to_ws, {.i = 3}},
-+    {MOD|ControlMask,XK_3,ws_toggle, {.i = 3}},
-+
-     {MOD,           XK_4, ws_go,     {.i = 4}},
-     {MOD|ShiftMask, XK_4, win_to_ws, {.i = 4}},
-+    {MOD|ControlMask,XK_4,ws_toggle, {.i = 4}},
-+
-     {MOD,           XK_5, ws_go,     {.i = 5}},
-     {MOD|ShiftMask, XK_5, win_to_ws, {.i = 5}},
-+    {MOD|ControlMask,XK_5,ws_toggle, {.i = 5}},
-+
-     {MOD,           XK_6, ws_go,     {.i = 6}},
-     {MOD|ShiftMask, XK_6, win_to_ws, {.i = 6}},
-+    {MOD|ControlMask,XK_6,ws_toggle, {.i = 6}},
-+    
-+    {MOD,           XK_0, ws_toggle_all, {.i = 0}},
- };
- 
- #endif
-Common subdirectories: a/patches and b/patches
-Only in b/: sowm-almost-tags-0.3.diff
-diff -up a/sowm.c b/sowm.c
---- a/sowm.c	2019-10-17 19:48:23.000000000 +0300
-+++ b/sowm.c	2019-10-18 19:02:41.959290919 +0300
-@@ -43,11 +43,14 @@ static void win_prev();
- static void win_next();
- static void win_to_ws(const Arg arg);
- static void ws_go(const Arg arg);
-+static void ws_toggle(const Arg arg);
-+static void ws_toggle_all(const Arg arg);
- static int  xerror() { return 0;}
- 
- static client       *list = {0}, *ws_list[10] = {0}, *cur;
- static int          ws = 1, sw, sh, wx, wy, numlock;
- static unsigned int ww, wh;
-+static int			is_ws_enabled[10] = {0}; /* +1 the amount of ws */
- 
- static Display      *d;
- static XButtonEvent mouse;
-@@ -235,24 +238,68 @@ void win_next() {
- }
- 
- void ws_go(const Arg arg) {
--    int tmp = ws;
--
--    if (arg.i == ws) return;
--
-+    int i;
-+	
-     ws_save(ws);
--    ws_sel(arg.i);
- 
--    for win XMapWindow(d, c->w);
--
--    ws_sel(tmp);
--
--    for win XUnmapWindow(d, c->w);
-+	for (i = 1; i <= 9; i++) {
-+		if (i != arg.i) {
-+			ws_sel(i);
-+			if (list) for win XUnmapWindow(d, c->w);
-+			is_ws_enabled[i] = 0;
-+		}
-+	}
- 
-     ws_sel(arg.i);
- 
-+    if (list) for win XMapWindow(d, c->w);
-     if (list) win_focus(list); else cur = 0;
- }
- 
-+void
-+ws_toggle(const Arg arg)
-+{
-+	int i, tmp = -1;
-+
-+	if (arg.i == ws) {
-+		for (i = 1; i <= 9; i++) {
-+			if (is_ws_enabled[i] && i != ws) {
-+				tmp = i;
-+				break;
-+			}
-+		}
-+
-+		if (tmp > 0)
-+			ws_sel(tmp);
-+		else
-+			return;
-+	}
-+
-+	tmp = ws;
-+
-+	ws_sel(arg.i);
-+	if (is_ws_enabled[arg.i]) {
-+		is_ws_enabled[arg.i] = 0;
-+		if (list) for win XUnmapWindow(d, c->w);
-+	} else {
-+		is_ws_enabled[arg.i] = 1;
-+		if (list) for win XMapWindow(d, c->w);
-+	}
-+	ws_sel(tmp);
-+}
-+
-+void
-+ws_toggle_all(const Arg arg)
-+{
-+	int i, tmp = ws;
-+	for (i = 1; i <= 6; i++) {
-+		ws_sel(i);
-+		if (list) for win XMapWindow(d, c->w);
-+		is_ws_enabled[i] = 1;
-+	}
-+	ws_sel(tmp);
-+}
-+
- void configure_request(XEvent *e) {
-     XConfigureRequestEvent *ev = &e->xconfigurerequest;
- 
diff --git a/patches/sowm-almost-tags-1.0.diff b/patches/sowm-almost-tags-1.0.diff
@@ -1,134 +0,0 @@
-diff -up a/config.def.h b/config.def.h
---- a/config.def.h	2019-10-28 23:55:17.000000000 +0200
-+++ b/config.def.h	2019-11-09 22:30:45.057057111 +0200
-@@ -32,16 +32,29 @@ static struct key keys[] = {
- 
-     {MOD,           XK_1, ws_go,     {.i = 1}},
-     {MOD|ShiftMask, XK_1, win_to_ws, {.i = 1}},
-+    {MOD|ControlMask,XK_1,ws_toggle, {.i = 1}},
-+
-     {MOD,           XK_2, ws_go,     {.i = 2}},
-     {MOD|ShiftMask, XK_2, win_to_ws, {.i = 2}},
-+    {MOD|ControlMask,XK_2,ws_toggle, {.i = 2}},
-+
-     {MOD,           XK_3, ws_go,     {.i = 3}},
-     {MOD|ShiftMask, XK_3, win_to_ws, {.i = 3}},
-+    {MOD|ControlMask,XK_3,ws_toggle, {.i = 3}},
-+
-     {MOD,           XK_4, ws_go,     {.i = 4}},
-     {MOD|ShiftMask, XK_4, win_to_ws, {.i = 4}},
-+    {MOD|ControlMask,XK_4,ws_toggle, {.i = 4}},
-+
-     {MOD,           XK_5, ws_go,     {.i = 5}},
-     {MOD|ShiftMask, XK_5, win_to_ws, {.i = 5}},
-+    {MOD|ControlMask,XK_5,ws_toggle, {.i = 5}},
-+
-     {MOD,           XK_6, ws_go,     {.i = 6}},
-     {MOD|ShiftMask, XK_6, win_to_ws, {.i = 6}},
-+    {MOD|ControlMask,XK_6,ws_toggle, {.i = 6}},
-+    
-+    {MOD,           XK_0, ws_toggle_all, {.i = 0}},
- };
- 
- #endif
-Only in b/: config.h
-Common subdirectories: a/patches and b/patches
-Only in b/: sowm
-diff -up a/sowm.c b/sowm.c
---- a/sowm.c	2019-10-28 23:55:17.000000000 +0200
-+++ b/sowm.c	2019-11-09 22:34:10.660379162 +0200
-@@ -45,11 +45,14 @@ static void win_kill();
- static void win_next();
- static void win_to_ws(const Arg arg);
- static void ws_go(const Arg arg);
-+static void ws_toggle(const Arg arg);
-+static void ws_toggle_all(const Arg arg);
- static int  xerror() { return 0;}
- 
- static client       *list = {0}, *ws_list[10] = {0}, *cur;
- static int          ws = 1, sw, sh, wx, wy, numlock;
- static unsigned int ww, wh;
-+static int			is_ws_enabled[10] = {0}; /* +1 the amount of ws */
- 
- static Display      *d;
- static XButtonEvent mouse;
-@@ -212,24 +215,69 @@ void win_next() {
- }
- 
- void ws_go(const Arg arg) {
--    int tmp = ws;
--
--    if (arg.i == ws) return;
-+	int i;
- 
-     ws_save(ws);
--    ws_sel(arg.i);
- 
--    for win XMapWindow(d, c->w);
--
--    ws_sel(tmp);
--
--    for win XUnmapWindow(d, c->w);
-+	for (i = 1; i <= 9; i++) {
-+		if (i != arg.i) {
-+			ws_sel(i);
-+			if (list) for win XUnmapWindow(d, c->w);
-+			is_ws_enabled[i] = 0;
-+		}
-+	}
- 
-     ws_sel(arg.i);
- 
-+    if (list) for win XMapWindow(d, c->w);
-     if (list) win_focus(list); else cur = 0;
- }
- 
-+void
-+ws_toggle(const Arg arg)
-+{
-+	int i, tmp = -1;
-+
-+	if (arg.i == ws) {
-+		for (i = 1; i <= 9; i++) {
-+			if (is_ws_enabled[i] && i != ws) {
-+				tmp = i;
-+				break;
-+			}
-+		}
-+
-+		if (tmp > 0)
-+			ws_sel(tmp);
-+		else
-+			return;
-+	}
-+
-+	tmp = ws;
-+
-+	ws_sel(arg.i);
-+	if (is_ws_enabled[arg.i]) {
-+		is_ws_enabled[arg.i] = 0;
-+		if (list) for win XUnmapWindow(d, c->w);
-+	} else {
-+		is_ws_enabled[arg.i] = 1;
-+		if (list) for win XMapWindow(d, c->w);
-+	}
-+	ws_sel(tmp);
-+}
-+
-+void
-+ws_toggle_all(const Arg arg)
-+{
-+	int i, tmp = ws;
-+	for (i = 1; i <= 6; i++) {
-+		ws_sel(i);
-+		if (list) for win XMapWindow(d, c->w);
-+		is_ws_enabled[i] = 1;
-+	}
-+	ws_sel(tmp);
-+}
-+
-+
- void configure_request(XEvent *e) {
-     XConfigureRequestEvent *ev = &e->xconfigurerequest;
- 
-Only in b/: sowm.o
diff --git a/patches/sowm-handlebar.patch b/patches/sowm-handlebar.patch
@@ -1,184 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index cae2009..7e422a9 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 48222c6..551c8eb 100644
---- a/sowm.c
-+++ b/sowm.c
-@@ -55,6 +55,10 @@ static unsigned int ww, wh;
- static Display      *d;
- static XButtonEvent mouse;
- 
-+static Window hb = 0;
-+static XColor hbc;
-+static int    hba = 0;
-+
- static void (*events[LASTEvent])(XEvent *e) = {
-     [ButtonPress]      = button_press,
-     [ButtonRelease]    = button_release,
-@@ -77,8 +81,37 @@ 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) {
-+        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) return;
-+    XUnmapWindow(d, hb);
-+    XDestroyWindow(d, hb);
-+    hb = 0;
-+}
-+
- void win_focus(client *c) {
-+    if (hba) return;
-     cur = c;
-+    configure_hb_for_window(c->w);
-     XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
- }
- 
-@@ -95,7 +128,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));
- 
-@@ -107,6 +155,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) {
-@@ -122,6 +172,14 @@ void key_press(XEvent *e) {
- }
- 
- void button_press(XEvent *e) {
-+    if (e->xbutton.window == hb) {
-+        mouse = e->xbutton;
-+        hba   = 1;
-+        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);
-@@ -131,6 +189,7 @@ void button_press(XEvent *e) {
- 
- void button_release() {
-     mouse.subwindow = 0;
-+    hba             = 0;
- }
- 
- void win_add(Window w) {
-@@ -160,6 +219,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;
-@@ -180,6 +241,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() {
-@@ -188,9 +251,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) {
-@@ -207,6 +272,8 @@ void win_to_ws(const Arg arg) {
-     XUnmapWindow(d, cur->w);
-     ws_save(tmp);
- 
-+    destroy_hb();
-+
-     if (list) win_focus(list);
- }
- 
-@@ -240,6 +307,8 @@ void ws_go(const Arg arg) {
- 
-     ws_sel(arg.i);
- 
-+    destroy_hb();
-+
-     if (list) win_focus(list); else cur = 0;
- }
- 
-@@ -303,6 +372,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);
- }
diff --git a/patches/sowm-init.patch b/patches/sowm-init.patch
@@ -1,40 +0,0 @@
-diff --git a/sowm.c b/sowm.c
-index 6b9f794..a5bad10 100644
---- a/sowm.c
-+++ b/sowm.c
-@@ -28,6 +28,7 @@ typedef struct client {
-     Window w;
- } client;
- 
-+static void init();
- static void button_press(XEvent *e);
- static void button_release();
- static void configure_request(XEvent *e);
-@@ -76,6 +77,18 @@ static void (*events[LASTEvent])(XEvent *e) = {
-     XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \
-                  &(unsigned int){0}, &(unsigned int){0})
- 
-+void init() {
-+    Window *child;
-+    unsigned int nchild;
-+    XQueryTree(d, RootWindow(d, DefaultScreen(d)), &(Window){0},
-+        &(Window){0}, &child, &nchild);
-+    for(unsigned int i = 0; i < nchild; i++) {
-+        XSelectInput(d, child[i], StructureNotifyMask|EnterWindowMask);
-+        XMapWindow(d, child[i]);
-+        win_add(child[i]);
-+    }
-+}
-+
- void win_focus(client *c) {
-     cur = c;
-     XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
-@@ -290,6 +303,8 @@ int main(void) {
-     XSelectInput(d,  root, SubstructureRedirectMask);
-     XDefineCursor(d, root, XCreateFontCursor(d, 68));
- 
-+    init();
-+
-     for (unsigned int i=0; i < sizeof(keys)/sizeof(*keys); ++i)
-         XGrabKey(d, XKeysymToKeycode(d, keys[i].keysym), keys[i].mod,
-                  root, True, GrabModeAsync, GrabModeAsync);
diff --git a/patches/sowm-normal-kill.patch b/patches/sowm-normal-kill.patch
@@ -1,23 +0,0 @@
-diff --git a/sowm.c b/sowm.c
-index d1b4c2a..49d8af2 100644
---- a/sowm.c
-+++ b/sowm.c
-@@ -165,7 +165,17 @@ void win_del(Window w) {
- }
- 
- void win_kill() {
--    if (cur) XKillClient(d, cur->w);
-+    if (!cur) return;
-+
-+    XEvent ev = { .type = ClientMessage };
-+
-+    ev.xclient.window       = cur->w;
-+    ev.xclient.format       = 32;
-+    ev.xclient.message_type = XInternAtom(d, "WM_PROTOCOLS", True);
-+    ev.xclient.data.l[0]    = XInternAtom(d, "WM_DELETE_WINDOW", True);
-+    ev.xclient.data.l[1]    = CurrentTime;
-+
-+    XSendEvent(d, cur->w, False, NoEventMask, &ev);
- }
- 
- void win_center() {
diff --git a/patches/sowm-primitive-multimonitor.patch b/patches/sowm-primitive-multimonitor.patch
@@ -1,88 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 8573837..72e9542 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,5 +1,5 @@
- CFLAGS+= -std=c99 -Wall -Wextra -Wmissing-prototypes -pedantic
--LDADD+= -lX11
-+LDADD+= -lX11 -lXinerama
- LDFLAGS=
- PREFIX?= /usr
- BINDIR?= $(PREFIX)/bin
-diff --git a/sowm.c b/sowm.c
-index 0cc1293..6f858a9 100644
---- a/sowm.c
-+++ b/sowm.c
-@@ -4,6 +4,7 @@
- #include <X11/XF86keysym.h>
- #include <X11/keysym.h>
- #include <X11/XKBlib.h>
-+#include <X11/extensions/Xinerama.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <unistd.h>
-@@ -48,7 +49,7 @@ static void ws_go(const Arg arg);
- static int  xerror() { return 0;}
- 
- static client       *list = {0}, *ws_list[10] = {0}, *cur;
--static int          ws = 1, sw, sh, wx, wy, numlock;
-+static int          ws = 1, sw, sh, wx, wy, numlock, monitors;
- static unsigned int ww, wh;
- 
- static Display      *d;
-@@ -108,6 +109,7 @@ void notify_motion(XEvent *e) {
-         wy + (mouse.button == 1 ? yd : 0),
-         ww + (mouse.button == 3 ? xd : 0),
-         wh + (mouse.button == 3 ? yd : 0));
-+    win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh);
- }
- 
- void key_press(XEvent *e) {
-@@ -172,12 +174,35 @@ void win_kill() {
-     if (cur) XKillClient(d, cur->w);
- }
- 
-+int multimonitor_center_fs (int fs) {
-+    if (!XineramaIsActive(d)) return 1;
-+    XineramaScreenInfo *screen_info = XineramaQueryScreens(d, &monitors);
-+    for (int i = 0; i < monitors; i++) {
-+        if ((cur->wx >= screen_info[i].x_org && cur->wx < screen_info[i].x_org + screen_info[i].width)
-+            && (cur->wy >= screen_info[i].y_org && cur->wy < screen_info[i].y_org + screen_info[i].height)) {
-+            if (fs)
-+                XMoveResizeWindow(d, cur->w,
-+                                  screen_info[i].x_org, screen_info[i].y_org,
-+                                  screen_info[i].width, screen_info[i].height);
-+            else
-+                XMoveWindow(d, cur->w,
-+                            screen_info[i].x_org + ((screen_info[i].width  - ww) / 2),
-+                            screen_info[i].y_org + ((screen_info[i].height - wh) / 2));
-+            break;
-+        }
-+    }
-+    return 0;
-+}
-+
- void win_center() {
-     if (!cur) return;
- 
-     win_size(cur->w, &(int){0}, &(int){0}, &ww, &wh);
- 
--    XMoveWindow(d, cur->w, (sw - ww) / 2, (sh - wh) / 2);
-+    if (multimonitor_center_fs(0))
-+        XMoveWindow(d, cur->w, (sw - ww) / 2, (sh - wh) / 2);
-+
-+    win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh);
- }
- 
- void win_fs() {
-@@ -185,8 +210,8 @@ 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);
--
-+        if(multimonitor_center_fs(1))
-+            XMoveResizeWindow(d, cur->w, 0, 0, sw, sh);
-     } else
-         XMoveResizeWindow(d, cur->w, cur->wx, cur->wy, cur->ww, cur->wh);
- }
diff --git a/patches/sowm-rect-to-move.patch b/patches/sowm-rect-to-move.patch
@@ -1,117 +0,0 @@
-diff --git a/sowm.c b/sowm.c
-index bc14c4e..4ae3a8f 100644
---- a/sowm.c
-+++ b/sowm.c
-@@ -65,6 +65,9 @@ static void (*events[LASTEvent])(XEvent *e) = {
-     [MotionNotify]     = notify_motion
- };
- 
-+
-+Window WaitingWindow;
-+
- #include "config.h"
- 
- #define win        (client *t=0, *c=list; c && t!=list->prev; t=c, c=c->next)
-@@ -75,6 +78,23 @@ static void (*events[LASTEvent])(XEvent *e) = {
-     XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \
-                  &(unsigned int){0}, &(unsigned int){0})
- 
-+#define ABS(N) (((N)<0)?-(N):(N))
-+
-+void draw_outline(int x1, int y1, int x2, int y2) {
-+    XClearWindow(d, RootWindow(d, DefaultScreen(d)));
-+
-+    GC gc = XCreateGC(d, RootWindow(d, DefaultScreen(d)), 0, NULL);
-+    if(!gc)return;
-+
-+    XSetForeground(d, gc, WhitePixel(d, DefaultScreen(d)));
-+    XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x1, y1, x1, y2);
-+    XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x1, y1, x2, y1);
-+    XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x1, y2, x2, y2);
-+    XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x2, y1, x2, y2);
-+    XFreeGC(d, gc);
-+    XFlush(d);
-+}
-+
- void win_focus(client *c) {
-     cur = c;
-     XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
-@@ -93,7 +113,10 @@ void notify_enter(XEvent *e) {
- }
- 
- void notify_motion(XEvent *e) {
--    if (!mouse.subwindow || cur->f) return;
-+    if (!mouse.subwindow || cur->f) {
-+        draw_outline(mouse.x_root, mouse.y_root, e->xbutton.x_root, e->xbutton.y_root);
-+        return;
-+    }
- 
-     while(XCheckTypedEvent(d, MotionNotify, e));
- 
-@@ -116,15 +139,43 @@ void key_press(XEvent *e) {
- }
- 
- void button_press(XEvent *e) {
--    if (!e->xbutton.subwindow) return;
-+    mouse = e->xbutton;
- 
-+    if (!e->xbutton.subwindow) return;
-     win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh);
-     XRaiseWindow(d, e->xbutton.subwindow);
--    mouse = e->xbutton;
- }
- 
--void button_release() {
--    mouse.subwindow = 0;
-+void button_release(XEvent *e) {
-+    XClearWindow(d, RootWindow(d, DefaultScreen(d)));
-+
-+    if(WaitingWindow){
-+        XSelectInput(d, WaitingWindow, StructureNotifyMask|EnterWindowMask);
-+        win_size(WaitingWindow, &wx, &wy, &ww, &wh);
-+        win_add(WaitingWindow);
-+        cur = list->prev;
-+
-+        XMoveResizeWindow(d, cur->w,
-+            e->xbutton.x_root > mouse.x_root ? mouse.x_root : e->xbutton.x_root,
-+            e->xbutton.y_root > mouse.y_root ? mouse.y_root : e->xbutton.y_root,
-+            ABS(mouse.x_root - e->xbutton.x_root),
-+            ABS(mouse.y_root - e->xbutton.y_root));
-+
-+        XMapWindow(d, WaitingWindow);
-+        win_focus(list->prev);
-+
-+        WaitingWindow = 0;
-+
-+    } else if(!mouse.subwindow && cur) {
-+
-+        XMoveResizeWindow(d, cur->w,
-+            e->xbutton.x_root > mouse.x_root ? mouse.x_root : e->xbutton.x_root,
-+            e->xbutton.y_root > mouse.y_root ? mouse.y_root : e->xbutton.y_root,
-+            ABS(mouse.x_root - e->xbutton.x_root),
-+            ABS(mouse.y_root - e->xbutton.y_root));
-+
-+        mouse.subwindow = 0;
-+    }
- }
- 
- void win_add(Window w) {
-@@ -244,17 +295,7 @@ void configure_request(XEvent *e) {
- }
- 
- void map_request(XEvent *e) {
--    Window w = e->xmaprequest.window;
--
--    XSelectInput(d, w, StructureNotifyMask|EnterWindowMask);
--    win_size(w, &wx, &wy, &ww, &wh);
--    win_add(w);
--    cur = list->prev;
--
--    if (wx + wy == 0) win_center();
--
--    XMapWindow(d, w);
--    win_focus(list->prev);
-+    WaitingWindow = e->xmaprequest.window;
- }
- 
- void run(const Arg arg) {
diff --git a/patches/sowm-rounded-corners.patch b/patches/sowm-rounded-corners.patch
@@ -1,112 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 8573837..738af94 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,5 +1,5 @@
- CFLAGS+= -std=c99 -Wall -Wextra -Wmissing-prototypes -pedantic
--LDADD+= -lX11
-+LDADD+= -lX11 -lXext
- LDFLAGS=
- PREFIX?= /usr
- BINDIR?= $(PREFIX)/bin
-diff --git a/config.def.h b/config.def.h
-index aaaf38d..b25dc08 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -2,6 +2,7 @@
- #define CONFIG_H
- 
- #define MOD Mod4Mask
-+#define ROUND_CORNERS 20
- 
- const char* menu[]    = {"dmenu_run",      0};
- const char* term[]    = {"st",             0};
-diff --git a/sowm.c b/sowm.c
-index d1b4c2a..56bf509 100644
---- a/sowm.c
-+++ b/sowm.c
-@@ -4,6 +4,7 @@
- #include <X11/XF86keysym.h>
- #include <X11/keysym.h>
- #include <X11/XKBlib.h>
-+#include <X11/extensions/shape.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <unistd.h>
-@@ -43,6 +44,7 @@ static void win_del(Window w);
- static void win_kill();
- static void win_prev();
- static void win_next();
-+static void win_round_corners(Window w, int rad);
- static void win_to_ws(const Arg arg);
- static void ws_go(const Arg arg);
- static int  xerror() { return 0;}
-@@ -105,6 +107,9 @@ 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.button == 3)
-+        win_round_corners(mouse.subwindow, ROUND_CORNERS);
- }
- 
- void key_press(XEvent *e) {
-@@ -185,6 +190,41 @@ void win_fs() {
- 
-     } else
-         XMoveResizeWindow(d, cur->w, cur->wx, cur->wy, cur->ww, cur->wh);
-+
-+    win_round_corners(cur->w, cur->f ? 0 : ROUND_CORNERS);
-+}
-+
-+void win_round_corners(Window w, int rad) {
-+    unsigned int ww, wh, dia = 2 * rad;
-+
-+    win_size(w, &(int){1}, &(int){1}, &ww, &wh);
-+
-+    if (ww < dia || wh < dia) return;
-+
-+    Pixmap mask = XCreatePixmap(d, w, ww, wh, 1);
-+
-+    if (!mask) return;
-+
-+    XGCValues xgcv;
-+    GC shape_gc = XCreateGC(d, mask, 0, &xgcv);
-+
-+    if (!shape_gc) {
-+        XFreePixmap(d, mask);
-+        return;
-+    }
-+
-+    XSetForeground(d, shape_gc, 0);
-+    XFillRectangle(d, mask, shape_gc, 0, 0, ww, wh);
-+    XSetForeground(d, shape_gc, 1);
-+    XFillArc(d, mask, shape_gc, 0, 0, dia, dia, 0, 23040);
-+    XFillArc(d, mask, shape_gc, ww-dia-1, 0, dia, dia, 0, 23040);
-+    XFillArc(d, mask, shape_gc, 0, wh-dia-1, dia, dia, 0, 23040);
-+    XFillArc(d, mask, shape_gc, ww-dia-1, wh-dia-1, dia, dia, 0, 23040);
-+    XFillRectangle(d, mask, shape_gc, rad, 0, ww-dia, wh);
-+    XFillRectangle(d, mask, shape_gc, 0, rad, ww, wh-dia);
-+    XShapeCombineMask(d, w, ShapeBounding, 0, 0, mask, ShapeSet);
-+    XFreePixmap(d, mask);
-+    XFreeGC(d, shape_gc);
- }
- 
- void win_to_ws(const Arg arg) {
-@@ -241,6 +281,8 @@ void configure_request(XEvent *e) {
-         .sibling    = ev->above,
-         .stack_mode = ev->detail
-     });
-+
-+    win_round_corners(ev->window, ROUND_CORNERS);
- }
- 
- void map_request(XEvent *e) {
-@@ -253,6 +295,7 @@ void map_request(XEvent *e) {
- 
-     if (wx + wy == 0) win_center();
- 
-+    win_round_corners(w, ROUND_CORNERS);
-     XMapWindow(d, w);
-     win_focus(list->prev);
- }
diff --git a/patches/sowm-wheelresize.patch b/patches/sowm-wheelresize.patch
@@ -1,41 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index cae2009..a7a9fa7 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -1,6 +1,7 @@
- #ifndef CONFIG_H
- #define CONFIG_H
- 
-+#define WHELLSTEP 5
- #define MOD Mod4Mask
- 
- const char* menu[]    = {"dmenu_run",      0};
-diff --git a/sowm.c b/sowm.c
-index 90ae3bc..cbb56b5 100644
---- a/sowm.c
-+++ b/sowm.c
-@@ -126,6 +126,15 @@ void button_press(XEvent *e) {
- 
-     win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh);
-     XRaiseWindow(d, e->xbutton.subwindow);
-+
-+		int sd = 0;
-+		if(e->xbutton.button == Button4) sd = WHELLSTEP;
-+		else if(e->xbutton.button == Button5) sd = -WHELLSTEP;
-+
-+		XMoveResizeWindow(d, e->xbutton.subwindow,
-+				wx - sd, wy - sd,
-+				ww + sd*2, wh + sd*2);
-+
-     mouse = e->xbutton;
- }
- 
-@@ -295,7 +304,7 @@ void input_grab(Window root) {
-                 XGrabKey(d, code, keys[i].mod | modifiers[j], root,
-                         True, GrabModeAsync, GrabModeAsync);
- 
--    for (i = 1; i < 4; i += 2)
-+    for (i = 1; i < 6; i++)
-         for (j = 0; j < sizeof(modifiers)/sizeof(*modifiers); j++)
-             XGrabButton(d, i, MOD | modifiers[j], root, True,
-                 ButtonPressMask|ButtonReleaseMask|PointerMotionMask,