diff --git a/.forgejo/workflows/renovate.yml b/.forgejo/workflows/renovate.yml
deleted file mode 100644
index cc9ea6c..0000000
--- a/.forgejo/workflows/renovate.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: Renovate
-
-on:
-  schedule:
-    - cron: "0 * * * *"
-
-jobs:
-  renovate:
-    runs-on: docker
-    container: renovate/renovate@sha256:5894fa7fae274b30ccb8c9edcd7b8f106cc7da2f4e3eda2c62c2daff32235830
-    env:
-      RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }}
-      GITHUB_COM_TOKEN: ${{ secrets.GH_NOPRIV_TOKEN }}
-      RENOVATE_GIT_PRIVATE_KEY: ${{ secrets.JOHNNY5_GPG_PRIVKEY }}
-      RENOVATE_PLATFORM: gitea
-      RENOVATE_ENDPOINT: ${{ github.server_url }}
-      RENOVATE_GIT_AUTHOR: "Johnny5 <bot@snaile.de>"
-
-    steps:
-      - uses: https://code.forgejo.org/actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
-
-      - name: Renovate
-        run: renovate ${{ github.repository }}
diff --git a/.forgejo/workflows/void-packages.yml b/.forgejo/workflows/void-packages.yml
deleted file mode 100644
index 584181b..0000000
--- a/.forgejo/workflows/void-packages.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
-name: Update void-packages template
-
-on:
-  push:
-    tags: ["*"]
-
-jobs:
-  update-template:
-    name: Update xbps-src template
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-        with:
-          fetch-depth: 0
-          token: ${{ secrets.FORGEJO_PUSH_TOKEN }}
-          repository: "snailed/void-custom"
-          sparse-checkout: "srcpkgs/dwm-custom/"
-          ref: "main"
-
-      - name: Modify template
-        id: checksum
-        run: |
-          sed -i '/version=/ c version=${{ github.ref_name }}' srcpkgs/dwm-custom/template
-
-          wget https://git.snaile.de/snailed/dwm-custom/archive/${{ github.ref_name }}.tar.gz
-          sha256sum="$(sha256sum ${{ github.ref_name }}.tar.gz | cut -d ' ' -f 1)"
-          sed -i "/checksum=/ c checksum=${sha256sum}" srcpkgs/dwm-custom/template
-          sed -i "/revision=/ c revision=1" srcpkgs/dwm-custom/template
-
-      - name: Commit
-        uses: https://github.com/stefanzweifel/git-auto-commit-action@3ea6ae190baf489ba007f7c92608f33ce20ef04a # v4.16.0
-        with:
-          commit_user_name: "Johnny5"
-          commit_user_email: "bot@snaile.de"
-          commit_author: "Johnny5 <bot@snaile.de>"
-          commit_message: "dwm-custom: update to ${{ github.ref_name }}."
diff --git a/.gitignore b/.gitignore
index aaaff05..f6b676c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,3 @@
-drw.o
-dwm
-dwm.o
-util.o
-README.md
+dwm-final
+dwm-dev-1.0.0_1.x86_64.xbps
+pkg/usr
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..1b17b6d
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "dwm-flexipatch"]
+	path = dwm-flexipatch
+	url = https://github.com/bakkeby/dwm-flexipatch
+[submodule "flexipatch-finalizer"]
+	path = flexipatch-finalizer
+	url = https://github.com/bakkeby/flexipatch-finalizer
diff --git a/.renovaterc.json b/.renovaterc.json
deleted file mode 100644
index 468a904..0000000
--- a/.renovaterc.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
-  "extends": [
-    "local>snailed/renovate-config"
-  ]
-}
diff --git a/.woodpecker.yml b/.woodpecker.yml
new file mode 100644
index 0000000..c6150b5
--- /dev/null
+++ b/.woodpecker.yml
@@ -0,0 +1,70 @@
+when:
+  - event: tag
+  - event: manual
+
+steps:
+  build:
+    image: gcc
+    commands: |
+      apt-get update
+      apt-get install -y \
+        libx11-dev libx11-xcb-dev libxcb1-dev \
+        libxcb-res0-dev libxft-dev libxinerama-dev \
+        libfreetype6-dev libfontconfig1-dev \
+        libpango1.0-dev
+      cp -f config.mk patches.h dwm-flexipatch/
+      flexipatch-finalizer/flexipatch-finalizer.sh -r -d dwm-flexipatch -o dwm-final
+      # for patch in patches/*.diff; do
+      #     patch -d dwm-final <"$patch"
+      # done
+      cp -f config.h dwm-final/
+      cd dwm-final || exit 1
+      make clean install DESTDIR="$${CI_WORKSPACE}/pkg" PREFIX="/usr"
+
+
+  package-xbps:
+    image: ghcr.io/void-linux/void-musl-busybox
+    environment:
+      - LICENSE=GPL-2.0
+      - SHORT_DESCRIPTION=Customized dwm
+      - DEPENDENCIES="pango"
+    commands: |
+      xbps-create -A x86_64 \
+                  -H "$${CI_REPO_URL}" \
+                  -l "$${LICENSE}" \
+                  -n "$${CI_REPO_NAME}-$${CI_COMMIT_TAG}_1" \
+                  -m "$${CI_COMMIT_AUTHOR} <$${CI_COMMIT_AUTHOR_EMAIL}>" \
+                  -s "$${SHORT_DESCRIPTION}" \
+                  -D "$${DEPENDENCIES}" \
+                  "$${CI_WORKSPACE}/pkg"
+
+  package-targz:
+    image: alpine
+    commands: |
+      tar czf $${CI_REPO_NAME}-$${CI_COMMIT_TAG}.tar.gz --directory=$${CI_WORKSPACE}/pkg .
+
+  publish:
+    image: woodpeckerci/plugin-gitea-release
+    settings:
+      base_url: https://git.snaile.de
+      files:
+        - "${CI_REPO_NAME}-${CI_COMMIT_TAG}.tar.gz"
+      api_key:
+        from_secret: gitea_release
+      target: main
+
+  publish-xbps:
+    image: ghcr.io/void-linux/void-musl-busybox
+    environment:
+      - XBPS_TARGET_ARCH=x86_64
+    secrets: 
+      - source: xbps_pem_passphrase
+        target: XBPS_PASSPHRASE
+    volumes:
+      - /var/www/xbps:/target
+      - /etc/woodpecker/:/etc/woodpecker:ro
+    commands: |
+      export XBPS_TARGET_ARCH
+      mv $${CI_REPO_NAME}-$${CI_COMMIT_TAG}_1.x86_64.xbps /target
+      xbps-rindex -a /target/$${CI_REPO_NAME}-$${CI_COMMIT_TAG}_1.x86_64.xbps
+      xbps-rindex -S --signedby "$${CI_COMMIT_AUTHOR} <$${CI_COMMIT_AUTHOR_EMAIL}>" --privkey /etc/woodpecker/privkey.pem /target/$${CI_REPO_NAME}-$${CI_COMMIT_TAG}_1.x86_64.xbps
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 995172f..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,38 +0,0 @@
-MIT/X Consortium License
-
-© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
-© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
-© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
-© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
-© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
-© 2007-2009 Christof Musik <christof at sendfax dot de>
-© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
-© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
-© 2008 Martin Hurton <martin dot hurton at gmail dot com>
-© 2008 Neale Pickett <neale dot woozle dot org>
-© 2009 Mate Nagy <mnagy at port70 dot net>
-© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
-© 2010-2012 Connor Lane Smith <cls@lubutu.com>
-© 2011 Christoph Lohmann <20h@r-36.net>
-© 2015-2016 Quentin Rameau <quinq@fifth.space>
-© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
-© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
-© 2020-2022 Chris Down <chris@chrisdown.name>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 92f52ba..0000000
--- a/Makefile
+++ /dev/null
@@ -1,66 +0,0 @@
-# dwm - dynamic window manager
-# See LICENSE file for copyright and license details.
-
-include config.mk
-
-SRC = drw.c dwm.c util.c
-OBJ = ${SRC:.c=.o}
-
-# FreeBSD users, prefix all ifdef, else and endif statements with a . for this to work (e.g. .ifdef)
-
-ifdef YAJLLIBS
-all: dwm dwm-msg README.md
-else
-all: dwm README.md
-endif
-
-.c.o:
-	${CC} -c ${CFLAGS} $<
-
-${OBJ}: config.h config.mk
-
-config.h:
-	cp config.def.h $@
-
-README.md:
-	./docs.awk config.h >$@
-
-dwm: ${OBJ}
-	${CC} -o $@ ${OBJ} ${LDFLAGS}
-
-ifdef YAJLLIBS
-dwm-msg:
-	${CC} -o $@ patch/ipc/dwm-msg.c ${LDFLAGS}
-endif
-
-clean:
-	rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
-	rm -f dwm-msg
-	rm -f README.md
-
-dist: clean
-	mkdir -p dwm-${VERSION}
-	cp -R LICENSE Makefile README.md config.def.h config.mk\
-		drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
-	tar -cf dwm-${VERSION}.tar dwm-${VERSION}
-	gzip dwm-${VERSION}.tar
-	rm -rf dwm-${VERSION}
-
-install: all
-	mkdir -p ${DESTDIR}${PREFIX}/bin
-	cp -f dwm ${DESTDIR}${PREFIX}/bin
-	mkdir -p ${DESTDIR}${PREFIX}/share/doc/dwm
-	cp -f README.md ${DESTDIR}${PREFIX}/share/doc/dwm
-ifdef YAJLLIBS
-	cp -f dwm-msg ${DESTDIR}${PREFIX}/bin
-endif
-	chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
-ifdef YAJLLIBS
-	chmod 755 ${DESTDIR}${PREFIX}/bin/dwm-msg
-endif
-
-uninstall:
-	rm -f ${DESTDIR}${PREFIX}/bin/dwm\
-		${DESTDIR}${PREFIX}/share/doc/dwm/README.md
-
-.PHONY: all clean dist install uninstall
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..4f1eab0
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+cp config.mk patches.h dwm-flexipatch/
+flexipatch-finalizer/flexipatch-finalizer.sh -r -d dwm-flexipatch -o dwm-final
+for patch in patches/*.diff; do
+	patch -d dwm-final <"$patch"
+done
+cp config.h dwm-final/
+cd dwm-final || exit 1
+make clean install DESTDIR="../pkg" PREFIX="/usr"
+cd - || exit 1
+
+# xbps-create -A x86_64 \
+# 	-n "dwm-dev-1.0.0_1" \
+# 	-s "Test build of dwm" \
+# 	pkg
diff --git a/config.def.h b/config.def.h
deleted file mode 100644
index 80e3821..0000000
--- a/config.def.h
+++ /dev/null
@@ -1,335 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/* Helper macros for spawning commands */
-#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
-#define CMD(...)   { .v = (const char*[]){ __VA_ARGS__, NULL } }
-
-/* appearance */
-static const unsigned int borderpx       = 1;   /* border pixel of windows */
-static const unsigned int snap           = 32;  /* snap pixel */
-static const int showbar                 = 1;   /* 0 means no bar */
-static const int topbar                  = 1;   /* 0 means bottom bar */
-static const int focusonwheel            = 0;
-static int floatposgrid_x                = 5;  /* float grid columns */
-static int floatposgrid_y                = 5;  /* float grid rows */
-/* Status is to be shown on: -1 (all monitors), 0 (a specific monitor by index), 'A' (active monitor) */
-static const int statusmon               = 'A';
-
-/* Indicators: see patch/bar_indicators.h for options */
-static int tagindicatortype              = INDICATOR_TOP_LEFT_SQUARE;
-static int tiledindicatortype            = INDICATOR_NONE;
-static int floatindicatortype            = INDICATOR_TOP_LEFT_SQUARE;
-static const char font[]                 = "monospace 10";
-static const char dmenufont[]            = "monospace:size=10";
-
-static char c000000[]                    = "#000000"; // placeholder value
-
-static char normfgcolor[]                = "#bbbbbb";
-static char normbgcolor[]                = "#222222";
-static char normbordercolor[]            = "#444444";
-static char normfloatcolor[]             = "#db8fd9";
-
-static char selfgcolor[]                 = "#eeeeee";
-static char selbgcolor[]                 = "#005577";
-static char selbordercolor[]             = "#005577";
-static char selfloatcolor[]              = "#005577";
-
-static char titlenormfgcolor[]           = "#bbbbbb";
-static char titlenormbgcolor[]           = "#222222";
-static char titlenormbordercolor[]       = "#444444";
-static char titlenormfloatcolor[]        = "#db8fd9";
-
-static char titleselfgcolor[]            = "#eeeeee";
-static char titleselbgcolor[]            = "#005577";
-static char titleselbordercolor[]        = "#005577";
-static char titleselfloatcolor[]         = "#005577";
-
-static char tagsnormfgcolor[]            = "#bbbbbb";
-static char tagsnormbgcolor[]            = "#222222";
-static char tagsnormbordercolor[]        = "#444444";
-static char tagsnormfloatcolor[]         = "#db8fd9";
-
-static char tagsselfgcolor[]             = "#eeeeee";
-static char tagsselbgcolor[]             = "#005577";
-static char tagsselbordercolor[]         = "#005577";
-static char tagsselfloatcolor[]          = "#005577";
-
-static char hidnormfgcolor[]             = "#005577";
-static char hidselfgcolor[]              = "#227799";
-static char hidnormbgcolor[]             = "#222222";
-static char hidselbgcolor[]              = "#222222";
-
-static char urgfgcolor[]                 = "#bbbbbb";
-static char urgbgcolor[]                 = "#222222";
-static char urgbordercolor[]             = "#ff0000";
-static char urgfloatcolor[]              = "#db8fd9";
-
-static char scratchselfgcolor[]          = "#FFF7D4";
-static char scratchselbgcolor[]          = "#77547E";
-static char scratchselbordercolor[]      = "#894B9F";
-static char scratchselfloatcolor[]       = "#894B9F";
-
-static char scratchnormfgcolor[]         = "#FFF7D4";
-static char scratchnormbgcolor[]         = "#664C67";
-static char scratchnormbordercolor[]     = "#77547E";
-static char scratchnormfloatcolor[]      = "#77547E";
-
-static char *colors[][ColCount] = {
-	/*                       fg                bg                border                float */
-	[SchemeNorm]         = { normfgcolor,      normbgcolor,      normbordercolor,      normfloatcolor },
-	[SchemeSel]          = { selfgcolor,       selbgcolor,       selbordercolor,       selfloatcolor },
-	[SchemeTitleNorm]    = { titlenormfgcolor, titlenormbgcolor, titlenormbordercolor, titlenormfloatcolor },
-	[SchemeTitleSel]     = { titleselfgcolor,  titleselbgcolor,  titleselbordercolor,  titleselfloatcolor },
-	[SchemeTagsNorm]     = { tagsnormfgcolor,  tagsnormbgcolor,  tagsnormbordercolor,  tagsnormfloatcolor },
-	[SchemeTagsSel]      = { tagsselfgcolor,   tagsselbgcolor,   tagsselbordercolor,   tagsselfloatcolor },
-	[SchemeHidNorm]      = { hidnormfgcolor,   hidnormbgcolor,   c000000,              c000000 },
-	[SchemeHidSel]       = { hidselfgcolor,    hidselbgcolor,    c000000,              c000000 },
-	[SchemeUrg]          = { urgfgcolor,       urgbgcolor,       urgbordercolor,       urgfloatcolor },
-	[SchemeScratchSel]  = { scratchselfgcolor, scratchselbgcolor, scratchselbordercolor, scratchselfloatcolor },
-	[SchemeScratchNorm] = { scratchnormfgcolor, scratchnormbgcolor, scratchnormbordercolor, scratchnormfloatcolor },
-};
-
-static const char *const autostart[] = {
-	"st", NULL,
-	NULL /* terminate */
-};
-
-static const char *scratchpadcmd[] = {"s", "st", "-n", "spterm", NULL};
-
-/* Tags
- * In a traditional dwm the number of tags in use can be changed simply by changing the number
- * of strings in the tags array. This build does things a bit different which has some added
- * benefits. If you need to change the number of tags here then change the NUMTAGS macro in dwm.c.
- *
- * Examples:
- *
- *  1) static char *tagicons[][NUMTAGS*2] = {
- *         [DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I" },
- *     }
- *
- *  2) static char *tagicons[][1] = {
- *         [DEFAULT_TAGS] = { "•" },
- *     }
- *
- * The first example would result in the tags on the first monitor to be 1 through 9, while the
- * tags for the second monitor would be named A through I. A third monitor would start again at
- * 1 through 9 while the tags on a fourth monitor would also be named A through I. Note the tags
- * count of NUMTAGS*2 in the array initialiser which defines how many tag text / icon exists in
- * the array. This can be changed to *3 to add separate icons for a third monitor.
- *
- * For the second example each tag would be represented as a bullet point. Both cases work the
- * same from a technical standpoint - the icon index is derived from the tag index and the monitor
- * index. If the icon index is is greater than the number of tag icons then it will wrap around
- * until it an icon matches. Similarly if there are two tag icons then it would alternate between
- * them. This works seamlessly with alternative tags and alttagsdecoration patches.
- */
-static char *tagicons[][NUMTAGS] =
-{
-	[DEFAULT_TAGS]        = { "1", "2", "3", "4", "5", "6", "7", "8", "9" },
-	[ALTERNATIVE_TAGS]    = { "A", "B", "C", "D", "E", "F", "G", "H", "I" },
-	[ALT_TAGS_DECORATION] = { "<1>", "<2>", "<3>", "<4>", "<5>", "<6>", "<7>", "<8>", "<9>" },
-};
-
-/* There are two options when it comes to per-client rules:
- *  - a typical struct table or
- *  - using the RULE macro
- *
- * A traditional struct table looks like this:
- *    // class      instance  title  wintype  tags mask  isfloating  monitor
- *    { "Gimp",     NULL,     NULL,  NULL,    1 << 4,    0,          -1 },
- *    { "Firefox",  NULL,     NULL,  NULL,    1 << 7,    0,          -1 },
- *
- * The RULE macro has the default values set for each field allowing you to only
- * specify the values that are relevant for your rule, e.g.
- *
- *    RULE(.class = "Gimp", .tags = 1 << 4)
- *    RULE(.class = "Firefox", .tags = 1 << 7)
- *
- * Refer to the Rule struct definition for the list of available fields depending on
- * the patches you enable.
- */
-static const Rule rules[] = {
-	/* xprop(1):
-	 *	WM_CLASS(STRING) = instance, class
-	 *	WM_NAME(STRING) = title
-	 *	WM_WINDOW_ROLE(STRING) = role
-	 *	_NET_WM_WINDOW_TYPE(ATOM) = wintype
-	 */
-	RULE(.wintype = WTYPE "DIALOG", .isfloating = 1)
-	RULE(.wintype = WTYPE "UTILITY", .isfloating = 1)
-	RULE(.wintype = WTYPE "TOOLBAR", .isfloating = 1)
-	RULE(.wintype = WTYPE "SPLASH", .isfloating = 1)
-	RULE(.class = "Gimp", .tags = 1 << 4)
-	RULE(.class = "Firefox", .tags = 1 << 7)
-	RULE(.instance = "spterm", .scratchkey = 's', .isfloating = 1)
-};
-
-/* Bar rules allow you to configure what is shown where on the bar, as well as
- * introducing your own bar modules.
- *
- *    monitor:
- *      -1  show on all monitors
- *       0  show on monitor 0
- *      'A' show on active monitor (i.e. focused / selected) (or just -1 for active?)
- *    bar - bar index, 0 is default, 1 is extrabar
- *    alignment - how the module is aligned compared to other modules
- *    widthfunc, drawfunc, clickfunc - providing bar module width, draw and click functions
- *    name - does nothing, intended for visual clue and for logging / debugging
- */
-static const BarRule barrules[] = {
-	/* monitor   bar    alignment         widthfunc                 drawfunc                clickfunc                hoverfunc                name */
-	{ -1,        0,     BAR_ALIGN_LEFT,   width_tags,               draw_tags,              click_tags,              hover_tags,              "tags" },
-	{ -1,        0,     BAR_ALIGN_LEFT,   width_ltsymbol,           draw_ltsymbol,          click_ltsymbol,          NULL,                    "layout" },
-	{ statusmon, 0,     BAR_ALIGN_RIGHT,  width_status,             draw_status,            click_statuscmd,         NULL,                    "status" },
-	{ -1,        0,     BAR_ALIGN_NONE,   width_wintitle,           draw_wintitle,          click_wintitle,          NULL,                    "wintitle" },
-};
-
-/* layout(s) */
-static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */
-static const int nmaster     = 1;    /* number of clients in master area */
-static const int resizehints = 0;    /* 1 means respect size hints in tiled resizals */
-static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
-
-static const Layout layouts[] = {
-	/* symbol     arrange function */
-	{ "[]=",      tile },    /* first entry is default */
-	{ "><>",      NULL },    /* no layout function means floating behavior */
-	{ "TTT",      bstack },
-	{ ":::",      gaplessgrid },
-};
-
-/* key definitions */
-#define MODKEY Mod1Mask
-#define TAGKEYS(KEY,TAG) \
-	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
-	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
-	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
-	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
-
-#define STACKKEYS(MOD,ACTION) \
-	{ MOD, XK_j,     ACTION##stack, {.i = INC(+1) } }, \
-	{ MOD, XK_k,     ACTION##stack, {.i = INC(-1) } }, \
-	{ MOD, XK_s,     ACTION##stack, {.i = PREVSEL } }, \
-	{ MOD, XK_w,     ACTION##stack, {.i = 0 } }, \
-	{ MOD, XK_e,     ACTION##stack, {.i = 1 } }, \
-	{ MOD, XK_a,     ACTION##stack, {.i = 2 } }, \
-	{ MOD, XK_z,     ACTION##stack, {.i = -1 } },
-
-/* commands */
-static const char *dmenucmd[] = {
-	"dmenu_run",
-	"-fn", dmenufont,
-	"-nb", normbgcolor,
-	"-nf", normfgcolor,
-	"-sb", selbgcolor,
-	"-sf", selfgcolor,
-	NULL
-};
-static const char *termcmd[]  = { "st", NULL };
-
-/* This defines the name of the executable that handles the bar (used for signalling purposes) */
-#define STATUSBAR "dwmblocks"
-
-static const Key keys[] = {
-	/* modifier                     key            function                argument */
-	{ MODKEY,                       XK_p,          spawn,                  {.v = dmenucmd } },
-	{ MODKEY|ShiftMask,             XK_Return,     spawn,                  {.v = termcmd } },
-	{ MODKEY,                       XK_b,          togglebar,              {0} },
-	STACKKEYS(MODKEY,                              focus)
-	STACKKEYS(MODKEY|ShiftMask,                    push)
-	{ MODKEY,                       XK_i,          incnmaster,             {.i = +1 } },
-	{ MODKEY,                       XK_d,          incnmaster,             {.i = -1 } },
-	{ MODKEY,                       XK_h,          setmfact,               {.f = -0.05} },
-	{ MODKEY,                       XK_l,          setmfact,               {.f = +0.05} },
-	{ MODKEY,                       XK_Return,     zoom,                   {0} },
-	{ MODKEY,                       XK_Tab,        view,                   {0} },
-	{ MODKEY|ShiftMask,             XK_c,          killclient,             {0} },
-	{ MODKEY|ShiftMask,             XK_q,          quit,                   {0} },
-	{ MODKEY|ControlMask|ShiftMask, XK_q,          quit,                   {1} },
-	{ MODKEY,                       XK_t,          setlayout,              {.v = &layouts[0]} },
-	{ MODKEY,                       XK_f,          setlayout,              {.v = &layouts[1]} },
-	{ MODKEY,                       XK_m,          setlayout,              {.v = &layouts[2]} },
-	{ MODKEY,                       XK_space,      setlayout,              {0} },
-	{ MODKEY|ShiftMask,             XK_space,      togglefloating,         {0} },
-	{ MODKEY,                       XK_grave,      togglescratch,          {.v = scratchpadcmd } },
-	{ MODKEY|ControlMask,           XK_grave,      setscratch,             {.v = scratchpadcmd } },
-	{ MODKEY|ShiftMask,             XK_grave,      removescratch,          {.v = scratchpadcmd } },
-	{ MODKEY|Mod4Mask,              XK_space,      unfloatvisible,         {0} },
-	{ MODKEY|ShiftMask,             XK_t,          unfloatvisible,         {.v = &layouts[0]} },
-	{ MODKEY,                       XK_y,          togglefullscreen,       {0} },
-	{ MODKEY,                       XK_0,          view,                   {.ui = ~0 } },
-	{ MODKEY|ShiftMask,             XK_0,          tag,                    {.ui = ~0 } },
-	{ MODKEY,                       XK_comma,      focusmon,               {.i = -1 } },
-	{ MODKEY,                       XK_period,     focusmon,               {.i = +1 } },
-	{ MODKEY|ShiftMask,             XK_comma,      tagmon,                 {.i = -1 } },
-	{ MODKEY|ShiftMask,             XK_period,     tagmon,                 {.i = +1 } },
-	/* Note that due to key limitations the below example kybindings are defined with a Mod3Mask,
-	 * which is not always readily available. Refer to the patch wiki for more details. */
-	/* Client position is limited to monitor window area */
-	{ Mod3Mask,                     XK_u,            floatpos,               {.v = "-26x -26y" } }, // ↖
-	{ Mod3Mask,                     XK_i,            floatpos,               {.v = "  0x -26y" } }, // ↑
-	{ Mod3Mask,                     XK_o,            floatpos,               {.v = " 26x -26y" } }, // ↗
-	{ Mod3Mask,                     XK_j,            floatpos,               {.v = "-26x   0y" } }, // ←
-	{ Mod3Mask,                     XK_l,            floatpos,               {.v = " 26x   0y" } }, // →
-	{ Mod3Mask,                     XK_m,            floatpos,               {.v = "-26x  26y" } }, // ↙
-	{ Mod3Mask,                     XK_comma,        floatpos,               {.v = "  0x  26y" } }, // ↓
-	{ Mod3Mask,                     XK_period,       floatpos,               {.v = " 26x  26y" } }, // ↘
-	/* Absolute positioning (allows moving windows between monitors) */
-	{ Mod3Mask|ControlMask,         XK_u,            floatpos,               {.v = "-26a -26a" } }, // ↖
-	{ Mod3Mask|ControlMask,         XK_i,            floatpos,               {.v = "  0a -26a" } }, // ↑
-	{ Mod3Mask|ControlMask,         XK_o,            floatpos,               {.v = " 26a -26a" } }, // ↗
-	{ Mod3Mask|ControlMask,         XK_j,            floatpos,               {.v = "-26a   0a" } }, // ←
-	{ Mod3Mask|ControlMask,         XK_l,            floatpos,               {.v = " 26a   0a" } }, // →
-	{ Mod3Mask|ControlMask,         XK_m,            floatpos,               {.v = "-26a  26a" } }, // ↙
-	{ Mod3Mask|ControlMask,         XK_comma,        floatpos,               {.v = "  0a  26a" } }, // ↓
-	{ Mod3Mask|ControlMask,         XK_period,       floatpos,               {.v = " 26a  26a" } }, // ↘
-	/* Resize client, client center position is fixed which means that client expands in all directions */
-	{ Mod3Mask|ShiftMask,           XK_u,            floatpos,               {.v = "-26w -26h" } }, // ↖
-	{ Mod3Mask|ShiftMask,           XK_i,            floatpos,               {.v = "  0w -26h" } }, // ↑
-	{ Mod3Mask|ShiftMask,           XK_o,            floatpos,               {.v = " 26w -26h" } }, // ↗
-	{ Mod3Mask|ShiftMask,           XK_j,            floatpos,               {.v = "-26w   0h" } }, // ←
-	{ Mod3Mask|ShiftMask,           XK_k,            floatpos,               {.v = "800W 800H" } }, // ·
-	{ Mod3Mask|ShiftMask,           XK_l,            floatpos,               {.v = " 26w   0h" } }, // →
-	{ Mod3Mask|ShiftMask,           XK_m,            floatpos,               {.v = "-26w  26h" } }, // ↙
-	{ Mod3Mask|ShiftMask,           XK_comma,        floatpos,               {.v = "  0w  26h" } }, // ↓
-	{ Mod3Mask|ShiftMask,           XK_period,       floatpos,               {.v = " 26w  26h" } }, // ↘
-	/* Client is positioned in a floating grid, movement is relative to client's current position */
-	{ Mod3Mask|Mod1Mask,            XK_u,            floatpos,               {.v = "-1p -1p" } }, // ↖
-	{ Mod3Mask|Mod1Mask,            XK_i,            floatpos,               {.v = " 0p -1p" } }, // ↑
-	{ Mod3Mask|Mod1Mask,            XK_o,            floatpos,               {.v = " 1p -1p" } }, // ↗
-	{ Mod3Mask|Mod1Mask,            XK_j,            floatpos,               {.v = "-1p  0p" } }, // ←
-	{ Mod3Mask|Mod1Mask,            XK_k,            floatpos,               {.v = " 0p  0p" } }, // ·
-	{ Mod3Mask|Mod1Mask,            XK_l,            floatpos,               {.v = " 1p  0p" } }, // →
-	{ Mod3Mask|Mod1Mask,            XK_m,            floatpos,               {.v = "-1p  1p" } }, // ↙
-	{ Mod3Mask|Mod1Mask,            XK_comma,        floatpos,               {.v = " 0p  1p" } }, // ↓
-	{ Mod3Mask|Mod1Mask,            XK_period,       floatpos,               {.v = " 1p  1p" } }, // ↘
-	TAGKEYS(                        XK_1,                                  0)
-	TAGKEYS(                        XK_2,                                  1)
-	TAGKEYS(                        XK_3,                                  2)
-	TAGKEYS(                        XK_4,                                  3)
-	TAGKEYS(                        XK_5,                                  4)
-	TAGKEYS(                        XK_6,                                  5)
-	TAGKEYS(                        XK_7,                                  6)
-	TAGKEYS(                        XK_8,                                  7)
-	TAGKEYS(                        XK_9,                                  8)
-};
-
-/* button definitions */
-/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
-static const Button buttons[] = {
-	/* click                event mask           button          function        argument */
-	{ ClkLtSymbol,          0,                   Button1,        setlayout,      {0} },
-	{ ClkLtSymbol,          0,                   Button3,        setlayout,      {.v = &layouts[2]} },
-	{ ClkWinTitle,          0,                   Button2,        zoom,           {0} },
-	{ ClkStatusText,        0,                   Button1,        sigstatusbar,   {.i = 1 } },
-	{ ClkStatusText,        0,                   Button2,        sigstatusbar,   {.i = 2 } },
-	{ ClkStatusText,        0,                   Button3,        sigstatusbar,   {.i = 3 } },
-	{ ClkClientWin,         MODKEY,              Button1,        movemouse,      {0} },
-	{ ClkClientWin,         MODKEY,              Button2,        togglefloating, {0} },
-	{ ClkClientWin,         MODKEY,              Button3,        resizemouse,    {0} },
-	{ ClkTagBar,            0,                   Button1,        view,           {0} },
-	{ ClkTagBar,            0,                   Button3,        toggleview,     {0} },
-	{ ClkTagBar,            MODKEY,              Button1,        tag,            {0} },
-	{ ClkTagBar,            MODKEY,              Button3,        toggletag,      {0} },
-};
-
diff --git a/config.h b/config.h
index 8c0c92d..063a608 100644
--- a/config.h
+++ b/config.h
@@ -1,138 +1,169 @@
 /* See LICENSE file for copyright and license details. */
-
 #define TERM "st"
 #define TERM_FLAG_NAME "-n"
 #define TERM_FLAG_EXEC "-e"
-#define TERM_FLAG_CLASS "-c"
-
-#define BROWSER "floorp"
-#define BROWSER_FLAG_INCOG "--private-window"
-#define BROWSER_FLAG_1 "--disable-pinch"
+#define TERM_START "tmux"
 
 #define STATUSBAR "dwmblocks"
 
+#define BROWSER "brave-browser"
+#define BROWSER_FLAG_INCOG "--incognito"
+#define BROWSER_FLAG_1 "--enable-blink-features=MiddleClickAutoscroll"
+
 /* appearance */
-static const unsigned int borderpx = 2;   /* border pixel of windows */
-static const unsigned int snap     = 32;  /* snap pixel */
-static const int showbar           = 1;   /* 0 means no bar */
-static const int topbar            = 1;   /* 0 means bottom bar */
-static const int focusonwheel      = 0;
-static int floatposgrid_x          = 5;  /* float grid columns */
-static int floatposgrid_y          = 5;  /* float grid rows */
-/* Status is to be shown on: -1 (all monitors), 0 (a specific monitor by index), 'A' (active monitor) */
+static const unsigned int borderpx       = 2;
+static const unsigned int snap           = 33;
+static const int swallowfloating         = 1;
+static const int showbar                 = 1;
+static const int topbar                  = 1;
+static const int focusonwheel            = 1;
+static int floatposgrid_x                = 5;
+static int floatposgrid_y                = 3;
+static const unsigned int systrayspacing = 3;
+static const int showsystray             = 1;
 
 /* Indicators: see patch/bar_indicators.h for options */
 static int tagindicatortype              = INDICATOR_NONE;
 static int tiledindicatortype            = INDICATOR_NONE;
 static int floatindicatortype            = INDICATOR_NONE;
-static const int quit_empty_window_count = 0;   /* only allow dwm to quit if no (<= count) windows are open */
-static const char font[]                 = "FiraCode Nerd Font 12";
 
-#define BLACK "#15161E"
-#define RED "#f7768e"
-#define GREEN "#9ece6a"
-#define ORANGE "#e0af68"
-#define BLUE "#7aa2f7"
-#define MAGENTA "#bb9af7"
-#define CYAN "#7dcfff"
-#define LIGHT_GRAY "#a9b1d6"
-#define GRAY "#414868"
-#define WHITE "#c0caf5"
-#define UNDEFINED "#ff0000"
+static const char font[] = "FiraCode Nerd Font 28";
 
-static char undefined[]              = UNDEFINED; // placeholder value
+#define NOCOLOR "#FF0000"
+#define COLOR0  "#15161E"
+#define COLOR1  "#f7768e"
+#define COLOR2  "#9ece6a"
+#define COLOR3  "#e0af68"
+#define COLOR4  "#7aa2f7"
+#define COLOR5  "#bb9af7"
+#define COLOR6  "#7dcfff"
+#define COLOR7  "#a9b1d6"
+#define COLOR8  "#414868" 
+#define COLOR9  "#f7768e" 
+#define COLOR10 "#9ece6a" 
+#define COLOR11 "#e0af68" 
+#define COLOR12 "#7aa2f7" 
+#define COLOR13 "#bb9af7" 
+#define COLOR14 "#7dcfff" 
+#define COLOR15 "#c0caf5"
 
-static char normfgcolor[]            = WHITE;
-static char normbgcolor[]            = BLACK;
-static char normbordercolor[]        = GRAY;
-static char normfloatcolor[]         = GRAY;
+#define BORDERNORM "#383c4a"
+#define BORDERSEL  COLOR4
 
-static char selfgcolor[]             = UNDEFINED;
-static char selbgcolor[]             = UNDEFINED;
-static char selbordercolor[]         = BLUE;
-static char selfloatcolor[]          = BLUE;
+static char normfgcolor[]            = COLOR15;
+static char normbgcolor[]            = COLOR0;
+static char normbordercolor[]        = BORDERNORM;
+static char normfloatcolor[]         = BORDERNORM;
 
-static char titlenormfgcolor[]       = WHITE;
-static char titlenormbgcolor[]       = BLACK;
-static char titlenormbordercolor[]   = UNDEFINED;
-static char titlenormfloatcolor[]    = UNDEFINED;
+static char selfgcolor[]             = COLOR15;
+static char selbgcolor[]             = COLOR4;
+static char selbordercolor[]         = BORDERSEL;
+static char selfloatcolor[]          = BORDERSEL;
 
-static char titleselfgcolor[]        = LIGHT_GRAY;
-static char titleselbgcolor[]        = BLACK;
-static char titleselbordercolor[]    = UNDEFINED;
-static char titleselfloatcolor[]     = UNDEFINED;
+static char titlenormfgcolor[]       = COLOR7;
+static char titlenormbgcolor[]       = COLOR0;
+static char titlenormbordercolor[]   = NOCOLOR;
+static char titlenormfloatcolor[]    = NOCOLOR;
 
-static char tagsnormfgcolor[]        = LIGHT_GRAY;
-static char tagsnormbgcolor[]        = BLACK;
-static char tagsnormbordercolor[]    = UNDEFINED;
-static char tagsnormfloatcolor[]     = UNDEFINED;
+static char titleselfgcolor[]        = COLOR7;
+static char titleselbgcolor[]        = COLOR0;
+static char titleselbordercolor[]    = NOCOLOR;
+static char titleselfloatcolor[]     = NOCOLOR;
 
-static char tagsselfgcolor[]         = BLACK;
-static char tagsselbgcolor[]         = BLUE;
-static char tagsselbordercolor[]     = UNDEFINED;
-static char tagsselfloatcolor[]      = UNDEFINED;
+static char tagsnormfgcolor[]        = COLOR7;
+static char tagsnormbgcolor[]        = COLOR0;
+static char tagsnormbordercolor[]    = NOCOLOR;
+static char tagsnormfloatcolor[]     = NOCOLOR;
 
-static char hidnormfgcolor[]         = UNDEFINED;
-static char hidselfgcolor[]          = UNDEFINED;
-static char hidnormbgcolor[]         = UNDEFINED;
-static char hidselbgcolor[]          = UNDEFINED;
+static char tagsselfgcolor[]         = COLOR0;
+static char tagsselbgcolor[]         = COLOR4;
+static char tagsselbordercolor[]     = NOCOLOR;
+static char tagsselfloatcolor[]      = NOCOLOR;
 
-static char urgfgcolor[]             = BLACK;
-static char urgbgcolor[]             = RED;
-static char urgbordercolor[]         = RED;
-static char urgfloatcolor[]          = RED;
+static char hidnormfgcolor[]         = NOCOLOR;
+static char hidselfgcolor[]          = NOCOLOR;
+static char hidnormbgcolor[]         = NOCOLOR;
+static char hidselbgcolor[]          = NOCOLOR;
 
-static char scratchselfgcolor[]      = UNDEFINED;
-static char scratchselbgcolor[]      = UNDEFINED;
-static char scratchselbordercolor[]  = BLUE;
-static char scratchselfloatcolor[]   = BLUE;
+static char urgfgcolor[]             = COLOR0;
+static char urgbgcolor[]             = COLOR1;
+static char urgbordercolor[]         = COLOR1;
+static char urgfloatcolor[]          = COLOR1;
 
-static char scratchnormfgcolor[]     = UNDEFINED;
-static char scratchnormbgcolor[]     = UNDEFINED;
-static char scratchnormbordercolor[] = GRAY;
-static char scratchnormfloatcolor[]  = GRAY;
+static char scratchselfgcolor[]      = COLOR15;
+static char scratchselbgcolor[]      = COLOR4;
+static char scratchselbordercolor[]  = BORDERSEL;
+static char scratchselfloatcolor[]   = BORDERSEL;
+
+static char scratchnormfgcolor[]     = COLOR15;
+static char scratchnormbgcolor[]     = COLOR0;
+static char scratchnormbordercolor[] = BORDERNORM;
+static char scratchnormfloatcolor[]  = BORDERNORM;
+
+static const unsigned int baralpha = 0xcc;
+static const unsigned int borderalpha = OPAQUE;
+static const unsigned int alphas[][3] = {
+    /*                       fg      bg        border     */
+    [SchemeNorm]         = { OPAQUE, baralpha, borderalpha },
+    [SchemeSel]          = { OPAQUE, baralpha, borderalpha },
+    [SchemeTitleNorm]    = { OPAQUE, baralpha, borderalpha },
+    [SchemeTitleSel]     = { OPAQUE, baralpha, borderalpha },
+    [SchemeTagsNorm]     = { OPAQUE, baralpha, borderalpha },
+    [SchemeTagsSel]      = { OPAQUE, OPAQUE, borderalpha },
+    [SchemeHidNorm]      = { OPAQUE, baralpha, borderalpha },
+    [SchemeHidSel]       = { OPAQUE, baralpha, borderalpha },
+    [SchemeUrg]          = { OPAQUE, OPAQUE, borderalpha },
+    [SchemeScratchSel]  = { OPAQUE, baralpha, borderalpha },
+    [SchemeScratchNorm] = { OPAQUE, baralpha, borderalpha },
+};
 
 static char *colors[][ColCount] = {
-	/*                       fg                bg                border                float */
-	[SchemeNorm]        = { normfgcolor,        normbgcolor,        normbordercolor,        normfloatcolor },
-	[SchemeSel]         = { selfgcolor,         selbgcolor,         selbordercolor,         selfloatcolor },
-	[SchemeTitleNorm]   = { titlenormfgcolor,   titlenormbgcolor,   titlenormbordercolor,   titlenormfloatcolor },
-	[SchemeTitleSel]    = { titleselfgcolor,    titleselbgcolor,    titleselbordercolor,    titleselfloatcolor },
-	[SchemeTagsNorm]    = { tagsnormfgcolor,    tagsnormbgcolor,    tagsnormbordercolor,    tagsnormfloatcolor },
-	[SchemeTagsSel]     = { tagsselfgcolor,     tagsselbgcolor,     tagsselbordercolor,     tagsselfloatcolor },
-	[SchemeHidNorm]     = { hidnormfgcolor,     hidnormbgcolor,     undefined,              undefined },
-	[SchemeHidSel]      = { hidselfgcolor,      hidselbgcolor,      undefined,              undefined },
-	[SchemeUrg]         = { urgfgcolor,         urgbgcolor,         urgbordercolor,         urgfloatcolor },
-	[SchemeScratchSel]  = { scratchselfgcolor,  scratchselbgcolor,  scratchselbordercolor,  scratchselfloatcolor },
-	[SchemeScratchNorm] = { scratchnormfgcolor, scratchnormbgcolor, scratchnormbordercolor, scratchnormfloatcolor },
+    /*                      fg                  bg                  border                  float */
+    [SchemeNorm]        = { normfgcolor,        normbgcolor,        normbordercolor,        normfloatcolor },
+    [SchemeSel]         = { selfgcolor,         selbgcolor,         selbordercolor,         selfloatcolor },
+    [SchemeTitleNorm]   = { titlenormfgcolor,   titlenormbgcolor,   titlenormbordercolor,   titlenormfloatcolor },
+    [SchemeTitleSel]    = { titleselfgcolor,    titleselbgcolor,    titleselbordercolor,    titleselfloatcolor },
+    [SchemeTagsNorm]    = { tagsnormfgcolor,    tagsnormbgcolor,    tagsnormbordercolor,    tagsnormfloatcolor },
+    [SchemeTagsSel]     = { tagsselfgcolor,     tagsselbgcolor,     tagsselbordercolor,     tagsselfloatcolor },
+    [SchemeHidNorm]     = { hidnormfgcolor,     hidnormbgcolor,     NOCOLOR,                NOCOLOR },
+    [SchemeHidSel]      = { hidselfgcolor,      hidselbgcolor,      NOCOLOR,                NOCOLOR },
+    [SchemeUrg]         = { urgfgcolor,         urgbgcolor,         urgbordercolor,         urgfloatcolor },
+    [SchemeScratchSel]  = { scratchselfgcolor,  scratchselbgcolor,  scratchselbordercolor,  scratchselfloatcolor },
+    [SchemeScratchNorm] = { scratchnormfgcolor, scratchnormbgcolor, scratchnormbordercolor, scratchnormfloatcolor },
 };
 
-static char *tagicons[][NUMTAGS] =
-{
-	[DEFAULT_TAGS]        = { "1", "2", "3", "4", "5", "6", "7", "8", "9" },
-};
+static const char *layoutmenu_cmd = "xmenulayout";
+// static const char *layoutxmenu = "$HOME/.local/libexec/dwm/xmenulayout"; // TODO: Patch layoutmenu to accept arguments
+// static const char *layoutdmenu = "$HOME/.local/libexec/dwm/dmenulayout"; // TODO: Patch layoutmenu to accept shell commands
 
-static const int autostart_kill_signal = SIGHUP;
 static const char *const autostart[] = {
-    "/bin/sh", "-c", "exec run-parts \"${XDG_CONFIG_HOME}/dwm/autorun.d\"", NULL,
-    "/bin/sh", "-c", "exec runsvdir \"${SVDIR}\"", NULL,
+    "sh", "-c", "run-parts $HOME/.local/libexec/dwm/autorun.d", NULL,
+    "pipewire", NULL,
+    "wireplumber", NULL,
+    "pipewire", "-c", "pipewire-pulse.conf", NULL,
+    "dunst", NULL,
+    "picom", NULL,
+    "unclutter", "-noevents", "-idle", "3", NULL,
+    "syncthingtray", NULL,
+    "sh", "-c", "$HOME/.local/libexec/daemons/remapd", NULL,
+    "sh", "-c", "env PATH=\"$HOME/.local/libexec/statusbar:$PATH\" dwmblocks", NULL,
+    "sh", "-c", "$HOME/.local/libexec/dwm/locker", NULL,
     NULL
 };
 
-static const char *spterm[] = { "t", TERM, TERM_FLAG_CLASS, "spterm", NULL };
-static const char *spfile[] = { "f", TERM, TERM_FLAG_CLASS, "spfile", TERM_FLAG_EXEC, "lfX", NULL };
-static const char *spchat[] = { "a", TERM, TERM_FLAG_CLASS, "spchat", TERM_FLAG_EXEC, "aichat", "-s", NULL };
-static const char *spproc[] = { "p", TERM, TERM_FLAG_CLASS, "spproc", TERM_FLAG_EXEC, "btm", NULL };
-static const char *spdisk[] = { "d", TERM, TERM_FLAG_CLASS, "spdisk", TERM_FLAG_EXEC, "dua", "i", "/", NULL };
-static const char *spvolm[] = { "v", TERM, TERM_FLAG_CLASS, "spvolm", TERM_FLAG_EXEC, "ncpamixer", NULL };
-static const char *sphelp[] = { "h", TERM, TERM_FLAG_CLASS, "sphelp", TERM_FLAG_EXEC, "glow", "-p", "-s", "tokyo-night", "/usr/share/doc/dwm/README.md", NULL };
-static const char *spnetm[] = { "m", TERM, TERM_FLAG_CLASS, "spnetm", TERM_FLAG_EXEC, "/bin/sh", "-c", "sleep 0.01; nmtui", NULL }; // This sleep is needed to wait for DWM to size the window
-static const char *spblue[] = { "b", TERM, TERM_FLAG_CLASS, "spnetm", TERM_FLAG_EXEC, "bluetuith", NULL };
-static const char *spnetu[] = { "u", TERM, TERM_FLAG_CLASS, "spnetu", TERM_FLAG_EXEC, "bandwhich", NULL };
-static const char *spwiki1[] = { "w", TERM, TERM_FLAG_CLASS, "spwiki", TERM_FLAG_EXEC, "/bin/sh", "-c", "sleep 0.01; zk edit -t index -i", NULL };
-static const char *spwiki2[] = { "w", TERM, TERM_FLAG_CLASS, "spwiki", TERM_FLAG_EXEC, "/bin/sh", "-c", "sleep 0.01; zk edit -i", NULL };
-static const char *sptask[] = { "s", TERM, TERM_FLAG_CLASS, "sptask", TERM_FLAG_EXEC, "taskwarrior-tui", NULL };
-static const char *spcalc[] = { "c", TERM, TERM_FLAG_CLASS, "spcalc", TERM_FLAG_EXEC, "/bin/sh", "-c", "HOME=$XDG_DATA_HOME wcalc -C", NULL };
+static const char *spterm[] = { "t", TERM, "-n", "spterm", TERM_FLAG_EXEC, "tmux", NULL };
+static const char *spfile[] = { "f", TERM, "-n", "spfile", TERM_FLAG_EXEC, "lf-sixel", NULL };
+static const char *spproc[] = { "p", TERM, "-n", "spproc", TERM_FLAG_EXEC, "htop", NULL };
+static const char *spvolm[] = { "v", TERM, "-n", "spvolm", TERM_FLAG_EXEC, "pulsemixer", NULL };
+static const char *sphelp[] = { "h", TERM, "-n", "sphelp", TERM_FLAG_EXEC, "/bin/sh", "-c", "glow -p -s $XDG_CONFIG_HOME/glow/style.json /usr/share/dwm/dwm.md", NULL };
+static const char *spinet[] = { "i", TERM, "-n", "spinet", TERM_FLAG_EXEC, "nmtui", NULL };
+static const char *spwiki[] = { "w", TERM, "-n", "spwiki", TERM_FLAG_EXEC, "zk", "edit", "-i", NULL };
+static const char *spcalc[] = { "c", TERM, "-n", "spcalc", TERM_FLAG_EXEC, "bc", "-li", NULL };
+
+static char *tagicons[][NUMTAGS] =
+{
+    [DEFAULT_TAGS]        = { "1", "2", "3", "4", "5", "6", "7", "8", "9" },
+};
 
 static const Rule rules[] = {
     /* xprop(1):
@@ -145,93 +176,110 @@ static const Rule rules[] = {
     RULE(.wintype = WTYPE "UTILITY", .isfloating = 1)
     RULE(.wintype = WTYPE "TOOLBAR", .isfloating = 1)
     RULE(.wintype = WTYPE "SPLASH", .isfloating = 1)
-    RULE(.role = "pop-up", .isfloating = 1)
-    RULE(.class = "Dragon-drop", .isfloating = 1, .iscentered = 1)
-    RULE(.class = "St", .isfloating = 0)
-    RULE(.class = "mpv", .isfloating = 0)
-    RULE(.class = "Element", .monitor = 1, .tags = 1 << 0)
-    RULE(.class = "Thunderbird", .monitor = 1, .tags = 1 << 1)
-    RULE(.class = "sphelp", .scratchkey = 'h', .isfloating = 1, .iscentered = 1, .floatpos = "50% 50% 50% 90%")
-    RULE(.class = "spwiki", .scratchkey = 'w', .isfloating = 1, .iscentered = 1, .floatpos = "50% 50% 50% 90%")
-    RULE(.class = "sptask", .scratchkey = 's', .isfloating = 1, .iscentered = 1, .floatpos = "50% 50% 50% 90%")
-    RULE(.class = "spterm", .scratchkey = 't', .isfloating = 1, .iscentered = 1, .floatpos = "50% 50% 90% 90%")
-    RULE(.class = "spfile", .scratchkey = 'f', .isfloating = 1, .iscentered = 1, .floatpos = "50% 50% 90% 90%")
-    RULE(.class = "spchat", .scratchkey = 'a', .isfloating = 1, .iscentered = 1, .floatpos = "50% 50% 90% 90%")
-    RULE(.class = "spdisk", .scratchkey = 'd', .isfloating = 1, .iscentered = 1, .floatpos = "50% 50% 90% 90%")
-    RULE(.class = "spproc", .scratchkey = 'p', .isfloating = 1, .iscentered = 1, .floatpos = "50% 50% 90% 90%")
-    RULE(.class = "spnetu", .scratchkey = 'u', .isfloating = 1, .iscentered = 1, .floatpos = "50% 50% 90% 90%")
-    RULE(.class = "spcalc", .scratchkey = 'c', .isfloating = 1, .floatpos = "100% 100% 600W 900H")
-    RULE(.class = "spvolm", .scratchkey = 'v', .isfloating = 1, .floatpos = "100% 100% 900W 500H")
-    RULE(.class = "spnetm", .scratchkey = 'm', .isfloating = 1, .floatpos = "100% 100% 900W 900H")
-    RULE(.class = "spblue", .scratchkey = 'b', .isfloating = 1, .floatpos = "100% 100% 900W 900H")
+    RULE(.title = "Event Tester", .noswallow = 1)
+    RULE(.class = "St", .isterminal = 1)
+    RULE(.instance = "sphelp", .scratchkey = 'h', .isfloating = 1, .floatpos = "50% 50% 40% 80%")
+    RULE(.instance = "spcalc", .scratchkey = 'c', .isfloating = 1, .floatpos = "50% 50% 40% 80%")
+    RULE(.instance = "spterm", .scratchkey = 't', .isfloating = 1, .floatpos = "50% 50% 80% 80%")
+    RULE(.instance = "spfile", .scratchkey = 'f', .isfloating = 1, .floatpos = "50% 50% 80% 80%")
+    RULE(.instance = "spproc", .scratchkey = 'p', .isfloating = 1, .floatpos = "50% 50% 80% 80%")
+    RULE(.instance = "spwiki", .scratchkey = 'w', .isfloating = 1, .floatpos = "50% 50% 80% 80%")
+    RULE(.instance = "spvolm", .scratchkey = 'v', .isfloating = 1, .floatpos = "100% 100% 900W 600H")
+    RULE(.instance = "spinet", .scratchkey = 'i', .isfloating = 1, .floatpos = "100% 100% 800W 800H")
 };
 
+/* Bar rules allow you to configure what is shown where on the bar, as well as
+ * introducing your own bar modules.
+ *
+ *    monitor:
+ *      -1  show on all monitors
+ *       0  show on monitor 0
+ *      'A' show on active monitor (i.e. focused / selected) (or just -1 for active?)
+ *    bar - bar index, 0 is default, 1 is extrabar
+ *    alignment - how the module is aligned compared to other modules
+ *    widthfunc, drawfunc, clickfunc - providing bar module width, draw and click functions
+ *    name - does nothing, intended for visual clue and for logging / debugging
+ */
 static const BarRule barrules[] = {
-	/* monitor bar alignment        widthfunc       drawfunc       clickfunc       hoverfunc   name */
-	{ -1,      0,  BAR_ALIGN_LEFT,  width_tags,     draw_tags,     click_tags,     hover_tags, "tags" },
-	{ -1,      0,  BAR_ALIGN_LEFT,  width_ltsymbol, draw_ltsymbol, click_ltsymbol, NULL,       "layout" },
-	{  'A',    0,  BAR_ALIGN_RIGHT, width_status,   draw_status,   click_status,   NULL,       "status" },
-	{ -1,      0,  BAR_ALIGN_NONE,  width_wintitle, draw_wintitle, click_wintitle, NULL,       "wintitle" },
+    /* monitor bar alignment        widthfunc       drawfunc       clickfunc       hoverfunc   name */
+    { -1,      0,  BAR_ALIGN_LEFT,  width_tags,     draw_tags,     click_tags,     hover_tags, "tags" },
+    { 'A',     0,  BAR_ALIGN_RIGHT, width_systray,  draw_systray,  click_systray,  NULL,       "systray" },
+    { -1,      0,  BAR_ALIGN_LEFT,  width_ltsymbol, draw_ltsymbol, click_ltsymbol, NULL,       "layout" },
+    { 'A',     0,  BAR_ALIGN_RIGHT, width_status,   draw_status,   click_status,   NULL,       "status" },
+    { -1,      0,  BAR_ALIGN_NONE,  width_wintitle, draw_wintitle, click_wintitle, NULL,       "wintitle" },
 };
 
 /* layout(s) */
 static const float mfact        = 0.50; /* factor of master area size [0.05..0.95] */
 static const int nmaster        = 1;    /* number of clients in master area */
+static const int nstack         = 0;    /* number of clients in primary stack area */
 static const int resizehints    = 0;    /* 1 means respect size hints in tiled resizals */
 static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
+static const int decorhints     = 1;    /* 1 means respect decoration hints */
+
+
 
 static const Layout layouts[] = {
-	/* symbol arrange function */
-	{ "[]=",  tile },    /* first entry is default */
-	{ "TTT",  bstack },
-	{ ":::",  gaplessgrid },
-	{ "><>",  NULL },    /* no layout function means floating behavior */
+    /* symbol     arrange function, { nmaster, nstack, layout, master axis, stack axis, secondary stack axis, symbol func } */
+    { "[]=",      flextile,         { -1, -1, SPLIT_VERTICAL, TOP_TO_BOTTOM, TOP_TO_BOTTOM, 0, NULL } }, // default tile layout
+    { "><>",      NULL,             {0} },    /* no layout function means floating behavior */
+    { "[M]",      flextile,         { -1, -1, NO_SPLIT, MONOCLE, MONOCLE, 0, NULL } }, // monocle
+    { "|||",      flextile,         { -1, -1, SPLIT_VERTICAL, LEFT_TO_RIGHT, TOP_TO_BOTTOM, 0, NULL } }, // columns (col) layout
+    { ">M>",      flextile,         { -1, -1, FLOATING_MASTER, LEFT_TO_RIGHT, LEFT_TO_RIGHT, 0, NULL } }, // floating master
+    { "[D]",      flextile,         { -1, -1, SPLIT_VERTICAL, TOP_TO_BOTTOM, MONOCLE, 0, NULL } }, // deck
+    { "TTT",      flextile,         { -1, -1, SPLIT_HORIZONTAL, LEFT_TO_RIGHT, LEFT_TO_RIGHT, 0, NULL } }, // bstack
+    { "===",      flextile,         { -1, -1, SPLIT_HORIZONTAL, LEFT_TO_RIGHT, TOP_TO_BOTTOM, 0, NULL } }, // bstackhoriz
+    { "|M|",      flextile,         { -1, -1, SPLIT_CENTERED_VERTICAL, LEFT_TO_RIGHT, TOP_TO_BOTTOM, TOP_TO_BOTTOM, NULL } }, // centeredmaster
+    { "-M-",      flextile,         { -1, -1, SPLIT_CENTERED_HORIZONTAL, TOP_TO_BOTTOM, LEFT_TO_RIGHT, LEFT_TO_RIGHT, NULL } }, // centeredmaster horiz
+    { ":::",      flextile,         { -1, -1, NO_SPLIT, GAPPLESSGRID, GAPPLESSGRID, 0, NULL } }, // gappless grid
+    { "[\\]",     flextile,         { -1, -1, NO_SPLIT, DWINDLE, DWINDLE, 0, NULL } }, // fibonacci dwindle
+    { "(@)",      flextile,         { -1, -1, NO_SPLIT, SPIRAL, SPIRAL, 0, NULL } }, // fibonacci spiral
+    { "[T]",      flextile,         { -1, -1, SPLIT_VERTICAL, LEFT_TO_RIGHT, TATAMI, 0, NULL } }, // tatami mats
+    { "[M]",      monocle,          {0} },
 };
 
 
 /* key definitions */
 #define MODKEY Mod4Mask
 #define TAGKEYS(KEY,TAG) \
-	{ MODKEY,                       KEY, view,       {.ui = 1 << TAG} }, \
-	{ MODKEY|ControlMask,           KEY, toggleview, {.ui = 1 << TAG} }, \
-	{ MODKEY|ShiftMask,             KEY, tag,        {.ui = 1 << TAG} }, \
-	{ MODKEY|ControlMask|ShiftMask, KEY, toggletag,  {.ui = 1 << TAG} }
+    { MODKEY,                       KEY,      view,      {.ui = 1 << TAG} }, \
+    { MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
+    { MODKEY|ShiftMask,             KEY,      tag,       {.ui = 1 << TAG} }, \
+    { MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} }
 
-/* helper for spawning shell commands in the pre dwm-5.0 fashion */
 #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
 
 /* commands */
-static const char *termcmd[]  = { TERM, NULL };
+static const char *termcmd[]  = { TERM, TERM_FLAG_EXEC, TERM_START, NULL };
 
 #include <X11/XF86keysym.h>
 static const Key keys[] = {
-    /* START KEYBINDS */
-    { MODKEY,             XK_F1,               togglescratch,      {.v = sphelp} }, // Toggle help
+    /* modifier            key                 function            argument */
+    { MODKEY,              XK_F1,              togglescratch,      {.v = sphelp} },
     // { MODKEY | ShiftMask,  XK_F1,              spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_F2,              spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenuhandler") },
+    { MODKEY,              XK_F2,              spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenuhandler") },
     // { MODKEY | ShiftMask,  XK_F2,              spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_F3,              spawn,              SHCMD("$HOME/.local/libexec/dwm/togtouchpad") }, // Toggle touchpad
+    { MODKEY,              XK_F3,              spawn,              SHCMD("$HOME/.local/libexec/dwm/togtouchpad") },
     // { MODKEY | ShiftMask,  XK_F3,              spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_F4,              spawn,              SHCMD("$HOME/.local/libexec/dwm/togcompositor") }, // Toggle compositor
+    { MODKEY,              XK_F4,              spawn,              SHCMD("$HOME/.local/libexec/dwm/togcompositor") },
     // { MODKEY | ShiftMask,  XK_F4,              spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_F5,              spawn,              {.v = (const char *[]){"clipmenu", NULL}} }, // Open copy/paste history
-    // { MODKEY | ShiftMask,  XK_F5,              spawn,              {.v = (const char *[]){NULL}} },
+    { MODKEY,              XK_F5,              xrdb,                  {.v = NULL } },
     // { MODKEY,              XK_F6,              spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_F6,              spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY,              XK_F7,              spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_F7,              spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY,              XK_F8,              spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_F8,              spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_F9,              spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenumount") },
+    { MODKEY,              XK_F9,              spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenumount") },
     // { MODKEY | ShiftMask,  XK_F9,              spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_F10,             spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenuumount") },
+    { MODKEY,              XK_F10,             spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenuumount") },
     // { MODKEY | ShiftMask,  XK_F10,             spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_F11,             spawn,              SHCMD("$HOME/.local/libexec/dwm/displayselect") },
+    { MODKEY,              XK_F11,             spawn,              SHCMD("$HOME/.local/libexec/dwm/displayselect") },
     // { MODKEY | ShiftMask,  XK_F11,             spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_F12,             spawn,              {.v = (const char *[]){"remaps", NULL}} }, // Rotate keyboard layout
+    { MODKEY,              XK_F12,             spawn,              SHCMD("$HOME/.local/libexec/dwm/remaps") },
     // { MODKEY | ShiftMask,  XK_F12,             spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_grave,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenuunicode --nocopy") }, // Insert an emoji
-    { MODKEY | ShiftMask,  XK_grave,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenuunicode") }, // Copy an emoji
+    { MODKEY,              XK_grave,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenuunicode --nocopy") },
+    { MODKEY | ShiftMask,  XK_grave,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenuunicode") },
     TAGKEYS(               XK_1,                                   0),
     TAGKEYS(               XK_2,                                   1),
     TAGKEYS(               XK_3,                                   2),
@@ -241,165 +289,165 @@ static const Key keys[] = {
     TAGKEYS(               XK_7,                                   6),
     TAGKEYS(               XK_8,                                   7),
     TAGKEYS(               XK_9,                                   8),
-    { MODKEY,              XK_0,               view,               {.ui = ~0} }, // View all tags
-    { MODKEY | ShiftMask,  XK_0,               tag,                {.ui = ~0} }, // Make focused window sticky
-    // { MODKEY | ShiftMask,  XK_0,               spawn,              {.v = (const char *[]){NULL}} },
+    { MODKEY,              XK_0,               view,          {.ui = ~0} },
+    { MODKEY | ShiftMask,  XK_0,               tag,           {.ui = ~0} },
+    { MODKEY | Mod1Mask,   XK_0,               winview,       {0} },
     // { MODKEY,              XK_bracketleft,     spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_bracketleft,     spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY,              XK_bracketright,    spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_bracketright,    spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_BackSpace,       spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenusys") }, // Open shutdown menu
+    { MODKEY,              XK_BackSpace,       spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenusys") },
     // { MODKEY | ShiftMask,  XK_BackSpace,       spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_Tab,             spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_Tab,             spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY,              XK_Tab,             spawn,              {.v = (const char *[]){NULL}} }, 
+    // { MODKEY | ShiftMask,  XK_Tab,             spawn,              {.v = (const char *[]){NULL}} }, 
     // { MODKEY,              XK_apostrophe,      spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_apostrophe,      spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_comma,           focusmon,           {.i = +1} }, // Focus next monitor
-    { MODKEY | ShiftMask,  XK_comma,           tagmon,             {.i = +1} }, // Move focused window to next monitor
-    { MODKEY,              XK_period,          focusmon,           {.i = -1} }, // Focus last monitor
-    { MODKEY | ShiftMask,  XK_period,          tagmon,             {.i = -1} }, // Move focused window to last monitor
-    { MODKEY,              XK_p,               spawn,              {.v = (const char *[]){"playerctl", "play-pause", NULL}} }, // Pause current player
+    { MODKEY,              XK_comma,           focusmon,           {.i = +1} },
+    { MODKEY | ShiftMask,  XK_comma,           tagmon,             {.i = +1} },
+    { MODKEY,              XK_period,          focusmon,           {.i = -1} },
+    { MODKEY | ShiftMask,  XK_period,          tagmon,             {.i = -1} },
+    { MODKEY,              XK_p,               spawn,              {.v = (const char *[]){"playerctl", "play-pause", NULL}} },
     // { MODKEY | ShiftMask,  XK_p,               spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY,              XK_y,               spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_y,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_f,               togglefullscreen,   {0} }, // Toggle fullscreen for focused window
+    { MODKEY,              XK_f,               togglefullscreen,      {0} },
     // { MODKEY | ShiftMask,  XK_f,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_g,               setlayout,          {.v = &layouts[0]} }, // Select default tile layout
-    // { MODKEY | ShiftMask,  XK_g,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_c,               setlayout,          {.v = &layouts[1]} }, // Select bottom stack layout
-    // { MODKEY | ShiftMask,  XK_c,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_r,               setlayout,          {.v = &layouts[2]} }, // Select grid layout
-    // { MODKEY | ShiftMask,  XK_r,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_l,               pushstack,          {.i = INC(+1)} }, // Move focused window down stack
-    { MODKEY | ShiftMask,  XK_l,               setmfact,           {.f = +0.05} }, // Increase size of master stack
+    { MODKEY,              XK_g,               cyclelayout,        {.i = -1} },
+    { MODKEY | ShiftMask,  XK_g,               rotatelayoutaxis,   {.i = -1} },
+    { MODKEY,              XK_c,               setlayout,          {.v = &layouts[0]} },
+    // { MODKEY | ShiftMask,  XK_c,               spawn,              {.v = (const char *[]){NULL}} }, /* TODO: reset axis */
+    { MODKEY,              XK_r,               cyclelayout,        {.i = +1} },
+    { MODKEY | ShiftMask,  XK_r,               rotatelayoutaxis,   {.i = +1} },
+    { MODKEY,              XK_l,               setmfact,           {.f = +0.05} },
+    { MODKEY | ShiftMask,  XK_l,               setcfact,           {.f = +0.1} },
     // { MODKEY,              XK_slash,           spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_slash,           spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY,              XK_equal,           spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_equal,           spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_a,               togglescratch,      {.v = spchat} }, // Toggle AI chat
+    // { MODKEY,              XK_a,               spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_a,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_o,               togglescratch,      {.v = spproc} }, // Toggle process manager
-    { MODKEY | ShiftMask,  XK_o,               togglescratch,      {.v = spnetu} }, // Toggle network usage analyzer
-    { MODKEY,              XK_e,               togglescratch,      {.v = spfile} }, // Toggle file manager
-    { MODKEY | ShiftMask,  XK_e,               togglescratch,      {.v = spdisk} }, // Toggle disk usage analyzer
-    { MODKEY,              XK_u,               spawn,              {.v = (const char *[]){"dmenu_run", NULL}} }, // Run a program
+    { MODKEY,              XK_o,               togglescratch,      {.v = spproc} },
+    // { MODKEY | ShiftMask,  XK_o,               spawn,              {.v = (const char *[]){NULL}} },
+    { MODKEY,              XK_e,               togglescratch,      {.v = spfile} },
+    // { MODKEY | ShiftMask,  XK_e,               spawn,              {.v = (const char *[]){NULL}} }, 
+    { MODKEY,              XK_u,               spawn,              {.v = (const char *[]){"dmenu_run", NULL}} },
     // { MODKEY | ShiftMask,  XK_u,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_i,               spawn,              {.v = (const char *[]){"dunstctl", "close", NULL}} }, // Close last notification
-    { MODKEY | ShiftMask,  XK_i,               spawn,              {.v = (const char *[]){"dunstctl", "history-pop", NULL}} }, // Reopen last notification
-    { MODKEY,              XK_d,               spawn,              {.v = (const char *[]){"dunstctl", "context", NULL}} }, // Select notification option
-    { MODKEY | ShiftMask,  XK_d,               spawn,              {.v = (const char *[]){"dunstctl", "action", "0", NULL}} }, // Autoselect first notification option
-    { MODKEY,              XK_h,               pushstack,          {.i = INC(-1)} }, // Move focused window up stack
-    { MODKEY | ShiftMask,  XK_h,               setmfact,           {.f = -0.05} }, // Decrease size of master stack
-    { MODKEY,              XK_t,               spawn,              {.v = (const char *[]){BROWSER, BROWSER_FLAG_1, NULL}} }, // Start a browser window
-    { MODKEY | ShiftMask,  XK_t,               spawn,              {.v = (const char *[]){BROWSER, BROWSER_FLAG_1, BROWSER_FLAG_INCOG, NULL}} }, // Start an incognito browser window
-    { MODKEY,              XK_n,               focusstack,         {.i = PREVSEL} }, // Focus last focused window
-    { MODKEY | ShiftMask,  XK_n,               focusstack,         {.i = 0} }, // Focus master stack
-    // { MODKEY,              XK_s,               spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_s,               spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_s,               spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_minus,           spawn,              {.v = (const char *[]){NULL}} },
+    { MODKEY,              XK_i,               spawn,              {.v = (const char *[]){"dunstctl", "close", NULL}} },
+    { MODKEY | ShiftMask,  XK_i,               spawn,              {.v = (const char *[]){"dunstctl", "history-pop", NULL}} },
+    { MODKEY,              XK_d,               spawn,              {.v = (const char *[]){"dunstctl", "context", NULL}} },
+    { MODKEY | ShiftMask,  XK_d,               spawn,              {.v = (const char *[]){"dunstctl", "action", "0", NULL}} },
+    { MODKEY,              XK_h,               setmfact,           {.f = -0.05} },
+    { MODKEY | ShiftMask,  XK_h,               setcfact,           {.f = -0.1} },
+    { MODKEY,              XK_t,               spawn,              {.v = (const char *[]){BROWSER, BROWSER_FLAG_1, NULL}} },
+    { MODKEY | ShiftMask,  XK_t,               spawn,              {.v = (const char *[]){BROWSER, BROWSER_FLAG_1, BROWSER_FLAG_INCOG, NULL}} },
+    { MODKEY,              XK_n,               focusstack,         {.i = PREVSEL} },
+    { MODKEY | ShiftMask,  XK_n,               pushstack,          {.i = PREVSEL} },
+    { MODKEY,              XK_s,               incnmaster,         {.i = +1 } },
+    { MODKEY | ShiftMask,  XK_s,               incnmaster,         {.i = -1 } },
+    // { MODKEY,              XK_minus,           spawn,              {.v = (const char *[]){NULL}} }, /* TODO: reset nmaster */
     // { MODKEY | ShiftMask,  XK_minus,           spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY,              XK_backslash,       spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_backslash,       spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_Return,          zoom,               {0} }, // Move focused window to master stack
-    // { MODKEY | ShiftMask,  XK_Return,          spawn,              {.v = (const char *[]){NULL}} },
+    { MODKEY,              XK_Return,           zoom,              {0} },
+    { MODKEY | ShiftMask,  XK_Return,           mirrorlayout,      {0} },
     // { MODKEY,              XK_semicolon,       spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_semicolon,       spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_q,               killclient,         {0} }, // Close focused window
+    { MODKEY,              XK_q,               killclient,         {0} },
     // { MODKEY | ShiftMask,  XK_q,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_j,               focusstack,         {.i = INC(+1) } }, // Focus next window in stack
-    /* { MODKEY | ShiftMask,  XK_j,               focusstack,         {.i = INC(+1) } }, */
-    { MODKEY,              XK_k,               focusstack,         {.i = INC(-1) } }, // Focus last window in stack
-    /* { MODKEY | ShiftMask,  XK_k,               focusstack,         {.i = INC(-1) } }, */
-    { MODKEY,              XK_x,               togglefloating,     {0} }, // Toggle floating for focused window
-    { MODKEY | ShiftMask,  XK_x,               unfloatvisible,     {0} }, // Unfloat visible floating windows
-    { MODKEY,              XK_b,               togglescratch,      {.v = spnetm} }, // Toggle network manager
-    { MODKEY | ShiftMask,  XK_b,               togglescratch,      {.v = spblue} }, // Toggle bluetooth manager
-    { MODKEY,              XK_m,               togglescratch,      {.v = spvolm} }, // Toggle volume manager
-    { MODKEY | ShiftMask,  XK_m,               spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify -t") }, // Mute volume
-    { MODKEY,              XK_w,               togglescratch,      {.v = spwiki1} }, // Toggle wiki
-    { MODKEY | ShiftMask,  XK_w,               togglescratch,      {.v = spwiki2} }, // Toggle full wiki search
-    { MODKEY,              XK_v,               togglescratch,      {.v = spcalc} }, // Toggle calculator
+    { MODKEY,              XK_j,               focusstack,         {.i = INC(+1)} },
+    { MODKEY | ShiftMask,  XK_j,               pushstack,          {.i = INC(+1)} },
+    { MODKEY,              XK_k,               focusstack,         {.i = INC(-1)} },
+    { MODKEY | ShiftMask,  XK_k,               pushstack,          {.i = INC(-1)} },
+    { MODKEY,              XK_x,               togglescratch,      {.v = spcalc }},
+    // { MODKEY | ShiftMask,  XK_x,               spawn,              {.v = (const char *[]){NULL}} },
+    { MODKEY,              XK_b,               togglescratch,      {.v = spinet} },
+    // { MODKEY | ShiftMask,  XK_b,               spawn,              {.v = (const char *[]){NULL}} },
+    { MODKEY,              XK_m,               togglescratch,      {.v = spvolm} },
+    // { MODKEY | ShiftMask,  XK_m,               spawn,              {.v = (const char *[]){NULL}} },
+    { MODKEY,              XK_w,               togglescratch,      {.v = spwiki} },
+    // { MODKEY | ShiftMask,  XK_w,               spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY,              XK_v,               spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_v,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_z,               togglescratch,      {.v = sptask} }, // Toggle task manager
+    // { MODKEY,              XK_z,               spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY | ShiftMask,  XK_z,               spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_space,           spawn,              {.v = termcmd} }, // Open terminal
-    { MODKEY | ShiftMask,  XK_space,           togglescratch,      {.v = spterm} }, // Open scratch terminal
-    { MODKEY,              XK_Print,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenurecord") }, // Open video recording menu
-    { MODKEY | ShiftMask,  XK_Print,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenurecord kill") }, // Kill recording
-    { 0,                   XK_Print,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenumaim full") }, // Screenshot full screen
-    { ShiftMask,           XK_Print,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenumaim") }, // Open screenshot menu
-    // { MODKEY,              XK_Scroll_Lock,     spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_Scroll_Lock,     spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_Pause,           spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_Pause,           spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_Insert,          spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_Insert,          spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_Home,            spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_Home,            spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_Page_Up,         spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_Page_Up,         spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_Delete,          spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY | ShiftMask,  XK_Delete,          quit,               {0} }, // Kill window manager
+    { MODKEY,              XK_space,           spawn,              {.v = termcmd} },
+    { MODKEY | ShiftMask,  XK_space,           togglescratch,      {.v = spterm} },
+    { MODKEY,              XK_Print,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenurecord") },
+    { MODKEY | ShiftMask,  XK_Print,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenurecord kill") },
+    { 0,                   XK_Print,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenumaim full") },
+    { ShiftMask,           XK_Print,           spawn,              SHCMD("$HOME/.local/libexec/dwm/dmenumaim") },
+    // { MODKEY,              XK_scroll_lock,     spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY | ShiftMask,  XK_scroll_lock,     spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY,              XK_pause,           spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY | ShiftMask,  XK_pause,           spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY,              XK_insert,          spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY | ShiftMask,  XK_insert,          spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY,              XK_home,            spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY | ShiftMask,  XK_home,            spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY,              XK_page_up,         spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY | ShiftMask,  XK_page_up,         spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY,              XK_delete,          spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY | ShiftMask,  XK_delete,          spawn,              {.v = (const char *[]){NULL}} },
     // { MODKEY,              XK_End,             spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_End,             spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY,              XK_Page_Down,       spawn,              {.v = (const char *[]){NULL}} },
-    // { MODKEY | ShiftMask,  XK_Page_Down,       spawn,              {.v = (const char *[]){NULL}} },
-    { MODKEY,              XK_Left,            spawn,              {.v = (const char *[]){"playerctl", "position", "5-", NULL}} }, // Spool current player back 5 seconds
-    { MODKEY | ShiftMask,  XK_Left,            spawn,              {.v = (const char *[]){"playerctl", "previous", NULL}} }, // Skip to previous track in current player
-    { MODKEY,              XK_Right,           spawn,              {.v = (const char *[]){"playerctl", "position", "5+", NULL}} }, // Spool current player forward 5 seconds
-    { MODKEY | ShiftMask,  XK_Right,           spawn,              {.v = (const char *[]){"playerctl", "next", NULL}} }, // Skip to next track in current player
-    { MODKEY,              XK_Up,              spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify --allow-boost -i 5") }, // Increase volume
-    { MODKEY | ShiftMask,  XK_Up,              spawn,              {.v = (const char *[]){"playerctl", "volume", "5+", NULL}} }, // Increase volume in player
-    { MODKEY,              XK_Down,            spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify --allow-boost -d 5") }, // Decrease volume
-    { MODKEY | ShiftMask,  XK_Down,            spawn,              {.v = (const char *[]){"playerctl", "volume", "5-", NULL}} }, // Decrease volume in player
+    { MODKEY | ShiftMask,  XK_End,             quit,               {0} },
+    // { MODKEY,              XK_page_down,       spawn,              {.v = (const char *[]){NULL}} },
+    // { MODKEY | ShiftMask,  XK_page_down,       spawn,              {.v = (const char *[]){NULL}} },
+    { MODKEY,              XK_Left,            spawn,              {.v = (const char *[]){"playerctl", "position", "5-", NULL}} },
+    { MODKEY | ShiftMask,  XK_Left,            spawn,              {.v = (const char *[]){"playerctl", "previous", NULL}} },
+    { MODKEY,              XK_Right,           spawn,              {.v = (const char *[]){"playerctl", "position", "5+", NULL}} },
+    { MODKEY | ShiftMask,  XK_Right,           spawn,              {.v = (const char *[]){"playerctl", "next", NULL}} },
+    { MODKEY,              XK_Up,              spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify --allow-boost -i 5") },
+    { MODKEY | ShiftMask,  XK_Up,              spawn,              {.v = (const char *[]){"playerctl", "volume", "5+", NULL}} },
+    { MODKEY,              XK_Down,            spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify --allow-boost -d 5") },
+    { MODKEY | ShiftMask,  XK_Down,            spawn,              {.v = (const char *[]){"playerctl", "volume", "5-", NULL}} },
 
-    { 0,             XF86XK_AudioMute,         spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify -t") }, // Mute volume
-    { 0,             XF86XK_AudioRaiseVolume,  spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify --allow-boost -i 5") }, // Increase volume
-    { 0,             XF86XK_AudioLowerVolume,  spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify --allow-boost -d 5") }, // Decrease volume
-    { 0,             XF86XK_AudioPrev,         spawn,              {.v = (const char *[]){"playerctl", "previous", NULL}} }, // Skip to previous track in current player
-    { 0,             XF86XK_AudioNext,         spawn,              {.v = (const char *[]){"playerctl", "next", NULL}} }, // Skip to next track in current player
-    { 0,             XF86XK_AudioPause,        spawn,              {.v = (const char *[]){"playerctl", "pause", NULL}} }, // Pause current player
-    { 0,             XF86XK_AudioPlay,         spawn,              {.v = (const char *[]){"playerctl", "play-pause", NULL}} }, // Toggle pause/unpause in current player
-    { 0,             XF86XK_AudioStop,         spawn,              {.v = (const char *[]){"playerctl", "stop", NULL}} }, // Stop current player
-    { 0,             XF86XK_AudioRewind,       spawn,              {.v = (const char *[]){"playerctl", "position", "5-", NULL}} }, // Spool current player back 5 seconds
-    { 0,             XF86XK_AudioForward,      spawn,              {.v = (const char *[]){"playerctl", "position", "5+", NULL}} }, // Spool current player forward 5 seconds
+    { 0,             XF86XK_AudioMute,         spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify -t") },
+    { 0,             XF86XK_AudioRaiseVolume,  spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify --allow-boost -i 5") },
+    { 0,             XF86XK_AudioLowerVolume,  spawn,              SHCMD("$HOME/.local/libexec/dwm/pamixer-notify --allow-boost -d 5") },
+    { 0,             XF86XK_AudioPrev,         spawn,              {.v = (const char *[]){"playerctl", "previous", NULL}} },
+    { 0,             XF86XK_AudioNext,         spawn,              {.v = (const char *[]){"playerctl", "next", NULL}} },
+    { 0,             XF86XK_AudioPause,        spawn,              {.v = (const char *[]){"playerctl", "pause", NULL}} },
+    { 0,             XF86XK_AudioPlay,         spawn,              {.v = (const char *[]){"playerctl", "play-pause", NULL}} }, // Most keyboards only have a play button
+    { 0,             XF86XK_AudioStop,         spawn,              {.v = (const char *[]){"playerctl", "stop", NULL}} },
+    { 0,             XF86XK_AudioRewind,       spawn,              {.v = (const char *[]){"playerctl", "position", "5-", NULL}} },
+    { 0,             XF86XK_AudioForward,      spawn,              {.v = (const char *[]){"playerctl", "position", "5+", NULL}} },
     // {             0, XF86XK_AudioMedia,        spawn,              {.v = (const char *[]){NULL}} },
-    { 0,             XF86XK_AudioMicMute,      spawn,              SHCMD("$HOME/.local/libexec/dwm/togmic") }, // Toggle microphone mute
-    { 0,             XF86XK_PowerOff,          spawn,              {.v = (const char *[]){"dmenusys", NULL}} }, // Open shutdown menu
-    { 0,             XF86XK_Calculator,        togglescratch,      {.v = spcalc} }, // Toggle calculator
-    { 0,             XF86XK_Sleep,             spawn,              {.v = (const char *[]){"loginctl", "suspend", "-i", NULL}} }, // Sleep system
-    { 0,             XF86XK_WWW,               spawn,              {.v = (const char *[]){BROWSER, BROWSER_FLAG_1, NULL}} }, // Open browser
+    { 0,             XF86XK_AudioMicMute,      spawn,              {.v = (const char *[]){"pactl", "set-source-mute", "@DEFAULT_SOURCE@", "toggle", NULL}} }, /* TODO: Test this */
+    { 0,             XF86XK_PowerOff,          spawn,              {.v = (const char *[]){"dmenusys", NULL}} },
+    { 0,             XF86XK_Calculator,        spawn,              {.v = (const char *[]){TERM, "-e", "bc", "-li", NULL}} },
+    { 0,             XF86XK_Sleep,             spawn,              {.v = (const char *[]){"loginctl", "suspend", "-i", NULL}} },
+    { 0,             XF86XK_WWW,               spawn,              {.v = (const char *[]){BROWSER, BROWSER_FLAG_1, NULL}} },
     // {             0, XF86XK_WLAN,              spawn,              {.v = (const char *[]){NULL}} },
-    { 0,             XF86XK_DOS,               spawn,              {.v = (const char *[]){TERM, NULL}} }, // Open terminal
-    { 0,             XF86XK_ScreenSaver,       spawn,              {.v = (const char *[]){"xset", "s", "activate", NULL}} }, // Lock session
-    { 0,             XF86XK_TaskPane,          togglescratch,      {.v = spproc} }, // Toggle process manager
+    { 0,             XF86XK_DOS,               spawn,              {.v = (const char *[]){TERM, NULL}} },
+    { 0,             XF86XK_ScreenSaver,       spawn,              {.v = (const char *[]){"xset", "s", "activate", NULL}} },
+    { 0,             XF86XK_TaskPane,          spawn,              {.v = (const char *[]){TERM, "-e", "htop", NULL}} },
     // {             0, XF86XK_Mail,              spawn,              {.v = (const char *[]){NULL}} },
-    { 0,             XF86XK_MyComputer,        togglescratch,      {.v = spfile} }, // Toggle file manager
+    { 0,             XF86XK_MyComputer,        spawn,              {.v = (const char *[]){TERM, "-e", "lfX", "/", NULL}} },
     // {             0, XF86XK_Battery,           spawn,              {.v = (const char *[]){NULL}} },
     // {             0, XF86XK_Launch1,           spawn,              {.v = (const char *[]){NULL}} },
-    { 0,             XF86XK_TouchpadToggle,    spawn,              SHCMD("$HOME/.local/libexec/dwm/togtouchpad") }, // Toggle touchpad
-    { 0,             XF86XK_TouchpadOff,       spawn,              SHCMD("$HOME/.local/libexec/dwm/togtouchpad -n") }, // Disable touchpad
-    { 0,             XF86XK_TouchpadOn,        spawn,              SHCMD("$HOME/.local/libexec/dwm/togtouchpad -y") }, // Enable touchpad
-    { 0,             XF86XK_MonBrightnessUp,   spawn,              SHCMD("$HOME/.local/libexec/dwm/brightness-notify +5") }, // Increase monitor brightness
-    { 0,             XF86XK_MonBrightnessDown, spawn,              SHCMD("$HOME/.local/libexec/dwm/brightness-notify -5") }, // Decrease monitor brightness
-    /* END KEYBINDS */
+    { 0,             XF86XK_TouchpadToggle,    spawn,              SHCMD("$HOME/.local/libexec/dwm/togtouchpad") },
+    { 0,             XF86XK_TouchpadOff,       spawn,              SHCMD("$HOME/.local/libexec/dwm/togtouchpad -n") },
+    { 0,             XF86XK_TouchpadOn,        spawn,              SHCMD("$HOME/.local/libexec/dwm/togtouchpad -y") },
+    { 0,             XF86XK_MonBrightnessUp,   spawn,              SHCMD("$HOME/.local/libexec/dwm/brightness-notify +5") },
+    { 0,             XF86XK_MonBrightnessDown, spawn,              SHCMD("$HOME/.local/libexec/dwm/brightness-notify -5") },
+    /* WARN: If you have multiple backlight controllers this will fail */
 };
 
-
 /* button definitions */
 /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
 static const Button buttons[] = {
-	/* click                event mask           button          function        argument */
-	/*{ ClkLtSymbol,          0,                   Button1,        setlayout,      {0} },*/
-	/*{ ClkLtSymbol,          0,                   Button3,        setlayout,      {.v = &layouts[2]} },*/
-	/*{ ClkWinTitle,          0,                   Button2,        zoom,           {0} },*/
+    /* click                event mask           button          function        argument */
+    { ClkLtSymbol,          0,                   Button1,        layoutmenu,      {0} },
+    // { ClkLtSymbol,          0,                   Button3,        setlayout,      {.v = &layouts[2]} },
+    // { ClkWinTitle,          0,                   Button2,        zoom,           {0} },
 	{ ClkStatusText,        0,                   Button2,        spawn,          {.v = termcmd } },
-	{ ClkClientWin,         MODKEY,              Button1,        movemouse,      {0} },
-	{ ClkClientWin,         MODKEY,              Button2,        togglefloating, {0} },
-	{ ClkClientWin,         MODKEY,              Button3,        resizemouse,    {0} },
-	{ ClkTagBar,            0,                   Button1,        view,           {0} },
-	{ ClkTagBar,            0,                   Button3,        toggleview,     {0} },
-	{ ClkTagBar,            MODKEY,              Button1,        tag,            {0} },
-	{ ClkTagBar,            MODKEY,              Button3,        toggletag,      {0} },
+    { ClkClientWin,         MODKEY,              Button1,        movemouse,      {0} },
+    { ClkClientWin,         MODKEY,              Button2,        togglefloating, {0} },
+    { ClkClientWin,         MODKEY,              Button3,        resizemouse,    {0} },
+    { ClkTagBar,            0,                   Button1,        view,           {0} },
+    { ClkTagBar,            0,                   Button3,        toggleview,     {0} },
+    // { ClkTagBar,            MODKEY,              Button1,        tag,            {0} },
+    // { ClkTagBar,            MODKEY,              Button3,        toggletag,      {0} },
 };
+
+
diff --git a/config.mk b/config.mk
index c2ba037..a3dd682 100644
--- a/config.mk
+++ b/config.mk
@@ -7,8 +7,8 @@ VERSION = 6.4
 PREFIX = /usr/local
 MANPREFIX = ${PREFIX}/share/man
 
-X11INC = /usr/include/X11
-X11LIB = /usr/lib
+X11INC = /usr/X11R6/include
+X11LIB = /usr/X11R6/lib
 
 # FreeBSD (uncomment)
 #X11INC = /usr/local/include
@@ -29,7 +29,7 @@ FREETYPEINC = /usr/include/freetype2
 #KVMLIB = -lkvm
 
 # Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH)
-# XRENDER = -lXrender
+XRENDER = -lXrender
 
 # Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH
 #MPDCLIENT = -lmpdclient
@@ -46,7 +46,7 @@ PANGOLIB = `pkg-config --libs xft pango pangoxft`
 #XEXTLIB = -lXext
 
 # Uncomment this for the swallow patch / SWALLOW_PATCH
-# XCBLIBS = -lX11-xcb -lxcb -lxcb-res
+XCBLIBS = -lX11-xcb -lxcb -lxcb-res
 
 # This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH
 #IMLIB2LIBS = -lImlib2
diff --git a/docs.awk b/docs.awk
deleted file mode 100755
index 03c61d4..0000000
--- a/docs.awk
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/awk -f
-
-BEGINFILE {
-    printf "# DWM Keybinds\n"
-    printf "|Keybind|Function|\n"
-    printf "|-|-|\n"
-}
-
-/^#define MODKEY/ {
-    modkey = $3
-}
-
-/START KEYBINDS/ {
-    in_keybinds = 1
-    next
-}
-
-/END KEYBINDS/ {
-    in_keybinds = 0
-    next
-}
-
-in_keybinds {
-    if (/^[[:space:]]*$/ || /^[[:space:]]*\/(\/|\*)/ || /^[[:space:]]*TAGKEYS\(/) {
-        next
-    }
-
-    if (match($0, /\{[[:space:]]*([^,]+)/, modifier_matches)) {
-        modifier = modifier_matches[1]
-    } else {
-        modifier = "0"
-    }
-
-    gsub(/MODKEY/, modkey, modifier)
-    gsub(/\|/, "+", modifier)
-    gsub(/Mod1Mask/, "Alt", modifier)
-    gsub(/Mod4Mask/, "Super", modifier)
-    gsub(/ControlMask/, "Control", modifier)
-    gsub(/ShiftMask/, "Shift", modifier)
-
-    match($0, /[[:space:]]*XK_([^,]+)/, key_matches)
-    key = key_matches[1]
-    key = toupper(substr(key,1,1)) substr(key,2)
-
-    match($0, /,[[:space:]]*\/\/[[:space:]]*(.+)$/, comment_matches)
-    comment = comment_matches[1]
-    comment = toupper(substr(comment,1,1)) substr(comment,2)
-
-    printf "|"
-    if (modifier != "0") {
-        printf "%s + ", modifier
-    }
-    printf "%s|%s|\n", key, comment
-}
diff --git a/drw.c b/drw.c
deleted file mode 100644
index 4f67cb3..0000000
--- a/drw.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-Drw *
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
-{
-	Drw *drw = ecalloc(1, sizeof(Drw));
-
-	drw->dpy = dpy;
-	drw->screen = screen;
-	drw->root = root;
-	drw->w = w;
-	drw->h = h;
-
-	drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
-	drw->gc = XCreateGC(dpy, root, 0, NULL);
-	XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
-
-	return drw;
-}
-
-void
-drw_resize(Drw *drw, unsigned int w, unsigned int h)
-{
-	if (!drw)
-		return;
-
-	drw->w = w;
-	drw->h = h;
-	if (drw->drawable)
-		XFreePixmap(drw->dpy, drw->drawable);
-	drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
-}
-
-void
-drw_free(Drw *drw)
-{
-	XFreePixmap(drw->dpy, drw->drawable);
-	XFreeGC(drw->dpy, drw->gc);
-	drw_fontset_free(drw->fonts);
-	free(drw);
-}
-
-/* This function is an implementation detail. Library users should use
- * drw_font_create instead.
- */
-static Fnt *
-xfont_create(Drw *drw, const char *fontname)
-{
-	Fnt *font;
-	PangoFontMap *fontmap;
-	PangoContext *context;
-	PangoFontDescription *desc;
-	PangoFontMetrics *metrics;
-
-	if (!fontname) {
-		die("no font specified.");
-	}
-
-	font = ecalloc(1, sizeof(Fnt));
-	font->dpy = drw->dpy;
-
-	fontmap = pango_xft_get_font_map(drw->dpy, drw->screen);
-	context = pango_font_map_create_context(fontmap);
-	desc = pango_font_description_from_string(fontname);
-	font->layout = pango_layout_new(context);
-	pango_layout_set_font_description(font->layout, desc);
-
-	metrics = pango_context_get_metrics(context, desc, pango_language_from_string ("en-us"));
-	font->h = pango_font_metrics_get_height(metrics) / PANGO_SCALE;
-
-	pango_font_metrics_unref(metrics);
-	g_object_unref(context);
-
-	return font;
-}
-
-static void
-xfont_free(Fnt *font)
-{
-	if (!font)
-		return;
-	if (font->layout)
-		g_object_unref(font->layout);
-	free(font);
-}
-
-Fnt*
-drw_font_create(Drw* drw, const char font[])
-{
-	Fnt *fnt = NULL;
-
-	if (!drw || !font)
-		return NULL;
-
-	fnt = xfont_create(drw, font);
-
-	return (drw->fonts = fnt);
-}
-
-void
-drw_fontset_free(Fnt *font)
-{
-	if (font) {
-		xfont_free(font);
-	}
-}
-
-void
-drw_clr_create(
-	Drw *drw,
-	Clr *dest,
-	const char *clrname
-) {
-	if (!drw || !dest || !clrname)
-		return;
-
-	if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
-	                       DefaultColormap(drw->dpy, drw->screen),
-	                       clrname, dest))
-		die("error, cannot allocate color '%s'", clrname);
-
-	dest->pixel |= 0xff << 24;
-}
-
-/* Wrapper to create color schemes. The caller has to call free(3) on the
- * returned color scheme when done using it. */
-Clr *
-drw_scm_create(
-	Drw *drw,
-	char *clrnames[],
-	size_t clrcount
-) {
-	size_t i;
-	Clr *ret;
-
-	/* need at least two colors for a scheme */
-	if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
-		return NULL;
-
-	for (i = 0; i < clrcount; i++)
-		drw_clr_create(drw, &ret[i], clrnames[i]);
-	return ret;
-}
-
-void
-drw_setscheme(Drw *drw, Clr *scm)
-{
-	if (drw)
-		drw->scheme = scm;
-}
-
-void
-drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
-{
-	if (!drw || !drw->scheme)
-		return;
-	XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
-	if (filled)
-		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
-	else
-		XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
-}
-
-int
-drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup)
-{
-	char buf[1024];
-	int i, ty, th;
-	unsigned int ew, eh;
-	XftDraw *d = NULL;
-	size_t len;
-	int render = x || y || w || h;
-
-	if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
-		return 0;
-
-	if (!render) {
-		w = ~w;
-	} else {
-		XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
-		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
-		if (w < lpad)
-			return x + w;
-		d = XftDrawCreate(drw->dpy, drw->drawable,
-		                  DefaultVisual(drw->dpy, drw->screen),
-		                  DefaultColormap(drw->dpy, drw->screen));
-		x += lpad;
-		w -= lpad;
-	}
-
-	len = strlen(text);
-
-	if (len) {
-		drw_font_getexts(drw->fonts, text, len, &ew, &eh, markup);
-		th = eh;
-		/* shorten text if necessary */
-		for (len = MIN(len, sizeof(buf) - 1); len && ew > w; len--) {
-			drw_font_getexts(drw->fonts, text, len, &ew, &eh, markup);
-			if (eh > th)
-				th = eh;
-		}
-
-		if (len) {
-			memcpy(buf, text, len);
-			buf[len] = '\0';
-			if (len < strlen(text))
-				for (i = len; i && i > len - 3; buf[--i] = '.')
-					; /* NOP */
-
-			if (render) {
-				ty = y + (h - th) / 2;
-				if (markup)
-					pango_layout_set_markup(drw->fonts->layout, buf, len);
-				else
-					pango_layout_set_text(drw->fonts->layout, buf, len);
-				pango_xft_render_layout(d, &drw->scheme[invert ? ColBg : ColFg],
-					drw->fonts->layout, x * PANGO_SCALE, ty * PANGO_SCALE);
-				if (markup) /* clear markup attributes */
-					pango_layout_set_attributes(drw->fonts->layout, NULL);
-			}
-			x += ew;
-			w -= ew;
-		}
-	}
-	if (d)
-		XftDrawDestroy(d);
-
-	return x + (render ? w : 0);
-}
-
-void
-drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
-{
-	if (!drw)
-		return;
-
-	XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
-	XSync(drw->dpy, False);
-}
-
-unsigned int
-drw_fontset_getwidth(Drw *drw, const char *text, Bool markup)
-{
-	if (!drw || !drw->fonts || !text)
-		return 0;
-	return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup);
-}
-
-void
-drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup)
-{
-	if (!font || !text)
-		return;
-
-	PangoRectangle r;
-	if (markup)
-		pango_layout_set_markup(font->layout, text, len);
-	else
-		pango_layout_set_text(font->layout, text, len);
-	pango_layout_get_extents(font->layout, 0, &r);
-	if (markup) /* clear markup attributes */
-		pango_layout_set_attributes(font->layout, NULL);
-	if (w)
-		*w = r.width / PANGO_SCALE;
-	if (h)
-		*h = r.height / PANGO_SCALE;
-}
-
-Cur *
-drw_cur_create(Drw *drw, int shape)
-{
-	Cur *cur;
-
-	if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
-		return NULL;
-
-	cur->cursor = XCreateFontCursor(drw->dpy, shape);
-
-	return cur;
-}
-
-void
-drw_cur_free(Drw *drw, Cur *cursor)
-{
-	if (!cursor)
-		return;
-
-	XFreeCursor(drw->dpy, cursor->cursor);
-	free(cursor);
-}
diff --git a/drw.h b/drw.h
deleted file mode 100644
index 701bed3..0000000
--- a/drw.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-#include <pango/pango.h>
-#include <pango/pangoxft.h>
-
-typedef struct {
-	Cursor cursor;
-} Cur;
-
-typedef struct Fnt {
-	Display *dpy;
-	unsigned int h;
-	PangoLayout *layout;
-} Fnt;
-
-enum { ColFg, ColBg, ColBorder, ColFloat, ColCount }; /* Clr scheme index */
-typedef XftColor Clr;
-
-typedef struct {
-	unsigned int w, h;
-	Display *dpy;
-	int screen;
-	Window root;
-	Drawable drawable;
-	GC gc;
-	Clr *scheme;
-	Fnt *fonts;
-} Drw;
-
-/* Drawable abstraction */
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
-void drw_resize(Drw *drw, unsigned int w, unsigned int h);
-void drw_free(Drw *drw);
-
-/* Fnt abstraction */
-Fnt *drw_font_create(Drw* drw, const char font[]);
-void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup);
-void drw_fontset_free(Fnt* set);
-unsigned int drw_fontset_getwidth(Drw *drw, const char *text, Bool markup);
-
-/* Colorscheme abstraction */
-void drw_clr_create(
-	Drw *drw,
-	Clr *dest,
-	const char *clrname
-);
-Clr *drw_scm_create(
-	Drw *drw,
-	char *clrnames[],
-	size_t clrcount
-);
-
-/* Cursor abstraction */
-Cur *drw_cur_create(Drw *drw, int shape);
-void drw_cur_free(Drw *drw, Cur *cursor);
-
-/* Drawing context manipulation */
-void drw_setscheme(Drw *drw, Clr *scm);
-
-/* Drawing functions */
-void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
-int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup);
-
-/* Map functions */
-void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
-
diff --git a/dwm-flexipatch b/dwm-flexipatch
new file mode 160000
index 0000000..5e85bc8
--- /dev/null
+++ b/dwm-flexipatch
@@ -0,0 +1 @@
+Subproject commit 5e85bc8b5c784b47cdd3015b53c5bb517500ba9c
diff --git a/dwm.c b/dwm.c
deleted file mode 100644
index 44b9ef0..0000000
--- a/dwm.c
+++ /dev/null
@@ -1,2706 +0,0 @@
-/* See LICENSE file for copyright and license details.
- *
- * dynamic window manager is designed like any other X client as well. It is
- * driven through handling X events. In contrast to other X clients, a window
- * manager selects for SubstructureRedirectMask on the root window, to receive
- * events about window (dis-)appearance. Only one X connection at a time is
- * allowed to select for this event mask.
- *
- * The event handlers of dwm are organized in an array which is accessed
- * whenever a new event has been fetched. This allows event dispatching
- * in O(1) time.
- *
- * Each child of the root window is called a client, except windows which have
- * set the override_redirect flag. Clients are organized in a linked client
- * list on each monitor, the focus history is remembered through a stack list
- * on each monitor. Each client contains a bit array to indicate the tags of a
- * client.
- *
- * Keys and tagging rules are organized as arrays and defined in config.h.
- *
- * To understand everything else, start reading main().
- */
-#include <errno.h>
-#include <locale.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <X11/cursorfont.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif /* XINERAMA */
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-#include <pango/pango.h>
-
-#include <poll.h>
-
-/* macros */
-#define Button6                 6
-#define Button7                 7
-#define Button8                 8
-#define Button9                 9
-#define NUMTAGS                 9
-#define NUMVIEWHIST             NUMTAGS
-#define BARRULES                20
-#define BUTTONMASK              (ButtonPressMask|ButtonReleaseMask)
-#define CLEANMASK(mask)         (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
-#define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
-                               * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
-#define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
-#define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
-#define WIDTH(X)                ((X)->w + 2 * (X)->bw)
-#define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
-#define WTYPE                   "_NET_WM_WINDOW_TYPE_"
-#define TAGMASK                 ((1 << NUMTAGS) - 1)
-#define TEXTWM(X)               (drw_fontset_getwidth(drw, (X), True) + lrpad)
-#define TEXTW(X)                (drw_fontset_getwidth(drw, (X), False) + lrpad)
-#define HIDDEN(C)               ((getstate(C->win) == IconicState))
-
-/* enums */
-enum {
-	CurResizeBR,
-	CurResizeBL,
-	CurResizeTR,
-	CurResizeTL,
-	CurNormal,
-	CurResize,
-	CurMove,
-	CurLast
-}; /* cursor */
-
-enum {
-	SchemeNorm,
-	SchemeSel,
-	SchemeTitleNorm,
-	SchemeTitleSel,
-	SchemeTagsNorm,
-	SchemeTagsSel,
-	SchemeHidNorm,
-	SchemeHidSel,
-	SchemeUrg,
-	SchemeScratchSel,
-	SchemeScratchNorm,
-}; /* color schemes */
-
-enum {
-	NetSupported, NetWMName, NetWMState, NetWMCheck,
-	NetWMFullscreen, NetActiveWindow, NetWMWindowType,
-	NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop,
-	NetClientList,
-	NetClientListStacking,
-	NetLast
-}; /* EWMH atoms */
-
-enum {
-	WMProtocols,
-	WMDelete,
-	WMState,
-	WMTakeFocus,
-	WMWindowRole,
-	WMLast
-}; /* default atoms */
-
-enum {
-	ClientFields,
-	ClientTags,
-	ClientLast
-}; /* dwm client atoms */
-
-enum {
-	ClkTagBar,
-	ClkLtSymbol,
-	ClkStatusText,
-	ClkWinTitle,
-	ClkClientWin,
-	ClkRootWin,
-	ClkLast
-}; /* clicks */
-
-enum {
-	BAR_ALIGN_LEFT,
-	BAR_ALIGN_CENTER,
-	BAR_ALIGN_RIGHT,
-	BAR_ALIGN_LEFT_LEFT,
-	BAR_ALIGN_LEFT_RIGHT,
-	BAR_ALIGN_LEFT_CENTER,
-	BAR_ALIGN_NONE,
-	BAR_ALIGN_RIGHT_LEFT,
-	BAR_ALIGN_RIGHT_RIGHT,
-	BAR_ALIGN_RIGHT_CENTER,
-	BAR_ALIGN_LAST
-}; /* bar alignment */
-
-typedef union {
-	int i;
-	unsigned int ui;
-	float f;
-	const void *v;
-} Arg;
-
-typedef struct Monitor Monitor;
-typedef struct Bar Bar;
-struct Bar {
-	Window win;
-	Monitor *mon;
-	Bar *next;
-	int idx;
-	int showbar;
-	int topbar;
-	int external;
-	int borderpx;
-	int borderscheme;
-	int bx, by, bw, bh; /* bar geometry */
-	int w[BARRULES]; // width, array length == barrules, then use r index for lookup purposes
-	int x[BARRULES]; // x position, array length == ^
-};
-
-typedef struct {
-	int x;
-	int y;
-	int h;
-	int w;
-} BarArg;
-
-typedef struct {
-	int monitor;
-	int bar;
-	int alignment; // see bar alignment enum
-	int (*widthfunc)(Bar *bar, BarArg *a);
-	int (*drawfunc)(Bar *bar, BarArg *a);
-	int (*clickfunc)(Bar *bar, Arg *arg, BarArg *a);
-	int (*hoverfunc)(Bar *bar, BarArg *a, XMotionEvent *ev);
-	char *name; // for debugging
-	int x, w; // position, width for internal use
-} BarRule;
-
-typedef struct {
-	unsigned int click;
-	unsigned int mask;
-	unsigned int button;
-	void (*func)(const Arg *arg);
-	const Arg arg;
-} Button;
-
-typedef struct Client Client;
-struct Client {
-	char name[256];
-	float mina, maxa;
-	int x, y, w, h;
-	int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode revert */
-	unsigned int idx;
-	int oldx, oldy, oldw, oldh;
-	int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
-	int bw, oldbw;
-	unsigned int tags;
-	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
-	int iscentered;
-	Client *next;
-	Client *snext;
-	Monitor *mon;
-	Window win;
-	char scratchkey;
-};
-
-typedef struct {
-	unsigned int mod;
-	KeySym keysym;
-	void (*func)(const Arg *);
-	const Arg arg;
-} Key;
-
-typedef struct {
-	const char *symbol;
-	void (*arrange)(Monitor *);
-} Layout;
-
-typedef struct Pertag Pertag;
-struct Monitor {
-	char ltsymbol[16];
-	float mfact;
-	int nmaster;
-	int num;
-	int mx, my, mw, mh;   /* screen size */
-	int wx, wy, ww, wh;   /* window area  */
-	unsigned int seltags;
-	unsigned int sellt;
-	unsigned int tagset[2];
-	int showbar;
-	Client *clients;
-	Client *sel;
-	Client *stack;
-	Monitor *next;
-	Bar *bar;
-	const Layout *lt[2];
-	Pertag *pertag;
-};
-
-typedef struct {
-	const char *class;
-	const char *role;
-	const char *instance;
-	const char *title;
-	const char *wintype;
-	unsigned int tags;
-	int iscentered;
-	int isfloating;
-	const char *floatpos;
-	int monitor;
-	const char scratchkey;
-} Rule;
-
-#define RULE(...) { .monitor = -1, __VA_ARGS__ },
-
-/* Cross patch compatibility rule macro helper macros */
-#define FLOATING , .isfloating = 1
-#define CENTERED , .iscentered = 1
-#define PERMANENT
-#define FAKEFULLSCREEN
-#define NOSWALLOW
-#define TERMINAL
-#define SWITCHTAG
-
-/* function declarations */
-static void applyrules(Client *c);
-static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
-static void arrange(Monitor *m);
-static void arrangemon(Monitor *m);
-static void attach(Client *c);
-static void attachstack(Client *c);
-static void buttonpress(XEvent *e);
-static void checkotherwm(void);
-static void cleanup(void);
-static void cleanupmon(Monitor *mon);
-static void clientmessage(XEvent *e);
-static void configure(Client *c);
-static void configurenotify(XEvent *e);
-static void configurerequest(XEvent *e);
-static Monitor *createmon(void);
-static void destroynotify(XEvent *e);
-static void detach(Client *c);
-static void detachstack(Client *c);
-static Monitor *dirtomon(int dir);
-static void drawbar(Monitor *m);
-static void drawbars(void);
-static void drawbarwin(Bar *bar);
-static void expose(XEvent *e);
-static void focus(Client *c);
-static void focusin(XEvent *e);
-static void focusmon(const Arg *arg);
-static Atom getatomprop(Client *c, Atom prop, Atom req);
-static int getrootptr(int *x, int *y);
-static long getstate(Window w);
-static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
-static void grabbuttons(Client *c, int focused);
-static void grabkeys(void);
-static void incnmaster(const Arg *arg);
-static void keypress(XEvent *e);
-static void killclient(const Arg *arg);
-static void manage(Window w, XWindowAttributes *wa);
-static void mappingnotify(XEvent *e);
-static void maprequest(XEvent *e);
-static void motionnotify(XEvent *e);
-static void movemouse(const Arg *arg);
-static Client *nexttiled(Client *c);
-static void pop(Client *c);
-static void propertynotify(XEvent *e);
-static void quit(const Arg *arg);
-static Monitor *recttomon(int x, int y, int w, int h);
-static void resize(Client *c, int x, int y, int w, int h, int interact);
-static void resizeclient(Client *c, int x, int y, int w, int h);
-static void resizemouse(const Arg *arg);
-static void restack(Monitor *m);
-static void run(void);
-static void scan(void);
-static int sendevent(Client *c, Atom proto);
-static void sendmon(Client *c, Monitor *m);
-static void setclientstate(Client *c, long state);
-static void setfocus(Client *c);
-static void setfullscreen(Client *c, int fullscreen);
-static void setlayout(const Arg *arg);
-static void setmfact(const Arg *arg);
-static void setup(void);
-static void seturgent(Client *c, int urg);
-static void sigchld(int unused);
-static void showhide(Client *c);
-static void spawn(const Arg *arg);
-static void tag(const Arg *arg);
-static void tagmon(const Arg *arg);
-static void togglebar(const Arg *arg);
-static void togglefloating(const Arg *arg);
-static void toggletag(const Arg *arg);
-static void toggleview(const Arg *arg);
-static void unfocus(Client *c, int setfocus, Client *nextfocus);
-static void unmanage(Client *c, int destroyed);
-static void unmapnotify(XEvent *e);
-static void updatebarpos(Monitor *m);
-static void updatebars(void);
-static void updateclientlist(void);
-static int updategeom(void);
-static void updatenumlockmask(void);
-static void updatesizehints(Client *c);
-static void updatestatus(void);
-static void updatetitle(Client *c);
-static void updatewmhints(Client *c);
-static void view(const Arg *arg);
-static Client *wintoclient(Window w);
-static Monitor *wintomon(Window w);
-static int xerror(Display *dpy, XErrorEvent *ee);
-static int xerrordummy(Display *dpy, XErrorEvent *ee);
-static int xerrorstart(Display *dpy, XErrorEvent *ee);
-static void zoom(const Arg *arg);
-
-/* bar functions */
-
-#include "patch/include.h"
-
-/* variables */
-static const char broken[] = "broken";
-static char stext[8192];
-static char rawstext[8192];
-
-static int screen;
-static int sw, sh;           /* X display screen geometry width, height */
-static int bh;               /* bar geometry */
-static int lrpad;            /* sum of left and right padding for text */
-/* Some clients (e.g. alacritty) helpfully send configure requests with a new size or position
- * when they detect that they have been moved to another monitor. This can cause visual glitches
- * when moving (or resizing) client windows from one monitor to another. This variable is used
- * internally to ignore such configure requests while movemouse or resizemouse are being used. */
-static int ignoreconfigurerequests = 0;
-static int (*xerrorxlib)(Display *, XErrorEvent *);
-static unsigned int numlockmask = 0;
-static void (*handler[LASTEvent]) (XEvent *) = {
-	[ButtonPress] = buttonpress,
-	[ClientMessage] = clientmessage,
-	[ConfigureRequest] = configurerequest,
-	[ConfigureNotify] = configurenotify,
-	[DestroyNotify] = destroynotify,
-	[Expose] = expose,
-	[FocusIn] = focusin,
-	[KeyPress] = keypress,
-	[MappingNotify] = mappingnotify,
-	[MapRequest] = maprequest,
-	[MotionNotify] = motionnotify,
-	[PropertyNotify] = propertynotify,
-	[UnmapNotify] = unmapnotify
-};
-static Atom wmatom[WMLast], netatom[NetLast];
-static Atom clientatom[ClientLast];
-static volatile sig_atomic_t running = 1;
-static Cur *cursor[CurLast];
-static Clr **scheme;
-static Display *dpy;
-static Drw *drw;
-static Monitor *mons, *selmon;
-static Window root, wmcheckwin;
-
-/* configuration, allows nested code to access above variables */
-#include "config.h"
-
-#include "patch/include.c"
-
-/* compile-time check if all tags fit into an unsigned int bit array. */
-struct NumTags { char limitexceeded[NUMTAGS > 31 ? -1 : 1]; };
-
-/* function implementations */
-void
-applyrules(Client *c)
-{
-	const char *class, *instance;
-	Atom wintype;
-	char role[64];
-	unsigned int i;
-	const Rule *r;
-	Monitor *m;
-	XClassHint ch = { NULL, NULL };
-
-	/* rule matching */
-	c->isfloating = 0;
-	c->tags = 0;
-	c->scratchkey = 0;
-	XGetClassHint(dpy, c->win, &ch);
-	class    = ch.res_class ? ch.res_class : broken;
-	instance = ch.res_name  ? ch.res_name  : broken;
-	wintype  = getatomprop(c, netatom[NetWMWindowType], XA_ATOM);
-	gettextprop(c->win, wmatom[WMWindowRole], role, sizeof(role));
-
-	for (i = 0; i < LENGTH(rules); i++) {
-		r = &rules[i];
-		if ((!r->title || strstr(c->name, r->title))
-		&& (!r->class || strstr(class, r->class))
-		&& (!r->role || strstr(role, r->role))
-		&& (!r->instance || strstr(instance, r->instance))
-		&& (!r->wintype || wintype == XInternAtom(dpy, r->wintype, False)))
-		{
-			c->iscentered = r->iscentered;
-			c->isfloating = r->isfloating;
-			c->tags |= r->tags;
-			c->scratchkey = r->scratchkey;
-			for (m = mons; m && m->num != r->monitor; m = m->next);
-			if (m)
-				c->mon = m;
-			if (c->isfloating && r->floatpos) {
-				c->iscentered = 0;
-				setfloatpos(c, r->floatpos);
-			}
-
-		}
-	}
-	if (ch.res_class)
-		XFree(ch.res_class);
-	if (ch.res_name)
-		XFree(ch.res_name);
-	c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
-}
-
-int
-applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
-{
-	int baseismin;
-	Monitor *m = c->mon;
-
-	/* set minimum possible */
-	*w = MAX(1, *w);
-	*h = MAX(1, *h);
-	if (interact) {
-		if (*x > sw)
-			*x = sw - WIDTH(c);
-		if (*y > sh)
-			*y = sh - HEIGHT(c);
-		if (*x + *w + 2 * c->bw < 0)
-			*x = 0;
-		if (*y + *h + 2 * c->bw < 0)
-			*y = 0;
-	} else {
-		if (*x >= m->wx + m->ww)
-			*x = m->wx + m->ww - WIDTH(c);
-		if (*y >= m->wy + m->wh)
-			*y = m->wy + m->wh - HEIGHT(c);
-		if (*x + *w + 2 * c->bw <= m->wx)
-			*x = m->wx;
-		if (*y + *h + 2 * c->bw <= m->wy)
-			*y = m->wy;
-	}
-	if (*h < bh)
-		*h = bh;
-	if (*w < bh)
-		*w = bh;
-	if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
-		if (!c->hintsvalid)
-			updatesizehints(c);
-		/* see last two sentences in ICCCM 4.1.2.3 */
-		baseismin = c->basew == c->minw && c->baseh == c->minh;
-		if (!baseismin) { /* temporarily remove base dimensions */
-			*w -= c->basew;
-			*h -= c->baseh;
-		}
-		/* adjust for aspect limits */
-		if (c->mina > 0 && c->maxa > 0) {
-			if (c->maxa < (float)*w / *h)
-				*w = *h * c->maxa + 0.5;
-			else if (c->mina < (float)*h / *w)
-				*h = *w * c->mina + 0.5;
-		}
-		if (baseismin) { /* increment calculation requires this */
-			*w -= c->basew;
-			*h -= c->baseh;
-		}
-		/* adjust for increment value */
-		if (c->incw)
-			*w -= *w % c->incw;
-		if (c->inch)
-			*h -= *h % c->inch;
-		/* restore base dimensions */
-		*w = MAX(*w + c->basew, c->minw);
-		*h = MAX(*h + c->baseh, c->minh);
-		if (c->maxw)
-			*w = MIN(*w, c->maxw);
-		if (c->maxh)
-			*h = MIN(*h, c->maxh);
-	}
-	return *x != c->x || *y != c->y || *w != c->w || *h != c->h;
-}
-
-void
-arrange(Monitor *m)
-{
-	if (m)
-		showhide(m->stack);
-	else for (m = mons; m; m = m->next)
-		showhide(m->stack);
-	if (m) {
-		arrangemon(m);
-		restack(m);
-	} else for (m = mons; m; m = m->next)
-		arrangemon(m);
-}
-
-void
-arrangemon(Monitor *m)
-{
-	strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
-	if (m->lt[m->sellt]->arrange)
-		m->lt[m->sellt]->arrange(m);
-}
-
-void
-attach(Client *c)
-{
-	c->next = c->mon->clients;
-	c->mon->clients = c;
-}
-
-void
-attachstack(Client *c)
-{
-	c->snext = c->mon->stack;
-	c->mon->stack = c;
-}
-
-void
-buttonpress(XEvent *e)
-{
-	int click, i, r;
-	Arg arg = {0};
-	Client *c;
-	Monitor *m;
-	Bar *bar;
-	XButtonPressedEvent *ev = &e->xbutton;
-	const BarRule *br;
-	BarArg carg = { 0, 0, 0, 0 };
-	click = ClkRootWin;
-
-	/* focus monitor if necessary */
-	if ((m = wintomon(ev->window)) && m != selmon
-		&& (focusonwheel || (ev->button != Button4 && ev->button != Button5))
-	) {
-		unfocus(selmon->sel, 1, NULL);
-		selmon = m;
-		focus(NULL);
-	}
-
-	for (bar = selmon->bar; bar; bar = bar->next) {
-		if (ev->window == bar->win) {
-			for (r = 0; r < LENGTH(barrules); r++) {
-				br = &barrules[r];
-				if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->clickfunc == NULL)
-					continue;
-				if (br->monitor != 'A' && br->monitor != -1 && br->monitor != bar->mon->num)
-					continue;
-				if (bar->x[r] <= ev->x && ev->x <= bar->x[r] + bar->w[r]) {
-					carg.x = ev->x - bar->x[r];
-					carg.y = ev->y - bar->borderpx;
-					carg.w = bar->w[r];
-					carg.h = bar->bh - 2 * bar->borderpx;
-					click = br->clickfunc(bar, &arg, &carg);
-					if (click < 0)
-						return;
-					break;
-				}
-			}
-			break;
-		}
-	}
-
-	if (click == ClkRootWin && (c = wintoclient(ev->window))) {
-		if (focusonwheel || (ev->button != Button4 && ev->button != Button5))
-			focus(c);
-		XAllowEvents(dpy, ReplayPointer, CurrentTime);
-		click = ClkClientWin;
-	}
-
-	for (i = 0; i < LENGTH(buttons); i++) {
-		if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
-				&& CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
-			buttons[i].func(
-				(
-					click == ClkTagBar
-				) && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg
-			);
-		}
-	}
-}
-
-void
-checkotherwm(void)
-{
-	xerrorxlib = XSetErrorHandler(xerrorstart);
-	/* this causes an error if some other window manager is running */
-	XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
-	XSync(dpy, False);
-	XSetErrorHandler(xerror);
-	XSync(dpy, False);
-}
-
-void
-cleanup(void)
-{
-	Monitor *m;
-	Layout foo = { "", NULL };
-	size_t i;
-
-	for (m = mons; m; m = m->next)
-		persistmonitorstate(m);
-
-	/* kill child processes */
-	for (i = 0; i < autostart_len; i++) {
-		if (0 < autostart_pids[i]) {
-			kill(autostart_pids[i], autostart_kill_signal);
-			waitpid(autostart_pids[i], NULL, 0);
-		}
-	}
-
-	selmon->lt[selmon->sellt] = &foo;
-	for (m = mons; m; m = m->next)
-		while (m->stack)
-			unmanage(m->stack, 0);
-	XUngrabKey(dpy, AnyKey, AnyModifier, root);
-	while (mons)
-		cleanupmon(mons);
-	for (i = 0; i < CurLast; i++)
-		drw_cur_free(drw, cursor[i]);
-	for (i = 0; i < LENGTH(colors); i++)
-		free(scheme[i]);
-	free(scheme);
-	XDestroyWindow(dpy, wmcheckwin);
-	drw_free(drw);
-	XSync(dpy, False);
-	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
-	XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
-
-}
-
-void
-cleanupmon(Monitor *mon)
-{
-	Monitor *m;
-	Bar *bar;
-
-	if (mon == mons)
-		mons = mons->next;
-	else {
-		for (m = mons; m && m->next != mon; m = m->next);
-		m->next = mon->next;
-	}
-	for (bar = mon->bar; bar; bar = mon->bar) {
-		if (!bar->external) {
-			XUnmapWindow(dpy, bar->win);
-			XDestroyWindow(dpy, bar->win);
-		}
-		mon->bar = bar->next;
-		free(bar);
-	}
-	free(mon->pertag);
-	free(mon);
-}
-
-void
-clientmessage(XEvent *e)
-{
-	XClientMessageEvent *cme = &e->xclient;
-	Client *c = wintoclient(cme->window);
-
-	if (!c)
-		return;
-	if (cme->message_type == netatom[NetWMState]) {
-		if (cme->data.l[1] == netatom[NetWMFullscreen]
-		|| cme->data.l[2] == netatom[NetWMFullscreen]) {
-			setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD    */
-				|| (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */
-				&& !c->isfullscreen
-			)));
-		}
-	} else if (cme->message_type == netatom[NetActiveWindow]) {
-		if (c != selmon->sel && !c->isurgent)
-			seturgent(c, 1);
-	}
-}
-
-void
-configure(Client *c)
-{
-	XConfigureEvent ce;
-
-	ce.type = ConfigureNotify;
-	ce.display = dpy;
-	ce.event = c->win;
-	ce.window = c->win;
-	ce.x = c->x;
-	ce.y = c->y;
-	ce.width = c->w;
-	ce.height = c->h;
-	ce.border_width = c->bw;
-
-	ce.above = None;
-	ce.override_redirect = False;
-	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
-}
-
-void
-configurenotify(XEvent *e)
-{
-	Monitor *m;
-	Bar *bar;
-	Client *c;
-	XConfigureEvent *ev = &e->xconfigure;
-	int dirty;
-	/* TODO: updategeom handling sucks, needs to be simplified */
-	if (ev->window == root) {
-		dirty = (sw != ev->width || sh != ev->height);
-		sw = ev->width;
-		sh = ev->height;
-		if (updategeom() || dirty) {
-			drw_resize(drw, sw, sh);
-			updatebars();
-			for (m = mons; m; m = m->next) {
-				for (c = m->clients; c; c = c->next)
-					if (c->isfullscreen)
-						resizeclient(c, m->mx, m->my, m->mw, m->mh);
-				for (bar = m->bar; bar; bar = bar->next)
-					XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
-			}
-			arrange(NULL);
-			focus(NULL);
-		}
-	}
-}
-
-void
-configurerequest(XEvent *e)
-{
-	Client *c;
-	Monitor *m;
-	XConfigureRequestEvent *ev = &e->xconfigurerequest;
-	XWindowChanges wc;
-
-	if (ignoreconfigurerequests)
-		return;
-
-	if ((c = wintoclient(ev->window))) {
-		if (ev->value_mask & CWBorderWidth)
-			c->bw = ev->border_width;
-		else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
-			m = c->mon;
-			if (ev->value_mask & CWX) {
-				c->oldx = c->x;
-				c->x = m->mx + ev->x;
-			}
-			if (ev->value_mask & CWY) {
-				c->oldy = c->y;
-				c->y = m->my + ev->y;
-			}
-			if (ev->value_mask & CWWidth) {
-				c->oldw = c->w;
-				c->w = ev->width;
-			}
-			if (ev->value_mask & CWHeight) {
-				c->oldh = c->h;
-				c->h = ev->height;
-			}
-			if ((c->x + c->w) > m->mx + m->mw && c->isfloating)
-				c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2);  /* center in x direction */
-			if ((c->y + c->h) > m->my + m->mh && c->isfloating)
-				c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */
-			if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
-				configure(c);
-			if (ISVISIBLE(c))
-				XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
-		} else
-			configure(c);
-	} else {
-		wc.x = ev->x;
-		wc.y = ev->y;
-		wc.width = ev->width;
-		wc.height = ev->height;
-		wc.border_width = ev->border_width;
-		wc.sibling = ev->above;
-		wc.stack_mode = ev->detail;
-		XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
-	}
-	XSync(dpy, False);
-}
-
-Monitor *
-createmon(void)
-{
-	Monitor *m, *mon;
-	int i, n, mi, max_bars = 2, istopbar = topbar;
-
-	const BarRule *br;
-	Bar *bar;
-
-	m = ecalloc(1, sizeof(Monitor));
-	m->tagset[0] = m->tagset[1] = 1;
-	m->mfact = mfact;
-	m->nmaster = nmaster;
-	m->showbar = showbar;
-	for (mi = 0, mon = mons; mon; mon = mon->next, mi++); // monitor index
-	m->num = mi;
-	m->lt[0] = &layouts[0];
-	m->lt[1] = &layouts[1 % LENGTH(layouts)];
-	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
-
-	/* Derive the number of bars for this monitor based on bar rules */
-	for (n = -1, i = 0; i < LENGTH(barrules); i++) {
-		br = &barrules[i];
-		if (br->monitor == 'A' || br->monitor == -1 || br->monitor == m->num)
-			n = MAX(br->bar, n);
-	}
-
-	m->bar = NULL;
-	for (i = 0; i <= n && i < max_bars; i++) {
-		bar = ecalloc(1, sizeof(Bar));
-		bar->mon = m;
-		bar->idx = i;
-		bar->next = m->bar;
-		bar->topbar = istopbar;
-		m->bar = bar;
-		istopbar = !istopbar;
-		bar->showbar = 1;
-		bar->external = 0;
-		bar->borderpx = 0;
-		bar->bh = bh + bar->borderpx * 2;
-		bar->borderscheme = SchemeNorm;
-	}
-
-	if (!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag))))
-		die("fatal: could not malloc() %u bytes\n", sizeof(Pertag));
-	m->pertag->curtag = 1;
-	for (i = 0; i <= NUMTAGS; i++) {
-
-		/* init nmaster */
-		m->pertag->nmasters[i] = m->nmaster;
-
-		/* init mfacts */
-		m->pertag->mfacts[i] = m->mfact;
-
-		/* init layouts */
-		m->pertag->ltidxs[i][0] = m->lt[0];
-		m->pertag->ltidxs[i][1] = m->lt[1];
-		m->pertag->sellts[i] = m->sellt;
-
-	}
-
-	restoremonitorstate(m);
-
-	return m;
-}
-
-void
-destroynotify(XEvent *e)
-{
-	Client *c;
-	XDestroyWindowEvent *ev = &e->xdestroywindow;
-
-	if ((c = wintoclient(ev->window)))
-		unmanage(c, 1);
-}
-
-void
-detach(Client *c)
-{
-	Client **tc;
-	c->idx = 0;
-
-	for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
-	*tc = c->next;
-	c->next = NULL;
-}
-
-void
-detachstack(Client *c)
-{
-	Client **tc, *t;
-
-	for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
-	*tc = c->snext;
-
-	if (c == c->mon->sel) {
-		for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext);
-		c->mon->sel = t;
-	}
-	c->snext = NULL;
-}
-
-Monitor *
-dirtomon(int dir)
-{
-	Monitor *m = NULL;
-
-	if (dir > 0) {
-		if (!(m = selmon->next))
-			m = mons;
-	} else if (selmon == mons)
-		for (m = mons; m->next; m = m->next);
-	else
-		for (m = mons; m->next != selmon; m = m->next);
-	return m;
-}
-
-void
-drawbar(Monitor *m)
-{
-	Bar *bar;
-	
-	if (m->showbar)
-		for (bar = m->bar; bar; bar = bar->next)
-			drawbarwin(bar);
-}
-
-void
-drawbars(void)
-{
-	Monitor *m;
-	for (m = mons; m; m = m->next)
-		drawbar(m);
-}
-
-void
-drawbarwin(Bar *bar)
-{
-	if (!bar || !bar->win || bar->external)
-		return;
-	int r, w, total_drawn = 0;
-	int rx, lx, rw, lw; // bar size, split between left and right if a center module is added
-	const BarRule *br;
-
-	if (bar->borderpx) {
-		XSetForeground(drw->dpy, drw->gc, scheme[bar->borderscheme][ColBorder].pixel);
-		XFillRectangle(drw->dpy, drw->drawable, drw->gc, 0, 0, bar->bw, bar->bh);
-	}
-
-	BarArg warg = { 0 };
-	BarArg darg  = { 0 };
-	warg.h = bar->bh - 2 * bar->borderpx;
-
-	rw = lw = bar->bw - 2 * bar->borderpx;
-	rx = lx = bar->borderpx;
-
-	drw_setscheme(drw, scheme[SchemeNorm]);
-	drw_rect(drw, lx, bar->borderpx, lw, bar->bh - 2 * bar->borderpx, 1, 1);
-	for (r = 0; r < LENGTH(barrules); r++) {
-		br = &barrules[r];
-		if (br->bar != bar->idx || !br->widthfunc || (br->monitor == 'A' && bar->mon != selmon))
-			continue;
-		if (br->monitor != 'A' && br->monitor != -1 && br->monitor != bar->mon->num)
-			continue;
-		drw_setscheme(drw, scheme[SchemeNorm]);
-		warg.w = (br->alignment < BAR_ALIGN_RIGHT_LEFT ? lw : rw);
-
-		w = br->widthfunc(bar, &warg);
-		w = MIN(warg.w, w);
-
-		if (lw <= 0) { // if left is exhausted then switch to right side, and vice versa
-			lw = rw;
-			lx = rx;
-		} else if (rw <= 0) {
-			rw = lw;
-			rx = lx;
-		}
-
-		switch(br->alignment) {
-		default:
-		case BAR_ALIGN_NONE:
-		case BAR_ALIGN_LEFT_LEFT:
-		case BAR_ALIGN_LEFT:
-			bar->x[r] = lx;
-			if (lx == rx) {
-				rx += w;
-				rw -= w;
-			}
-			lx += w;
-			lw -= w;
-			break;
-		case BAR_ALIGN_LEFT_RIGHT:
-		case BAR_ALIGN_RIGHT:
-			bar->x[r] = lx + lw - w;
-			if (lx == rx)
-				rw -= w;
-			lw -= w;
-			break;
-		case BAR_ALIGN_LEFT_CENTER:
-		case BAR_ALIGN_CENTER:
-			bar->x[r] = lx + lw / 2 - w / 2;
-			if (lx == rx) {
-				rw = rx + rw - bar->x[r] - w;
-				rx = bar->x[r] + w;
-			}
-			lw = bar->x[r] - lx;
-			break;
-		case BAR_ALIGN_RIGHT_LEFT:
-			bar->x[r] = rx;
-			if (lx == rx) {
-				lx += w;
-				lw -= w;
-			}
-			rx += w;
-			rw -= w;
-			break;
-		case BAR_ALIGN_RIGHT_RIGHT:
-			bar->x[r] = rx + rw - w;
-			if (lx == rx)
-				lw -= w;
-			rw -= w;
-			break;
-		case BAR_ALIGN_RIGHT_CENTER:
-			bar->x[r] = rx + rw / 2 - w / 2;
-			if (lx == rx) {
-				lw = lx + lw - bar->x[r] + w;
-				lx = bar->x[r] + w;
-			}
-			rw = bar->x[r] - rx;
-			break;
-		}
-		bar->w[r] = w;
-		darg.x = bar->x[r];
-		darg.y = bar->borderpx;
-		darg.h = bar->bh - 2 * bar->borderpx;
-		darg.w = bar->w[r];
-		if (br->drawfunc)
-			total_drawn += br->drawfunc(bar, &darg);
-	}
-
-	if (total_drawn == 0 && bar->showbar) {
-		bar->showbar = 0;
-		updatebarpos(bar->mon);
-		XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
-		arrange(bar->mon);
-	}
-	else if (total_drawn > 0 && !bar->showbar) {
-		bar->showbar = 1;
-		updatebarpos(bar->mon);
-		XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
-		drw_map(drw, bar->win, 0, 0, bar->bw, bar->bh);
-		arrange(bar->mon);
-	} else
-		drw_map(drw, bar->win, 0, 0, bar->bw, bar->bh);
-}
-
-void
-expose(XEvent *e)
-{
-	Monitor *m;
-	XExposeEvent *ev = &e->xexpose;
-
-	if (ev->count == 0 && (m = wintomon(ev->window))) {
-		drawbar(m);
-	}
-}
-
-void
-focus(Client *c)
-{
-	if (!c || !ISVISIBLE(c))
-		for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
-	if (selmon->sel && selmon->sel != c)
-		unfocus(selmon->sel, 0, c);
-	if (c) {
-		if (c->mon != selmon)
-			selmon = c->mon;
-		if (c->isurgent)
-			seturgent(c, 0);
-		detachstack(c);
-		attachstack(c);
-		grabbuttons(c, 1);
-		if (c->scratchkey != 0 && c->isfloating)
-			XSetWindowBorder(dpy, c->win, scheme[SchemeScratchSel][ColFloat].pixel);
-		else if (c->scratchkey != 0)
-			XSetWindowBorder(dpy, c->win, scheme[SchemeScratchSel][ColBorder].pixel);
-		else if (c->isfloating)
-			XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColFloat].pixel);
-		else
-			XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
-		setfocus(c);
-	} else {
-		XSetInputFocus(dpy, selmon->bar && selmon->bar->win ? selmon->bar->win : root, RevertToPointerRoot, CurrentTime);
-		XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
-	}
-	selmon->sel = c;
-	drawbars();
-
-}
-
-/* there are some broken focus acquiring clients needing extra handling */
-void
-focusin(XEvent *e)
-{
-	XFocusChangeEvent *ev = &e->xfocus;
-
-	if (selmon->sel && ev->window != selmon->sel->win)
-		setfocus(selmon->sel);
-}
-
-void
-focusmon(const Arg *arg)
-{
-	Monitor *m;
-	Client *sel;
-
-	if (!mons->next)
-		return;
-	if ((m = dirtomon(arg->i)) == selmon)
-		return;
-	sel = selmon->sel;
-	selmon = m;
-	unfocus(sel, 0, NULL);
-	focus(NULL);
-}
-
-Atom
-getatomprop(Client *c, Atom prop, Atom req)
-{
-	int di;
-	unsigned long dl;
-	unsigned char *p = NULL;
-	Atom da, atom = None;
-
-	/* FIXME getatomprop should return the number of items and a pointer to
-	 * the stored data instead of this workaround */
-	if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
-		&da, &di, &dl, &dl, &p) == Success && p) {
-		atom = *(Atom *)p;
-		XFree(p);
-	}
-	return atom;
-}
-
-int
-getrootptr(int *x, int *y)
-{
-	int di;
-	unsigned int dui;
-	Window dummy;
-
-	return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui);
-}
-
-long
-getstate(Window w)
-{
-	int format;
-	long result = -1;
-	unsigned char *p = NULL;
-	unsigned long n, extra;
-	Atom real;
-
-	if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState],
-		&real, &format, &n, &extra, (unsigned char **)&p) != Success)
-		return -1;
-	if (n != 0)
-		result = *p;
-	XFree(p);
-	return result;
-}
-
-int
-gettextprop(Window w, Atom atom, char *text, unsigned int size)
-{
-	char **list = NULL;
-	int n;
-	XTextProperty name;
-
-	if (!text || size == 0)
-		return 0;
-	text[0] = '\0';
-	if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems)
-		return 0;
-	if (name.encoding == XA_STRING) {
-		strncpy(text, (char *)name.value, size - 1);
-	} else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
-		strncpy(text, *list, size - 1);
-		XFreeStringList(list);
-	}
-	text[size - 1] = '\0';
-	XFree(name.value);
-	return 1;
-}
-
-void
-grabbuttons(Client *c, int focused)
-{
-	updatenumlockmask();
-	{
-		unsigned int i, j;
-		unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
-		XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
-		if (!focused)
-			XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
-				BUTTONMASK, GrabModeSync, GrabModeSync, None, None);
-		for (i = 0; i < LENGTH(buttons); i++)
-			if (buttons[i].click == ClkClientWin
-			)
-				for (j = 0; j < LENGTH(modifiers); j++)
-					XGrabButton(dpy, buttons[i].button,
-						buttons[i].mask | modifiers[j],
-						c->win, False, BUTTONMASK,
-						GrabModeAsync, GrabModeSync, None, None);
-	}
-}
-
-void
-grabkeys(void)
-{
-	updatenumlockmask();
-	{
-		unsigned int i, j, k;
-		unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
-		int start, end, skip;
-		KeySym *syms;
-
-		XUngrabKey(dpy, AnyKey, AnyModifier, root);
-		XDisplayKeycodes(dpy, &start, &end);
-		syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip);
-		if (!syms)
-			return;
-		for (k = start; k <= end; k++)
-			for (i = 0; i < LENGTH(keys); i++)
-				/* skip modifier codes, we do that ourselves */
-				if (keys[i].keysym == syms[(k - start) * skip])
-					for (j = 0; j < LENGTH(modifiers); j++)
-						XGrabKey(dpy, k,
-							 keys[i].mod | modifiers[j],
-							 root, True,
-							 GrabModeAsync, GrabModeAsync);
-		XFree(syms);
-	}
-}
-
-void
-incnmaster(const Arg *arg)
-{
-	selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
-	arrange(selmon);
-}
-
-#ifdef XINERAMA
-static int
-isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
-{
-	while (n--)
-		if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org
-		&& unique[n].width == info->width && unique[n].height == info->height)
-			return 0;
-	return 1;
-}
-#endif /* XINERAMA */
-
-void
-keypress(XEvent *e)
-{
-	unsigned int i;
-	int keysyms_return;
-	KeySym* keysym;
-	XKeyEvent *ev;
-
-	ev = &e->xkey;
-	keysym = XGetKeyboardMapping(dpy, (KeyCode)ev->keycode, 1, &keysyms_return);
-	for (i = 0; i < LENGTH(keys); i++)
-		if (*keysym == keys[i].keysym
-				&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
-				&& keys[i].func)
-			keys[i].func(&(keys[i].arg));
-	XFree(keysym);
-}
-
-void
-killclient(const Arg *arg)
-{
-	if (!selmon->sel)
-		return;
-	if (!sendevent(selmon->sel, wmatom[WMDelete]))
-	{
-		XGrabServer(dpy);
-		XSetErrorHandler(xerrordummy);
-		XSetCloseDownMode(dpy, DestroyAll);
-		XKillClient(dpy, selmon->sel->win);
-		XSync(dpy, False);
-		XSetErrorHandler(xerror);
-		XUngrabServer(dpy);
-	}
-}
-
-void
-manage(Window w, XWindowAttributes *wa)
-{
-	Client *c, *t = NULL;
-	int settings_restored;
-	Window trans = None;
-	XWindowChanges wc;
-
-	c = ecalloc(1, sizeof(Client));
-	c->win = w;
-	/* geometry */
-	c->sfx = c->sfy = c->sfw = c->sfh = -9999;
-	c->x = c->oldx = wa->x;
-	c->y = c->oldy = wa->y;
-	c->w = c->oldw = wa->width;
-	c->h = c->oldh = wa->height;
-	c->oldbw = wa->border_width;
-	settings_restored = restoreclientstate(c);
-	updatetitle(c);
-
-	if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
-		c->mon = t->mon;
-		c->tags = t->tags;
-		c->bw = borderpx;
-		c->x = t->x + WIDTH(t) / 2 - WIDTH(c) / 2;
-		c->y = t->y + HEIGHT(t) / 2 - HEIGHT(c) / 2;
-	} else {
-		if (!settings_restored || c->mon == NULL) {
-			c->mon = selmon;
-			settings_restored = 0;
-		}
-		if (c->x == c->mon->wx && c->y == c->mon->wy)
-			c->iscentered = 1;
-		c->bw = borderpx;
-		if (!settings_restored)
-			applyrules(c);
-	}
-
-	if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
-		c->x = c->mon->wx + c->mon->ww - WIDTH(c);
-	if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh)
-		c->y = c->mon->wy + c->mon->wh - HEIGHT(c);
-	c->x = MAX(c->x, c->mon->wx);
-	c->y = MAX(c->y, c->mon->wy);
-
-	wc.border_width = c->bw;
-	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
-	if (c->isfloating)
-		XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColFloat].pixel);
-	else
-		XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
-	configure(c); /* propagates border_width, if size doesn't change */
-	updatesizehints(c);
-	updatewmhints(c);
-
-	if (c->iscentered) {
-		c->sfx = c->x = c->mon->wx + (c->mon->ww - WIDTH(c)) / 2;
-		c->sfy = c->y = c->mon->wy + (c->mon->wh - HEIGHT(c)) / 2;
-	}
-	if (c->sfw == -9999) {
-		c->sfw = c->w;
-		c->sfh = c->h;
-	}
-
-	if (getatomprop(c, netatom[NetWMState], XA_ATOM) == netatom[NetWMFullscreen])
-		setfullscreen(c, 1);
-
-	XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
-	grabbuttons(c, 0);
-
-	if (!c->isfloating)
-		c->isfloating = c->oldstate = trans != None || c->isfixed;
-	if (c->isfloating) {
-		XRaiseWindow(dpy, c->win);
-		XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColFloat].pixel);
-	}
-	attachx(c);
-	attachstack(c);
-	XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
-		(unsigned char *) &(c->win), 1);
-	XChangeProperty(dpy, root, netatom[NetClientListStacking], XA_WINDOW, 32, PropModePrepend,
-		(unsigned char *) &(c->win), 1);
-	XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
-
-	setclientstate(c, NormalState);
-	if (c->mon == selmon)
-		unfocus(selmon->sel, 0, c);
-	c->mon->sel = c;
-	arrange(c->mon);
-	XMapWindow(dpy, c->win);
-	focus(NULL);
-
-	setfloatinghint(c);
-}
-
-void
-mappingnotify(XEvent *e)
-{
-	XMappingEvent *ev = &e->xmapping;
-
-	XRefreshKeyboardMapping(ev);
-	if (ev->request == MappingKeyboard)
-		grabkeys();
-}
-
-void
-maprequest(XEvent *e)
-{
-	static XWindowAttributes wa;
-	XMapRequestEvent *ev = &e->xmaprequest;
-
-	if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect)
-		return;
-	if (!wintoclient(ev->window))
-		manage(ev->window, &wa);
-}
-
-void
-motionnotify(XEvent *e)
-{
-	Bar *bar;
-	XMotionEvent *ev = &e->xmotion;
-
-	if ((bar = wintobar(ev->window))) {
-		barhover(e, bar);
-		return;
-	}
-
-}
-
-void
-movemouse(const Arg *arg)
-{
-	int x, y, ocx, ocy, nx, ny;
-	Client *c;
-	Monitor *m;
-	XEvent ev;
-	Time lasttime = 0;
-
-	if (!(c = selmon->sel))
-		return;
-	if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
-		return;
-	restack(selmon);
-	nx = ocx = c->x;
-	ny = ocy = c->y;
-	if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
-		None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
-		return;
-	if (!getrootptr(&x, &y))
-		return;
-	ignoreconfigurerequests = 1;
-	do {
-		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
-		switch(ev.type) {
-		case ConfigureRequest:
-		case Expose:
-		case MapRequest:
-			handler[ev.type](&ev);
-			break;
-		case MotionNotify:
-			if ((ev.xmotion.time - lasttime) <= (1000 / 60))
-				continue;
-			lasttime = ev.xmotion.time;
-
-			nx = ocx + (ev.xmotion.x - x);
-			ny = ocy + (ev.xmotion.y - y);
-			if (abs(selmon->wx - nx) < snap)
-				nx = selmon->wx;
-			else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
-				nx = selmon->wx + selmon->ww - WIDTH(c);
-			if (abs(selmon->wy - ny) < snap)
-				ny = selmon->wy;
-			else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
-				ny = selmon->wy + selmon->wh - HEIGHT(c);
-			if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
-			&& (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) {
-				c->sfx = -9999; // disable savefloats when using movemouse
-				togglefloating(NULL);
-			}
-			if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) {
-				resize(c, nx, ny, c->w, c->h, 1);
-			}
-			break;
-		}
-	} while (ev.type != ButtonRelease);
-
-	XUngrabPointer(dpy, CurrentTime);
-	if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
-		sendmon(c, m);
-		selmon = m;
-		focus(NULL);
-	}
-	/* save last known float coordinates */
-	if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) {
-		c->sfx = nx;
-		c->sfy = ny;
-	}
-	ignoreconfigurerequests = 0;
-}
-
-Client *
-nexttiled(Client *c)
-{
-	for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
-	return c;
-}
-
-void
-pop(Client *c)
-{
-	detach(c);
-	attach(c);
-	focus(c);
-	arrange(c->mon);
-}
-
-void
-propertynotify(XEvent *e)
-{
-	Client *c;
-	Window trans;
-	XPropertyEvent *ev = &e->xproperty;
-
-	if ((ev->window == root) && (ev->atom == XA_WM_NAME)) {
-		updatestatus();
-	} else if (ev->state == PropertyDelete) {
-		return; /* ignore */
-	} else if ((c = wintoclient(ev->window))) {
-		switch(ev->atom) {
-		default: break;
-		case XA_WM_TRANSIENT_FOR:
-			if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) &&
-				(c->isfloating = (wintoclient(trans)) != NULL))
-				arrange(c->mon);
-			break;
-		case XA_WM_NORMAL_HINTS:
-			c->hintsvalid = 0;
-			break;
-		case XA_WM_HINTS:
-			updatewmhints(c);
-			if (c->isurgent)
-				drawbars();
-			break;
-		}
-		if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
-			updatetitle(c);
-			if (c == c->mon->sel)
-				drawbar(c->mon);
-		}
-	}
-}
-
-void
-quit(const Arg *arg)
-{
-	restart = arg->i;
-	running = 0;
-}
-
-Monitor *
-recttomon(int x, int y, int w, int h)
-{
-	Monitor *m, *r = selmon;
-	int a, area = 0;
-
-	for (m = mons; m; m = m->next)
-		if ((a = INTERSECT(x, y, w, h, m)) > area) {
-			area = a;
-			r = m;
-		}
-	return r;
-}
-
-void
-resize(Client *c, int x, int y, int w, int h, int interact)
-{
-	if (applysizehints(c, &x, &y, &w, &h, interact))
-		resizeclient(c, x, y, w, h);
-}
-
-void
-resizeclient(Client *c, int x, int y, int w, int h)
-{
-	XWindowChanges wc;
-
-	c->oldx = c->x; c->x = wc.x = x;
-	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;
-	wc.border_width = c->bw;
-	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
-	configure(c);
-	XSync(dpy, False);
-}
-
-void
-resizemouse(const Arg *arg)
-{
-	int ocx, ocy, nw, nh, nx, ny;
-	int opx, opy, och, ocw;
-	int horizcorner, vertcorner;
-	unsigned int dui;
-	Window dummy;
-	Client *c;
-	Monitor *m;
-	XEvent ev;
-	Time lasttime = 0;
-
-	if (!(c = selmon->sel))
-		return;
-	if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
-		return;
-	restack(selmon);
-	nx = ocx = c->x;
-	ny = ocy = c->y;
-	nh = c->h;
-	nw = c->w;
-	och = c->h;
-	ocw = c->w;
-	if (!XQueryPointer(dpy, c->win, &dummy, &dummy, &opx, &opy, &nx, &ny, &dui))
-		return;
-	horizcorner = nx < c->w / 2;
-	vertcorner  = ny < c->h / 2;
-	if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
-		None, cursor[horizcorner | (vertcorner << 1)]->cursor, CurrentTime) != GrabSuccess)
-		return;
-	ignoreconfigurerequests = 1;
-	do {
-		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
-		switch(ev.type) {
-		case ConfigureRequest:
-		case Expose:
-		case MapRequest:
-			handler[ev.type](&ev);
-			break;
-		case MotionNotify:
-			if ((ev.xmotion.time - lasttime) <= (1000 / 60))
-				continue;
-			lasttime = ev.xmotion.time;
-
-			nx = horizcorner ? (ocx + ev.xmotion.x - opx) : c->x;
-			ny = vertcorner ? (ocy + ev.xmotion.y - opy) : c->y;
-			nw = MAX(horizcorner ? (ocx + ocw - nx) : (ocw + (ev.xmotion.x - opx)), 1);
-			nh = MAX(vertcorner ? (ocy + och - ny) : (och + (ev.xmotion.y - opy)), 1);
-			if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
-			&& c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
-			{
-				if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
-				&& (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) {
-					c->sfx = -9999; // disable savefloats when using resizemouse
-					togglefloating(NULL);
-				}
-			}
-			if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) {
-				resize(c, nx, ny, nw, nh, 1);
-			}
-			break;
-		}
-	} while (ev.type != ButtonRelease);
-
-	XUngrabPointer(dpy, CurrentTime);
-	while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
-	if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
-		sendmon(c, m);
-		selmon = m;
-		focus(NULL);
-	}
-	/* save last known float dimensions */
-	if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) {
-		c->sfx = nx;
-		c->sfy = ny;
-		c->sfw = nw;
-		c->sfh = nh;
-	}
-	ignoreconfigurerequests = 0;
-}
-
-void
-restack(Monitor *m)
-{
-	Client *c, *f = NULL;
-	XEvent ev;
-	XWindowChanges wc;
-
-	drawbar(m);
-	if (!m->sel)
-		return;
-	if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
-		XRaiseWindow(dpy, m->sel->win);
-	if (m->lt[m->sellt]->arrange) {
-		wc.stack_mode = Below;
-		if (m->bar) {
-			wc.sibling = m->bar->win;
-		} else {
-			for (f = m->stack; f && (f->isfloating || !ISVISIBLE(f)); f = f->snext); // find first tiled stack client
-			if (f)
-				wc.sibling = f->win;
-		}
-		for (c = m->stack; c; c = c->snext)
-			if (!c->isfloating && ISVISIBLE(c) && c != f) {
-				XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
-				wc.sibling = c->win;
-			}
-	}
-	XSync(dpy, False);
-	while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
-}
-
-void
-run(void)
-{
-	XEvent ev;
-	XSync(dpy, False);
-	/* main event loop */
-	while (running) {
-		struct pollfd pfd = {
-			.fd = ConnectionNumber(dpy),
-			.events = POLLIN,
-		};
-		int pending = XPending(dpy) > 0 || poll(&pfd, 1, -1) > 0;
-
-		if (!running)
-			break;
-		if (!pending)
-			continue;
-
-		XNextEvent(dpy, &ev);
-		if (handler[ev.type])
-			handler[ev.type](&ev); /* call handler */
-	}
-}
-
-void
-scan(void)
-{
-	unsigned int i, num;
-	Window d1, d2, *wins = NULL;
-	XWindowAttributes wa;
-
-	if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
-		for (i = 0; i < num; i++) {
-			if (!XGetWindowAttributes(dpy, wins[i], &wa)
-			|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
-				continue;
-			if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
-				manage(wins[i], &wa);
-		}
-		for (i = 0; i < num; i++) { /* now the transients */
-			if (!XGetWindowAttributes(dpy, wins[i], &wa))
-				continue;
-			if (XGetTransientForHint(dpy, wins[i], &d1)
-			&& (wa.map_state == IsViewable || getstate(wins[i]) == IconicState))
-				manage(wins[i], &wa);
-		}
-		XFree(wins);
-	}
-}
-
-void
-sendmon(Client *c, Monitor *m)
-{
-	if (c->mon == m)
-		return;
-	int hadfocus = (c == selmon->sel);
-	unfocus(c, 1, NULL);
-	detach(c);
-	detachstack(c);
-	arrange(c->mon);
-	c->mon = m;
-	c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
-	attachx(c);
-	attachstack(c);
-	arrange(m);
-	if (hadfocus) {
-		focus(c);
-		restack(m);
-	} else {
-		focus(NULL);
-	}
-}
-
-void
-setclientstate(Client *c, long state)
-{
-	long data[] = { state, None };
-
-	XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
-		PropModeReplace, (unsigned char *)data, 2);
-}
-
-int
-sendevent(Client *c, Atom proto)
-{
-	int n;
-	Atom *protocols;
-	int exists = 0;
-	XEvent ev;
-
-	if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
-		while (!exists && n--)
-			exists = protocols[n] == proto;
-		XFree(protocols);
-	}
-
-	if (exists) {
-		ev.type = ClientMessage;
-		ev.xclient.window = c->win;
-		ev.xclient.message_type = wmatom[WMProtocols];
-		ev.xclient.format = 32;
-		ev.xclient.data.l[0] = proto;
-		ev.xclient.data.l[1] = CurrentTime;
-		XSendEvent(dpy, c->win, False, NoEventMask, &ev);
-	}
-	return exists;
-}
-
-void
-setfocus(Client *c)
-{
-	if (!c->neverfocus) {
-		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
-		XChangeProperty(dpy, root, netatom[NetActiveWindow],
-			XA_WINDOW, 32, PropModeReplace,
-			(unsigned char *) &(c->win), 1);
-	}
-	sendevent(c, wmatom[WMTakeFocus]);
-}
-
-void
-setfullscreen(Client *c, int fullscreen)
-{
-	if (fullscreen && !c->isfullscreen) {
-		XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
-			PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
-		c->isfullscreen = 1;
-		c->oldbw = c->bw;
-		c->oldstate = c->isfloating;
-		c->bw = 0;
-		c->isfloating = 1;
-		resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
-		XRaiseWindow(dpy, c->win);
-	} else if (!fullscreen && c->isfullscreen){
-		XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
-			PropModeReplace, (unsigned char*)0, 0);
-		c->isfullscreen = 0;
-		c->bw = c->oldbw;
-		c->isfloating = c->oldstate;
-		c->x = c->oldx;
-		c->y = c->oldy;
-		c->w = c->oldw;
-		c->h = c->oldh;
-		resizeclient(c, c->x, c->y, c->w, c->h);
-		arrange(c->mon);
-	}
-}
-
-void
-setlayout(const Arg *arg)
-{
-	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) {
-		selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
-		selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
-	}
-	if (arg && arg->v)
-		selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
-	selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
-
-	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
-	if (selmon->sel)
-		arrange(selmon);
-	else
-		drawbar(selmon);
-}
-
-/* arg > 1.0 will set mfact absolutely */
-void
-setmfact(const Arg *arg)
-{
-	float f;
-
-	if (!arg || !selmon->lt[selmon->sellt]->arrange)
-		return;
-	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
-	if (f < 0.05 || f > 0.95)
-		return;
-	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
-	arrange(selmon);
-}
-
-void
-setup(void)
-{
-	int i;
-	XSetWindowAttributes wa;
-	Atom utf8string;
-	/* clean up any zombies immediately */
-	sigchld(0);
-
-	signal(SIGHUP, sighup);
-	signal(SIGTERM, sigterm);
-
-	/* the one line of bloat that would have saved a lot of time for a lot of people */
-	putenv("_JAVA_AWT_WM_NONREPARENTING=1");
-
-	/* init screen */
-	screen = DefaultScreen(dpy);
-	sw = DisplayWidth(dpy, screen);
-	sh = DisplayHeight(dpy, screen);
-	root = RootWindow(dpy, screen);
-	drw = drw_create(dpy, screen, root, sw, sh);
-	if (!drw_font_create(drw, font))
-		die("no fonts could be loaded.");
-	lrpad = drw->fonts->h;
-	bh = drw->fonts->h + 2;
-	updategeom();
-	/* init atoms */
-	utf8string = XInternAtom(dpy, "UTF8_STRING", False);
-	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
-	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-	wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
-	wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
-	wmatom[WMWindowRole] = XInternAtom(dpy, "WM_WINDOW_ROLE", False);
-	clientatom[ClientFields] = XInternAtom(dpy, "_DWM_CLIENT_FIELDS", False);
-	clientatom[ClientTags] = XInternAtom(dpy, "_DWM_CLIENT_TAGS", False);
-	netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
-	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
-	netatom[NetDesktopViewport] = XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False);
-	netatom[NetNumberOfDesktops] = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
-	netatom[NetCurrentDesktop] = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
-	netatom[NetDesktopNames] = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False);
-	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
-	netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
-	netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
-	netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
-	netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
-	netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
-	netatom[NetClientListStacking] = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
-	/* init cursors */
-	cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
-	cursor[CurResize] = drw_cur_create(drw, XC_sizing);
-	cursor[CurResizeBR] = drw_cur_create(drw, XC_bottom_right_corner);
-	cursor[CurResizeBL] = drw_cur_create(drw, XC_bottom_left_corner);
-	cursor[CurResizeTR] = drw_cur_create(drw, XC_top_right_corner);
-	cursor[CurResizeTL] = drw_cur_create(drw, XC_top_left_corner);
-	cursor[CurMove] = drw_cur_create(drw, XC_fleur);
-	/* init appearance */
-	scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
-	for (i = 0; i < LENGTH(colors); i++)
-		scheme[i] = drw_scm_create(drw, colors[i], ColCount);
-
-	updatebars();
-	updatestatus();
-
-	/* supporting window for NetWMCheck */
-	wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
-	XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
-		PropModeReplace, (unsigned char *) &wmcheckwin, 1);
-	XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8,
-		PropModeReplace, (unsigned char *) "dwm", 3);
-	XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
-		PropModeReplace, (unsigned char *) &wmcheckwin, 1);
-	/* EWMH support per view */
-	XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
-		PropModeReplace, (unsigned char *) netatom, NetLast);
-	setnumdesktops();
-	setcurrentdesktop();
-	setdesktopnames();
-	setviewport();
-	XDeleteProperty(dpy, root, netatom[NetClientList]);
-	XDeleteProperty(dpy, root, netatom[NetClientListStacking]);
-	/* select events */
-	wa.cursor = cursor[CurNormal]->cursor;
-	wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
-		|ButtonPressMask|PointerMotionMask|EnterWindowMask
-		|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
-	XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
-	XSelectInput(dpy, root, wa.event_mask);
-
-	grabkeys();
-	focus(NULL);
-}
-
-void
-seturgent(Client *c, int urg)
-{
-	XWMHints *wmh;
-
-	c->isurgent = urg;
-	if (!(wmh = XGetWMHints(dpy, c->win)))
-		return;
-	wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint);
-	XSetWMHints(dpy, c->win, wmh);
-	XFree(wmh);
-}
-
-void
-showhide(Client *c)
-{
-	if (!c)
-		return;
-	if (ISVISIBLE(c)) {
-		/* show clients top down */
-		if (!c->mon->lt[c->mon->sellt]->arrange && c->sfx != -9999 && !c->isfullscreen) {
-			XMoveResizeWindow(dpy, c->win, c->sfx, c->sfy, c->sfw, c->sfh);
-			resize(c, c->sfx, c->sfy, c->sfw, c->sfh, 0);
-			showhide(c->snext);
-			return;
-		}
-		XMoveWindow(dpy, c->win, c->x, c->y);
-		if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating)
-			&& !c->isfullscreen
-			)
-			resize(c, c->x, c->y, c->w, c->h, 0);
-		showhide(c->snext);
-	} else {
-		/* hide clients bottom up */
-		showhide(c->snext);
-		XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
-	}
-}
-
-void
-sigchld(int unused)
-{
-	pid_t pid;
-
-	if (signal(SIGCHLD, sigchld) == SIG_ERR)
-		die("can't install SIGCHLD handler:");
-
-	while (0 < (pid = waitpid(-1, NULL, WNOHANG))) {
-		pid_t *p, *lim;
-
-		if (!(p = autostart_pids))
-			continue;
-		lim = &p[autostart_len];
-
-		for (; p < lim; p++) {
-			if (*p == pid) {
-				*p = -1;
-				break;
-			}
-		}
-	}
-}
-
-void
-spawn(const Arg *arg)
-{
-	struct sigaction sa;
-
-	if (fork() == 0)
-	{
-		if (dpy)
-			close(ConnectionNumber(dpy));
-
-		setsid();
-
-		sigemptyset(&sa.sa_mask);
-		sa.sa_flags = 0;
-		sa.sa_handler = SIG_DFL;
-		sigaction(SIGCHLD, &sa, NULL);
-
-		execvp(((char **)arg->v)[0], (char **)arg->v);
-		die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]);
-	}
-}
-
-void
-tag(const Arg *arg)
-{
-
-	if (selmon->sel && arg->ui & TAGMASK) {
-		selmon->sel->tags = arg->ui & TAGMASK;
-		arrange(selmon);
-		focus(NULL);
-	}
-}
-
-void
-tagmon(const Arg *arg)
-{
-	Client *c = selmon->sel;
-	Monitor *dest;
-	int restored;
-	if (!c || !mons->next)
-		return;
-	dest = dirtomon(arg->i);
-	savewindowfloatposition(c, c->mon);
-	restored = restorewindowfloatposition(c, dest);
-	if (restored && (!dest->lt[dest->sellt]->arrange || c->isfloating)) {
-		XMoveResizeWindow(dpy, c->win, c->sfx, c->sfy, c->sfw, c->sfh);
-		resize(c, c->sfx, c->sfy, c->sfw, c->sfh, 1);
-	}
-	if (c->isfullscreen) {
-		c->isfullscreen = 0;
-		sendmon(c, dest);
-		c->isfullscreen = 1;
-		resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
-		XRaiseWindow(dpy, c->win);
-    } else if (c->isfloating && c->scratchkey != 0) {
- 		sendmon(c, dest);
- 		applyrules(c);
- 		XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
-	} else
-		sendmon(c, dest);
-}
-
-void
-togglebar(const Arg *arg)
-{
-	Bar *bar;
-	selmon->showbar = !selmon->showbar;
-	updatebarpos(selmon);
-	for (bar = selmon->bar; bar; bar = bar->next)
-		XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
-	arrange(selmon);
-}
-
-void
-togglefloating(const Arg *arg)
-{
-	Client *c = selmon->sel;
-	if (arg && arg->v)
-		c = (Client*)arg->v;
-	if (!c)
-		return;
-	if (c->isfullscreen) /* no support for fullscreen windows */
-		return;
-	c->isfloating = !c->isfloating || c->isfixed;
-	if (c->scratchkey != 0 && c->isfloating)
-		XSetWindowBorder(dpy, c->win, scheme[SchemeScratchSel][ColFloat].pixel);
-	else if (c->scratchkey != 0)
-		XSetWindowBorder(dpy, c->win, scheme[SchemeScratchSel][ColBorder].pixel);
-	else if (c->isfloating)
-		XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColFloat].pixel);
-	else
-		XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
-	if (c->isfloating) {
-		if (c->sfx != -9999) {
-			/* restore last known float dimensions */
-			resize(c, c->sfx, c->sfy, c->sfw, c->sfh, 0);
-		} else
-		resize(c, c->x, c->y, c->w, c->h, 0);
-	} else {
-		/* save last known float dimensions */
-		c->sfx = c->x;
-		c->sfy = c->y;
-		c->sfw = c->w;
-		c->sfh = c->h;
-	}
-	arrange(c->mon);
-
-	setfloatinghint(c);
-}
-
-void
-toggletag(const Arg *arg)
-{
-	unsigned int newtags;
-
-	if (!selmon->sel)
-		return;
-	newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
-	if (newtags) {
-		selmon->sel->tags = newtags;
-		arrange(selmon);
-		focus(NULL);
-	}
-	updatecurrentdesktop();
-}
-
-void
-toggleview(const Arg *arg)
-{
-	unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);;
-	int i;
-
-	if (newtagset) {
-		selmon->tagset[selmon->seltags] = newtagset;
-
-		if (newtagset == ~0)
-		{
-			selmon->pertag->curtag = 0;
-		}
-		/* test if the user did not select the same tag */
-		if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
-			for (i = 0; !(newtagset & 1 << i); i++) ;
-			selmon->pertag->curtag = i + 1;
-		}
-
-		/* apply settings for this view */
-		selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
-		selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
-		selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
-		selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
-		selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
-		arrange(selmon);
-		focus(NULL);
-	}
-	updatecurrentdesktop();
-}
-
-void
-unfocus(Client *c, int setfocus, Client *nextfocus)
-{
-	if (!c)
-		return;
-	if (c->isfullscreen && ISVISIBLE(c) && c->mon == selmon && nextfocus && !nextfocus->isfloating) {
-		setfullscreen(c, 0);
-	}
-	grabbuttons(c, 0);
-	if (c->scratchkey != 0 && c->isfloating)
-		XSetWindowBorder(dpy, c->win, scheme[SchemeScratchNorm][ColFloat].pixel);
-	else if (c->scratchkey != 0)
-		XSetWindowBorder(dpy, c->win, scheme[SchemeScratchNorm][ColBorder].pixel);
-	else if (c->isfloating)
-		XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColFloat].pixel);
-	else
-		XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
-	if (setfocus) {
-		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
-		XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
-	}
-}
-
-void
-unmanage(Client *c, int destroyed)
-{
-	Monitor *m;
-	XWindowChanges wc;
-
-	m = c->mon;
-
-	detach(c);
-	detachstack(c);
-	if (!destroyed) {
-		wc.border_width = c->oldbw;
-		XGrabServer(dpy); /* avoid race conditions */
-		XSetErrorHandler(xerrordummy);
-		XSelectInput(dpy, c->win, NoEventMask);
-		XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
-		XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
-		if (!HIDDEN(c))
-			setclientstate(c, WithdrawnState);
-		XSync(dpy, False);
-		XSetErrorHandler(xerror);
-		XUngrabServer(dpy);
-	}
-
-	free(c);
-	arrange(m);
-	focus(NULL);
-	updateclientlist();
-}
-
-void
-unmapnotify(XEvent *e)
-{
-	Client *c;
-	XUnmapEvent *ev = &e->xunmap;
-
-	if ((c = wintoclient(ev->window))) {
-		if (ev->send_event)
-			setclientstate(c, WithdrawnState);
-		else
-			unmanage(c, 0);
-	}
-}
-
-void
-updatebars(void)
-{
-	Bar *bar;
-	Monitor *m;
-	XSetWindowAttributes wa = {
-		.override_redirect = True,
-		.background_pixmap = ParentRelative,
-		.event_mask = ButtonPressMask|ExposureMask
-	};
-	XClassHint ch = {"dwm", "dwm"};
-	for (m = mons; m; m = m->next) {
-		for (bar = m->bar; bar; bar = bar->next) {
-			if (bar->external)
-				continue;
-			if (!bar->win) {
-				bar->win = XCreateWindow(dpy, root, bar->bx, bar->by, bar->bw, bar->bh, 0, DefaultDepth(dpy, screen),
-						CopyFromParent, DefaultVisual(dpy, screen),
-						CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
-				XDefineCursor(dpy, bar->win, cursor[CurNormal]->cursor);
-				XMapRaised(dpy, bar->win);
-				XSetClassHint(dpy, bar->win, &ch);
-			}
-		}
-	}
-}
-
-void
-updatebarpos(Monitor *m)
-{
-
-	m->wx = m->mx;
-	m->wy = m->my;
-	m->ww = m->mw;
-	m->wh = m->mh;
-	Bar *bar;
-	int y_pad = 0;
-	int x_pad = 0;
-
-	for (bar = m->bar; bar; bar = bar->next) {
-		bar->bx = m->wx + x_pad;
-		bar->bw = m->ww - 2 * x_pad;
-	}
-
-	for (bar = m->bar; bar; bar = bar->next)
-		if (!m->showbar || !bar->showbar)
-			bar->by = -bar->bh - y_pad;
-
-	if (!m->showbar)
-		return;
-	for (bar = m->bar; bar; bar = bar->next) {
-		if (!bar->showbar)
-			continue;
-		if (bar->topbar)
-			m->wy = m->wy + bar->bh + y_pad;
-		m->wh -= y_pad + bar->bh;
-		bar->by = (bar->topbar ? m->wy - bar->bh : m->wy + m->wh);
-	}
-}
-
-void
-updateclientlist(void)
-{
-	Client *c;
-	Monitor *m;
-
-	XDeleteProperty(dpy, root, netatom[NetClientList]);
-	for (m = mons; m; m = m->next)
-		for (c = m->clients; c; c = c->next)
-			XChangeProperty(dpy, root, netatom[NetClientList],
-				XA_WINDOW, 32, PropModeAppend,
-				(unsigned char *) &(c->win), 1);
-
-	XDeleteProperty(dpy, root, netatom[NetClientListStacking]);
-	for (m = mons; m; m = m->next)
-		for (c = m->stack; c; c = c->snext)
-			XChangeProperty(dpy, root, netatom[NetClientListStacking],
-				XA_WINDOW, 32, PropModeAppend,
-				(unsigned char *) &(c->win), 1);
-}
-
-int
-updategeom(void)
-{
-	int dirty = 0;
-
-#ifdef XINERAMA
-	if (XineramaIsActive(dpy)) {
-		int i, j, n, nn;
-		Client *c;
-		Monitor *m;
-		XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
-		XineramaScreenInfo *unique = NULL;
-
-		for (n = 0, m = mons; m; m = m->next, n++);
-		/* only consider unique geometries as separate screens */
-		unique = ecalloc(nn, sizeof(XineramaScreenInfo));
-		for (i = 0, j = 0; i < nn; i++)
-			if (isuniquegeom(unique, j, &info[i]))
-				memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
-		XFree(info);
-		nn = j;
-		/* new monitors if nn > n */
-		for (i = n; i < nn; i++) {
-			for (m = mons; m && m->next; m = m->next);
-			if (m)
-				m->next = createmon();
-			else
-				mons = createmon();
-		}
-		for (i = 0, m = mons; i < nn && m; m = m->next, i++)
-			if (i >= n
-			|| unique[i].x_org != m->mx || unique[i].y_org != m->my
-			|| unique[i].width != m->mw || unique[i].height != m->mh)
-			{
-				dirty = 1;
-				m->num = i;
-				m->mx = m->wx = unique[i].x_org;
-				m->my = m->wy = unique[i].y_org;
-				m->mw = m->ww = unique[i].width;
-				m->mh = m->wh = unique[i].height;
-				updatebarpos(m);
-			}
-		/* removed monitors if n > nn */
-		for (i = nn; i < n; i++) {
-			for (m = mons; m && m->next; m = m->next);
-			while ((c = m->clients)) {
-				dirty = 1;
-				m->clients = c->next;
-				detachstack(c);
-				c->mon = mons;
-				attach(c);
-				attachstack(c);
-			}
-			if (m == selmon)
-				selmon = mons;
-			cleanupmon(m);
-		}
-		free(unique);
-	} else
-#endif /* XINERAMA */
-	{ /* default monitor setup */
-		if (!mons)
-			mons = createmon();
-		if (mons->mw != sw || mons->mh != sh) {
-			dirty = 1;
-			mons->mw = mons->ww = sw;
-			mons->mh = mons->wh = sh;
-			updatebarpos(mons);
-		}
-	}
-	if (dirty) {
-		selmon = mons;
-		selmon = wintomon(root);
-	}
-	return dirty;
-}
-
-void
-updatenumlockmask(void)
-{
-	unsigned int i, j;
-	XModifierKeymap *modmap;
-
-	numlockmask = 0;
-	modmap = XGetModifierMapping(dpy);
-	for (i = 0; i < 8; i++)
-		for (j = 0; j < modmap->max_keypermod; j++)
-			if (modmap->modifiermap[i * modmap->max_keypermod + j]
-				== XKeysymToKeycode(dpy, XK_Num_Lock))
-				numlockmask = (1 << i);
-	XFreeModifiermap(modmap);
-}
-
-void
-updatesizehints(Client *c)
-{
-	long msize;
-	XSizeHints size;
-
-	if (!XGetWMNormalHints(dpy, c->win, &size, &msize))
-		/* size is uninitialized, ensure that size.flags aren't used */
-		size.flags = 0;
-	if (size.flags & PBaseSize) {
-		c->basew = size.base_width;
-		c->baseh = size.base_height;
-	} else if (size.flags & PMinSize) {
-		c->basew = size.min_width;
-		c->baseh = size.min_height;
-	} else
-		c->basew = c->baseh = 0;
-	if (size.flags & PResizeInc) {
-		c->incw = size.width_inc;
-		c->inch = size.height_inc;
-	} else
-		c->incw = c->inch = 0;
-	if (size.flags & PMaxSize) {
-		c->maxw = size.max_width;
-		c->maxh = size.max_height;
-	} else
-		c->maxw = c->maxh = 0;
-	if (size.flags & PMinSize) {
-		c->minw = size.min_width;
-		c->minh = size.min_height;
-	} else if (size.flags & PBaseSize) {
-		c->minw = size.base_width;
-		c->minh = size.base_height;
-	} else
-		c->minw = c->minh = 0;
-	if (size.flags & PAspect) {
-		c->mina = (float)size.min_aspect.y / size.min_aspect.x;
-		c->maxa = (float)size.max_aspect.x / size.max_aspect.y;
-	} else
-		c->maxa = c->mina = 0.0;
-	if (size.flags & PSize)
-	{
-		c->basew = size.base_width;
-		c->baseh = size.base_height;
-		c->isfloating = 1;
-	}
-	checkfloatingrules(c);
-	c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh);
-	c->hintsvalid = 1;
-}
-
-void
-updatestatus(void)
-{
-	Monitor *m;
-	if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext)))
-		strcpy(stext, "dwm-"VERSION);
-	else
-		copyvalidchars(stext, rawstext);
-	for (m = mons; m; m = m->next)
-		drawbar(m);
-}
-
-void
-updatetitle(Client *c)
-{
-
-	if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
-		gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
-	if (c->name[0] == '\0') /* hack to mark broken clients */
-		strcpy(c->name, broken);
-
-}
-
-void
-updatewmhints(Client *c)
-{
-	XWMHints *wmh;
-
-	if ((wmh = XGetWMHints(dpy, c->win))) {
-		if (c == selmon->sel && wmh->flags & XUrgencyHint) {
-			wmh->flags &= ~XUrgencyHint;
-			XSetWMHints(dpy, c->win, wmh);
-		} else
-			c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0;
-		if (c->isurgent) {
-			if (c->isfloating)
-				XSetWindowBorder(dpy, c->win, scheme[SchemeUrg][ColFloat].pixel);
-			else
-				XSetWindowBorder(dpy, c->win, scheme[SchemeUrg][ColBorder].pixel);
-		}
-		if (wmh->flags & InputHint)
-			c->neverfocus = !wmh->input;
-		else
-			c->neverfocus = 0;
-		XFree(wmh);
-	}
-}
-
-void
-view(const Arg *arg)
-{
-	if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
-	{
-		return;
-	}
-	selmon->seltags ^= 1; /* toggle sel tagset */
-	if (arg->ui & TAGMASK)
-		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
-	pertagview(arg);
-	arrange(selmon);
-	focus(NULL);
-	updatecurrentdesktop();
-}
-
-Client *
-wintoclient(Window w)
-{
-	Client *c;
-	Monitor *m;
-
-	for (m = mons; m; m = m->next)
-		for (c = m->clients; c; c = c->next)
-			if (c->win == w)
-				return c;
-	return NULL;
-}
-
-Monitor *
-wintomon(Window w)
-{
-	int x, y;
-	Client *c;
-	Monitor *m;
-	Bar *bar;
-
-	if (w == root && getrootptr(&x, &y))
-		return recttomon(x, y, 1, 1);
-	for (m = mons; m; m = m->next)
-		for (bar = m->bar; bar; bar = bar->next)
-			if (w == bar->win)
-				return m;
-	if ((c = wintoclient(w)))
-		return c->mon;
-	return selmon;
-}
-
-/* There's no way to check accesses to destroyed windows, thus those cases are
- * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
- * default error handler, which may call exit. */
-int
-xerror(Display *dpy, XErrorEvent *ee)
-{
-	if (ee->error_code == BadWindow
-	|| (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch)
-	|| (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable)
-	|| (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable)
-	|| (ee->request_code == X_PolySegment && ee->error_code == BadDrawable)
-	|| (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch)
-	|| (ee->request_code == X_GrabButton && ee->error_code == BadAccess)
-	|| (ee->request_code == X_GrabKey && ee->error_code == BadAccess)
-	|| (ee->request_code == X_CopyArea && ee->error_code == BadDrawable))
-		return 0;
-	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
-		ee->request_code, ee->error_code);
-	return xerrorxlib(dpy, ee); /* may call exit */
-}
-
-int
-xerrordummy(Display *dpy, XErrorEvent *ee)
-{
-	return 0;
-}
-
-/* Startup Error handler to check if another window manager
- * is already running. */
-int
-xerrorstart(Display *dpy, XErrorEvent *ee)
-{
-	die("dwm: another window manager is already running");
-	return -1;
-}
-
-void
-zoom(const Arg *arg)
-{
-	Client *c = selmon->sel;
-	if (arg && arg->v)
-		c = (Client*)arg->v;
-	if (!c)
-		return;
-
-	if (!c->mon->lt[c->mon->sellt]->arrange || !c || c->isfloating)
-		return;
-
-	if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next)))
-		return;
-	pop(c);
-}
-
-int
-main(int argc, char *argv[])
-{
-	if (argc == 2 && !strcmp("-v", argv[1]))
-		die("dwm-"VERSION);
-	else if (argc != 1)
-		die("usage: dwm [-v]");
-	if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
-		fputs("warning: no locale support\n", stderr);
-	if (!(dpy = XOpenDisplay(NULL)))
-		die("dwm: cannot open display");
-	checkotherwm();
-	autostart_exec();
-	setup();
-#ifdef __OpenBSD__
-	if (pledge("stdio rpath proc exec", NULL) == -1)
-		die("pledge");
-#endif /* __OpenBSD__ */
-	scan();
-	run();
-	cleanup();
-	XCloseDisplay(dpy);
-	if (restart)
-		execvp(argv[0], argv);
-	return EXIT_SUCCESS;
-}
-
diff --git a/flexipatch-finalizer b/flexipatch-finalizer
new file mode 160000
index 0000000..7c66a3d
--- /dev/null
+++ b/flexipatch-finalizer
@@ -0,0 +1 @@
+Subproject commit 7c66a3d0560d33d9d49b3e856859ef8a0af1fd6a
diff --git a/patch/attachx.c b/patch/attachx.c
deleted file mode 100644
index 5b9f7d9..0000000
--- a/patch/attachx.c
+++ /dev/null
@@ -1,27 +0,0 @@
-void
-attachx(Client *c)
-{
-	Client *at;
-
-	if (c->idx > 0) { /* then the client has a designated position in the client list */
-		for (at = c->mon->clients; at; at = at->next) {
-			if (c->idx < at->idx) {
-				c->next = at;
-				c->mon->clients = c;
-				return;
-			} else if (at->idx <= c->idx && (!at->next || c->idx <= at->next->idx)) {
-				c->next = at->next;
-				at->next = c;
-				return;
-			}
-		}
-	}
-
-	if (!(c->mon->sel == NULL || c->mon->sel == c || c->mon->sel->isfloating)) {
-		c->next = c->mon->sel->next;
-		c->mon->sel->next = c;
-		return;
-	}
-	attach(c); // master (default)
-}
-
diff --git a/patch/attachx.h b/patch/attachx.h
deleted file mode 100644
index e522d27..0000000
--- a/patch/attachx.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void attachx(Client *c);
-
diff --git a/patch/bar.c b/patch/bar.c
deleted file mode 100644
index 65e1a69..0000000
--- a/patch/bar.c
+++ /dev/null
@@ -1,39 +0,0 @@
-void
-barhover(XEvent *e, Bar *bar)
-{
-	const BarRule *br;
-	Monitor *m = bar->mon;
-	XMotionEvent *ev = &e->xmotion;
-	BarArg barg = { 0, 0, 0, 0 };
-	int r;
-
-	for (r = 0; r < LENGTH(barrules); r++) {
-		br = &barrules[r];
-		if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->hoverfunc == NULL)
-			continue;
-		if (br->monitor != 'A' && br->monitor != -1 && br->monitor != bar->mon->num)
-			continue;
-		if (bar->x[r] > ev->x || ev->x > bar->x[r] + bar->w[r])
-			continue;
-
-		barg.x = ev->x - bar->x[r];
-		barg.y = ev->y - bar->borderpx;
-		barg.w = bar->w[r];
-		barg.h = bar->bh - 2 * bar->borderpx;
-
-		br->hoverfunc(bar, &barg, ev);
-		break;
-	}
-}
-
-Bar *
-wintobar(Window win)
-{
-	Monitor *m;
-	Bar *bar;
-	for (m = mons; m; m = m->next)
-		for (bar = m->bar; bar; bar = bar->next)
-			if (bar->win == win)
-				return bar;
-	return NULL;
-}
diff --git a/patch/bar.h b/patch/bar.h
deleted file mode 100644
index 3e006dc..0000000
--- a/patch/bar.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void barhover(XEvent *e, Bar *bar);
-static Bar *wintobar(Window win);
diff --git a/patch/bar_dwmblocks.c b/patch/bar_dwmblocks.c
deleted file mode 100644
index 0a4b097..0000000
--- a/patch/bar_dwmblocks.c
+++ /dev/null
@@ -1,41 +0,0 @@
-static int statussig;
-pid_t statuspid = -1;
-
-pid_t
-getstatusbarpid()
-{
-	char buf[32], *str = buf, *c;
-	FILE *fp;
-
-	if (statuspid > 0) {
-		snprintf(buf, sizeof(buf), "/proc/%u/cmdline", statuspid);
-		if ((fp = fopen(buf, "r"))) {
-			fgets(buf, sizeof(buf), fp);
-			while ((c = strchr(str, '/')))
-				str = c + 1;
-			fclose(fp);
-			if (!strcmp(str, STATUSBAR))
-				return statuspid;
-		}
-	}
-	if (!(fp = popen("pgrep -o "STATUSBAR, "r")))
-		return -1;
-	fgets(buf, sizeof(buf), fp);
-	pclose(fp);
-	return strtol(buf, NULL, 10);
-}
-
-void
-sigstatusbar(const Arg *arg)
-{
-	union sigval sv;
-
-	if (!statussig)
-		return;
-	if ((statuspid = getstatusbarpid()) <= 0)
-		return;
-
-	sv.sival_int = arg->i;
-	sigqueue(statuspid, SIGRTMIN+statussig, sv);
-}
-
diff --git a/patch/bar_dwmblocks.h b/patch/bar_dwmblocks.h
deleted file mode 100644
index 4db9467..0000000
--- a/patch/bar_dwmblocks.h
+++ /dev/null
@@ -1,3 +0,0 @@
-static int getstatusbarpid();
-static void sigstatusbar(const Arg *arg);
-
diff --git a/patch/bar_ewmhtags.c b/patch/bar_ewmhtags.c
deleted file mode 100644
index 46ee5e4..0000000
--- a/patch/bar_ewmhtags.c
+++ /dev/null
@@ -1,52 +0,0 @@
-void
-setcurrentdesktop(void)
-{
-	long data[] = { 0 };
-	XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
-}
-
-void
-setdesktopnames(void)
-{
-	int i;
-	XTextProperty text;
-	char *tags[NUMTAGS];
-	for (i = 0; i < NUMTAGS; i++)
-		tags[i] = tagicon(selmon, i);
-	Xutf8TextListToTextProperty(dpy, tags, NUMTAGS, XUTF8StringStyle, &text);
-	XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]);
-}
-
-void
-setfloatinghint(Client *c)
-{
-	Atom target = XInternAtom(dpy, "_IS_FLOATING", 0);
-	unsigned int floating[1] = {c->isfloating};
-	XChangeProperty(dpy, c->win, target, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)floating, 1);
-}
-
-void
-setnumdesktops(void)
-{
-	long data[] = { NUMTAGS };
-	XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
-}
-
-void
-setviewport(void)
-{
-	long data[] = { 0, 0 };
-	XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2);
-}
-
-void
-updatecurrentdesktop(void)
-{
-	long rawdata[] = { selmon->tagset[selmon->seltags] };
-	int i = 0;
-	while (*rawdata >> (i + 1)) {
-		i++;
-	}
-	long data[] = { i };
-	XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
-}
diff --git a/patch/bar_ewmhtags.h b/patch/bar_ewmhtags.h
deleted file mode 100644
index 4d6a74b..0000000
--- a/patch/bar_ewmhtags.h
+++ /dev/null
@@ -1,7 +0,0 @@
-static void setcurrentdesktop(void);
-static void setdesktopnames(void);
-static void setfloatinghint(Client *c);
-static void setnumdesktops(void);
-static void setviewport(void);
-static void updatecurrentdesktop(void);
-
diff --git a/patch/bar_indicators.c b/patch/bar_indicators.c
deleted file mode 100644
index b003fc8..0000000
--- a/patch/bar_indicators.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Indicator properties, you can override these in your config.h if you want. */
-#ifndef TAGSINDICATOR
-#define TAGSINDICATOR 1 // 0 = off, 1 = on if >1 client/view tag, 2 = always on
-#endif
-#ifndef TAGSPX
-#define TAGSPX 5        // # pixels for tag grid boxes
-#endif
-#ifndef TAGSROWS
-#define TAGSROWS 3      // # rows in tag grid (9 tags, e.g. 3x3)
-#endif
-
-void
-drawindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert, int type)
-{
-	int i, boxw, boxs, indn = 0;
-	if (!(occ & 1 << tag) || type == INDICATOR_NONE)
-		return;
-
-	boxs = drw->fonts->h / 9;
-	boxw = drw->fonts->h / 6 + 2;
-	if (filled == -1)
-		filled = m == selmon && m->sel && m->sel->tags & 1 << tag;
-
-	switch (type) {
-	default:
-	case INDICATOR_TOP_LEFT_SQUARE:
-		drw_rect(drw, x + boxs, y + boxs, boxw, boxw, filled, invert);
-		break;
-	case INDICATOR_TOP_LEFT_LARGER_SQUARE:
-		drw_rect(drw, x + boxs + 2, y + boxs+1, boxw+1, boxw+1, filled, invert);
-		break;
-	case INDICATOR_TOP_BAR:
-		drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), boxw/2, filled, invert);
-		break;
-	case INDICATOR_TOP_BAR_SLIM:
-		drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), 1, 0, invert);
-		break;
-	case INDICATOR_BOTTOM_BAR:
-		drw_rect(drw, x + boxw, y + h - boxw/2, w - ( 2 * boxw + 1), boxw/2, filled, invert);
-		break;
-	case INDICATOR_BOTTOM_BAR_SLIM:
-		drw_rect(drw, x + boxw, y + h - 1, w - ( 2 * boxw + 1), 1, 0, invert);
-		break;
-	case INDICATOR_BOX:
-		drw_rect(drw, x + boxw, y, w - 2 * boxw, h, 0, invert);
-		break;
-	case INDICATOR_BOX_WIDER:
-		drw_rect(drw, x + boxw/2, y, w - boxw, h, 0, invert);
-		break;
-	case INDICATOR_BOX_FULL:
-		drw_rect(drw, x, y, w - 2, h, 0, invert);
-		break;
-	case INDICATOR_CLIENT_DOTS:
-		for (c = m->clients; c; c = c->next) {
-			if (c->tags & (1 << tag)) {
-				drw_rect(drw, x, 1 + (indn * 2), m->sel == c ? 6 : 1, 1, 1, invert);
-				indn++;
-			}
-			if (h <= 1 + (indn * 2)) {
-				indn = 0;
-				x += 2;
-			}
-		}
-		break;
-	case INDICATOR_RIGHT_TAGS:
-		if (!c)
-			break;
-		for (i = 0; i < NUMTAGS; i++) {
-			drw_rect(drw,
-				( x + w - 2 - ((NUMTAGS / TAGSROWS) * TAGSPX)
-					- (i % (NUMTAGS/TAGSROWS)) + ((i % (NUMTAGS / TAGSROWS)) * TAGSPX)
-				),
-				( y + 2 + ((i / (NUMTAGS/TAGSROWS)) * TAGSPX)
-					- ((i / (NUMTAGS/TAGSROWS)))
-				),
-				TAGSPX, TAGSPX, (c->tags >> i) & 1, 0
-			);
-		}
-		break;
-	case INDICATOR_PLUS_AND_LARGER_SQUARE:
-		boxs += 2;
-		boxw += 2;
-		/* falls through */
-	case INDICATOR_PLUS_AND_SQUARE:
-		drw_rect(drw, x + boxs, y + boxs, boxw % 2 ? boxw : boxw + 1, boxw % 2 ? boxw : boxw + 1, filled, invert);
-		/* falls through */
-	case INDICATOR_PLUS:
-		if (!(boxw % 2))
-			boxw += 1;
-		drw_rect(drw, x + boxs + boxw / 2, y + boxs, 1, boxw, filled, invert); // |
-		drw_rect(drw, x + boxs, y + boxs + boxw / 2, boxw + 1, 1, filled, invert); // ‒
-		break;
-	}
-}
-
-void
-drawstateindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert)
-{
-	if (c->isfloating)
-		drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, floatindicatortype);
-	else
-		drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, tiledindicatortype);
-}
-
diff --git a/patch/bar_indicators.h b/patch/bar_indicators.h
deleted file mode 100644
index c66e4f0..0000000
--- a/patch/bar_indicators.h
+++ /dev/null
@@ -1,21 +0,0 @@
-enum {
-	INDICATOR_NONE,
-	INDICATOR_TOP_LEFT_SQUARE,
-	INDICATOR_TOP_LEFT_LARGER_SQUARE,
-	INDICATOR_TOP_BAR,
-	INDICATOR_TOP_BAR_SLIM,
-	INDICATOR_BOTTOM_BAR,
-	INDICATOR_BOTTOM_BAR_SLIM,
-	INDICATOR_BOX,
-	INDICATOR_BOX_WIDER,
-	INDICATOR_BOX_FULL,
-	INDICATOR_CLIENT_DOTS,
-	INDICATOR_RIGHT_TAGS,
-	INDICATOR_PLUS,
-	INDICATOR_PLUS_AND_SQUARE,
-	INDICATOR_PLUS_AND_LARGER_SQUARE,
-};
-
-static void drawindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert, int type);
-static void drawstateindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert);
-
diff --git a/patch/bar_ltsymbol.c b/patch/bar_ltsymbol.c
deleted file mode 100644
index 1004378..0000000
--- a/patch/bar_ltsymbol.c
+++ /dev/null
@@ -1,17 +0,0 @@
-int
-width_ltsymbol(Bar *bar, BarArg *a)
-{
-	return TEXTW(bar->mon->ltsymbol);
-}
-
-int
-draw_ltsymbol(Bar *bar, BarArg *a)
-{
-	return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, bar->mon->ltsymbol, 0, False);
-}
-
-int
-click_ltsymbol(Bar *bar, Arg *arg, BarArg *a)
-{
-	return ClkLtSymbol;
-}
diff --git a/patch/bar_ltsymbol.h b/patch/bar_ltsymbol.h
deleted file mode 100644
index 4188584..0000000
--- a/patch/bar_ltsymbol.h
+++ /dev/null
@@ -1,3 +0,0 @@
-static int width_ltsymbol(Bar *bar, BarArg *a);
-static int draw_ltsymbol(Bar *bar, BarArg *a);
-static int click_ltsymbol(Bar *bar, Arg *arg, BarArg *a);
diff --git a/patch/bar_status.c b/patch/bar_status.c
deleted file mode 100644
index 19ff219..0000000
--- a/patch/bar_status.c
+++ /dev/null
@@ -1,18 +0,0 @@
-int
-width_status(Bar *bar, BarArg *a)
-{
-	return TEXTWM(stext);
-}
-
-int
-draw_status(Bar *bar, BarArg *a)
-{
-	return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, stext, 0, True);
-}
-
-int
-click_status(Bar *bar, Arg *arg, BarArg *a)
-{
-	return ClkStatusText;
-}
-
diff --git a/patch/bar_status.h b/patch/bar_status.h
deleted file mode 100644
index c580597..0000000
--- a/patch/bar_status.h
+++ /dev/null
@@ -1,4 +0,0 @@
-static int width_status(Bar *bar, BarArg *a);
-static int draw_status(Bar *bar, BarArg *a);
-static int click_status(Bar *bar, Arg *arg, BarArg *a);
-
diff --git a/patch/bar_statuscmd.c b/patch/bar_statuscmd.c
deleted file mode 100644
index 2e74f9f..0000000
--- a/patch/bar_statuscmd.c
+++ /dev/null
@@ -1,44 +0,0 @@
-int
-click_statuscmd(Bar *bar, Arg *arg, BarArg *a)
-{
-	return click_statuscmd_text(arg, a->x, rawstext);
-}
-
-int
-click_statuscmd_text(Arg *arg, int rel_x, char *text)
-{
-	int i = -1;
-	int x = 0;
-	char ch;
-	statussig = -1;
-	while (text[++i]) {
-		if ((unsigned char)text[i] < ' ') {
-			ch = text[i];
-			text[i] = '\0';
-			x += TEXTWM(text) - lrpad;
-			text[i] = ch;
-			text += i+1;
-			i = -1;
-			if (x >= rel_x && statussig != -1)
-				break;
-			statussig = ch;
-		}
-	}
-	if (statussig == -1)
-		statussig = 0;
-	return ClkStatusText;
-}
-
-void
-copyvalidchars(char *text, char *rawtext)
-{
-	int i = -1, j = 0;
-
-	while (rawtext[++i]) {
-		if ((unsigned char)rawtext[i] >= ' ') {
-			text[j++] = rawtext[i];
-		}
-	}
-	text[j] = '\0';
-}
-
diff --git a/patch/bar_statuscmd.h b/patch/bar_statuscmd.h
deleted file mode 100644
index 1ec24a6..0000000
--- a/patch/bar_statuscmd.h
+++ /dev/null
@@ -1,9 +0,0 @@
-static int click_statuscmd(Bar *bar, Arg *arg, BarArg *a);
-static int click_statuscmd_text(Arg *arg, int rel_x, char *text);
-static void copyvalidchars(char *text, char *rawtext);
-
-typedef struct {
-	const char *cmd;
-	int id;
-} StatusCmd;
-
diff --git a/patch/bar_tagicons.c b/patch/bar_tagicons.c
deleted file mode 100644
index 57d1629..0000000
--- a/patch/bar_tagicons.c
+++ /dev/null
@@ -1,9 +0,0 @@
-char *
-tagicon(Monitor *m, int tag)
-{
-	int tagindex = tag + NUMTAGS * m->num;
-	if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS]))
-		tagindex = tagindex % LENGTH(tagicons[DEFAULT_TAGS]);
-	return tagicons[DEFAULT_TAGS][tagindex];
-}
-
diff --git a/patch/bar_tagicons.h b/patch/bar_tagicons.h
deleted file mode 100644
index 16fad2a..0000000
--- a/patch/bar_tagicons.h
+++ /dev/null
@@ -1,8 +0,0 @@
-enum {
-	DEFAULT_TAGS,
-	ALTERNATIVE_TAGS,
-	ALT_TAGS_DECORATION,
-};
-
-static char * tagicon(Monitor *m, int tag);
-
diff --git a/patch/bar_tags.c b/patch/bar_tags.c
deleted file mode 100644
index 8aa37b2..0000000
--- a/patch/bar_tags.c
+++ /dev/null
@@ -1,81 +0,0 @@
-int
-width_tags(Bar *bar, BarArg *a)
-{
-	int w, i;
-	Client *c;
-	unsigned int occ = 0;
-	for (c = bar->mon->clients; c; c = c->next)
-		occ |= c->tags == 255 ? 0 : c->tags;
-
-	for (w = 0, i = 0; i < NUMTAGS; i++) {
-		if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
-			continue;
-		w += TEXTW(tagicon(bar->mon, i));
-	}
-	return w;
-}
-
-int
-draw_tags(Bar *bar, BarArg *a)
-{
-	int invert;
-	int w, x = a->x;
-	unsigned int i, occ = 0, urg = 0;
-	char *icon;
-	Client *c;
-	Monitor *m = bar->mon;
-
-	for (c = m->clients; c; c = c->next) {
-		occ |= c->tags == 255 ? 0 : c->tags;
-		if (c->isurgent)
-			urg |= c->tags;
-	}
-	for (i = 0; i < NUMTAGS; i++) {
-		/* do not draw vacant tags */
-		if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
-			continue;
-
-		icon = tagicon(bar->mon, i);
-		invert = 0;
-		w = TEXTW(icon);
-		drw_setscheme(drw, scheme[
-			m->tagset[m->seltags] & 1 << i
-			? SchemeTagsSel
-			: urg & 1 << i
-			? SchemeUrg
-			: SchemeTagsNorm
-		]);
-		drw_text(drw, x, a->y, w, a->h, lrpad / 2, icon, invert, False);
-		drawindicator(m, NULL, occ, x, a->y, w, a->h, i, -1, invert, tagindicatortype);
-		x += w;
-	}
-
-	return 1;
-}
-
-int
-click_tags(Bar *bar, Arg *arg, BarArg *a)
-{
-	int i = 0, x = 0;
-	Client *c;
-	unsigned int occ = 0;
-	for (c = bar->mon->clients; c; c = c->next)
-		occ |= c->tags == 255 ? 0 : c->tags;
-
-	do {
-		if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
-			continue;
-		x += TEXTW(tagicon(bar->mon, i));
-	} while (a->x >= x && ++i < NUMTAGS);
-	if (i < NUMTAGS) {
-		arg->ui = 1 << i;
-	}
-	return ClkTagBar;
-}
-
-int
-hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev)
-{
-
-	return 1;
-}
diff --git a/patch/bar_tags.h b/patch/bar_tags.h
deleted file mode 100644
index 70040d2..0000000
--- a/patch/bar_tags.h
+++ /dev/null
@@ -1,4 +0,0 @@
-static int width_tags(Bar *bar, BarArg *a);
-static int draw_tags(Bar *bar, BarArg *a);
-static int click_tags(Bar *bar, Arg *arg, BarArg *a);
-static int hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev);
diff --git a/patch/bar_wintitle.c b/patch/bar_wintitle.c
deleted file mode 100644
index 4468f93..0000000
--- a/patch/bar_wintitle.c
+++ /dev/null
@@ -1,49 +0,0 @@
-int
-width_wintitle(Bar *bar, BarArg *a)
-{
-	return a->w;
-}
-
-int
-draw_wintitle(Bar *bar, BarArg *a)
-{
-	int x = a->x, w = a->w;
-	Monitor *m = bar->mon;
-	Client *c = m->sel;
-
-	if (!c) {
-		drw_setscheme(drw, scheme[SchemeTitleNorm]);
-		drw_rect(drw, x, a->y, w, a->h, 1, 1);
-		return 0;
-	}
-
-	int tpad = lrpad / 2;
-	int tx = x;
-	int tw = w;
-
-	drw_setscheme(drw, scheme[m == selmon ? SchemeTitleSel : SchemeTitleNorm]);
-	XSetErrorHandler(xerrordummy);
-
-	if (w <= TEXTW("A") - lrpad + tpad) // reduce text padding if wintitle is too small
-		tpad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2);
-
-	XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel);
-	XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, w, a->h);
-
-	tx += tpad;
-	tw -= lrpad;
-
-	drw_text(drw, tx, a->y, tw, a->h, 0, c->name, 0, False);
-
-	XSync(dpy, False);
-	XSetErrorHandler(xerror);
-	drawstateindicator(m, c, 1, x, a->y, w, a->h, 0, 0, c->isfixed);
-	return 1;
-}
-
-int
-click_wintitle(Bar *bar, Arg *arg, BarArg *a)
-{
-	return ClkWinTitle;
-}
-
diff --git a/patch/bar_wintitle.h b/patch/bar_wintitle.h
deleted file mode 100644
index 7e8cce5..0000000
--- a/patch/bar_wintitle.h
+++ /dev/null
@@ -1,4 +0,0 @@
-static int width_wintitle(Bar *bar, BarArg *a);
-static int draw_wintitle(Bar *bar, BarArg *a);
-static int click_wintitle(Bar *bar, Arg *arg, BarArg *a);
-
diff --git a/patch/cool_autostart.c b/patch/cool_autostart.c
deleted file mode 100644
index 848f5ab..0000000
--- a/patch/cool_autostart.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* dwm will keep pid's of processes from autostart array and kill them at quit */
-static pid_t *autostart_pids;
-static size_t autostart_len;
-
-/* execute command from autostart array */
-static void
-autostart_exec()
-{
-	const char *const *p;
-	struct sigaction sa;
-	size_t i = 0;
-
-	/* count entries */
-	for (p = autostart; *p; autostart_len++, p++)
-		while (*++p);
-
-	autostart_pids = malloc(autostart_len * sizeof(pid_t));
-	for (p = autostart; *p; i++, p++) {
-		if ((autostart_pids[i] = fork()) == 0) {
-			setsid();
-
-			/* Restore SIGCHLD sighandler to default before spawning a program */
-			sigemptyset(&sa.sa_mask);
-			sa.sa_flags = 0;
-			sa.sa_handler = SIG_DFL;
-			sigaction(SIGCHLD, &sa, NULL);
-
-			execvp(*p, (char *const *)p);
-			fprintf(stderr, "dwm: execvp %s\n", *p);
-			perror(" failed");
-			_exit(EXIT_FAILURE);
-		}
-		/* skip arguments */
-		while (*++p);
-	}
-}
-
diff --git a/patch/cool_autostart.h b/patch/cool_autostart.h
deleted file mode 100644
index 5534d99..0000000
--- a/patch/cool_autostart.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void autostart_exec(void);
-
diff --git a/patch/floatpos.c b/patch/floatpos.c
deleted file mode 100644
index d935d23..0000000
--- a/patch/floatpos.c
+++ /dev/null
@@ -1,179 +0,0 @@
-void
-floatpos(const Arg *arg)
-{
-	Client *c = selmon->sel;
-
-	if (!c || (selmon->lt[selmon->sellt]->arrange && !c->isfloating))
-		return;
-
-	setfloatpos(c, (char *)arg->v);
-	resizeclient(c, c->x, c->y, c->w, c->h);
-
-}
-
-void
-setfloatpos(Client *c, const char *floatpos)
-{
-	char xCh, yCh, wCh, hCh;
-	int x, y, w, h, wx, ww, wy, wh;
-
-	if (!c || !floatpos)
-		return;
-	if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
-		return;
-
-	switch(sscanf(floatpos, "%d%c %d%c %d%c %d%c", &x, &xCh, &y, &yCh, &w, &wCh, &h, &hCh)) {
-		case 4:
-			if (xCh == 'w' || xCh == 'W') {
-				w = x; wCh = xCh;
-				h = y; hCh = yCh;
-				x = -1; xCh = 'C';
-				y = -1; yCh = 'C';
-			} else if (xCh == 'p' || xCh == 'P') {
-				w = x; wCh = xCh;
-				h = y; hCh = yCh;
-				x = 0; xCh = 'G';
-				y = 0; yCh = 'G';
-			} else if (xCh == 'm' || xCh == 'M') {
-				getrootptr(&x, &y);
-			} else {
-				w = 0; wCh = 0;
-				h = 0; hCh = 0;
-			}
-			break;
-		case 8:
-			if (xCh == 'm' || xCh == 'M')
-				getrootptr(&x, &y);
-			break;
-		default:
-			return;
-	}
-
-	wx = c->mon->wx;
-	wy = c->mon->wy;
-	ww = c->mon->ww;
-	wh = c->mon->wh;
-
-	getfloatpos(x, xCh, w, wCh, wx, ww, c->x, c->w, c->bw, floatposgrid_x, &c->x, &c->w);
-	getfloatpos(y, yCh, h, hCh, wy, wh, c->y, c->h, c->bw, floatposgrid_y, &c->y, &c->h);
-}
-
-/* p - position, s - size, cp and cs represents current position and size */
-void
-getfloatpos(int pos, char pCh, int size, char sCh, int min_p, int max_s, int cp, int cs, int cbw, int defgrid, int *out_p, int *out_s)
-{
-	int abs_p, abs_s, i, delta, rest;
-
-	abs_p = pCh == 'A' || pCh == 'a';
-	abs_s = sCh == 'A' || sCh == 'a';
-
-	cs += 2*cbw;
-
-	switch(pCh) {
-	case 'A': // absolute position
-		cp = pos;
-		break;
-	case 'a': // absolute relative position
-		cp += pos;
-		break;
-	case 'y':
-	case 'x': // client relative position
-		cp = MIN(cp + pos, min_p + max_s);
-		break;
-	case 'Y':
-	case 'X': // client position relative to monitor
-		cp = min_p + MIN(pos, max_s);
-		break;
-	case 'S': // fixed client position (sticky)
-	case 'C': // fixed client position (center)
-	case 'Z': // fixed client right-hand position (position + size)
-		if (pos == -1)
-			break;
-		pos = MAX(MIN(pos, max_s), 0);
-		if (pCh == 'Z')
-			cs = abs((cp + cs) - (min_p + pos));
-		else if (pCh == 'C')
-			cs = abs((cp + cs / 2) - (min_p + pos));
-		else
-			cs = abs(cp - (min_p + pos));
-		cp = min_p + pos;
-		sCh = 0; // size determined by position, override defined size
-		break;
-	case 'G': // grid
-		if (pos <= 0)
-			pos = defgrid; // default configurable
-		if (size == 0 || pos < 2 || (sCh != 'p' && sCh != 'P'))
-			break;
-		delta = (max_s - cs) / (pos - 1);
-		rest = max_s - cs - delta * (pos - 1);
-		if (sCh == 'P') {
-			if (size < 1 || size > pos)
-				break;
-			cp = min_p + delta * (size - 1);
-		} else {
-			for (i = 0; i < pos && cp >= min_p + delta * i + (i > pos - rest ? i + rest - pos + 1 : 0); i++);
-			cp = min_p + delta * (MAX(MIN(i + size, pos), 1) - 1) + (i > pos - rest ? i + rest - pos + 1 : 0);
-		}
-		break;
-	}
-
-	switch(sCh) {
-	case 'A': // absolute size
-		cs = size;
-		break;
-	case 'a': // absolute relative size
-		cs = MAX(1, cs + size);
-		break;
-	case '%': // client size percentage in relation to monitor window area size
-		if (size <= 0)
-			break;
-		size = max_s * MIN(size, 100) / 100;
-		/* falls through */
-	case 'h':
-	case 'w': // size relative to client
-		if (sCh == 'w' || sCh == 'h') {
-			if (size == 0)
-				break;
-			size += cs;
-		}
-		/* falls through */
-	case 'H':
-	case 'W': // normal size, position takes precedence
-		if (pCh == 'S' && cp + size > min_p + max_s)
-			size = min_p + max_s - cp;
-		else if (size > max_s)
-			size = max_s;
-
-		if (pCh == 'C') { // fixed client center, expand or contract client
-			delta = size - cs;
-			if (delta < 0 || (cp - delta / 2 + size <= min_p + max_s))
-				cp -= delta / 2;
-			else if (cp - delta / 2 < min_p)
-				cp = min_p;
-			else if (delta)
-				cp = min_p + max_s;
-		} else if (pCh == 'Z')
-			cp -= size - cs;
-
-		cs = size;
-		break;
-	}
-
-	if (pCh == '%') // client mid-point position in relation to monitor window area size
-		cp = min_p + max_s * MAX(MIN(pos, 100), 0) / 100 - (cs) / 2;
-	if (pCh == 'm' || pCh == 'M')
-		cp = pos - cs / 2;
-
-	if (!abs_p && cp < min_p)
-		cp = min_p;
-	if (cp + cs > min_p + max_s && !(abs_p && abs_s)) {
-		if (abs_p || cp == min_p)
-			cs = min_p + max_s - cp;
-		else
-			cp = min_p + max_s - cs;
-	}
-
-	*out_p = cp;
-	*out_s = MAX(cs - 2*cbw, 1);
-}
-
diff --git a/patch/floatpos.h b/patch/floatpos.h
deleted file mode 100644
index ecdcf0b..0000000
--- a/patch/floatpos.h
+++ /dev/null
@@ -1,4 +0,0 @@
-static void floatpos(const Arg *arg);
-static void setfloatpos(Client *c, const char *floatpos);
-static void getfloatpos(int pos, char pCh, int size, char sCh, int min_p, int max_s, int cp, int cs, int cbw, int defgrid, int *out_p, int *out_s);
-
diff --git a/patch/include.c b/patch/include.c
deleted file mode 100644
index f376a05..0000000
--- a/patch/include.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Bar functionality */
-#include "bar_indicators.c"
-#include "bar_tagicons.c"
-#include "bar.c"
-
-#include "bar_dwmblocks.c"
-#include "bar_ewmhtags.c"
-#include "bar_ltsymbol.c"
-#include "bar_status.c"
-#include "bar_statuscmd.c"
-#include "bar_tags.c"
-#include "bar_wintitle.c"
-
-/* Other patches */
-#include "attachx.c"
-#include "cool_autostart.c"
-#include "floatpos.c"
-#include "pertag.c"
-#include "restartsig.c"
-#include "renamed_scratchpads.c"
-#include "sizehints_ruled.c"
-#include "stacker.c"
-#include "togglefullscreen.c"
-#include "unfloatvisible.c"
-#include "seamless_restart.c"
-/* Layouts */
-#include "layout_facts.c"
-#include "layout_bstack.c"
-#include "layout_gapplessgrid.c"
-#include "layout_tile.c"
-
diff --git a/patch/include.h b/patch/include.h
deleted file mode 100644
index f9dbd4d..0000000
--- a/patch/include.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Bar functionality */
-#include "bar_indicators.h"
-#include "bar_tagicons.h"
-#include "bar.h"
-
-#include "bar_dwmblocks.h"
-#include "bar_ewmhtags.h"
-#include "bar_ltsymbol.h"
-#include "bar_status.h"
-#include "bar_statuscmd.h"
-#include "bar_tags.h"
-#include "bar_wintitle.h"
-
-/* Other patches */
-#include "attachx.h"
-#include "cool_autostart.h"
-#include "floatpos.h"
-#include "pertag.h"
-#include "restartsig.h"
-#include "renamed_scratchpads.h"
-#include "seamless_restart.h"
-#include "sizehints_ruled.h"
-#include "stacker.h"
-#include "togglefullscreen.h"
-#include "unfloatvisible.h"
-/* Layouts */
-#include "layout_bstack.h"
-#include "layout_gapplessgrid.h"
-#include "layout_tile.h"
-
diff --git a/patch/ipc/IPCClient.h b/patch/ipc/IPCClient.h
deleted file mode 100644
index ee93030..0000000
--- a/patch/ipc/IPCClient.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef IPC_CLIENT_H_
-#define IPC_CLIENT_H_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/epoll.h>
-
-typedef struct IPCClient IPCClient;
-/**
- * This structure contains the details of an IPC Client and pointers for a
- * linked list
- */
-struct IPCClient {
-  int fd;
-  int subscriptions;
-
-  char *buffer;
-  uint32_t buffer_size;
-
-  struct epoll_event event;
-  IPCClient *next;
-  IPCClient *prev;
-};
-
-typedef IPCClient *IPCClientList;
-
-/**
- * Allocate memory for new IPCClient with the specified file descriptor and
- * initialize struct.
- *
- * @param fd File descriptor of IPC client
- *
- * @return Address to allocated IPCClient struct
- */
-IPCClient *ipc_client_new(int fd);
-
-/**
- * Add an IPC Client to the specified list
- *
- * @param list Address of the list to add the client to
- * @param nc Address of the IPCClient
- */
-void ipc_list_add_client(IPCClientList *list, IPCClient *nc);
-
-/**
- * Remove an IPCClient from the specified list
- *
- * @param list Address of the list to remove the client from
- * @param c Address of the IPCClient
- */
-void ipc_list_remove_client(IPCClientList *list, IPCClient *c);
-
-/**
- * Get an IPCClient from the specified IPCClient list
- *
- * @param list List to remove the client from
- * @param fd File descriptor of the IPCClient
- */
-IPCClient *ipc_list_get_client(IPCClientList list, int fd);
-
-#endif  // IPC_CLIENT_H_
-
diff --git a/patch/ipc/dwm-msg.c b/patch/ipc/dwm-msg.c
deleted file mode 100644
index ca1e1a4..0000000
--- a/patch/ipc/dwm-msg.c
+++ /dev/null
@@ -1,549 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <yajl/yajl_gen.h>
-
-#define IPC_MAGIC "DWM-IPC"
-// clang-format off
-#define IPC_MAGIC_ARR { 'D', 'W', 'M', '-', 'I', 'P', 'C' }
-// clang-format on
-#define IPC_MAGIC_LEN 7  // Not including null char
-
-#define IPC_EVENT_TAG_CHANGE "tag_change_event"
-#define IPC_EVENT_CLIENT_FOCUS_CHANGE "client_focus_change_event"
-#define IPC_EVENT_LAYOUT_CHANGE "layout_change_event"
-#define IPC_EVENT_MONITOR_FOCUS_CHANGE "monitor_focus_change_event"
-#define IPC_EVENT_FOCUSED_TITLE_CHANGE "focused_title_change_event"
-#define IPC_EVENT_FOCUSED_STATE_CHANGE "focused_state_change_event"
-
-#define YSTR(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str))
-#define YINT(num) yajl_gen_integer(gen, num)
-#define YDOUBLE(num) yajl_gen_double(gen, num)
-#define YBOOL(v) yajl_gen_bool(gen, v)
-#define YNULL() yajl_gen_null(gen)
-#define YARR(body)                                                             \
-  {                                                                            \
-    yajl_gen_array_open(gen);                                                  \
-    body;                                                                      \
-    yajl_gen_array_close(gen);                                                 \
-  }
-#define YMAP(body)                                                             \
-  {                                                                            \
-    yajl_gen_map_open(gen);                                                    \
-    body;                                                                      \
-    yajl_gen_map_close(gen);                                                   \
-  }
-
-typedef unsigned long Window;
-
-const char *DEFAULT_SOCKET_PATH = "/tmp/dwm.sock";
-static int sock_fd = -1;
-static unsigned int ignore_reply = 0;
-
-typedef enum IPCMessageType {
-  IPC_TYPE_RUN_COMMAND = 0,
-  IPC_TYPE_GET_MONITORS = 1,
-  IPC_TYPE_GET_TAGS = 2,
-  IPC_TYPE_GET_LAYOUTS = 3,
-  IPC_TYPE_GET_DWM_CLIENT = 4,
-  IPC_TYPE_SUBSCRIBE = 5,
-  IPC_TYPE_EVENT = 6
-} IPCMessageType;
-
-// Every IPC message must begin with this
-typedef struct dwm_ipc_header {
-  uint8_t magic[IPC_MAGIC_LEN];
-  uint32_t size;
-  uint8_t type;
-} __attribute((packed)) dwm_ipc_header_t;
-
-static int
-recv_message(uint8_t *msg_type, uint32_t *reply_size, uint8_t **reply)
-{
-  uint32_t read_bytes = 0;
-  const int32_t to_read = sizeof(dwm_ipc_header_t);
-  char header[to_read];
-  char *walk = header;
-
-  // Try to read header
-  while (read_bytes < to_read) {
-    ssize_t n = read(sock_fd, header + read_bytes, to_read - read_bytes);
-
-    if (n == 0) {
-      if (read_bytes == 0) {
-        fprintf(stderr, "Unexpectedly reached EOF while reading header.");
-        fprintf(stderr,
-                "Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n",
-                read_bytes, to_read);
-        return -2;
-      } else {
-        fprintf(stderr, "Unexpectedly reached EOF while reading header.");
-        fprintf(stderr,
-                "Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n",
-                read_bytes, to_read);
-        return -3;
-      }
-    } else if (n == -1) {
-      return -1;
-    }
-
-    read_bytes += n;
-  }
-
-  // Check if magic string in header matches
-  if (memcmp(walk, IPC_MAGIC, IPC_MAGIC_LEN) != 0) {
-    fprintf(stderr, "Invalid magic string. Got '%.*s', expected '%s'\n",
-            IPC_MAGIC_LEN, walk, IPC_MAGIC);
-    return -3;
-  }
-
-  walk += IPC_MAGIC_LEN;
-
-  // Extract reply size
-  memcpy(reply_size, walk, sizeof(uint32_t));
-  walk += sizeof(uint32_t);
-
-  // Extract message type
-  memcpy(msg_type, walk, sizeof(uint8_t));
-  walk += sizeof(uint8_t);
-
-  (*reply) = malloc(*reply_size);
-
-  // Extract payload
-  read_bytes = 0;
-  while (read_bytes < *reply_size) {
-    ssize_t n = read(sock_fd, *reply + read_bytes, *reply_size - read_bytes);
-
-    if (n == 0) {
-      fprintf(stderr, "Unexpectedly reached EOF while reading payload.");
-      fprintf(stderr, "Read %" PRIu32 " bytes, expected %" PRIu32 " bytes.\n",
-              read_bytes, *reply_size);
-      free(*reply);
-      return -2;
-    } else if (n == -1) {
-      if (errno == EINTR || errno == EAGAIN) continue;
-      free(*reply);
-      return -1;
-    }
-
-    read_bytes += n;
-  }
-
-  return 0;
-}
-
-static int
-read_socket(IPCMessageType *msg_type, uint32_t *msg_size, char **msg)
-{
-  int ret = -1;
-
-  while (ret != 0) {
-    ret = recv_message((uint8_t *)msg_type, msg_size, (uint8_t **)msg);
-
-    if (ret < 0) {
-      // Try again (non-fatal error)
-      if (ret == -1 && (errno == EINTR || errno == EAGAIN)) continue;
-
-      fprintf(stderr, "Error receiving response from socket. ");
-      fprintf(stderr, "The connection might have been lost.\n");
-      exit(2);
-    }
-  }
-
-  return 0;
-}
-
-static ssize_t
-write_socket(const void *buf, size_t count)
-{
-  size_t written = 0;
-
-  while (written < count) {
-    const ssize_t n =
-        write(sock_fd, ((uint8_t *)buf) + written, count - written);
-
-    if (n == -1) {
-      if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
-        continue;
-      else
-        return n;
-    }
-    written += n;
-  }
-  return written;
-}
-
-static void
-connect_to_socket()
-{
-  struct sockaddr_un addr;
-
-  int sock = socket(AF_UNIX, SOCK_STREAM, 0);
-
-  // Initialize struct to 0
-  memset(&addr, 0, sizeof(struct sockaddr_un));
-
-  addr.sun_family = AF_UNIX;
-  strcpy(addr.sun_path, DEFAULT_SOCKET_PATH);
-
-  connect(sock, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un));
-
-  sock_fd = sock;
-}
-
-static int
-send_message(IPCMessageType msg_type, uint32_t msg_size, uint8_t *msg)
-{
-  dwm_ipc_header_t header = {
-      .magic = IPC_MAGIC_ARR, .size = msg_size, .type = msg_type};
-
-  size_t header_size = sizeof(dwm_ipc_header_t);
-  size_t total_size = header_size + msg_size;
-
-  uint8_t buffer[total_size];
-
-  // Copy header to buffer
-  memcpy(buffer, &header, header_size);
-  // Copy message to buffer
-  memcpy(buffer + header_size, msg, header.size);
-
-  write_socket(buffer, total_size);
-
-  return 0;
-}
-
-static int
-is_float(const char *s)
-{
-  size_t len = strlen(s);
-  int is_dot_used = 0;
-  int is_minus_used = 0;
-
-  // Floats can only have one decimal point in between or digits
-  // Optionally, floats can also be below zero (negative)
-  for (int i = 0; i < len; i++) {
-    if (isdigit(s[i]))
-      continue;
-    else if (!is_dot_used && s[i] == '.' && i != 0 && i != len - 1) {
-      is_dot_used = 1;
-      continue;
-    } else if (!is_minus_used && s[i] == '-' && i == 0) {
-      is_minus_used = 1;
-      continue;
-    } else
-      return 0;
-  }
-
-  return 1;
-}
-
-static int
-is_unsigned_int(const char *s)
-{
-  size_t len = strlen(s);
-
-  // Unsigned int can only have digits
-  for (int i = 0; i < len; i++) {
-    if (isdigit(s[i]))
-      continue;
-    else
-      return 0;
-  }
-
-  return 1;
-}
-
-static int
-is_signed_int(const char *s)
-{
-  size_t len = strlen(s);
-
-  // Signed int can only have digits and a negative sign at the start
-  for (int i = 0; i < len; i++) {
-    if (isdigit(s[i]))
-      continue;
-    else if (i == 0 && s[i] == '-') {
-      continue;
-    } else
-      return 0;
-  }
-
-  return 1;
-}
-
-static void
-flush_socket_reply()
-{
-  IPCMessageType reply_type;
-  uint32_t reply_size;
-  char *reply;
-
-  read_socket(&reply_type, &reply_size, &reply);
-
-  free(reply);
-}
-
-static void
-print_socket_reply()
-{
-  IPCMessageType reply_type;
-  uint32_t reply_size;
-  char *reply;
-
-  read_socket(&reply_type, &reply_size, &reply);
-
-  printf("%.*s\n", reply_size, reply);
-  fflush(stdout);
-  free(reply);
-}
-
-static int
-run_command(const char *name, char *args[], int argc)
-{
-  const unsigned char *msg;
-  size_t msg_size;
-
-  yajl_gen gen = yajl_gen_alloc(NULL);
-
-  // Message format:
-  // {
-  //   "command": "<name>",
-  //   "args": [ ... ]
-  // }
-  // clang-format off
-  YMAP(
-    YSTR("command"); YSTR(name);
-    YSTR("args"); YARR(
-      for (int i = 0; i < argc; i++) {
-        if (is_signed_int(args[i])) {
-          long long num = atoll(args[i]);
-          YINT(num);
-        } else if (is_float(args[i])) {
-          float num = atof(args[i]);
-          YDOUBLE(num);
-        } else {
-          YSTR(args[i]);
-        }
-      }
-    )
-  )
-  // clang-format on
-
-  yajl_gen_get_buf(gen, &msg, &msg_size);
-
-  send_message(IPC_TYPE_RUN_COMMAND, msg_size, (uint8_t *)msg);
-
-  if (!ignore_reply)
-    print_socket_reply();
-  else
-    flush_socket_reply();
-
-  yajl_gen_free(gen);
-
-  return 0;
-}
-
-static int
-get_monitors()
-{
-  send_message(IPC_TYPE_GET_MONITORS, 1, (uint8_t *)"");
-  print_socket_reply();
-  return 0;
-}
-
-static int
-get_tags()
-{
-  send_message(IPC_TYPE_GET_TAGS, 1, (uint8_t *)"");
-  print_socket_reply();
-
-  return 0;
-}
-
-static int
-get_layouts()
-{
-  send_message(IPC_TYPE_GET_LAYOUTS, 1, (uint8_t *)"");
-  print_socket_reply();
-
-  return 0;
-}
-
-static int
-get_dwm_client(Window win)
-{
-  const unsigned char *msg;
-  size_t msg_size;
-
-  yajl_gen gen = yajl_gen_alloc(NULL);
-
-  // Message format:
-  // {
-  //   "client_window_id": "<win>"
-  // }
-  // clang-format off
-  YMAP(
-    YSTR("client_window_id"); YINT(win);
-  )
-  // clang-format on
-
-  yajl_gen_get_buf(gen, &msg, &msg_size);
-
-  send_message(IPC_TYPE_GET_DWM_CLIENT, msg_size, (uint8_t *)msg);
-
-  print_socket_reply();
-
-  yajl_gen_free(gen);
-
-  return 0;
-}
-
-static int
-subscribe(const char *event)
-{
-  const unsigned char *msg;
-  size_t msg_size;
-
-  yajl_gen gen = yajl_gen_alloc(NULL);
-
-  // Message format:
-  // {
-  //   "event": "<event>",
-  //   "action": "subscribe"
-  // }
-  // clang-format off
-  YMAP(
-    YSTR("event"); YSTR(event);
-    YSTR("action"); YSTR("subscribe");
-  )
-  // clang-format on
-
-  yajl_gen_get_buf(gen, &msg, &msg_size);
-
-  send_message(IPC_TYPE_SUBSCRIBE, msg_size, (uint8_t *)msg);
-
-  if (!ignore_reply)
-    print_socket_reply();
-  else
-    flush_socket_reply();
-
-  yajl_gen_free(gen);
-
-  return 0;
-}
-
-static void
-usage_error(const char *prog_name, const char *format, ...)
-{
-  va_list args;
-  va_start(args, format);
-
-  fprintf(stderr, "Error: ");
-  vfprintf(stderr, format, args);
-  fprintf(stderr, "\nusage: %s <command> [...]\n", prog_name);
-  fprintf(stderr, "Try '%s help'\n", prog_name);
-
-  va_end(args);
-  exit(1);
-}
-
-static void
-print_usage(const char *name)
-{
-  printf("usage: %s [options] <command> [...]\n", name);
-  puts("");
-  puts("Commands:");
-  puts("  run_command <name> [args...]    Run an IPC command");
-  puts("");
-  puts("  get_monitors                    Get monitor properties");
-  puts("");
-  puts("  get_tags                        Get list of tags");
-  puts("");
-  puts("  get_layouts                     Get list of layouts");
-  puts("");
-  puts("  get_dwm_client <window_id>      Get dwm client proprties");
-  puts("");
-  puts("  subscribe [events...]           Subscribe to specified events");
-  puts("                                  Options: " IPC_EVENT_TAG_CHANGE ",");
-  puts("                                  " IPC_EVENT_LAYOUT_CHANGE ",");
-  puts("                                  " IPC_EVENT_CLIENT_FOCUS_CHANGE ",");
-  puts("                                  " IPC_EVENT_MONITOR_FOCUS_CHANGE ",");
-  puts("                                  " IPC_EVENT_FOCUSED_TITLE_CHANGE ",");
-  puts("                                  " IPC_EVENT_FOCUSED_STATE_CHANGE);
-  puts("");
-  puts("  help                            Display this message");
-  puts("");
-  puts("Options:");
-  puts("  --ignore-reply                  Don't print reply messages from");
-  puts("                                  run_command and subscribe.");
-  puts("");
-}
-
-int
-main(int argc, char *argv[])
-{
-  const char *prog_name = argv[0];
-
-  connect_to_socket();
-  if (sock_fd == -1) {
-    fprintf(stderr, "Failed to connect to socket\n");
-    return 1;
-  }
-
-  int i = 1;
-  if (i < argc && strcmp(argv[i], "--ignore-reply") == 0) {
-    ignore_reply = 1;
-    i++;
-  }
-
-  if (i >= argc) usage_error(prog_name, "Expected an argument, got none");
-
-  if (!argc || strcmp(argv[i], "help") == 0)
-    print_usage(prog_name);
-  else if (strcmp(argv[i], "run_command") == 0) {
-    if (++i >= argc) usage_error(prog_name, "No command specified");
-    // Command name
-    char *command = argv[i];
-    // Command arguments are everything after command name
-    char **command_args = argv + ++i;
-    // Number of command arguments
-    int command_argc = argc - i;
-    run_command(command, command_args, command_argc);
-  } else if (strcmp(argv[i], "get_monitors") == 0) {
-    get_monitors();
-  } else if (strcmp(argv[i], "get_tags") == 0) {
-    get_tags();
-  } else if (strcmp(argv[i], "get_layouts") == 0) {
-    get_layouts();
-  } else if (strcmp(argv[i], "get_dwm_client") == 0) {
-    if (++i < argc) {
-      if (is_unsigned_int(argv[i])) {
-        Window win = atol(argv[i]);
-        get_dwm_client(win);
-      } else
-        usage_error(prog_name, "Expected unsigned integer argument");
-    } else
-      usage_error(prog_name, "Expected the window id");
-  } else if (strcmp(argv[i], "subscribe") == 0) {
-    if (++i < argc) {
-      for (int j = i; j < argc; j++) subscribe(argv[j]);
-    } else
-      usage_error(prog_name, "Expected event name");
-    // Keep listening for events forever
-    while (1) {
-      print_socket_reply();
-    }
-  } else
-    usage_error(prog_name, "Invalid argument '%s'", argv[i]);
-
-  return 0;
-}
-
diff --git a/patch/ipc/yajl_dumps.h b/patch/ipc/yajl_dumps.h
deleted file mode 100644
index bb57a17..0000000
--- a/patch/ipc/yajl_dumps.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef YAJL_DUMPS_H_
-#define YAJL_DUMPS_H_
-
-#include <string.h>
-#include <yajl/yajl_gen.h>
-
-#define YSTR(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str))
-#define YINT(num) yajl_gen_integer(gen, num)
-#define YDOUBLE(num) yajl_gen_double(gen, num)
-#define YBOOL(v) yajl_gen_bool(gen, v)
-#define YNULL() yajl_gen_null(gen)
-#define YARR(body)                                                             \
-  {                                                                            \
-    yajl_gen_array_open(gen);                                                  \
-    body;                                                                      \
-    yajl_gen_array_close(gen);                                                 \
-  }
-#define YMAP(body)                                                             \
-  {                                                                            \
-    yajl_gen_map_open(gen);                                                    \
-    body;                                                                      \
-    yajl_gen_map_close(gen);                                                   \
-  }
-
-int dump_tag(yajl_gen gen, const char *name, const int tag_mask);
-
-int dump_tags(yajl_gen gen, int tags_len);
-
-int dump_client(yajl_gen gen, Client *c);
-
-int dump_monitor(yajl_gen gen, Monitor *mon, int is_selected);
-
-int dump_monitors(yajl_gen gen, Monitor *mons, Monitor *selmon);
-
-int dump_layouts(yajl_gen gen, const Layout layouts[], const int layouts_len);
-
-int dump_tag_state(yajl_gen gen, TagState state);
-
-int dump_tag_event(yajl_gen gen, int mon_num, TagState old_state,
-                   TagState new_state);
-
-int dump_client_focus_change_event(yajl_gen gen, Client *old_client,
-                                   Client *new_client, int mon_num);
-
-int dump_layout_change_event(yajl_gen gen, const int mon_num,
-                             const char *old_symbol, const Layout *old_layout,
-                             const char *new_symbol, const Layout *new_layout);
-
-int dump_monitor_focus_change_event(yajl_gen gen, const int last_mon_num,
-                                    const int new_mon_num);
-
-int dump_focused_title_change_event(yajl_gen gen, const int mon_num,
-                                    const Window client_id,
-                                    const char *old_name, const char *new_name);
-
-int dump_client_state(yajl_gen gen, const ClientState *state);
-
-int dump_focused_state_change_event(yajl_gen gen, const int mon_num,
-                                    const Window client_id,
-                                    const ClientState *old_state,
-                                    const ClientState *new_state);
-
-int dump_error_message(yajl_gen gen, const char *reason);
-
-#endif  // YAJL_DUMPS_H_
-
diff --git a/patch/layout_bstack.c b/patch/layout_bstack.c
deleted file mode 100644
index e72c57c..0000000
--- a/patch/layout_bstack.c
+++ /dev/null
@@ -1,39 +0,0 @@
-static void
-bstack(Monitor *m)
-{
-	unsigned int i, n;
-	int mx = 0, my = 0, mh = 0, mw = 0;
-	int sx = 0, sy = 0, sh = 0, sw = 0;
-	float mfacts, sfacts;
-	int mrest, srest;
-	Client *c;
-
-	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
-
-	if (n == 0)
-		return;
-
-	sx = mx = m->wx;
-	sy = my = m->wy;
-	sh = mh = m->wh;
-	sw = mw = m->ww;
-
-	if (m->nmaster && n > m->nmaster) {
-		sh = mh * (1 - m->mfact);
-		mh = mh * m->mfact;
-		sy = my + mh;
-	}
-
-	getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
-
-	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
-		if (i < m->nmaster) {
-			resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
-			mx += WIDTH(c);
-		} else {
-			resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
-			sx += WIDTH(c);
-		}
-	}
-}
-
diff --git a/patch/layout_bstack.h b/patch/layout_bstack.h
deleted file mode 100644
index 07e8c0a..0000000
--- a/patch/layout_bstack.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void bstack(Monitor *m);
-
diff --git a/patch/layout_facts.c b/patch/layout_facts.c
deleted file mode 100644
index 241d344..0000000
--- a/patch/layout_facts.c
+++ /dev/null
@@ -1,24 +0,0 @@
-void
-getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
-{
-	unsigned int n;
-	float mfacts, sfacts;
-	int mtotal = 0, stotal = 0;
-	Client *c;
-
-	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
-	mfacts = MIN(n, m->nmaster);
-	sfacts = n - m->nmaster;
-
-	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
-		if (n < m->nmaster)
-			mtotal += msize / mfacts;
-		else
-			stotal += ssize / sfacts;
-
-	*mf = mfacts; // total factor of master area
-	*sf = sfacts; // total factor of stack area
-	*mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
-	*sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
-}
-
diff --git a/patch/layout_gapplessgrid.c b/patch/layout_gapplessgrid.c
deleted file mode 100644
index ce23d5a..0000000
--- a/patch/layout_gapplessgrid.c
+++ /dev/null
@@ -1,48 +0,0 @@
-void
-gaplessgrid(Monitor *m)
-{
-	unsigned int i, n;
-	int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
-	Client *c;
-
-	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
-	if (n == 0)
-		return;
-
-	/* grid dimensions */
-	for (cols = 0; cols <= n/2; cols++)
-		if (cols*cols >= n)
-			break;
-	if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
-		cols = 2;
-	rows = n/cols;
-	cn = rn = 0; // reset column no, row no, client count
-
-	ch = m->wh / rows;
-	cw = m->ww / cols;
-	rrest = m->wh - ch * rows;
-	crest = m->ww - cw * cols;
-	x = m->wx;
-	y = m->wy;
-
-	for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
-		if (i/rows + 1 > cols - n%cols) {
-			rows = n/cols + 1;
-			ch = m->wh / rows;
-			rrest = m->wh - ch * rows;
-		}
-		resize(c,
-			x,
-			y + rn*ch + MIN(rn, rrest),
-			cw + (cn < crest ? 1 : 0) - 2*c->bw,
-			ch + (rn < rrest ? 1 : 0) - 2*c->bw,
-			0);
-		rn++;
-		if (rn >= rows) {
-			rn = 0;
-			x += cw + (cn < crest ? 1 : 0);
-			cn++;
-		}
-	}
-}
-
diff --git a/patch/layout_gapplessgrid.h b/patch/layout_gapplessgrid.h
deleted file mode 100644
index 1a4ffc2..0000000
--- a/patch/layout_gapplessgrid.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void gaplessgrid(Monitor *m);
-
diff --git a/patch/layout_tile.c b/patch/layout_tile.c
deleted file mode 100644
index 76b0078..0000000
--- a/patch/layout_tile.c
+++ /dev/null
@@ -1,38 +0,0 @@
-static void
-tile(Monitor *m)
-{
-	unsigned int i, n;
-	int mx = 0, my = 0, mh = 0, mw = 0;
-	int sx = 0, sy = 0, sh = 0, sw = 0;
-	float mfacts, sfacts;
-	int mrest, srest;
-	Client *c;
-
-	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
-
-	if (n == 0)
-		return;
-
-	sx = mx = m->wx;
-	sy = my = m->wy;
-	sh = mh = m->wh;
-	sw = mw = m->ww;
-
-	if (m->nmaster && n > m->nmaster) {
-		sw = mw * (1 - m->mfact);
-		mw = mw * m->mfact;
-		sx = mx + mw;
-	}
-
-	getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
-
-	for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
-		if (i < m->nmaster) {
-			resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
-			my += HEIGHT(c);
-		} else {
-			resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
-			sy += HEIGHT(c);
-		}
-}
-
diff --git a/patch/layout_tile.h b/patch/layout_tile.h
deleted file mode 100644
index 4aff634..0000000
--- a/patch/layout_tile.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void tile(Monitor *m);
-
diff --git a/patch/pertag.c b/patch/pertag.c
deleted file mode 100644
index c5f7f92..0000000
--- a/patch/pertag.c
+++ /dev/null
@@ -1,28 +0,0 @@
-struct Pertag {
-	unsigned int curtag; /* current tag index */
-	int nmasters[NUMTAGS + 1]; /* number of windows in master area */
-	const Layout *ltidxs[NUMTAGS + 1][2]; /* matrix of tags and layouts indexes  */
-	float mfacts[NUMTAGS + 1]; /* mfacts per tag */
-	unsigned int sellts[NUMTAGS + 1]; /* selected layouts */
-};
-
-void
-pertagview(const Arg *arg)
-{
-	int i;
-
-	if (arg->ui == ~0)
-		selmon->pertag->curtag = 0;
-	else {
-		for (i = 0; !(selmon->tagset[selmon->seltags] & 1 << i); i++);
-		selmon->pertag->curtag = i + 1;
-	}
-
-	selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
-	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
-	selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
-	selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
-	selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
-
-}
-
diff --git a/patch/pertag.h b/patch/pertag.h
deleted file mode 100644
index 5c53ac9..0000000
--- a/patch/pertag.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void pertagview(const Arg *arg);
-
diff --git a/patch/renamed_scratchpads.c b/patch/renamed_scratchpads.c
deleted file mode 100644
index 1a41e22..0000000
--- a/patch/renamed_scratchpads.c
+++ /dev/null
@@ -1,144 +0,0 @@
-void
-removescratch(const Arg *arg)
-{
-	Client *c = selmon->sel;
-	if (!c)
-		return;
-	c->scratchkey = 0;
-}
-
-void
-setscratch(const Arg *arg)
-{
-	Client *c = selmon->sel;
-	if (!c)
-		return;
-
-	c->scratchkey = ((char**)arg->v)[0][0];
-}
-
-void spawnscratch(const Arg *arg)
-{
-	if (fork() == 0) {
-		if (dpy)
-			close(ConnectionNumber(dpy));
-		setsid();
-		execvp(((char **)arg->v)[1], ((char **)arg->v)+1);
-		fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]);
-		perror(" failed");
-		exit(EXIT_SUCCESS);
-	}
-}
-
-void
-togglescratch(const Arg *arg)
-{
-	Client *c, *next, *last = NULL, *found = NULL, *monclients = NULL;
-	Monitor *mon;
-	int scratchvisible = 0; // whether the scratchpads are currently visible or not
-	int multimonscratch = 0; // whether we have scratchpads that are placed on multiple monitors
-	int scratchmon = -1; // the monitor where the scratchpads exist
-	int numscratchpads = 0; // count of scratchpads
-
-	/* Looping through monitors and client's twice, the first time to work out whether we need
-	   to move clients across from one monitor to another or not */
-	for (mon = mons; mon; mon = mon->next)
-		for (c = mon->clients; c; c = c->next) {
-			if (c->scratchkey != ((char**)arg->v)[0][0])
-				continue;
-			if (scratchmon != -1 && scratchmon != mon->num)
-				multimonscratch = 1;
-			if (c->mon->tagset[c->mon->seltags] & c->tags) // && !HIDDEN(c)
-				++scratchvisible;
-			scratchmon = mon->num;
-			++numscratchpads;
-		}
-
-	/* Now for the real deal. The logic should go like:
-	    - hidden scratchpads will be shown
-	    - shown scratchpads will be hidden, unless they are being moved to the current monitor
-	    - the scratchpads will be moved to the current monitor if they all reside on the same monitor
-	    - multiple scratchpads residing on separate monitors will be left in place
-	 */
-	for (mon = mons; mon; mon = mon->next) {
-		for (c = mon->stack; c; c = next) {
-			next = c->snext;
-			if (c->scratchkey != ((char**)arg->v)[0][0])
-				continue;
-
-			/* Record the first found scratchpad client for focus purposes, but prioritise the
-			   scratchpad on the current monitor if one exists */
-			if (!found || (mon == selmon && found->mon != selmon))
-				found = c;
-
-			/* If scratchpad clients reside on another monitor and we are moving them across then
-			   as we are looping through monitors we could be moving a client to a monitor that has
-			   not been processed yet, hence we could be processing a scratchpad twice. To avoid
-			   this we detach them and add them to a temporary list (monclients) which is to be
-			   processed later. */
-			if (!multimonscratch && c->mon != selmon) {
-				detach(c);
-				detachstack(c);
-				c->next = NULL;
-				/* Note that we are adding clients at the end of the list, this is to preserve the
-				   order of clients as they were on the adjacent monitor (relevant when tiled) */
-				if (last)
-					last = last->next = c;
-				else
-					last = monclients = c;
-			} else if (scratchvisible == numscratchpads) {
-				c->tags = 0;
-			} else {
-				XSetWindowBorder(dpy, c->win, scheme[SchemeScratchNorm][ColBorder].pixel);
-				c->tags = c->mon->tagset[c->mon->seltags];
-				if (c->isfloating)
-					XRaiseWindow(dpy, c->win);
-			}
-		}
-	}
-
-	/* Attach moved scratchpad clients on the selected monitor */
-	for (c = monclients; c; c = next) {
-		next = c->next;
-		mon = c->mon;
-		c->mon = selmon;
-		c->tags = selmon->tagset[selmon->seltags];
-		/* Attach scratchpad clients from other monitors at the bottom of the stack */
-		if (selmon->clients) {
-			for (last = selmon->clients; last && last->next; last = last->next);
-			last->next = c;
-		} else
-			selmon->clients = c;
-		c->next = NULL;
-		attachstack(c);
-
-		/* Center floating scratchpad windows when moved from one monitor to another */
-		if (c->isfloating) {
-			if (c->w > selmon->ww)
-				c->w = selmon->ww - c->bw * 2;
-			if (c->h > selmon->wh)
-				c->h = selmon->wh - c->bw * 2;
-
-			if (numscratchpads > 1) {
-				c->x = c->mon->wx + (c->x - mon->wx) * ((double)(abs(c->mon->ww - WIDTH(c))) / MAX(abs(mon->ww - WIDTH(c)), 1));
-				c->y = c->mon->wy + (c->y - mon->wy) * ((double)(abs(c->mon->wh - HEIGHT(c))) / MAX(abs(mon->wh - HEIGHT(c)), 1));
-			} else if (c->x < c->mon->mx || c->x > c->mon->mx + c->mon->mw ||
-			           c->y < c->mon->my || c->y > c->mon->my + c->mon->mh)	{
-				c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
-				c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
-			}
-			resizeclient(c, c->x, c->y, c->w, c->h);
-			XRaiseWindow(dpy, c->win);
-		}
-	}
-
-	if (found) {
-		focus(ISVISIBLE(found) ? found : NULL);
-		arrange(NULL);
-		if (found->isfloating)
-			XRaiseWindow(dpy, found->win);
-	} else {
-		spawnscratch(arg);
-	}
-}
-
diff --git a/patch/renamed_scratchpads.h b/patch/renamed_scratchpads.h
deleted file mode 100644
index 3260462..0000000
--- a/patch/renamed_scratchpads.h
+++ /dev/null
@@ -1,4 +0,0 @@
-static void removescratch(const Arg *arg);
-static void setscratch(const Arg *arg);
-static void spawnscratch(const Arg *arg);
-static void togglescratch(const Arg *arg);
diff --git a/patch/restartsig.c b/patch/restartsig.c
deleted file mode 100644
index adb61b5..0000000
--- a/patch/restartsig.c
+++ /dev/null
@@ -1,16 +0,0 @@
-static int restart = 0;
-
-void
-sighup(int unused)
-{
-	Arg a = {.i = 1};
-	quit(&a);
-}
-
-void
-sigterm(int unused)
-{
-	Arg a = {.i = 0};
-	quit(&a);
-}
-
diff --git a/patch/restartsig.h b/patch/restartsig.h
deleted file mode 100644
index b16975b..0000000
--- a/patch/restartsig.h
+++ /dev/null
@@ -1,3 +0,0 @@
-static void sighup(int unused);
-static void sigterm(int unused);
-
diff --git a/patch/seamless_restart.c b/patch/seamless_restart.c
deleted file mode 100644
index dd3c157..0000000
--- a/patch/seamless_restart.c
+++ /dev/null
@@ -1,314 +0,0 @@
-void
-persistmonitorstate(Monitor *m)
-{
-	Client *c;
-	unsigned int i;
-
-	setmonitortags(m);
-	setmonitorfields(m);
-
-	/* Set client atoms */
-	for (i = 1, c = m->clients; c; c = c->next, ++i) {
-		c->idx = i;
-		persistclientstate(c);
-	}
-}
-
-int
-restoremonitorstate(Monitor *m)
-{
-	return getmonitortags(m) | getmonitorfields(m);
-}
-
-void
-persistclientstate(Client *c)
-{
-	setclienttags(c);
-	setclientfields(c);
-	savewindowfloatposition(c, c->mon);
-}
-
-int
-restoreclientstate(Client *c)
-{
-	int restored = getclientfields(c);
-	getclienttags(c);
-	restorewindowfloatposition(c, c->mon ? c->mon : selmon);
-	return restored;
-}
-
-void setmonitorfields(Monitor *m)
-{
-	unsigned int i;
-	char atom[22] = {0};
-	Atom monitor_fields;
-
-	sprintf(atom, "_DWM_MONITOR_FIELDS_%u", m->num);
-	monitor_fields = XInternAtom(dpy, atom, False);
-
-	/* Perists workspace information in 32 bits laid out like this:
-	 *
-	 * |0|0000|0|0000|0000|0000|0000|0000|000|000
-	 * | |    | |    |    |    |    |    |   |-- nmaster
-	 * | |    | |    |    |    |    |    |-- nstack
-	 * | |    | |    |    |    |    |-- layout
-	 * | |    | |    |    |    |-- flextile LAYOUT (split)
-	 * | |    | |    |    |-- flextile MASTER
-	 * | |    | |    |-- flextile STACK1
-	 * | |    | |-- flextile STACK2
-	 * | |    |-- flextile mirror layout (indicated by negative layout)
-	 * | |
-	 * | |-- reserved
-	 * |-- showbar
-	 */
-	for (i = 0; i <= NUMTAGS; i++) {
-		uint32_t data[] = {
-			(m->pertag->nmasters[i] & 0x7) |
-			(getlayoutindex(m->pertag->ltidxs[i][m->pertag->sellts[i]]) & 0xF) << 6 |
-			m->showbar << 31
-		};
-
-		XChangeProperty(dpy, root, monitor_fields, XA_CARDINAL, 32,
-			i ? PropModeAppend : PropModeReplace, (unsigned char *)data, 1);
-	}
-}
-
-int
-getlayoutindex(const Layout *layout)
-{
-	int i;
-
-	for (i = 0; i < LENGTH(layouts) && &layouts[i] != layout; i++);
-	if (i == LENGTH(layouts))
-		i = 0;
-	return i;
-}
-
-int
-getmonitorfields(Monitor *m)
-{
-	int di, layout_index;
-	unsigned int i, restored = 0;
-	unsigned int tags = m->tagset[m->seltags] << 1;
-	unsigned long dl, nitems;
-	unsigned char *p = NULL;
-	char atom[22] = {0};
-	Atom da, state = None;
-
-	sprintf(atom, "_DWM_MONITOR_FIELDS_%u", m->num);
-	Atom dwm_monitor = XInternAtom(dpy, atom, False);
-	if (!dwm_monitor)
-		return 0;
-
-	for (i = 0; i <= NUMTAGS; i++) {
-		if (!(XGetWindowProperty(dpy, root, dwm_monitor, i, (NUMTAGS + 1) * sizeof dl,
-				False, AnyPropertyType, &da, &di, &nitems, &dl, &p) == Success && p)) {
-			break;
-		}
-
-		if (!nitems) {
-			XFree(p);
-			break;
-		}
-
-		/* See bit layout in the persistmonitorstate function */
-		state = *(Atom *)p;
-
-		m->pertag->nmasters[i] = state & 0x7;
-		layout_index = (state >> 6) & 0xF;
-		if (layout_index < LENGTH(layouts))
-			m->pertag->ltidxs[i][m->pertag->sellts[i]] = &layouts[layout_index];
-
-		if (!restored && i && (tags & (1 << i))) {
-			m->nmaster = m->pertag->nmasters[i];
-			m->sellt = m->pertag->sellts[i];
-			m->lt[m->sellt] = m->pertag->ltidxs[i][m->sellt];
-			m->showbar = (state >> 31) & 0x1;
-			restored = 1;
-		}
-
-		XFree(p);
-	}
-
-	return restored;
-}
-
-void
-setmonitortags(Monitor *m)
-{
-	char atom[22] = {0};
-	Atom monitor_tags;
-
-	sprintf(atom, "_DWM_MONITOR_TAGS_%u", m->num);
-	monitor_tags = XInternAtom(dpy, atom, False);
-
-	uint32_t data[] = { m->tagset[m->seltags] };
-	XChangeProperty(dpy, root, monitor_tags, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
-}
-
-int
-getmonitortags(Monitor *m)
-{
-	int di;
-	unsigned long dl, nitems;
-	unsigned char *p = NULL;
-	char atom[22] = {0};
-	Atom da, monitor_tags = None, tags;
-
-	sprintf(atom, "_DWM_MONITOR_TAGS_%u", m->num);
-	monitor_tags = XInternAtom(dpy, atom, False);
-
-	if (!(XGetWindowProperty(dpy, root, monitor_tags, 0L, sizeof dl,
-			False, AnyPropertyType, &da, &di, &nitems, &dl, &p) == Success && p)) {
-		return 0;
-	}
-
-	if (nitems) {
-		tags = *(Atom *)p;
-		m->tagset[m->seltags] = tags & TAGMASK;
-	}
-
-	XFree(p);
-	return 1;
-}
-
-void
-setclientfields(Client *c)
-{
-	/* Perists client information in 32 bits laid out like this:
-	 *
-	 * |00000000|00000|0|0|0|0|0|0|0|0|00000000|000
-	 * |        |     | | | | | | | | |        |-- monitor index
-	 * |        |     | | | | | | | | |-- client index
-	 * |        |     | | | | | | | |-- isfloating
-	 * |        |     | | | | | | |-- ispermanent
-	 * |        |     | | | | | |-- isterminal
-	 * |        |     | | | | |-- noswallow
-	 * |        |     | | | |-- issteam
-	 * |        |     | | |-- issticky
-	 * |        |     | |-- fakefullscreen
-	 * |        |     |-- isfreesize
-	 * |        |
-	 * |        |-- reserved
-	 * |-- scratchkey (for scratchpads)
-	 */
-	uint32_t data[] = {
-		(c->mon->num & 0x7)
-		| (c->idx & 0xFF) << 3
-		| (c->isfloating & 0x1) << 11
-		| (c->scratchkey & 0xFF) << 24
-	};
-	XChangeProperty(dpy, c->win, clientatom[ClientFields], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
-}
-
-int
-getclientfields(Client *c)
-{
-	Monitor *m;
-	Atom fields = getatomprop(c, clientatom[ClientFields], AnyPropertyType);
-	if (fields == None)
-		return 0;
-
-	/* See bit layout in the setclientfields function */
-	for (m = mons; m; m = m->next)
-		if (m->num == (fields & 0x7)) {
-			c->mon = m;
-			break;
-		}
-	c->idx = (fields >> 3) & 0xFF;
-	c->isfloating = (fields >> 11) & 0x1;
-	c->scratchkey = (fields >> 24) & 0xFF;
-	return 1;
-}
-
-void
-setclienttags(Client *c)
-{
-	uint32_t data[] = { c->tags };
-	XChangeProperty(dpy, c->win, clientatom[ClientTags], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
-}
-
-int
-getclienttags(Client *c)
-{
-	Atom tags = getatomprop(c, clientatom[ClientTags], AnyPropertyType);
-	if (tags == None)
-		return 0;
-
-	c->tags = tags & TAGMASK;
-	return 1;
-}
-
-void
-savewindowfloatposition(Client *c, Monitor *m)
-{
-	char atom[22] = {0};
-	if (c->sfx == -9999)
-		return;
-
-	sprintf(atom, "_DWM_FLOATPOS_%u", m->num);
-	uint32_t pos[] = { (MAX(c->sfx - m->mx, 0) & 0xffff) | ((MAX(c->sfy - m->my, 0) & 0xffff) << 16) };
-	XChangeProperty(dpy, c->win, XInternAtom(dpy, atom, False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)pos, 1);
-
-	sprintf(atom, "_DWM_FLOATSIZE_%u", m->num);
-	uint32_t size[] = { (c->sfw & 0xffff) | ((c->sfh & 0xffff) << 16) };
-	XChangeProperty(dpy, c->win, XInternAtom(dpy, atom, False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)size, 1);
-
-	XSync(dpy, False);
-}
-
-int
-restorewindowfloatposition(Client *c, Monitor *m)
-{
-	char atom[22] = {0};
-	Atom key, value;
-	int x, y, w, h;
-
-	if (m == NULL)
-		return 0;
-
-	sprintf(atom, "_DWM_FLOATPOS_%u", m->num);
-
-	key = XInternAtom(dpy, atom, False);
-	if (!key)
-		return 0;
-
-	value = getatomprop(c, key, AnyPropertyType);
-	if (!value)
-		return 0;
-
-	x = value & 0xffff;
-	y = value >> 16;
-
-	sprintf(atom, "_DWM_FLOATSIZE_%u", m->num);
-
-	key = XInternAtom(dpy, atom, False);
-	if (!key)
-		return 0;
-
-	value = getatomprop(c, key, AnyPropertyType);
-	if (!value)
-		return 0;
-
-	w = value & 0xffff;
-	h = value >> 16;
-
-	if (w <= 0 || h <= 0) {
-		fprintf(stderr, "restorewindowfloatposition: bad float values x = %d, y = %d, w = %d, h = %d for client = %s\n", x, y, w, h, c->name);
-		return 0;
-	}
-
-	c->sfx = m->mx + x;
-	c->sfy = m->my + y;
-	c->sfw = w;
-	c->sfh = h;
-
-	if (c->isfloating) {
-		c->x = c->sfx;
-		c->y = c->sfy;
-		c->w = c->sfw;
-		c->h = c->sfh;
-	}
-
-	return 1;
-}
diff --git a/patch/seamless_restart.h b/patch/seamless_restart.h
deleted file mode 100644
index 4d95b6a..0000000
--- a/patch/seamless_restart.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <stdint.h>
-
-static void persistmonitorstate(Monitor *m);
-static int restoremonitorstate(Monitor *m);
-static void persistclientstate(Client *c);
-static int restoreclientstate(Client *c);
-static void setmonitorfields(Monitor *m);
-static int getmonitorfields(Monitor *m);
-static void setmonitortags(Monitor *m);
-static int getmonitortags(Monitor *m);
-static void setclientfields(Client *c);
-static int getclientfields(Client *c);
-static void setclienttags(Client *c);
-static int getclienttags(Client *c);
-static int getlayoutindex(const Layout *layout);
-static void savewindowfloatposition(Client *c, Monitor *m);
-static int restorewindowfloatposition(Client *c, Monitor *m);
diff --git a/patch/sizehints_ruled.c b/patch/sizehints_ruled.c
deleted file mode 100644
index 32de43b..0000000
--- a/patch/sizehints_ruled.c
+++ /dev/null
@@ -1,33 +0,0 @@
-void
-checkfloatingrules(Client *c)
-{
-	const char *class, *instance;
-	Atom wintype;
-	char role[64];
-	unsigned int i;
-	const Rule *r;
-	XClassHint ch = { NULL, NULL };
-
-	XGetClassHint(dpy, c->win, &ch);
-	class    = ch.res_class ? ch.res_class : broken;
-	instance = ch.res_name  ? ch.res_name  : broken;
-	wintype  = getatomprop(c, netatom[NetWMWindowType], XA_ATOM);
-	gettextprop(c->win, wmatom[WMWindowRole], role, sizeof(role));
-
-	for (i = 0; i < LENGTH(rules); i++) {
-		r = &rules[i];
-		if ((!r->title || strstr(c->name, r->title))
-		&& (!r->class || strstr(class, r->class))
-		&& (!r->role || strstr(role, r->role))
-		&& (!r->instance || strstr(instance, r->instance))
-		&& (!r->wintype || wintype == XInternAtom(dpy, r->wintype, False)))
-		{
-			c->isfloating = r->isfloating;
-		}
-	}
-	if (ch.res_class)
-		XFree(ch.res_class);
-	if (ch.res_name)
-		XFree(ch.res_name);
-}
-
diff --git a/patch/sizehints_ruled.h b/patch/sizehints_ruled.h
deleted file mode 100644
index 14c6719..0000000
--- a/patch/sizehints_ruled.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void checkfloatingrules(Client *c);
-
diff --git a/patch/stacker.c b/patch/stacker.c
deleted file mode 100644
index 0ed1344..0000000
--- a/patch/stacker.c
+++ /dev/null
@@ -1,73 +0,0 @@
-void
-focusstack(const Arg *arg)
-{
-	int i = stackpos(arg);
-	Client *c, *p;
-
-	if (i < 0)
- 		return;
-
-	if (!selmon->sel)
-		return;
-
-	for (p = NULL, c = selmon->clients; c && (i || !ISVISIBLE(c));
-		i -= (ISVISIBLE(c) ? 1 : 0), p = c, c = c->next);
-	focus(c ? c : p);
-	restack(selmon);
-}
-
-void
-pushstack(const Arg *arg)
-{
-	int i = stackpos(arg);
-	Client *sel = selmon->sel, *c, *p;
-
-	if (i < 0)
-		return;
-	else if (i == 0) {
-		detach(sel);
-		attach(sel);
-	}
-	else {
-		for (p = NULL, c = selmon->clients; c; p = c, c = c->next)
-			if (!(i -= (ISVISIBLE(c) && c != sel)))
-				break;
-		c = c ? c : p;
-		detach(sel);
-		sel->next = c->next;
-		c->next = sel;
-	}
-	arrange(selmon);
-}
-
-int
-stackpos(const Arg *arg)
-{
-	int n, i;
-	Client *c, *l;
-
-	if (!selmon->clients)
-		return -1;
-
-	if (arg->i == PREVSEL) {
-		for (l = selmon->stack; l && (!ISVISIBLE(l) || l == selmon->sel); l = l->snext);
-		if (!l)
-			return -1;
-		for (i = 0, c = selmon->clients; c != l; i += (ISVISIBLE(c) ? 1 : 0), c = c->next);
-		return i;
-	}
-	else if (ISINC(arg->i)) {
-		if (!selmon->sel)
-			return -1;
-		for (i = 0, c = selmon->clients; c != selmon->sel; i += (ISVISIBLE(c) ? 1 : 0), c = c->next);
-		for (n = i; c; n += (ISVISIBLE(c) ? 1 : 0), c = c->next);
-		return MOD(i + GETINC(arg->i), n);
-	}
-	else if (arg->i < 0) {
-		for (i = 0, c = selmon->clients; c; i += (ISVISIBLE(c) ? 1 : 0), c = c->next);
-		return MAX(i + arg->i, 0);
-	}
-	else
-		return arg->i;
-}
-
diff --git a/patch/stacker.h b/patch/stacker.h
deleted file mode 100644
index ee420bd..0000000
--- a/patch/stacker.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#define GETINC(X)               ((X) - 2000)
-#define INC(X)                  ((X) + 2000)
-#define ISINC(X)                ((X) > 1000 && (X) < 3000)
-#define PREVSEL                 3000
-#define MOD(N,M)                ((N)%(M) < 0 ? (N)%(M) + (M) : (N)%(M))
-#define TRUNC(X,A,B)            (MAX((A), MIN((X), (B))))
-
-static void focusstack(const Arg *arg);
-static void pushstack(const Arg *arg);
-static int stackpos(const Arg *arg);
-
diff --git a/patch/togglefullscreen.c b/patch/togglefullscreen.c
deleted file mode 100644
index a62edef..0000000
--- a/patch/togglefullscreen.c
+++ /dev/null
@@ -1,10 +0,0 @@
-void
-togglefullscreen(const Arg *arg)
-{
-	Client *c = selmon->sel;
-	if (!c)
-		return;
-
-	setfullscreen(c, !c->isfullscreen);
-}
-
diff --git a/patch/togglefullscreen.h b/patch/togglefullscreen.h
deleted file mode 100644
index 96a6770..0000000
--- a/patch/togglefullscreen.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void togglefullscreen(const Arg *arg);
-
diff --git a/patch/unfloatvisible.c b/patch/unfloatvisible.c
deleted file mode 100644
index fb8888f..0000000
--- a/patch/unfloatvisible.c
+++ /dev/null
@@ -1,15 +0,0 @@
-void
-unfloatvisible(const Arg *arg)
-{
-    Client *c;
-
-    for (c = selmon->clients; c; c = c->next)
-        if (ISVISIBLE(c) && c->isfloating)
-            c->isfloating = c->isfixed;
-
-    if (arg && arg->v)
-        setlayout(arg);
-    else
-        arrange(selmon);
-}
-
diff --git a/patch/unfloatvisible.h b/patch/unfloatvisible.h
deleted file mode 100644
index f15bc66..0000000
--- a/patch/unfloatvisible.h
+++ /dev/null
@@ -1,2 +0,0 @@
-static void unfloatvisible(const Arg *arg);
-
diff --git a/patches.h b/patches.h
new file mode 100644
index 0000000..a633a2c
--- /dev/null
+++ b/patches.h
@@ -0,0 +1,1494 @@
+/*
+ * This file contains patch control flags.
+ *
+ * In principle you should be able to mix and match any patches
+ * you may want. In cases where patches are logically incompatible
+ * one patch may take precedence over the other as noted in the
+ * relevant descriptions.
+ *
+ * Although layouts typically come as patches they are differentiated
+ * here for grouping purposes.
+ */
+
+/**
+ * Bar modules
+ */
+
+/* Enhanced taskbar that shows the titles of all visible windows in the status bar
+ * and allows focus / hiding / unhiding of windows by clicking on the status bar.
+ * Awesomebar takes precedence over fancybar.
+ * https://dwm.suckless.org/patches/awesomebar/
+ */
+#define BAR_AWESOMEBAR_PATCH 0
+
+/* This patch depends on statuscmd patch and adds integration with a (patched)
+ * dwmblocks instance to give a clickable status bar. One must not necessarily
+ * have to use dwmblocks for this feature, any status updater that has support
+ * for real-time signals (SIGRTMIN) can be used.
+ *
+ * dwmblocks: https://github.com/torrinfail/dwmblocks
+ * https://dwm.suckless.org/patches/statuscmd/
+ */
+#define BAR_DWMBLOCKS_PATCH 0
+
+/* Originally the dwmblocks + statuscmd patch used a user defined signal (SIGUSR1)
+ * for communicating with dwmblocks to indicate update signal and what button was
+ * pressed. The signalling was later changed to SIGRTMIN instead.
+ *
+ * Ultimately this makes dwmblocks instances that were patched with the old patch
+ * are incompatible with the new dwm patch and vice versa.
+ *
+ * This is a compatibility patch that makes dwm use SIGUSR1 instead of SIGRTMIN so
+ * if button clicks are not working then you may want to try enabling this.
+ *
+ * If dwmblocks happen to die like this when clicking on a status
+ *
+ *    [1]    54355 user-defined signal 1  dwmblocks
+ *
+ * then it suggests that dwmblocks does not support user defined signals and this
+ * patch should be left disabled.
+ *
+ * Patch: https://gist.github.com/danbyl/54f7c1d57fc6507242a95b71c3d8fdea
+ * https://dwm.suckless.org/patches/statuscmd/
+ */
+#define BAR_DWMBLOCKS_SIGUSR1_PATCH 0
+
+/* This patch shows the titles of all visible windows in the status bar
+ * (as opposed to showing only the selected one).
+ * Awesomebar takes precedence over fancybar. Fancybar takes precedence over
+ * the centeredwindowname patch.
+ * https://dwm.suckless.org/patches/fancybar/
+ */
+#define BAR_FANCYBAR_PATCH 0
+
+/* Being an evolution of the bartabgroups patch the flexwintitle patch specifically
+ * taps into the many layout options that flextile-deluxe offers to produce a window
+ * title section in the bar that is representative of what is shown on screen.
+ */
+#define BAR_FLEXWINTITLE_PATCH 0
+
+/* This patch adds a context menu for layout switching.
+ *   - xmenu needs to be installed.
+ *   - Edit layoutmenu.sh with the installed layouts and with correct indexes.
+ *   - Place layoutmenu.sh in PATH.
+ *   - The text of the menu items is for display only. Name them however you want.
+ * https://dwm.suckless.org/patches/layoutmenu/
+ */
+#define BAR_LAYOUTMENU_PATCH 1
+
+/* Show layout symbol in bar */
+#define BAR_LTSYMBOL_PATCH 1
+
+/* Adds powerline arrows for the status.
+ * This uses statuscolors logic for choosing colors for the powerline. As these markers
+ * are also control characters there is no explicit statuscmd support for this patch.
+ *
+ * Powerline separators are defined as:
+ *    |\xXX  (creates a hard edge)
+ *    <\xXX  (creates a less than arrow)
+ *    /\xXX  (creates a diagonal line)
+ *
+ * Examples:
+ *    xsetroot -name "$(echo -e '<\x01a<\x02b<\x03c')"
+ *    xsetroot -name "$(echo -e '/\x01d/\x02e/\x03f')"
+ *
+ * https://gitlab.com/udiboy1209-suckless/dwm/-/commit/071f5063e8ac4280666828179f92788d893eea40#4b1a539194be7467cefbda22f675a3b7c19ceca7
+ * https://dwm.suckless.org/patches/statuscolors/
+ */
+#define BAR_POWERLINE_STATUS_PATCH 0
+
+/* Adds powerline arrows for the tags.
+ * https://gitlab.com/udiboy1209-suckless/dwm/-/commit/071f5063e8ac4280666828179f92788d893eea40#4b1a539194be7467cefbda22f675a3b7c19ceca7
+ */
+#define BAR_POWERLINE_TAGS_PATCH 0
+
+/* Alters the tags powerline to use forward slash instead of arrows */
+#define BAR_POWERLINE_TAGS_SLASH_PATCH 0
+
+/* This patch turns the titlebar area into a mfact-respecting tabbar showing each client's title.
+ * https://dwm.suckless.org/patches/bartabgroups/
+ */
+#define BAR_TABGROUPS_PATCH 0
+
+/* This patch adds an option to place tags in rows like in many other window managers.
+ * https://dwm.suckless.org/patches/taggrid/
+ */
+#define BAR_TAGGRID_PATCH 0
+
+/* Hover tag icons to see a preview of the windows on that tag.
+ *
+ * The patch depends on Imlib2 for icon scaling.
+ * You need to uncomment the corresponding line in config.mk to use the -lImlib2 library
+ *
+ * Arch Linux:
+ *     sudo pacman -S imlib2
+ * Debian:
+ *     sudo apt install libimlib2-dev
+ *
+ * As with the winicon patch you may want to consider adding the compiler flags of -O3 and
+ * -march=native to enable auto loop vectorize for better performance.
+ *
+ * https://dwm.suckless.org/patches/tag-previews/
+ */
+#define BAR_TAGPREVIEW_PATCH 0
+
+/* Show status in bar */
+#define BAR_STATUS_PATCH 1
+
+/* This patch adds a clickable button to the left hand side of the statusbar.
+ * https://dwm.suckless.org/patches/statusbutton/
+ */
+#define BAR_STATUSBUTTON_PATCH 0
+
+/* This patch adds the ability to execute shell commands based on the mouse button and position
+ * when clicking the status bar. Refer to the website for usage.
+ * https://dwm.suckless.org/patches/statuscmd/
+ */
+#define BAR_STATUSCMD_PATCH 0
+
+/* Status2d allows colors and rectangle drawing in your dwm status bar.
+ * This patch is incompatible with the statuscolors patch which takes precedence.
+ * This patch is incompatible with the extrabar patch.
+ * https://dwm.suckless.org/patches/status2d/
+ */
+#define BAR_STATUS2D_PATCH 0
+
+/* Supplementary patch should you want to disable alpha for the status2d section */
+#define BAR_STATUS2D_NO_ALPHA_PATCH 0
+
+/* Addition to the status2d patch that allows the use of terminal colors (color0 through color15)
+ * from xrdb in the status, allowing programs like pywal to change statusbar colors.
+ * This adds the C and B codes to use terminal foreground and background colors respectively.
+ * E.g. ^B5^ would use color5 as the background color.
+ * https://dwm.suckless.org/patches/status2d/
+ */
+#define BAR_STATUS2D_XRDB_TERMCOLORS_PATCH 0
+
+/* The systray patch adds systray for the status bar.
+ * https://dwm.suckless.org/patches/systray/
+ */
+#define BAR_SYSTRAY_PATCH 1
+
+/* Show tag symbols in the bar. */
+#define BAR_TAGS_PATCH 1
+
+/* Show tag symbols + class of master window in the bar.
+ * https://dwm.suckless.org/patches/taglabels/
+ */
+#define BAR_TAGLABELS_PATCH 0
+
+/* This patch underlines the selected tag, or optionally all tags.
+ * https://dwm.suckless.org/patches/underlinetags/
+ */
+#define BAR_UNDERLINETAGS_PATCH 0
+
+/* This patch adds the window icon next to the window title in the bar.
+ *
+ * The patch depends on Imlib2 for icon scaling.
+ * You need to uncomment the corresponding line in config.mk to use the -lImlib2 library
+ *
+ * Arch Linux:
+ *     sudo pacman -S imlib2
+ * Debian:
+ *     sudo apt install libimlib2-dev
+ *
+ * The author recommends adding the compiler flags of -O3 and -march=native to enable auto loop
+ * vectorize for better performance.
+ *
+ * https://github.com/AdamYuan/dwm-winicon
+ * https://dwm.suckless.org/patches/winicon
+ */
+#define BAR_WINICON_PATCH 0
+
+/* Show window title in bar */
+#define BAR_WINTITLE_PATCH 1
+
+/* Shows window titles in the bar, but only for floating clients.
+ * This depends on code from the flexwintitle patch.
+ * Note that the configuration in config.def.h for this is merely an example. If combined
+ * with the corresponding hidden patch then these two will overlap unless the width of the
+ * modules are controlled.
+ */
+#define BAR_WINTITLE_FLOATING_PATCH 0
+
+/* Shows window titles in the bar, but only for floating clients.
+ * This depends on code from the flexwintitle patch.
+ * Note that the configuration in config.def.h for this is merely an example. If combined
+ * with the corresponding floating patch then these two will overlap unless the width of the
+ * modules are controlled.
+ */
+#define BAR_WINTITLE_HIDDEN_PATCH 0
+
+/* Title bar modules such as wintitle (default), fancybar and awesomebar
+ * do not by default add left and/or right padding as they take up the
+ * remaining space. These options allow you explicitly add padding should
+ * you need it.
+ */
+#define BAR_TITLE_RIGHT_PAD_PATCH 0
+#define BAR_TITLE_LEFT_PAD_PATCH 0
+
+/**
+ * Bar options
+ */
+
+/* This patch changes the rectangle indicating if a tag is used by a client into a bar
+ * above the tag name for better visibility.
+ * Set the tagindicatortype variable in config.h to INDICATOR_TOP_BAR to enable this.
+ * https://dwm.suckless.org/patches/activetagindicatorbar/
+ */
+#define BAR_ACTIVETAGINDICATORBAR_PATCH N/A
+
+/* Alternative patch to the activetagindicatorbar patch, adds the bar below the tag
+ * icon rather than above.
+ * Set the tagindicatortype variable in config.h to INDICATOR_BOTTOM_BAR to enable this.
+ */
+#define BAR_ACTIVETAGINDICATORBAR_ALT1_PATCH N/A
+
+/* The alpha patch adds transparency for the status bar.
+ * You need to uncomment the corresponding line in config.mk to use the -lXrender library
+ * when including this patch.
+ * https://dwm.suckless.org/patches/alpha/
+ */
+#define BAR_ALPHA_PATCH 1
+
+/* This patch introduces alternative tags which can be switched on the fly for the
+ * sole purpose of providing visual aid.
+ * https://dwm.suckless.org/patches/alternativetags/
+ */
+#define BAR_ALTERNATIVE_TAGS_PATCH 0
+
+/* This patches provides the ability to use alternative text for tags which contain at
+ * least one window.
+ * https://dwm.suckless.org/patches/alttagsdecoration/
+ */
+#define BAR_ALTTAGSDECORATION_PATCH 0
+
+/* This patch enables dwm to manage external status bars such as lemonbar and polybar.
+ * dwm treats the external bar as it would its own, so all regular dwm commands such as
+ * togglebar affect the external bar in the same way.
+ *
+ * NB: Unless you want both anybar + dwm bar(s) then the recommendation is to disable all
+ * bar modules and have { -2 } in the barrules.
+ *
+ * https://dwm.suckless.org/patches/anybar/
+ */
+#define BAR_ANYBAR_PATCH 0
+
+/* Anybar option to place the next bar depending on previous bar's position (top or bottom) */
+#define BAR_ANYBAR_TOP_AND_BOTTOM_BARS_PATCH 0
+
+/* Anybar option to let dwm manage the width of the bar */
+#define BAR_ANYBAR_MANAGE_WIDTH_PATCH 0
+
+/* This patch adds a border around the status bar(s) just like the border of client windows.
+ * https://codemadness.org/paste/dwm-border-bar.patch
+ */
+#define BAR_BORDER_PATCH 0
+
+/* This patch centers the WM_NAME of the currently selected window on the status bar.
+ * This is compatible with the wintitle, bartabgroups, flexwintitle and awesomebar bar
+ * modules.
+ * https://dwm.suckless.org/patches/centeredwindowname/
+ */
+#define BAR_CENTEREDWINDOWNAME_PATCH 0
+
+/* Draws a dot indicator overlayed on each tag icon for each client. The selected client
+ * is drawn as a larger horizontal line.
+ * Set the tagindicatortype variable in config.h to INDICATOR_CLIENT_DOTS to enable this.
+ * https://dwm.suckless.org/patches/clientindicators/
+ */
+#define BAR_CLIENTINDICATOR_PATCH N/A
+
+/* Updates the position of dmenu to match that of the bar. I.e. if topbar is 0 then dmenu
+ * will appear at the bottom and if 1 then dmenu will appear at the top.
+ * https://dwm.suckless.org/patches/dmenumatchtop
+ */
+#define BAR_DMENUMATCHTOP_PATCH 0
+
+/* Originally this was the extrabar patch, but as the handling of extra bars is now built-in
+ * only the splitting of the status by a designated separator remains. As such this has been
+ * renamed to more accurately reflect what it does - creating an extra status.
+ * https://dwm.suckless.org/patches/extrabar/
+ */
+#define BAR_EXTRASTATUS_PATCH 0
+
+/* Adds EWMH support for _NET_NUMBER_OF_DESKTOPS, _NET_CURRENT_DESKTOP, _NET_DESKTOP_NAMES
+ * and _NET_DESKTOP_VIEWPORT, which allows for compatibility with other bars and programs
+ * that request workspace information. For example polybar's xworkspaces module.
+ *
+ * This patch also includes support for adding the _IS_FLOATING property for floating windows
+ * allowing for compositors to treat floating windows differently to tiled windows.
+ *
+ * E.g. this setting makes picom only render shadows for floating windows:
+ *
+ *     shadow-exclude = [ "! _IS_FLOATING@:32c = 1" ];
+ *
+ * https://github.com/bakkeby/dwm-flexipatch/issues/50 (_IS_FLOATING patch)
+ * https://dwm.suckless.org/patches/ewmhtags/
+ */
+#define BAR_EWMHTAGS_PATCH 1
+
+/* Allows the bar height to be explicitly set rather than being derived from font.
+ * https://dwm.suckless.org/patches/bar_height/
+ */
+#define BAR_HEIGHT_PATCH 0
+
+/* This patch prevents dwm from drawing tags with no clients (i.e. vacant) on the bar.
+ * https://dwm.suckless.org/patches/hide_vacant_tags/
+ */
+#define BAR_HIDEVACANTTAGS_PATCH 1
+
+/* With this patch dwm's built-in status bar is only shown when HOLDKEY is pressed
+ * and the bar will now overlay the display.
+ * http://dwm.suckless.org/patches/holdbar/
+ */
+#define BAR_HOLDBAR_PATCH 0
+
+/* Sometimes dwm crashes when it cannot render some glyphs in window titles (usually emoji).
+ * This patch is essentially a hack to ignore any errors when drawing text on the status bar.
+ * https://groups.google.com/forum/m/#!topic/wmii/7bncCahYIww
+ * https://docs.google.com/viewer?a=v&pid=forums&srcid=MDAwODA2MTg0MDQyMjE0OTgzMzMBMDQ3ODQzODkyMTU3NTAyMTMxNTYBX2RUMVNtOUtDQUFKATAuMQEBdjI&authuser=0
+ */
+#define BAR_IGNORE_XFT_ERRORS_WHEN_DRAWING_TEXT_PATCH 0
+
+/* This patch adds back in the workaround for a BadLength error in the Xft library when color
+ * glyphs are used. This is for systems that do not have an updated version of the Xft library
+ * (or generally prefer monochrome fonts).
+ */
+#define BAR_NO_COLOR_EMOJI_PATCH 0
+
+/* This patch adds vertical and horizontal space between the statusbar and the edge of the screen.
+ * https://dwm.suckless.org/patches/barpadding/
+ */
+#define BAR_PADDING_PATCH 0
+
+/* Same as barpadding patch but specifically tailored for the vanitygaps patch in that the outer
+ * bar padding is derived from the vanitygaps settings. In addition to this the bar padding is
+ * toggled in unison when vanitygaps are toggled. Increasing or decreasing gaps during runtime
+ * will not affect the bar padding.
+ */
+#define BAR_PADDING_VANITYGAPS_PATCH 0
+
+/* This patch adds simple markup for status messages using pango markup.
+ * This depends on the pango library v1.44 or greater.
+ * You need to uncomment the corresponding lines in config.mk to use the pango libraries
+ * when including this patch.
+ *
+ * Note that the pango patch does not protect against the BadLength error from Xft
+ * when color glyphs are used, which means that dwm will crash if color emoji is used.
+ *
+ * If you need color emoji then you may want to install this patched library from the AUR:
+ * https://aur.archlinux.org/packages/libxft-bgra/
+ *
+ * A long term fix for the libXft library is pending approval of this pull request:
+ * https://gitlab.freedesktop.org/xorg/lib/libxft/-/merge_requests/1
+ *
+ * Also see:
+ * https://developer.gnome.org/pygtk/stable/pango-markup-language.html
+ * https://lists.suckless.org/hackers/2004/17285.html
+ * https://dwm.suckless.org/patches/pango/
+ */
+#define BAR_PANGO_PATCH 1
+
+/* This patch allows the status text to be fixed to the bar on a specific
+ * monitor rather than being drawn on the focused monitor.
+ * The statusallmons patch takes precedence over this patch.
+ * https://dwm.suckless.org/patches/staticstatus/
+ */
+#define BAR_STATICSTATUS_PATCH 0
+
+/* This patch draws and updates the statusbar on all monitors.
+ * https://dwm.suckless.org/patches/statusallmons/
+ */
+#define BAR_STATUSALLMONS_PATCH 0
+
+/* This patch enables colored text in the status bar. It changes the way colors are defined
+ * in config.h allowing multiple color combinations for use in the status script.
+ * This patch is incompatible with and takes precedence over the status2d patch.
+ *
+ * This patch is compatible with the statuscmd patch with the caveat that the first 16 markers
+ * are reserved for status colors restricting block signals to 17 through 31.
+ *
+ * https://dwm.suckless.org/patches/statuscolors/
+ */
+#define BAR_STATUSCOLORS_PATCH 0
+
+/* This patch adds configuration options for horizontal and vertical padding in the status bar.
+ * https://dwm.suckless.org/patches/statuspadding/
+ */
+#define BAR_STATUSPADDING_PATCH 0
+
+/* This patch adds the ability for dwm to read colors from the linux virtual console.
+ *    /sys/module/vt/parameters/default_{red,grn,blu}
+ * Essentially this way the colors you use in your regular tty is "mirrored" to dwm.
+ * https://dwm.suckless.org/patches/vtcolors/
+ */
+#define BAR_VTCOLORS_PATCH 0
+
+/* This patch allows client windows to be hidden. This code was originally part of awesomebar,
+ * but has been separated out so that other bar modules can take advantage of it.
+ * Both awesomebar and bartabgroups patches depend on this patch and it will be auto-enabled
+ * during compile time if it is needed. Note that if using flexipatch-finalizer this must be
+ * explicitly enabled.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-barmodules-wintitleactions-6.2.diff
+ */
+#define BAR_WINTITLEACTIONS_PATCH BAR_AWESOMEBAR_PATCH || BAR_TABGROUPS_PATCH || BAR_FLEXWINTITLE_PATCH
+
+/***
+ * Other patches
+ */
+
+/* Adds a window task switcher toggled using alt-tab.
+ * https://dwm.suckless.org/patches/alt-tab/
+ */
+#define ALT_TAB_PATCH 0
+
+/* All floating windows are centered, like the center patch, but without a rule.
+ * The center patch takes precedence over this patch.
+ * This patch interferes with the center transient windows patches.
+ * https://dwm.suckless.org/patches/alwayscenter/
+ */
+#define ALWAYSCENTER_PATCH 0
+
+/* This patch allows windows to be resized with its aspect ratio remaining constant.
+ * https://dwm.suckless.org/patches/aspectresize/
+ */
+#define ASPECTRESIZE_PATCH 0
+
+/* This patch adds new clients above the selected client, instead of always
+ * becoming the new master. This behaviour is known from Xmonad.
+ * This patch takes precedence over ATTACHASIDE_PATCH.
+ * https://dwm.suckless.org/patches/attachabove/
+ */
+#define ATTACHABOVE_PATCH 0
+
+/* This patch adds new clients on top of the stack.
+ * This patch takes precedence over ATTACHBELOW_PATCH.
+ * https://dwm.suckless.org/patches/attachaside/
+ */
+#define ATTACHASIDE_PATCH 0
+
+/* This patch adds new clients below the selected client.
+ * This patch takes precedence over ATTACHBOTTOM_PATCH.
+ * https://dwm.suckless.org/patches/attachbelow/
+ */
+#define ATTACHBELOW_PATCH 1
+
+/* This patch adds new clients at the bottom of the stack.
+ * https://dwm.suckless.org/patches/attachbottom/
+ */
+#define ATTACHBOTTOM_PATCH 0
+
+/* This patch will make dwm run "~/.local/share/dwm/autostart_blocking.sh" and
+ * "~/.local/share/dwm/autostart.sh &" before entering the handler loop. One or
+ * both of these files can be ommited. Note the path inside .local/share rather
+ * than the original ~/.dwm folder.
+ * https://dwm.suckless.org/patches/autostart/
+ */
+#define AUTOSTART_PATCH 0
+
+/* By default, windows that are not visible when requesting a resize/move will not
+ * get resized/moved. With this patch, they will.
+ * https://dwm.suckless.org/patches/autoresize/
+ */
+#define AUTORESIZE_PATCH 0
+
+/* This patch adds proper support for Right-To-Left languages. (such as Farsi, Arabic or Hebrew).
+ *
+ * You need to uncomment the corresponding lines in config.mk to use the -lfribidi library
+ * when including this patch.
+ *
+ * This patch depends on the following additional library:
+ *    - fribidi
+ *
+ * https://dwm.suckless.org/patches/bidi/
+ */
+#define BIDI_PATCH 0
+
+/* This patch adds an iscentered rule to automatically center clients on the current monitor.
+ * This patch takes precedence over centeredwindowname, alwayscenter and fancybar patches.
+ * https://dwm.suckless.org/patches/center/
+ */
+#define CENTER_PATCH 0
+
+/* A transient window is one that is meant to be short lived and is usually raised by a
+ * parent window. Such windows are typically dialog boxes and the like.
+ * It should be noted that in dwm transient windows are not subject to normal client rules
+ * and they are always floating by default.
+ * This patch centers transient windows on the screen like the center patch does. Note that
+ * the 6.2 center patch piggy-backed on the updatewindowtype function to ensure that all
+ * dialog boxes were centered, transient or not. This function was removed in relation to
+ * adding wintype as a client rule filter, hence this no longer works out of the box. This
+ * patch restores previous behaviour with the center patch.
+ */
+#define CENTER_TRANSIENT_WINDOWS_PATCH 1
+
+/* As above, except that the transient window is centered within the position of the parent
+ * window, rather than at the center of the screen. This takes precedence over the above patch.
+ */
+#define CENTER_TRANSIENT_WINDOWS_BY_PARENT_PATCH 1
+
+/* This patch provides the ability to assign different weights to clients in their
+ * respective stack in tiled layout.
+ * https://dwm.suckless.org/patches/cfacts/
+ */
+#define CFACTS_PATCH 1
+
+/* This patch allows color attributes to be set through the command line.
+ * https://dwm.suckless.org/patches/cmdcustomize/
+ */
+#define CMDCUSTOMIZE_PATCH 0
+
+/* This patch tweaks the tagging interface so that you can select multiple tags for tag
+ * or view by pressing all the right keys as a combo. For example to view tags 1 and 3,
+ * hold MOD and then press and hold 1 and 3 together.
+ * https://dwm.suckless.org/patches/combo/
+ */
+#define COMBO_PATCH 0
+
+/* Allow dwm to execute commands from autostart array in your config.h file. When dwm exits
+ * then all processes from autostart array will be killed.
+ * https://dwm.suckless.org/patches/cool_autostart/
+ */
+#define COOL_AUTOSTART_PATCH 1
+
+/* The cyclelayouts patch lets you cycle through all your layouts.
+ * https://dwm.suckless.org/patches/cyclelayouts/
+ */
+#define CYCLELAYOUTS_PATCH 1
+
+/* Make dwm respect _MOTIF_WM_HINTS property, and not draw borders around windows requesting
+ * for it. Some applications use this property to notify window managers to not draw window
+ * decorations.
+ * Not respecting this property leads to issues with applications that draw their own borders,
+ * like chromium (with "Use system title bar and borders" turned off) or vlc in fullscreen mode.
+ * https://dwm.suckless.org/patches/decoration_hints/
+ */
+#define DECORATION_HINTS_PATCH 1
+
+/* This feature distributes all clients on the current monitor evenly across all tags.
+ * It is a variant of the reorganizetags patch.
+ * https://dwm.suckless.org/patches/reorganizetags/
+ */
+#define DISTRIBUTETAGS_PATCH 0
+
+/* By default dwm will terminate on color allocation failure and the behaviour is intended to
+ * catch and inform the user of color configuration issues.
+ *
+ * Some patches like status2d and xresources / xrdb can change colours during runtime, which
+ * means that if a color can't be allocated at this time then the window manager will abruptly
+ * terminate.
+ *
+ * This patch will ignore color allocation failures and continue on as normal. The effect of
+ * this is that the existing color, that was supposed to be replaced, will remain as-is.
+ */
+#define DO_NOT_DIE_ON_COLOR_ALLOCATION_FAILURE_PATCH 1
+
+/* Similarly to the dragmfact patch this allows you to click and drag clients to change the
+ * cfact to adjust the client's size in the stack. This patch depends on the cfacts patch.
+ */
+#define DRAGCFACT_PATCH 0
+
+/* This patch lets you resize the split in the tile layout (i.e. modify mfact) by holding
+ * the modkey and dragging the mouse.
+ * This patch can be a bit wonky with other layouts, but generally works.
+ * https://dwm.suckless.org/patches/dragmfact/
+ */
+#define DRAGMFACT_PATCH 0
+
+/* Simple dwmc client using a fork of fsignal to communicate with dwm.
+ * To use this either copy the patch/dwmc shell script to somewhere in your path or
+ * uncomment the following line in Makefile:
+ *    #cp -f patch/dwmc ${DESTDIR}${PREFIX}/bin
+ * http://dwm.suckless.org/patches/dwmc/
+ */
+#define DWMC_PATCH 0
+
+/* This patch allows no tag at all to be selected. The result is that dwm will start with
+ * no tag selected and when you start a client with no tag rule and no tag selected then
+ * it will be opened on the first tag.
+ * https://dwm.suckless.org/patches/emptyview/
+ */
+#define EMPTYVIEW_PATCH 0
+
+/* This patch allows the user to change size and placement of floating windows using only the
+ * keyboard. It also allows for temporary vertical and horizontal extension of windows similar
+ * to other WMs fill command.
+ * https://dwm.suckless.org/patches/exresize/
+ */
+#define EXRESIZE_PATCH 0
+
+/* Only allow clients to "fullscreen" into the space currently given to them.
+ * As an example, this will allow you to view a fullscreen video in your browser on
+ * one half of the screen, while having the other half available for other tasks.
+ * This patch takes precedence over the fakefullscreen client patch below.
+ * https://dwm.suckless.org/patches/fakefullscreen/
+ */
+#define FAKEFULLSCREEN_PATCH 0
+
+/* Similarly to the fakefullscreen patch this patch only allows clients to "fullscreen" into
+ * the space currently given to them.
+ * The "twist" with this patch is that fake fullscreen can be toggled on a per client basis
+ * rather than applying to all clients globally.
+ * Also see the selectivefakefullscreen option that adds a rule option to enabled this on client
+ * startup.
+ */
+#define FAKEFULLSCREEN_CLIENT_PATCH 0
+
+/* This patch adds a float rule allowing the size and position of floating windows to be specified
+ * It also allows the size and position of floating windows to be controlled similar to the
+ * exresize, moveresize, and moveplace patches.
+ * The size and position can be specified using absolute, relative or fixed co-ordinates and
+ * https://github.com/bakkeby/patches/wiki/floatpos/
+ */
+#define FLOATPOS_PATCH 1
+
+/* Add-on functionality for the above: make the float positions respect outer (vanity)gaps. */
+#define FLOATPOS_RESPECT_GAPS_PATCH 0
+
+/* This patch provides the ability to focus the tag on the immediate left or right of the
+ * currently focused tag. It also allows to send the focused window either on the left or
+ * the right tag.
+ * http://dwm.suckless.org/patches/focusadjacenttag/
+ */
+#define FOCUSADJACENTTAG_PATCH 0
+
+/* Allows focusing on clients based on direction (up, down, left, right) instead of client order.
+ * https://github.com/bakkeby/patches/wiki/focusdir/
+ */
+#define FOCUSDIR_PATCH 0
+
+/* When changing tags, closing windows or moving clients out of view then focus will revert to the
+ * client window that remains under the mouse cursor rather than the most recently focused window.
+ * https://github.com/bakkeby/patches/wiki/focusfollowmouse
+ */
+#define FOCUSFOLLOWMOUSE_PATCH 0
+
+/* A simple patch that just puts focus back to the master client.
+ * https://dwm.suckless.org/patches/focusmaster/
+ */
+#define FOCUSMASTER_PATCH 0
+
+/* A variant of the focusmaster patch that additionally allows the focus to be returned to the
+ * previously focused client
+ * https://dwm.suckless.org/patches/focusmaster/
+ */
+#define FOCUSMASTER_RETURN_PATCH 0
+
+/* Switch focus only by mouse click and not sloppy (focus follows mouse pointer).
+ * https://dwm.suckless.org/patches/focusonclick/
+ */
+#define FOCUSONCLICK_PATCH 1
+
+/* Selects the next window having the urgent flag regardless of the tag it is on.
+ * The urgent flag can be artificially set with the following xdotool command on any window:
+ *   xdotool selectwindow -- set_window --urgency 1
+ * https://dwm.suckless.org/patches/focusurgent/
+ */
+#define FOCUSURGENT_PATCH 0
+
+/* By default, dwm responds to _NET_ACTIVE_WINDOW client messages by setting
+ * the urgency bit on the named window. This patch activates the window instead.
+ * https://dwm.suckless.org/patches/focusonnetactive/
+ */
+#define FOCUSONNETACTIVE_PATCH 0
+
+/* Send "fake signals" to dwm for handling, using xsetroot. This will not conflict with the
+ * status bar, which also is managed using xsetroot.
+ * Also see the dwmc patch, which takes precedence over this patch.
+ * https://dwm.suckless.org/patches/fsignal/
+ */
+#define FSIGNAL_PATCH 0
+
+/* Applies the monocle layout with the focused client on top and hides the bar. When pressed
+ * again it shows the bar and restores the layout that was active before going fullscreen.
+ * https://dwm.suckless.org/patches/fullscreen/
+ */
+#define FULLSCREEN_PATCH 0
+
+/* This patch provides a keybinding to rotate all clients in the currently selected
+ * area (master or stack) without affecting the other area.
+ * https://dwm.suckless.org/patches/inplacerotate/
+ */
+#define INPLACEROTATE_PATCH 0
+
+/* This patch lets you define custom insets from each edge of the screen. One use case would be
+ * to arrange space for an external bar.
+ * https://dwm.suckless.org/patches/insets/
+ */
+#define INSETS_PATCH 0
+
+/* This patch (v1.5.7) implements inter-process communication through a UNIX socket for dwm. This
+ * allows for the window manager to be queried for information, e.g. listen for events such as tag
+ * or layout changes, as well as send commands to control the window manager via other programs.
+ *
+ * You need to uncomment the corresponding lines in config.mk to use the -lyajl library
+ * when including this patch.
+ * This patch depends on the following additional library:
+ *    - yajl
+ *
+ * https://github.com/mihirlad55/dwm-ipc
+ * https://dwm.suckless.org/patches/ipc/
+ */
+#define IPC_PATCH 0
+
+/* Adds rule option for clients to avoid accidental termination by killclient for sticky windows.
+ * https://dwm.suckless.org/patches/ispermanent/
+ */
+#define ISPERMANENT_PATCH 0
+
+/* This patch adds key modes (like in vim or emacs) where chains of keyboard shortcuts
+ * can be performed.
+ * https://dwm.suckless.org/patches/keymodes/
+ */
+#define KEYMODES_PATCH 0
+
+/* This patch adds a keybinding to kills all visible clients that are not selected.
+ * https://dwm.suckless.org/patches/killunsel/
+ */
+#define KILLUNSEL_PATCH 0
+
+/* This changes the window manager name to LG3d instead of dwm as a workaround for Java
+ * applications that assume that the window manager is using window reparenting.
+ * Refer to the ISSUES secton of the dwm man page for more details.
+ */
+#define LG3D_PATCH 0
+
+/* By default in dwm it is possible to make an application fullscreen, then use
+ * the focusstack keybindings to focus on other windows beneath the current window.
+ * It is also possible to spawn new windows (e.g. a terminal) that end up getting
+ * focus while the previous window remains in fullscreen. This patch ensures that
+ * in such scenarios the previous window loses fullscreen.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-losefullscreen-6.2.diff
+ */
+#define LOSEFULLSCREEN_PATCH 1
+
+/* This patch adds helper functions for maximizing, horizontally and vertically, floating
+ * windows using keybindings.
+ * https://dwm.suckless.org/patches/maximize/
+ */
+#define MAXIMIZE_PATCH 0
+
+/* Control Music Player Daemon via keybinds.
+ * You need to uncomment the corresponding line in config.mk to use the -lmpdclient library
+ * when including this patch.
+ * This patch depends on the following additional library:
+ *    - libmpdclient
+ * https://dwm.suckless.org/patches/mpdcontrol/
+ */
+#define MPDCONTROL_PATCH 0
+
+/* Adds rules per monitor, e.g. have default layouts per monitor.
+ * The use case for this is if the second monitor is vertical (i.e. rotated) then
+ * you may want to use a different default layout for this monitor than what is
+ * used for the main monitor. E.g. normal vertical split for main monitor and
+ * horizontal split for the second.
+ */
+#define MONITOR_RULES_PATCH 0
+
+/* Always display the the monocle-symbol as defined in config.h if the monocle-layout
+ * is activated. Do not display the number of open clients in the current tag.
+ * https://dwm.suckless.org/patches/monoclesymbol/
+ */
+#define MONOCLESYMBOL_PATCH 0
+
+/* Makes a window floating and 1/3rd the height and 1/3rd the width of the screen and is
+ * positioned in either the center or one of the 8 cardinal directions depending on which
+ * key is pressed.
+ * https://dwm.suckless.org/patches/moveplace/
+ */
+#define MOVEPLACE_PATCH 0
+
+/* This patch allows you to move and resize dwm's clients using keyboard bindings.
+ * https://dwm.suckless.org/patches/moveresize/
+ */
+#define MOVERESIZE_PATCH 0
+
+/* This patch allows you to move clients around in the stack and swap them with the master.
+ * https://dwm.suckless.org/patches/movestack/
+ */
+#define MOVESTACK_PATCH 0
+
+/* This patch allows you to change the names of tags during runtime.
+ *
+ * This is a bespoke version implemented specifically in relation to tagicons, which is integrated
+ * into dwm-flexipatch. By default it uses dmenu to retrieve the new name, but this can be
+ * customised via config along with the maximum text length and the format string.
+ *
+ * Special behaviour:
+ *    - if more than one tag is selected then the name change applies to all selected tags
+ *    - if tagicons is configured to have unique tags per monitor then the change only applies
+ *      for the current monitor
+ *    - the name change applies to the tag set that is active for the current tag:
+ *       * if used in combination with BAR_ALTTAGSDECORATION_PATCH and there are clients on the
+ *         given tag then the name change only applies to the ALT_TAGS_DECORATION tag set
+ *       * if used in combination with the BAR_ALTERNATIVE_TAGS_PATCH and alternative tags are
+ *         shown then the name change only applies to the ALTERNATIVE_TAGS tag set
+ *       * if used in combination with both then BAR_ALTTAGSDECORATION_PATCH takes precedence
+ *       * otherwise the name change applies to the DEFAULT_TAGS tag set
+ *
+ * https://dwm.suckless.org/patches/nametag/
+ */
+#define NAMETAG_PATCH 0
+
+/* Variant of the above which prepends the tag number to the given string.
+ * The toggle does nothing on its own and need to be enabled in combination with the above. */
+#define NAMETAG_PREPEND_PATCH 0
+
+/* Adds support for the _NET_CLIENT_LIST_STACKING atom, needed by certain applications like the
+ * Zoom video conferencing application.
+ * https://github.com/bakkeby/patches/wiki/netclientliststacking/
+ */
+#define NET_CLIENT_LIST_STACKING_PATCH 1
+
+/* Removes the border when there is only one window visible.
+ * https://dwm.suckless.org/patches/noborder/
+ */
+#define NOBORDER_PATCH 0
+
+/* Enable modifying or removing dmenu in config.def.h which resulted previously in a
+ * compilation error because two lines of code hardcode dmenu into dwm.
+ * https://dwm.suckless.org/patches/nodmenu/
+ */
+#define NODMENU_PATCH 1
+
+/* This patch allows for toggleable client button bindings that have no modifiers.
+ * This can, for example, allow you to move or resize using the mouse alone without holding
+ * down a modifier key. This can be practical if you have extra buttons on your mouse.
+ * While you can use button bindings with no modifiers without this patch in a bare dwm,
+ * those buttons are then unavailable for use within the application itself so being able to
+ * toggle these on and off can be necessary in certain situations (e.g. being able to use
+ * back and forward buttons in a browser).
+
+ * Example bindings:
+ *     { ClkClientWin,              0,              Button8,        movemouse,      {0} },
+ *     { ClkClientWin,              0,              Button9,        resizemouse,    {0} },
+ */
+#define NO_MOD_BUTTONS_PATCH 0
+
+/* When terminals have transparency then their borders also become transparent.
+ * This patch ensures that borders have no transparency. Note that this patch is
+ * only relevant if you are not using the alpha patch.
+ * https://github.com/szatanjl/dwm/commit/1529909466206016f2101457bbf37c67195714c8
+ * https://dwm.suckless.org/patches/alpha/dwm-fixborders-6.2.diff
+ */
+#define NO_TRANSPARENT_BORDERS_PATCH 0
+
+/* Port of InstantWM's on_empty_keys functionality allowing keybindings that apply only when
+ * a tag is empty. An example use case is being able to launch applications with first hand
+ * keys like "f" to launch firefox.
+ *
+ * https://github.com/instantOS/instantWM/
+ * https://github.com/bakkeby/dwm-flexipatch/issues/51
+ */
+#define ON_EMPTY_KEYS_PATCH 0
+
+/* Minor patch that prevents more than one rule being matched for a given client. */
+#define ONLY_ONE_RULE_MATCH_PATCH 0
+
+/* This patch makes it so dwm will only exit via quit() if no windows are open.
+ * This is to prevent you accidentally losing all your work.
+ * https://dwm.suckless.org/patches/onlyquitonempty/
+ */
+#define ONLYQUITONEMPTY_PATCH 0
+
+/* The pertag patch adds nmaster, mfacts and layouts per tag rather than per
+ * monitor (default).
+ * https://dwm.suckless.org/patches/pertag/
+ */
+#define PERTAG_PATCH 1
+
+/* Option to enable gaps on a per tag basis rather than globally.
+ * Depends on both pertag and vanitygaps patches being enabled.
+ */
+#define PERTAG_VANITYGAPS_PATCH 0
+
+/* This controls whether or not to also store bar position on a per
+ * tag basis, or leave it as one bar per monitor.
+ */
+#define PERTAGBAR_PATCH 0
+
+/* This patch lets you change the position of a client in the stack using the mouse.
+ * https://github.com/bakkeby/patches/wiki/placemouse
+ */
+#define PLACEMOUSE_PATCH 0
+
+/* This patch provides a way to move clients up and down inside the client list.
+ * https://dwm.suckless.org/patches/push/
+ */
+#define PUSH_PATCH 0
+
+/* This patch provides a way to move clients up and down inside the client list,
+ * but does not push up or down into the master area (except that it does not take
+ * nmaster into account).
+ * This takes precedence over the push patch above.
+ * https://dwm.suckless.org/patches/push/
+ */
+#define PUSH_NO_MASTER_PATCH 0
+
+/* Variant of the named scratchpads patch allowing scratch keys to be added or removed
+ * on demand, allowing multiple scratchpad windows to be toggled into and out of view
+ * in unison, as well as including multi-monitor support.
+ *
+ * https://github.com/bakkeby/patches/wiki/renamedscratchpads
+ */
+#define RENAMED_SCRATCHPADS_PATCH 1
+
+/* Renamed scratchpads option to auto-hide scratchpads when moving to a different tag.
+ * This behaviour is similar to that of the (multiple) scratchpads patch. */
+#define RENAMED_SCRATCHPADS_AUTO_HIDE_PATCH 1
+
+/* Shifts all clients per tag to leftmost unoccupied tags.
+ *
+ * For example, if clients A, B, C are tagged on tags 1, 5, 9 respectively, when
+ * this function is called, they will now be on 1, 2, and 3. The focused client
+ * will also remain focused.
+ *
+ * Clients on multiple tags will be treated as if they only were only on their
+ * leftmost tag, and will be reduced to one tag after the operation is complete.
+ * https://dwm.suckless.org/patches/reorganizetags/
+ */
+#define REORGANIZETAGS_PATCH 0
+
+/* By default, windows only resize from the bottom right corner. With this
+ * patch the mouse is warped to the nearest corner and you resize from there.
+ * https://dwm.suckless.org/patches/resizecorners/
+ */
+#define RESIZECORNERS_PATCH 0
+
+/* Practically the same as resizecorners, but the cursor does not warp to corners.
+ * This takes precedence over the resizecorners patch.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-resizepoint-6.2.diff
+ */
+#define RESIZEPOINT_PATCH 1
+
+/* Adds a keyboard shortcut to restart dwm or alternatively by using kill -HUP dwmpid.
+ * Additionally dwm can quit cleanly by using kill -TERM dwmpid.
+ * https://dwm.suckless.org/patches/restartsig/
+ */
+#define RESTARTSIG_PATCH 1
+
+/* Adds rio-like drawing to resize the selected client.
+ * This depends on an external tool slop being installed.
+ * This patch was backported from instantWM.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-riodraw-6.2.diff
+ */
+#define RIODRAW_PATCH 0
+
+/* This patch let's you rotate through the stack using keyboard shortcuts.
+ * https://dwm.suckless.org/patches/rotatestack/
+ */
+#define ROTATESTACK_PATCH 0
+
+/* This patch adds rounded corners to client windows in dwm.
+ * You need to uncomment the corresponding line in config.mk to use the -lXext library
+ * when including this patch. You will also want to set "borderpx = 0;" in your config.h.
+ * https://github.com/mitchweaver/suckless/blob/master/dwm/patches/mitch-06-rounded_corners-f04cac6d6e39cd9e3fc4fae526e3d1e8df5e34b2.patch
+ */
+#define ROUNDED_CORNERS_PATCH 0
+
+/* This patch saves size and position of every floating window before it is forced
+ * into tiled mode. If the window is made floating again then the old dimensions
+ * will be restored.
+ * https://dwm.suckless.org/patches/save_floats/
+ */
+#define SAVEFLOATS_PATCH 1
+
+/* The scratchpad patch allows you to spawn or restore floating terminal windows.
+ * It is typically useful when one need to do some short typing.
+ *
+ * Note that this patch changes TAGMASK to make room for special scratchpad tags,
+ * so ~0 does more than select all tags with this patch. Code that relies on ~0 to
+ * represent all tags should use ~SPTAGMASK instead.
+ *
+ * Upgraded to Christian Tenllado's multiple scratchpad version.
+ * https://lists.suckless.org/hackers/2004/17205.html
+ * https://dwm.suckless.org/patches/scratchpads/
+ */
+#define SCRATCHPADS_PATCH 0
+
+/* Minor alteration of the above allowing clients to keep their size and position when shown */
+#define SCRATCHPADS_KEEP_POSITION_AND_SIZE_PATCH 0
+
+/* This alternative patch enables a scratchpad feature in dwm similar to the scratchpad
+ * feature in i3wm.
+ * https://github.com/GasparVardanyan/dwm-scratchpad
+ */
+#define SCRATCHPAD_ALT_1_PATCH 0
+
+/* This patch persists some settings across window manager restarts. These include but are not
+ * limited to:
+ *    - client's assigned tag(s) on which monitor
+ *    - the order of clients
+ *    - nmaster
+ *    - selected layout
+ *    - plus various additions depending on what other patches are used
+ *
+ * The above is not persisted across reboots, however.
+ */
+#define SEAMLESS_RESTART_PATCH 1
+
+/* As opposed to the original patch this only adds a rule option allowing fake fullscreen
+ * to be enabled for applications when they start. This is intended to be used in combination
+ * with the fakefullscreenclient patch and offers no practical functionality without it.
+ * https://dwm.suckless.org/patches/selectivefakefullscreen/
+ */
+#define SELECTIVEFAKEFULLSCREEN_PATCH 0
+
+/* Allows restarting dwm without the dependency of an external script.
+ * https://dwm.suckless.org/patches/selfrestart/
+ */
+#define SELFRESTART_PATCH 0
+
+/* Floating windows being sent to another monitor will be centered.
+ * https://dwm.suckless.org/patches/sendmoncenter/
+ */
+#define SENDMON_CENTER_PATCH 0
+
+/* This patch allow clients to keep focus when being sent to another monitor.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-sendmon_keepfocus-6.2.diff
+ */
+#define SENDMON_KEEPFOCUS_PATCH 1
+
+/* This patch allows border pixels to be changed during runtime.
+ * https://dwm.suckless.org/patches/setborderpx/
+ */
+#define SETBORDERPX_PATCH 0
+
+/* Combines shifttag and shiftview. Basically moves the window to the next/prev tag and follows it.
+ * Also see the focusadjacenttag patch.
+ * https://dwm.suckless.org/patches/shift-tools/
+ */
+#define SHIFTBOTH_PATCH 0
+
+/* Swaps all the clients on the current tag with all the client on the next/prev tag.
+ * Depends on the swaptags patch.
+ * https://dwm.suckless.org/patches/shift-tools/
+ */
+#define SHIFTSWAPTAGS_PATCH 0
+
+/* Moves the current selected client to the adjacent tag.
+ * Also see the focusadjacenttag patch.
+ * https://dwm.suckless.org/patches/shift-tools/
+ */
+#define SHIFTTAG_PATCH 0
+
+/* Moves the current selected client to the adjacent tag that has at least one client, if none
+ * then it acts as shifttag.
+ * https://dwm.suckless.org/patches/shift-tools/
+ */
+#define SHIFTTAGCLIENTS_PATCH 0
+
+/* This patch adds keybindings for left and right circular shift through tags.
+ * https://github.com/chau-bao-long/dotfiles/blob/master/suckless/dwm/shiftview.diff
+ */
+#define SHIFTVIEW_PATCH 0
+
+/* This variant of the shiftview patch adds left and right circular shift through tags,
+ * but skips tags where there are no clients.
+ */
+#define SHIFTVIEW_CLIENTS_PATCH 0
+
+/* This patch makes dwm obey even "soft" sizehints for new clients. Any window
+ * that requests a specific initial size will be floated and set to that size.
+ * Unlike with "fixed size" windows, you are able to resize and/or unfloat these
+ * windows freely - only the initial state is affected.
+ * This version of the patch is honestly of limited utility since there are many
+ * clients that will abuse it.
+ * https://dwm.suckless.org/patches/sizehints/
+ */
+#define SIZEHINTS_PATCH 0
+
+/* This patch makes dwm obey even "soft" sizehints for new clients. This ruled
+ * version is essentially the same patch except it obeys the "isfloating" rule
+ * if it is available in config.h for the given client.
+ * https://dwm.suckless.org/patches/sizehints/
+ */
+#define SIZEHINTS_RULED_PATCH 0
+
+/* This patch makes dwm obey even "soft" sizehints for new clients. The isfreesize
+ * version is similar to the sizehints ruled patch except it allows you to specify
+ * via client rules which clients this should apply to. Soft sizehints applies by
+ * default to clients that are not ruled, and will be disabled by default for clients
+ * that are.
+ *
+ * Example client rule enabling soft sizehints:
+ *    - RULE(.wintype = WTYPE "DIALOG", .isfloating = 1, .isfreesize = 1)
+ *
+ * https://dwm.suckless.org/patches/sizehints/
+ */
+#define SIZEHINTS_ISFREESIZE_PATCH 1
+
+/* In a multi-head setup monitor 0 is by default the primary screen, with the left and right
+ * screen being monitor 1 and 2 respectively. This patch sorts screens left to right (or
+ * top to bottom in a vertical layout) which aims to address some inconsistencies when it
+ * comes to focusmon, tagmon and similar functionality.
+ * https://www.mail-archive.com/hackers@suckless.org/msg09400.html
+ */
+#define SORTSCREENS_PATCH 0
+
+/* Spawns programs from currently focused client's working directory.
+ * https://dwm.suckless.org/patches/spawn_cwd/
+ */
+#define SPAWNCMD_PATCH 0
+
+/* This patch provides comprehensive utilities for managing the client stack, providing
+ * keyboard shortcuts for focusing or placing a client at specific positions in the stack.
+ * Note that the default keybindings for this patch have been changed in dwm-flexipatch
+ * due to the many conflicts with other patches. As it provides similar functionality to the
+ * swapfocus patch it also uses the MOD+s shortcut to focus the previously selected client,
+ * thus note a conflict between these two patches.
+ * https://dwm.suckless.org/patches/stacker/
+ */
+#define STACKER_PATCH 1
+
+/* Steam, and steam windows (games), trigger a ConfigureNotify request every time the window
+ * gets focus. More so, the configure event passed along from Steam tends to have the wrong
+ * x and y co-ordinates which can make the window, if floating, jump around the screen.
+ *
+ * This patch works around this age-old issue by ignoring the x and y co-ordinates for
+ * ConfigureNotify requests relating to Steam windows.
+ *
+ * https://github.com/bakkeby/patches/wiki/steam
+ */
+#define STEAM_PATCH 0
+
+/* Adds toggleable keyboard shortcut to make a client 'sticky', i.e. visible on all tags.
+ * https://dwm.suckless.org/patches/sticky/
+ */
+#define STICKY_PATCH 0
+
+/* This patch adds "window swallowing" to dwm as known from Plan 9's windowing system rio.
+ * Clients marked with isterminal in config.h swallow a window opened by any child process,
+ * e.g. running xclock in a terminal. Closing the xclock window restores the terminal window
+ * in the current position.
+ *
+ * This patch depends on the following additional libraries:
+ *    - libxcb
+ *    - Xlib-libxcb
+ *    - xcb-res
+ *
+ * You need to uncomment the corresponding line in config.mk to use the above libraries when
+ * including this patch.
+ *
+ * https://dwm.suckless.org/patches/swallow/
+ */
+#define SWALLOW_PATCH 1
+
+/* This patch depends on the pertag patch and makes it possible to switch focus with a single
+ * shortcut (MOD+s) instead of having to think if you should use mod-j or mod-k for reaching
+ * the previously used window.
+ * https://dwm.suckless.org/patches/swapfocus/
+ */
+#define SWAPFOCUS_PATCH 0
+
+/* This patch allows swapping the contents of the currently selected tag with another tag using
+ * keyboard shortcuts.
+ * https://dwm.suckless.org/patches/swaptags/
+ */
+#define SWAPTAGS_PATCH 0
+
+/* Switch focus between the master and stack columns using a single keybinding.
+ * https://dwm.suckless.org/patches/switchcol/
+ */
+#define SWITCHCOL_PATCH 0
+
+/* By default dwm allow you to set application specific rules so that you can have your browser,
+ * for example, start up on tag 9 optionally on a given monitor when you open your browser it is
+ * then automatically moved to the configured tag, but you have to manually enable the tag to see
+ * the newly opened application.
+ * This patch adds an extra configuration option for individual rules where:
+ *   0 is default behaviour
+ *   1 automatically moves you to the tag of the newly opened application and
+ *   2 enables the tag of the newly opened application in addition to your existing enabled tags
+ *   3 as 1, but closing that window reverts the view back to what it was previously (*)
+ *   4 as 2, but closing that window reverts the view back to what it was previously (*)
+ *
+ * (*) except if the client has been moved between tags or to another monitor
+ *
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-switchtag-6.2.diff
+ * Also see https://dwm.suckless.org/patches/switchtotag
+ */
+#define SWITCHTAG_PATCH 0
+
+/* This patch transforms the monocle layout into a "tabbed" layout if more than one window is
+ * present on the monocle view. This patch has been added for demonstration purposes only and has
+ * limited compatibility with other patches. It will conflict space-wise with a second bar.
+ * Note that fancybar, awesomebar, bartabgroups and similar patches make the tab patch redundant.
+ * https://dwm.suckless.org/patches/tab/
+ */
+#define TAB_PATCH 0
+
+/* Adds keyboard shortcuts to move all (or only floating) windows from one tag to another.
+ * https://dwm.suckless.org/patches/tagall/
+ */
+#define TAGALL_PATCH 0
+
+/* This patch allows you to move all visible windows on a monitor to an adjacent monitor.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-tagallmon-6.2.diff
+ */
+#define TAGALLMON_PATCH 0
+
+/* This patch makes new clients attach into the stack area when you toggle a new tag into
+ * view. This means your master area will remain unchanged when toggling views.
+ * The allmaster patch will cause all clients in the master area to be left alone. This patch
+ * takes precedence over the onemaster tagintostack patch.
+ * https://dwm.suckless.org/patches/tagintostack/
+ */
+#define TAGINTOSTACK_ALLMASTER_PATCH 0
+
+/* This patch makes new clients attach into the stack area when you toggle a new tag into
+ * view. This means your master area will remain unchanged when toggling views.
+ * The onemaster patch will cause the first client in the master area to be left alone.
+ * https://dwm.suckless.org/patches/tagintostack/
+ */
+#define TAGINTOSTACK_ONEMASTER_PATCH 0
+
+/* If you try to send a fullscreen window to an adjacent monitor using tagmon then
+ * the window is moved behind the scenes, but it remains in fullscreen on the original
+ * monitor until you exit fullscreen view (at which point it will appear on the adjacent
+ * monitor). This patch allows a fullscreen window to be moved to an adjacent monitor
+ * while remaining in fullscreen.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-tagmonfixfs-6.2.diff
+ */
+#define TAGMONFIXFS_PATCH 1
+
+/* Add functions and keybindings to tag a window to a desired tag on the next (right)
+ * or previous (left) monitor from the currently selected monitor.
+ * https://dwm.suckless.org/patches/tagothermonitor/
+ */
+#define TAGOTHERMONITOR_PATCH 0
+
+/* This patch allows you to swap all visible windows on one monitor with those of an
+ * adjacent monitor.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-tagswapmon-6.2.diff
+ */
+#define TAGSWAPMON_PATCH 0
+
+/* Sync tag actions across all monitors.
+ * This is comparable to a sort of pseudo-desktop environment.
+ * Also refer to the desktop patch:
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-desktop-6.3.diff
+ */
+#define TAGSYNC_PATCH 0
+
+/* This patch can be useful to the touchpad users because it allows to
+ * resize windows using Mod + two-finger scroll. It is useful when
+ * two-finger scrolling is configured in libinput.
+ * https://dwm.suckless.org/patches/tapresize/
+ */
+#define TAPRESIZE_PATCH 0
+
+/* This patch allows you to toggle fullscreen on and off using a single shortcut key.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-togglefullscreen-6.2.diff
+ */
+#define TOGGLEFULLSCREEN_PATCH 1
+
+/* This patch allows for the bar position (top or bottom) to be toggled during runtime.
+ * https://dwm.suckless.org/patches/toggletopbar/
+ */
+#define TOGGLETOPBAR_PATCH 0
+
+/* Minor patch that lets you use the same keyboard shortcut to toggle to the previous layout if the
+ * designated layout is already active.
+ *
+ * This allows you to use e.g. MOD+m to change to the monocle layout and use the same keybinding to
+ * toggle back to what it was previously. The default behaviour in dwm forces you to use either
+ * MOD+space or MOD+t to change back to tiled layout.
+ *
+ * https://github.com/bakkeby/patches/wiki/togglelayout
+ */
+
+#define TOGGLELAYOUT_PATCH 1
+
+/* Minor patch that lets you use the same keyboard shortcut to toggle to the previous tag if the
+ * designated tag is already active.
+ *
+ * This allows you to use e.g. MOD+4 to quickly view the 4th tag and use the same keybinding to
+ * toggle back to what it was previously. The default behaviour in dwm forces you to use either
+ * MOD+tab or MOD+1 to change back to the previous tag.
+ *
+ * Idea ref.
+ * https://www.reddit.com/r/suckless/comments/ik27vd/key_toggle_between_next_and_previous_tag_dwm/
+ * https://github.com/bakkeby/patches/wiki/toggletag
+ */
+#define TOGGLETAG_PATCH 1
+
+/* Lets you transfer the currently focused client between the master and stack area
+ * while increasing or decreasing the master area (nmaster) accordingly.
+ * https://dwm.suckless.org/patches/transfer/
+ */
+#define TRANSFER_PATCH 0
+
+/* Lets you transfer all clients between the master and stack area
+ * while increasing or decreasing the master area (nmaster) accordingly.
+ * https://dwm.suckless.org/patches/transfer/
+ */
+#define TRANSFER_ALL_PATCH 0
+
+/* This patch resets isfloating on any visible windows that have it set.
+ * Optionally also applies a layout.
+ * https://dwm.suckless.org/patches/unfloatvisible/
+ */
+#define UNFLOATVISIBLE_PATCH 0
+
+/* This patch adds a client rule that allows for windows that do not specify the override-redirect
+ * to not be managed by the window manager. This can be useful for external bars, widgets,
+ * launchers, docks, desktop icons and more.
+ * https://github.com/bakkeby/patches/wiki/unmanaged
+ */
+#define UNMANAGED_PATCH 0
+
+/* This patch adds configurable gaps between windows differentiating between outer, inner,
+ * horizontal and vertical gaps.
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-vanitygaps-6.2.diff
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-cfacts-vanitygaps-6.2.diff
+ */
+#define VANITYGAPS_PATCH 0
+
+/* This patch adds outer gaps for the monocle layout.
+ * Most gaps patches tries to avoid gaps on the monocle layout, as it is often used as a
+ * fullscreen mode, hence this is enabled separately from the main vanitygaps patch.
+ */
+#define VANITYGAPS_MONOCLE_PATCH 0
+
+/* By default MOD+Tab will take the user back to the previous tag only. If the user keeps
+ * using MOD+Tab then the view will switch back and forth between the current and previous tag.
+ * This patch allows dwm to keep a longer history of previous tag changes such that MOD+Tab can
+ * be pressed multiple times to go further back to earlier tag selections.
+ *
+ * The number of history elements is defined by the NUMVIEWHIST macro in dwm.c and defaults to
+ * the number of tags in the system.
+ */
+#define VIEW_HISTORY_PATCH 0
+
+/* Follow a window to the tag it is being moved to.
+ * https://dwm.suckless.org/patches/viewontag/
+ */
+#define VIEWONTAG_PATCH 0
+
+/* This patch warps the mouse cursor to the center of the currently focused window or screen
+ * when the mouse cursor is (a) on a different screen or (b) on top of a different window.
+ * https://dwm.suckless.org/patches/warp/
+ */
+#define WARP_PATCH 1
+
+/* Sometimes a single application opens different windows depending on the task
+ * at hand and this is often reflected in the WM_WINDOW_ROLE(STRING) x property.
+ * This patch adds the role field to the rule configuration so that one can
+ * differentiate between, say, Firefox "browser" vs "Preferences" vs "Manager"
+ * or Google-chrome "browser" vs "pop-up".
+ * https://github.com/bakkeby/patches/blob/master/dwm/dwm-windowrolerule-6.2.diff
+ */
+#define WINDOWROLERULE_PATCH 1
+
+/* The winview patch allows switching the view to that of a given client from the all-window
+ * view (Mod-0) using a keyboard shortcut.
+ * http://dwm.suckless.org/patches/winview/
+ */
+#define WINVIEW_PATCH 1
+
+/* Remember keyboard layout per client.
+ * It is recommended that you configure xkb before using this patch as described in
+ * https://www.x.org/archive/X11R7.5/doc/input/XKB-Config.html
+ * https://dwm.suckless.org/patches/xkb/
+ */
+#define XKB_PATCH 0
+
+/* Allows dwm to read colors from xrdb (.Xresources) during runtime. Compatible with
+ * the float border color, awesomebar, urgentborder and titlecolor patches.
+ * https://dwm.suckless.org/patches/xrdb/
+ */
+#define XRDB_PATCH 1
+
+/* Simple patch that allows floating windows to be zoomed into the master stack position.
+ * https://www.reddit.com/r/suckless/comments/ie5fe3/zoomfloating_my_own_simple_original_patch/
+ */
+#define ZOOMFLOATING_PATCH 0
+
+/* The zoomswap patch allows a master and a stack window to swap places
+ * rather than every window on the screen changing position.
+ * https://dwm.suckless.org/patches/zoomswap/
+ */
+#define ZOOMSWAP_PATCH 0
+
+/**
+ * Layouts
+ */
+
+/* Bottomstack layout.
+ * https://dwm.suckless.org/patches/bottomstack/
+ */
+#define BSTACK_LAYOUT 0
+
+/* Bottomstack horizontal layout.
+ * https://dwm.suckless.org/patches/bottomstack/
+ */
+#define BSTACKHORIZ_LAYOUT 0
+
+/* Centered master layout.
+ * https://dwm.suckless.org/patches/centeredmaster/
+ */
+#define CENTEREDMASTER_LAYOUT 0
+
+/* Centered floating master layout.
+ * https://dwm.suckless.org/patches/centeredmaster/
+ */
+#define CENTEREDFLOATINGMASTER_LAYOUT 0
+
+/* Same as the default tile layout except clients in the master area are arranged in
+ * columns (i.e. left to right).
+ * https://dwm.suckless.org/patches/columns/
+ */
+#define COLUMNS_LAYOUT 0
+
+/* Deck layout.
+ * https://dwm.suckless.org/patches/deck/
+ */
+#define DECK_LAYOUT 0
+
+/* Fibonacci dwindle layout.
+ * https://dwm.suckless.org/patches/fibonacci/
+ */
+#define FIBONACCI_DWINDLE_LAYOUT 0
+
+/* Fibonacci spiral layout.
+ * https://dwm.suckless.org/patches/fibonacci/
+ */
+#define FIBONACCI_SPIRAL_LAYOUT 0
+
+/* Flextile deluxe layout.
+ * A revamped, more flexible, and over-the-top version of the original flextile layout.
+ * https://dwm.suckless.org/patches/flextile/ (original)
+ */
+#define FLEXTILE_DELUXE_LAYOUT 1
+
+/* Gappless grid layout.
+ * https://dwm.suckless.org/patches/gaplessgrid/
+ */
+#define GAPPLESSGRID_LAYOUT 0
+
+/* Gridmode (grid) layout.
+ * https://dwm.suckless.org/patches/gridmode/
+ */
+#define GRIDMODE_LAYOUT 0
+
+/* Horizontal grid (horizgrid) layout.
+ * https://dwm.suckless.org/patches/horizgrid/
+ */
+#define HORIZGRID_LAYOUT 0
+
+/* Grid layout where nmaster controls the number of rows.
+ * https://dwm.suckless.org/patches/nrowgrid/
+ */
+#define NROWGRID_LAYOUT 0
+
+/* The default tile layout.
+ * This can be optionally disabled in favour of other layouts.
+ */
+#define TILE_LAYOUT 0
+
+/* Monocle layout (default).
+ * This can be optionally disabled in favour of other layouts.
+ */
+#define MONOCLE_LAYOUT 1
diff --git a/todo b/todo
new file mode 100644
index 0000000..59e3862
--- /dev/null
+++ b/todo
@@ -0,0 +1 @@
+# TODO: customize layoutmenu patch
diff --git a/transient.c b/transient.c
deleted file mode 100644
index 158460f..0000000
--- a/transient.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* cc transient.c -o transient -lX11 */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-int main(void) {
-	Display *d;
-	Window r, f, t = None;
-	XSizeHints h;
-	XEvent e;
-
-	d = XOpenDisplay(NULL);
-	if (!d)
-		exit(1);
-	r = DefaultRootWindow(d);
-
-	f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
-	h.min_width = h.max_width = h.min_height = h.max_height = 400;
-	h.flags = PMinSize | PMaxSize;
-	XSetWMNormalHints(d, f, &h);
-	XStoreName(d, f, "floating");
-	XMapWindow(d, f);
-
-	XSelectInput(d, f, ExposureMask);
-	while (1) {
-		XNextEvent(d, &e);
-
-		if (t == None) {
-			sleep(5);
-			t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
-			XSetTransientForHint(d, t, f);
-			XStoreName(d, t, "transient");
-			XMapWindow(d, t);
-			XSelectInput(d, t, ExposureMask);
-		}
-	}
-
-	XCloseDisplay(d);
-	exit(0);
-}
-
diff --git a/util.c b/util.c
deleted file mode 100644
index 0cdc035..0000000
--- a/util.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "util.h"
-
-void
-die(const char *fmt, ...)
-{
-	va_list ap;
-	int saved_errno;
-
-	saved_errno = errno;
-	va_start(ap, fmt);
-	vfprintf(stderr, fmt, ap);
-	va_end(ap);
-
-	if (fmt[0] && fmt[strlen(fmt)-1] == ':')
-		fprintf(stderr, " %s", strerror(saved_errno));
-	fputc('\n', stderr);
-
-	exit(1);
-}
-
-void *
-ecalloc(size_t nmemb, size_t size)
-{
-	void *p;
-
-	if (!(p = calloc(nmemb, size)))
-		die("calloc:");
-	return p;
-}
diff --git a/util.h b/util.h
deleted file mode 100644
index 72ba202..0000000
--- a/util.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-#ifndef MAX
-#define MAX(A, B)               ((A) > (B) ? (A) : (B))
-#endif
-#ifndef MIN
-#define MIN(A, B)               ((A) < (B) ? (A) : (B))
-#endif
-#define BETWEEN(X, A, B)        ((A) <= (X) && (X) <= (B))
-#define LENGTH(X)               (sizeof (X) / sizeof (X)[0])
-
-#ifdef _DEBUG
-#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
-#else
-#define DEBUG(...)
-#endif
-
-void die(const char *fmt, ...);
-void *ecalloc(size_t nmemb, size_t size);
-