summaryrefslogtreecommitdiff
path: root/dwm/patches
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2025-03-08 15:21:28 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2025-03-08 15:21:28 +0900
commit4437d5b3c3eea76f6e2b0fd4a2ba21c02a098aeb (patch)
treee8dcb20bf144aacf88f93b012dccacdeb08015cd /dwm/patches
parentc2b06f0d5795a789f4ddab459179ff89aedfee98 (diff)
updates
Diffstat (limited to 'dwm/patches')
-rw-r--r--dwm/patches/alwaysontop-6.2.diff109
-rw-r--r--dwm/patches/dwm-accessnthmon.diff100
-rw-r--r--dwm/patches/dwm-actualfullscreen-20211013-cb3f58a.diff67
-rw-r--r--dwm/patches/dwm-allowkillrule-6.4.diff98
-rw-r--r--dwm/patches/dwm-alpha-20230401-348f655.diff287
-rw-r--r--dwm/patches/dwm-alttab2+winview-6.4.diff217
-rw-r--r--dwm/patches/dwm-alwayscenter-20200625-f04cac6.diff12
-rw-r--r--dwm/patches/dwm-bar-height-spacing-6.3.diff25
-rw-r--r--dwm/patches/dwm-barpadding-20211020-a786211.diff117
-rw-r--r--dwm/patches/dwm-bartoggle-keybinds-6.4.diff214
-rw-r--r--dwm/patches/dwm-borderrule-20231226-e7f651b.diff66
-rw-r--r--dwm/patches/dwm-bulkill-20231029-9f88553.diff85
-rw-r--r--dwm/patches/dwm-canfocusfloating-20210724-b914109.diff144
-rw-r--r--dwm/patches/dwm-cfacts-vanitygaps-6.4_combo.diff1018
-rw-r--r--dwm/patches/dwm-clientopacity-6.4.diff274
-rw-r--r--dwm/patches/dwm-clientresizehints-6.5.diff75
-rw-r--r--dwm/patches/dwm-colorbar-6.3.diff85
-rw-r--r--dwm/patches/dwm-exresize-r1606.diff372
-rw-r--r--dwm/patches/dwm-float-border-color-20231008-3a7ea45f.diff108
-rw-r--r--dwm/patches/dwm-floatborderwidth-6.3.diff68
-rw-r--r--dwm/patches/dwm-focusmaster-return-6.2.diff89
-rw-r--r--dwm/patches/dwm-gestures-6.4.diff126
-rw-r--r--dwm/patches/dwm-hide_vacant_tags-6.4.diff48
-rw-r--r--dwm/patches/dwm-keychord-6.4.diff234
-rw-r--r--dwm/patches/dwm-layoutmenu-6.2.diff88
-rw-r--r--dwm/patches/dwm-layoutscroll-6.2.diff67
-rw-r--r--dwm/patches/dwm-mark-new-6.2.diff247
-rw-r--r--dwm/patches/dwm-movecenter-6.5.diff41
-rw-r--r--dwm/patches/dwm-multimon-1-monitor_marker-6.4.diff194
-rw-r--r--dwm/patches/dwm-multimon-2-unified_view-6.4.diff181
-rw-r--r--dwm/patches/dwm-multimon-4-status_all-6.4.diff102
-rw-r--r--dwm/patches/dwm-multimon-6-swap_focus-6.4.diff185
-rw-r--r--dwm/patches/dwm-multimon-7-focus_on_active-6.4.diff59
-rw-r--r--dwm/patches/dwm-multiple-dynamic-scratchpads.diff207
-rw-r--r--dwm/patches/dwm-pertag_with_sel-20231003-9f88553.diff214
-rw-r--r--dwm/patches/dwm-preserveonrestart-6.3.diff118
-rw-r--r--dwm/patches/dwm-preventfocusshift-20240831-6.5.diff24
-rw-r--r--dwm/patches/dwm-refreshrate-20230826-9554a10.diff55
-rw-r--r--dwm/patches/dwm-resetlayout-6.2.diff64
-rw-r--r--dwm/patches/dwm-resetnmaster-pertag-6.3.diff36
-rw-r--r--dwm/patches/dwm-resizehere-20230824-e81f17d.diff60
-rw-r--r--dwm/patches/dwm-restartsig-20180523-6.2.diff138
-rw-r--r--dwm/patches/dwm-scratchpads-20200414-728d397b.diff198
-rw-r--r--dwm/patches/dwm-sendmoncenter-20210805-138b405f.diff27
-rw-r--r--dwm/patches/dwm-setborderpx-6.2.diff90
-rw-r--r--dwm/patches/dwm-shift-tools-6.2.diff55
-rw-r--r--dwm/patches/dwm-showselmon-6.2.diff46
-rw-r--r--dwm/patches/dwm-spawntag-6.2.diff84
-rw-r--r--dwm/patches/dwm-stacker-6.2.diff196
-rw-r--r--dwm/patches/dwm-stairs-fullgaps-20220430-8b48e30.diff98
-rw-r--r--dwm/patches/dwm-statuscmd-20241009-8933ebc.diff219
-rw-r--r--dwm/patches/dwm-sticky-6.5.diff145
-rw-r--r--dwm/patches/dwm-stickyindicator-6.2.diff65
-rw-r--r--dwm/patches/dwm-swallow-6.3.diff410
-rw-r--r--dwm/patches/dwm-switchallmonitortags-6.3.diff62
-rw-r--r--dwm/patches/dwm-taglabels-hide_vacant_tags_funcionality-6.2.diff91
-rw-r--r--dwm/patches/dwm-tiledmove-20231210-b731.diff82
-rw-r--r--dwm/patches/dwm-toggleallmonspertag-6.4.diff74
-rw-r--r--dwm/patches/dwm-toggleborder-6.3.diff52
-rw-r--r--dwm/patches/dwm-togglefloatingcenter-20210806-138b405f.diff30
-rw-r--r--dwm/patches/dwm-toggletopbar-barpadding-6.4.diff43
-rw-r--r--dwm/patches/dwm-unicode_ellipsis-20222909-d3f93c7.diff22
-rw-r--r--dwm/patches/dwm-xresources-20210827-138b405.diff239
-rw-r--r--dwm/patches/dwmblocks-statuscmd-20210402-96cbb45.diff126
64 files changed, 8572 insertions, 0 deletions
diff --git a/dwm/patches/alwaysontop-6.2.diff b/dwm/patches/alwaysontop-6.2.diff
new file mode 100644
index 0000000..1feb033
--- /dev/null
+++ b/dwm/patches/alwaysontop-6.2.diff
@@ -0,0 +1,109 @@
+# From 9cd160c4ba9c345c24644a7da77cc4f04fc93c4e Mon Sep 17 00:00:00 2001
+# From: Rob Pilling <robpilling@gmail.com>
+# Date: Mon, 27 Jul 2020 20:11:08 +0100
+# Subject: [PATCH] alwaysontop
+#
+# ---
+# config.def.h | 1 +
+# dwm.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
+# 2 files changed, 44 insertions(+), 2 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..c3c7edd 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -78,6 +78,7 @@ static Key keys[] = {
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_space, setlayout, {0} },
+ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
++ { MODKEY|ShiftMask, XK_space, togglealwaysontop, {0} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
+ { MODKEY, XK_comma, focusmon, {.i = -1 } },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..8d54b26 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -92,7 +92,7 @@ struct Client {
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh;
+ int bw, oldbw;
+ unsigned int tags;
+- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ int isfixed, iscentered, isfloating, isalwaysontop, isurgent, neverfocus, oldstate, isfullscreen;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void togglealwaysontop(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -732,8 +733,11 @@ drawbar(Monitor *m)
+ if (m->sel) {
+ drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+- if (m->sel->isfloating)
++ if (m->sel->isfloating) {
+ drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
++ if (m->sel->isalwaysontop)
++ drw_rect(drw, x + boxs, bh - boxw, boxw, boxw, 0, 0);
++ }
+ } else {
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, x, 0, w, bh, 1, 1);
+@@ -1356,6 +1360,17 @@ restack(Monitor *m)
+ return;
+ if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
+ XRaiseWindow(dpy, m->sel->win);
++
++ /* raise the aot window */
++ for(Monitor *m_search = mons; m_search; m_search = m_search->next){
++ for(c = m_search->clients; c; c = c->next){
++ if(c->isalwaysontop){
++ XRaiseWindow(dpy, c->win);
++ break;
++ }
++ }
++ }
++
+ if (m->lt[m->sellt]->arrange) {
+ wc.stack_mode = Below;
+ wc.sibling = m->barwin;
+@@ -1716,6 +1731,32 @@ togglefloating(const Arg *arg)
+ if (selmon->sel->isfloating)
+ resize(selmon->sel, selmon->sel->x, selmon->sel->y,
+ selmon->sel->w, selmon->sel->h, 0);
++ else
++ selmon->sel->isalwaysontop = 0; /* disabled, turn this off too */
++ arrange(selmon);
++}
++
++void
++togglealwaysontop(const Arg *arg)
++{
++ if (!selmon->sel)
++ return;
++ if (selmon->sel->isfullscreen)
++ return;
++
++ if(selmon->sel->isalwaysontop){
++ selmon->sel->isalwaysontop = 0;
++ }else{
++ /* disable others */
++ for(Monitor *m = mons; m; m = m->next)
++ for(Client *c = m->clients; c; c = c->next)
++ c->isalwaysontop = 0;
++
++ /* turn on, make it float too */
++ selmon->sel->isfloating = 1;
++ selmon->sel->isalwaysontop = 1;
++ }
++
+ arrange(selmon);
+ }
+
+--
+2.31.1
diff --git a/dwm/patches/dwm-accessnthmon.diff b/dwm/patches/dwm-accessnthmon.diff
new file mode 100644
index 0000000..a65ec15
--- /dev/null
+++ b/dwm/patches/dwm-accessnthmon.diff
@@ -0,0 +1,100 @@
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..8595a71 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -49,7 +49,10 @@ static const Layout layouts[] = {
+ { 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|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, \
++ { ALTMOD, KEY, focusnthmon, {.i = TAG } }, \
++ { ALTMOD|ShiftMask, KEY, tagnthmon, {.i = TAG } },
++
+
+ /* helper for spawning shell commands in the pre dwm-5.0 fashion */
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+diff --git a/dwm.c b/dwm.c
+index b0b3466..96fa0bd 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -161,6 +161,7 @@ static void destroynotify(XEvent *e);
+ static void detach(Client *c);
+ static void detachstack(Client *c);
+ static Monitor *dirtomon(int dir);
++static Monitor *numtomon(int num);
+ static void drawbar(Monitor *m);
+ static void drawbars(void);
+ static void enternotify(XEvent *e);
+@@ -168,6 +169,7 @@ static void expose(XEvent *e);
+ static void focus(Client *c);
+ static void focusin(XEvent *e);
+ static void focusmon(const Arg *arg);
++static void focusnthmon(const Arg *arg);
+ static void focusstack(const Arg *arg);
+ static Atom getatomprop(Client *c, Atom prop);
+ static int getrootptr(int *x, int *y);
+@@ -209,6 +211,7 @@ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
++static void tagnthmon(const Arg *arg);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+@@ -693,6 +696,18 @@ dirtomon(int dir)
+ return m;
+ }
+
++Monitor *
++numtomon(int num)
++{
++ Monitor *m = NULL;
++ int i = 0;
++
++ for(m = mons, i=0; m->next && i < num; m = m->next){
++ i++;
++ }
++ return m;
++}
++
+ void
+ drawbar(Monitor *m)
+ {
+@@ -830,6 +845,21 @@ focusmon(const Arg *arg)
+ focus(NULL);
+ }
+
++void
++focusnthmon(const Arg *arg)
++{
++ Monitor *m;
++
++ if (!mons->next)
++ return;
++
++ if ((m = numtomon(arg->i)) == selmon)
++ return;
++ unfocus(selmon->sel, 0);
++ selmon = m;
++ focus(NULL);
++}
++
+ void
+ focusstack(const Arg *arg)
+ {
+@@ -1671,6 +1701,14 @@ tagmon(const Arg *arg)
+ sendmon(selmon->sel, dirtomon(arg->i));
+ }
+
++void
++tagnthmon(const Arg *arg)
++{
++ if (!selmon->sel || !mons->next)
++ return;
++ sendmon(selmon->sel, numtomon(arg->i));
++}
++
+ void
+ tile(Monitor *m)
+ {
diff --git a/dwm/patches/dwm-actualfullscreen-20211013-cb3f58a.diff b/dwm/patches/dwm-actualfullscreen-20211013-cb3f58a.diff
new file mode 100644
index 0000000..364b3bd
--- /dev/null
+++ b/dwm/patches/dwm-actualfullscreen-20211013-cb3f58a.diff
@@ -0,0 +1,67 @@
+# From eea13010ffc3983392857ee1e3804e3aa1064d7a Mon Sep 17 00:00:00 2001
+# From: Soenke Lambert <s.lambert@mittwald.de>
+# Date: Wed, 13 Oct 2021 18:21:09 +0200
+# Subject: [PATCH] Fullscreen current window with [Alt]+[Shift]+[f]
+#
+# This actually fullscreens a window, instead of just hiding the statusbar
+# and applying the monocle layout.
+# ---
+# config.def.h | 1 +
+# dwm.1 | 3 +++
+# dwm.c | 8 ++++++++
+# 3 files changed, 12 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..8cd3204 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -78,6 +78,7 @@ static Key keys[] = {
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_space, setlayout, {0} },
+ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
++ { MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
+ { MODKEY, XK_comma, focusmon, {.i = -1 } },
+diff --git a/dwm.1 b/dwm.1
+index 13b3729..a368d05 100644
+--- a/dwm.1
++++ b/dwm.1
+@@ -116,6 +116,9 @@ Zooms/cycles focused window to/from master area (tiled layouts only).
+ .B Mod1\-Shift\-c
+ Close focused window.
+ .TP
++.B Mod1\-Shift\-f
++Toggle fullscreen for focused window.
++.TP
+ .B Mod1\-Shift\-space
+ Toggle focused window between tiled and floating state.
+ .TP
+diff --git a/dwm.c b/dwm.c
+index 4465af1..c1b899a 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void togglefullscr(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -1719,6 +1720,13 @@ togglefloating(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++togglefullscr(const Arg *arg)
++{
++ if(selmon->sel)
++ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
++}
++
+ void
+ toggletag(const Arg *arg)
+ {
+--
+2.30.2
diff --git a/dwm/patches/dwm-allowkillrule-6.4.diff b/dwm/patches/dwm-allowkillrule-6.4.diff
new file mode 100644
index 0000000..33365d7
--- /dev/null
+++ b/dwm/patches/dwm-allowkillrule-6.4.diff
@@ -0,0 +1,98 @@
+diff -up a/config.def.h b/config.def.h
+--- a/config.def.h 2022-10-04 19:38:18.000000000 +0200
++++ b/config.def.h 2023-05-06 22:19:27.298742237 +0200
+@@ -5,6 +5,7 @@ static const unsigned int borderpx = 1;
+ 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 allowkill = 1; /* allow killing clients by default? */
+ static const char *fonts[] = { "monospace:size=10" };
+ static const char dmenufont[] = "monospace:size=10";
+ static const char col_gray1[] = "#222222";
+@@ -26,9 +27,9 @@ static const Rule rules[] = {
+ * WM_CLASS(STRING) = instance, class
+ * WM_NAME(STRING) = title
+ */
+- /* class instance title tags mask isfloating monitor */
+- { "Gimp", NULL, NULL, 0, 1, -1 },
+- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
++ /* class instance title tags mask allowkill isfloating monitor */
++ { "Gimp", NULL, NULL, 0, 1, 1, -1 },
++ { "Firefox", NULL, NULL, 1 << 8, 1, 0, -1 },
+ };
+
+ /* layout(s) */
+@@ -78,6 +79,7 @@ static const Key keys[] = {
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_space, setlayout, {0} },
+ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
++ { MODKEY, XK_q, toggleallowkill,{0} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
+ { MODKEY, XK_comma, focusmon, {.i = -1 } },
+diff -up a/dwm.c b/dwm.c
+--- a/dwm.c 2022-10-04 19:38:18.000000000 +0200
++++ b/dwm.c 2023-05-06 22:18:43.239357744 +0200
+@@ -93,6 +93,7 @@ struct Client {
+ int bw, oldbw;
+ unsigned int tags;
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ int allowkill;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+@@ -137,6 +138,7 @@ typedef struct {
+ const char *instance;
+ const char *title;
+ unsigned int tags;
++ int allowkill;
+ int isfloating;
+ int monitor;
+ } Rule;
+@@ -212,6 +214,7 @@ static void tagmon(const Arg *arg);
+ static void tile(Monitor *m);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void toggleallowkill(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -288,6 +291,7 @@ applyrules(Client *c)
+ /* rule matching */
+ c->isfloating = 0;
+ c->tags = 0;
++ c->allowkill = allowkill;
+ XGetClassHint(dpy, c->win, &ch);
+ class = ch.res_class ? ch.res_class : broken;
+ instance = ch.res_name ? ch.res_name : broken;
+@@ -300,6 +304,7 @@ applyrules(Client *c)
+ {
+ c->isfloating = r->isfloating;
+ c->tags |= r->tags;
++ c->allowkill = r->allowkill;
+ for (m = mons; m && m->num != r->monitor; m = m->next);
+ if (m)
+ c->mon = m;
+@@ -1006,7 +1011,7 @@ keypress(XEvent *e)
+ void
+ killclient(const Arg *arg)
+ {
+- if (!selmon->sel)
++ if (!selmon->sel || !selmon->sel->allowkill)
+ return;
+ if (!sendevent(selmon->sel, wmatom[WMDelete])) {
+ XGrabServer(dpy);
+@@ -1704,6 +1709,13 @@ togglebar(const Arg *arg)
+ }
+
+ void
++toggleallowkill(const Arg *arg)
++{
++ if (!selmon->sel) return;
++ selmon->sel->allowkill = !selmon->sel->allowkill;
++}
++
++void
+ togglefloating(const Arg *arg)
+ {
+ if (!selmon->sel)
diff --git a/dwm/patches/dwm-alpha-20230401-348f655.diff b/dwm/patches/dwm-alpha-20230401-348f655.diff
new file mode 100644
index 0000000..8096f04
--- /dev/null
+++ b/dwm/patches/dwm-alpha-20230401-348f655.diff
@@ -0,0 +1,287 @@
+# From ad5887df95fda706291c81ee143d0786a1717b12 Mon Sep 17 00:00:00 2001
+# From: getimiskon <getimiskon@disroot.org>
+# Date: Sat, 1 Apr 2023 16:22:01 +0300
+# Subject: [PATCH] Allow dwm to have translucent bars, while keeping all the
+# text on it opaque, just like the alpha-patch for st. Updated for 348f655.
+#
+# ---
+# config.def.h | 7 +++++++
+# config.mk | 2 +-
+# drw.c | 26 ++++++++++++-----------
+# drw.h | 9 +++++---
+# dwm.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++------
+# 5 files changed, 81 insertions(+), 22 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..8b3789a 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -12,11 +12,18 @@ static const char col_gray2[] = "#444444";
+ static const char col_gray3[] = "#bbbbbb";
+ static const char col_gray4[] = "#eeeeee";
+ static const char col_cyan[] = "#005577";
++static const unsigned int baralpha = 0xd0;
++static const unsigned int borderalpha = OPAQUE;
+ static const char *colors[][3] = {
+ /* fg bg border */
+ [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+ [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ };
++static const unsigned int alphas[][3] = {
++ /* fg bg border*/
++ [SchemeNorm] = { OPAQUE, baralpha, borderalpha },
++ [SchemeSel] = { OPAQUE, baralpha, borderalpha },
++};
+
+ /* tagging */
+ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+diff --git a/config.mk b/config.mk
+index ba64d3d..d609c42 100644
+--- a/config.mk
++++ b/config.mk
+@@ -23,7 +23,7 @@ FREETYPEINC = /usr/include/freetype2
+
+ # includes and libs
+ INCS = -I${X11INC} -I${FREETYPEINC}
+-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
++LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender
+
+ # flags
+ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff --git a/drw.c b/drw.c
+index a58a2b4..d18e8d8 100644
+--- a/drw.c
++++ b/drw.c
+@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen)
+ }
+
+ Drw *
+-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
++drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
+ {
+ Drw *drw = ecalloc(1, sizeof(Drw));
+
+@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
+ 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);
++ drw->visual = visual;
++ drw->depth = depth;
++ drw->cmap = cmap;
++ drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
++ drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
+ XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
+
+ return drw;
+@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
+ 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));
++ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
+ }
+
+ void
+@@ -181,21 +184,22 @@ drw_fontset_free(Fnt *font)
+ }
+
+ void
+-drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
++drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
+ {
+ if (!drw || !dest || !clrname)
+ return;
+
+- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
+- DefaultColormap(drw->dpy, drw->screen),
++ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
+ clrname, dest))
+ die("error, cannot allocate color '%s'", clrname);
++
++ dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 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, const char *clrnames[], size_t clrcount)
++drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount)
+ {
+ size_t i;
+ Clr *ret;
+@@ -205,7 +209,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
+ return NULL;
+
+ for (i = 0; i < clrcount; i++)
+- drw_clr_create(drw, &ret[i], clrnames[i]);
++ drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
+ return ret;
+ }
+
+@@ -263,9 +267,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
+ } else {
+ XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+- d = XftDrawCreate(drw->dpy, drw->drawable,
+- DefaultVisual(drw->dpy, drw->screen),
+- DefaultColormap(drw->dpy, drw->screen));
++ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
+ x += lpad;
+ w -= lpad;
+ }
+diff --git a/drw.h b/drw.h
+index 6471431..2143533 100644
+--- a/drw.h
++++ b/drw.h
+@@ -20,6 +20,9 @@ typedef struct {
+ Display *dpy;
+ int screen;
+ Window root;
++ Visual *visual;
++ unsigned int depth;
++ Colormap cmap;
+ Drawable drawable;
+ GC gc;
+ Clr *scheme;
+@@ -27,7 +30,7 @@ typedef struct {
+ } Drw;
+
+ /* Drawable abstraction */
+-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
++Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
+ void drw_resize(Drw *drw, unsigned int w, unsigned int h);
+ void drw_free(Drw *drw);
+
+@@ -39,8 +42,8 @@ unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int
+ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
+
+ /* Colorscheme abstraction */
+-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
+-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
++void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
++Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
+
+ /* Cursor abstraction */
+ Cur *drw_cur_create(Drw *drw, int shape);
+diff --git a/dwm.c b/dwm.c
+index c2bd871..3b34de8 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -56,6 +56,7 @@
+ #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
+ #define TAGMASK ((1 << LENGTH(tags)) - 1)
+ #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
++#define OPAQUE 0xffU
+
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+@@ -232,6 +233,7 @@ 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 xinitvisual();
+ static void zoom(const Arg *arg);
+
+ /* variables */
+@@ -268,6 +270,11 @@ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
+
++static int useargb = 0;
++static Visual *visual;
++static int depth;
++static Colormap cmap;
++
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+
+@@ -1558,7 +1565,8 @@ setup(void)
+ sw = DisplayWidth(dpy, screen);
+ sh = DisplayHeight(dpy, screen);
+ root = RootWindow(dpy, screen);
+- drw = drw_create(dpy, screen, root, sw, sh);
++ xinitvisual();
++ drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap);
+ if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
+ die("no fonts could be loaded.");
+ lrpad = drw->fonts->h;
+@@ -1586,7 +1594,7 @@ setup(void)
+ /* init appearance */
+ scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
+ for (i = 0; i < LENGTH(colors); i++)
+- scheme[i] = drw_scm_create(drw, colors[i], 3);
++ scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3);
+ /* init bars */
+ updatebars();
+ updatestatus();
+@@ -1813,16 +1821,18 @@ updatebars(void)
+ Monitor *m;
+ XSetWindowAttributes wa = {
+ .override_redirect = True,
+- .background_pixmap = ParentRelative,
++ .background_pixel = 0,
++ .border_pixel = 0,
++ .colormap = cmap,
+ .event_mask = ButtonPressMask|ExposureMask
+ };
+ XClassHint ch = {"dwm", "dwm"};
+ for (m = mons; m; m = m->next) {
+ if (m->barwin)
+ continue;
+- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
+- CopyFromParent, DefaultVisual(dpy, screen),
+- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
++ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth,
++ InputOutput, visual,
++ CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
+ XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
+ XMapRaised(dpy, m->barwin);
+ XSetClassHint(dpy, m->barwin, &ch);
+@@ -2120,6 +2130,43 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
+ return -1;
+ }
+
++void
++xinitvisual()
++{
++ XVisualInfo *infos;
++ XRenderPictFormat *fmt;
++ int nitems;
++ int i;
++
++ XVisualInfo tpl = {
++ .screen = screen,
++ .depth = 32,
++ .class = TrueColor
++ };
++ long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
++
++ infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
++ visual = NULL;
++ for(i = 0; i < nitems; i ++) {
++ fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
++ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
++ visual = infos[i].visual;
++ depth = infos[i].depth;
++ cmap = XCreateColormap(dpy, root, visual, AllocNone);
++ useargb = 1;
++ break;
++ }
++ }
++
++ XFree(infos);
++
++ if (! visual) {
++ visual = DefaultVisual(dpy, screen);
++ depth = DefaultDepth(dpy, screen);
++ cmap = DefaultColormap(dpy, screen);
++ }
++}
++
+ void
+ zoom(const Arg *arg)
+ {
+--
+2.40.0
diff --git a/dwm/patches/dwm-alttab2+winview-6.4.diff b/dwm/patches/dwm-alttab2+winview-6.4.diff
new file mode 100644
index 0000000..38cb482
--- /dev/null
+++ b/dwm/patches/dwm-alttab2+winview-6.4.diff
@@ -0,0 +1,217 @@
+diff --git a/config.def.h b/config.def.h
+index 9efa774..95499bd 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -2,6 +2,8 @@
+
+ /* appearance */
+ static const unsigned int borderpx = 1; /* border pixel of windows */
++static const unsigned int tabModKey = 0x40;
++static const unsigned int tabCycleKey = 0x17;
+ 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 */
+@@ -95,6 +97,8 @@ static const Key keys[] = {
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY, XK_o, winview, {0} },
++ { Mod1Mask, XK_Tab, alttab, {0} },
+ };
+
+ /* button definitions */
+diff --git a/dwm.1 b/dwm.1
+index ddc8321..f8a809e 100644
+--- a/dwm.1
++++ b/dwm.1
+@@ -110,6 +110,9 @@ Increase master area size.
+ .B Mod1\-h
+ Decrease master area size.
+ .TP
++.B Mod1\-o
++Select view of the window in focus. The list of tags to be displayed is matched to the window tag list.
++.TP
+ .B Mod1\-Return
+ Zooms/cycles focused window to/from master area (tiled layouts only).
+ .TP
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..71d0ebc 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -28,6 +28,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <time.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <X11/cursorfont.h>
+@@ -142,6 +143,7 @@ typedef struct {
+ } Rule;
+
+ /* function declarations */
++static void alttab(const Arg *arg);
+ 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);
+@@ -168,6 +170,7 @@ static void expose(XEvent *e);
+ static void focus(Client *c);
+ static void focusin(XEvent *e);
+ static void focusmon(const Arg *arg);
++static void focusnext(const Arg *arg);
+ static void focusstack(const Arg *arg);
+ static Atom getatomprop(Client *c, Atom prop);
+ static int getrootptr(int *x, int *y);
+@@ -229,6 +232,7 @@ static void updatewmhints(Client *c);
+ static void view(const Arg *arg);
+ static Client *wintoclient(Window w);
+ static Monitor *wintomon(Window w);
++static void winview(const Arg* arg);
+ static int xerror(Display *dpy, XErrorEvent *ee);
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+@@ -268,6 +272,8 @@ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
+
++static int alt_tab_direction = 0;
++
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+
+@@ -275,6 +281,79 @@ static Window root, wmcheckwin;
+ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+
+ /* function implementations */
++
++static void
++alttab(const Arg *arg) {
++
++ view(&(Arg){ .ui = ~0 });
++ focusnext(&(Arg){ .i = alt_tab_direction });
++
++ int grabbed = 1;
++ int grabbed_keyboard = 1000;
++ for (int i = 0; i < 100; i += 1) {
++ struct timespec ts;
++ ts.tv_sec = 0;
++ ts.tv_nsec = 1000000;
++
++ if (grabbed_keyboard != GrabSuccess) {
++ grabbed_keyboard = XGrabKeyboard(dpy, DefaultRootWindow(dpy), True,
++ GrabModeAsync, GrabModeAsync, CurrentTime);
++ }
++ if (grabbed_keyboard == GrabSuccess) {
++ XGrabButton(dpy, AnyButton, AnyModifier, None, False,
++ BUTTONMASK, GrabModeAsync, GrabModeAsync,
++ None, None);
++ break;
++ }
++ nanosleep(&ts, NULL);
++ if (i == 100 - 1)
++ grabbed = 0;
++ }
++
++ XEvent event;
++ Client *c;
++ Monitor *m;
++ XButtonPressedEvent *ev;
++
++ while (grabbed) {
++ XNextEvent(dpy, &event);
++ switch (event.type) {
++ case KeyPress:
++ if (event.xkey.keycode == tabCycleKey)
++ focusnext(&(Arg){ .i = alt_tab_direction });
++ break;
++ case KeyRelease:
++ if (event.xkey.keycode == tabModKey) {
++ XUngrabKeyboard(dpy, CurrentTime);
++ XUngrabButton(dpy, AnyButton, AnyModifier, None);
++ grabbed = 0;
++ alt_tab_direction = !alt_tab_direction;
++ winview(0);
++ }
++ break;
++ case ButtonPress:
++ ev = &(event.xbutton);
++ if ((m = wintomon(ev->window)) && m != selmon) {
++ unfocus(selmon->sel, 1);
++ selmon = m;
++ focus(NULL);
++ }
++ if ((c = wintoclient(ev->window)))
++ focus(c);
++ XAllowEvents(dpy, AsyncBoth, CurrentTime);
++ break;
++ case ButtonRelease:
++ XUngrabKeyboard(dpy, CurrentTime);
++ XUngrabButton(dpy, AnyButton, AnyModifier, None);
++ grabbed = 0;
++ alt_tab_direction = !alt_tab_direction;
++ winview(0);
++ break;
++ }
++ }
++ return;
++}
++
+ void
+ applyrules(Client *c)
+ {
+@@ -835,6 +914,28 @@ focusmon(const Arg *arg)
+ focus(NULL);
+ }
+
++static void
++focusnext(const Arg *arg) {
++ Monitor *m;
++ Client *c;
++ m = selmon;
++ c = m->sel;
++
++ if (arg->i) {
++ if (c->next)
++ c = c->next;
++ else
++ c = m->clients;
++ } else {
++ Client *last = c;
++ if (last == m->clients)
++ last = NULL;
++ for (c = m->clients; c->next != last; c = c->next);
++ }
++ focus(c);
++ return;
++}
++
+ void
+ focusstack(const Arg *arg)
+ {
+@@ -2092,6 +2193,26 @@ wintomon(Window w)
+ return selmon;
+ }
+
++/* Selects for the view of the focused window. The list of tags */
++/* to be displayed is matched to the focused window tag list. */
++void
++winview(const Arg* arg){
++ Window win, win_r, win_p, *win_c;
++ unsigned nc;
++ int unused;
++ Client* c;
++ Arg a;
++
++ if (!XGetInputFocus(dpy, &win, &unused)) return;
++ while(XQueryTree(dpy, win, &win_r, &win_p, &win_c, &nc)
++ && win_p != win_r) win = win_p;
++
++ if (!(c = wintoclient(win))) return;
++
++ a.ui = c->tags;
++ view(&a);
++}
++
+ /* 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. */
diff --git a/dwm/patches/dwm-alwayscenter-20200625-f04cac6.diff b/dwm/patches/dwm-alwayscenter-20200625-f04cac6.diff
new file mode 100644
index 0000000..03ea9ef
--- /dev/null
+++ b/dwm/patches/dwm-alwayscenter-20200625-f04cac6.diff
@@ -0,0 +1,12 @@
+diff -up dwm/dwm.c dwmmod/dwm.c
+--- dwm/dwm.c 2020-06-25 00:21:30.383692180 -0300
++++ dwmmod/dwm.c 2020-06-25 00:20:35.643692330 -0300
+@@ -1057,6 +1057,8 @@ manage(Window w, XWindowAttributes *wa)
+ updatewindowtype(c);
+ updatesizehints(c);
+ updatewmhints(c);
++ c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
++ c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
+ XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
+ grabbuttons(c, 0);
+ if (!c->isfloating)
diff --git a/dwm/patches/dwm-bar-height-spacing-6.3.diff b/dwm/patches/dwm-bar-height-spacing-6.3.diff
new file mode 100644
index 0000000..cbdeb9a
--- /dev/null
+++ b/dwm/patches/dwm-bar-height-spacing-6.3.diff
@@ -0,0 +1,25 @@
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..9814500 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -5,6 +5,7 @@ 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 user_bh = 2; /* 2 is the default spacing around the bar's font */
+ static const char *fonts[] = { "monospace:size=10" };
+ static const char dmenufont[] = "monospace:size=10";
+ static const char col_gray1[] = "#222222";
+diff --git a/dwm.c b/dwm.c
+index 4465af1..2c27cb3 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -1545,7 +1545,7 @@ setup(void)
+ if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
+ die("no fonts could be loaded.");
+ lrpad = drw->fonts->h;
+- bh = drw->fonts->h + 2;
++ bh = drw->fonts->h + user_bh;
+ updategeom();
+ /* init atoms */
+ utf8string = XInternAtom(dpy, "UTF8_STRING", False);
diff --git a/dwm/patches/dwm-barpadding-20211020-a786211.diff b/dwm/patches/dwm-barpadding-20211020-a786211.diff
new file mode 100644
index 0000000..19a3150
--- /dev/null
+++ b/dwm/patches/dwm-barpadding-20211020-a786211.diff
@@ -0,0 +1,117 @@
+# From a3cfb215f7f647d83d67e33df8f33a73e43bd65f Mon Sep 17 00:00:00 2001
+# From: Bakkeby <bakkeby@gmail.com>
+# Date: Wed, 20 Oct 2021 09:14:07 +0200
+# Subject: [PATCH] barpadding: adds space between the statusbar and the edge of
+# the screen
+#
+# ---
+# config.def.h | 2 ++
+# dwm.c | 25 +++++++++++++++----------
+# 2 files changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index a2ac963..f0b739f 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -5,6 +5,8 @@ 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 vertpad = 10; /* vertical padding of bar */
++static const int sidepad = 10; /* horizontal padding of bar */
+ static const char *fonts[] = { "monospace:size=10" };
+ static const char dmenufont[] = "monospace:size=10";
+ static const char col_gray1[] = "#222222";
+diff --git a/dwm.c b/dwm.c
+index 5e4d494..df6d0d7 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -242,6 +242,8 @@ static int screen;
+ static int sw, sh; /* X display screen geometry width, height */
+ static int bh, blw = 0; /* bar geometry */
+ static int lrpad; /* sum of left and right padding for text */
++static int vp; /* vertical padding for bar */
++static int sp; /* side padding for bar */
+ static int (*xerrorxlib)(Display *, XErrorEvent *);
+ static unsigned int numlockmask = 0;
+ static void (*handler[LASTEvent]) (XEvent *) = {
+@@ -568,7 +570,7 @@ configurenotify(XEvent *e)
+ for (c = m->clients; c; c = c->next)
+ if (c->isfullscreen)
+ resizeclient(c, m->mx, m->my, m->mw, m->mh);
+- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
++ XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh);
+ }
+ focus(NULL);
+ arrange(NULL);
+@@ -706,7 +708,7 @@ drawbar(Monitor *m)
+ if (m == selmon) { /* status is only drawn on selected monitor */
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
++ drw_text(drw, m->ww - tw - 2 * sp, 0, tw, bh, 0, stext, 0);
+ }
+
+ for (c = m->clients; c; c = c->next) {
+@@ -732,12 +734,12 @@ drawbar(Monitor *m)
+ if ((w = m->ww - tw - x) > bh) {
+ if (m->sel) {
+ drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
++ drw_text(drw, x, 0, w - 2 * sp, bh, lrpad / 2, m->sel->name, 0);
+ if (m->sel->isfloating)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
+ } else {
+ drw_setscheme(drw, scheme[SchemeNorm]);
+- drw_rect(drw, x, 0, w, bh, 1, 1);
++ drw_rect(drw, x, 0, w - 2 * sp, bh, 1, 1);
+ }
+ }
+ drw_map(drw, m->barwin, 0, 0, m->ww, bh);
+@@ -1547,7 +1549,10 @@ setup(void)
+ die("no fonts could be loaded.");
+ lrpad = drw->fonts->h;
+ bh = drw->fonts->h + 2;
++ sp = sidepad;
++ vp = (topbar == 1) ? vertpad : - vertpad;
+ updategeom();
++
+ /* init atoms */
+ utf8string = XInternAtom(dpy, "UTF8_STRING", False);
+ wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
+@@ -1704,7 +1709,7 @@ togglebar(const Arg *arg)
+ {
+ selmon->showbar = !selmon->showbar;
+ updatebarpos(selmon);
+- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
++ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, bh);
+ arrange(selmon);
+ }
+
+@@ -1814,7 +1819,7 @@ updatebars(void)
+ for (m = mons; m; m = m->next) {
+ if (m->barwin)
+ continue;
+- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
++ m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh, 0, DefaultDepth(dpy, screen),
+ CopyFromParent, DefaultVisual(dpy, screen),
+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
+ XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
+@@ -1829,11 +1834,11 @@ updatebarpos(Monitor *m)
+ m->wy = m->my;
+ m->wh = m->mh;
+ if (m->showbar) {
+- m->wh -= bh;
+- m->by = m->topbar ? m->wy : m->wy + m->wh;
+- m->wy = m->topbar ? m->wy + bh : m->wy;
++ m->wh = m->wh - vertpad - bh;
++ m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad;
++ m->wy = m->topbar ? m->wy + bh + vp : m->wy;
+ } else
+- m->by = -bh;
++ m->by = -bh - vp;
+ }
+
+ void
+--
+2.33.0
diff --git a/dwm/patches/dwm-bartoggle-keybinds-6.4.diff b/dwm/patches/dwm-bartoggle-keybinds-6.4.diff
new file mode 100644
index 0000000..d06bedf
--- /dev/null
+++ b/dwm/patches/dwm-bartoggle-keybinds-6.4.diff
@@ -0,0 +1,214 @@
+# This patch adds keybinds to toggle each part of the dwm bar. This include the title, tags, layout indicator, status and floating indicator.
+# It also allows you to show/hide parts by default, similar to showbar.
+#
+# There is also a version without keybinds if you don't want keybinds, see the dwm-bartoggle-6.4.diff patch.
+
+diff -up a/config.def.h b/config.def.h
+--- a/config.def.h 2022-10-04 19:38:18.000000000 +0200
++++ b/config.def.h 2022-10-22 14:40:36.113933644 +0200
+@@ -4,6 +4,11 @@
+ 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 showtitle = 1; /* 0 means no title */
++static const int showtags = 1; /* 0 means no tags */
++static const int showlayout = 1; /* 0 means no layout indicator */
++static const int showstatus = 1; /* 0 means no status bar */
++static const int showfloating = 1; /* 0 means no floating indicator */
+ static const int topbar = 1; /* 0 means bottom bar */
+ static const char *fonts[] = { "monospace:size=10" };
+ static const char dmenufont[] = "monospace:size=10";
+@@ -78,6 +83,11 @@ static const Key keys[] = {
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_space, setlayout, {0} },
+ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
++ { MODKEY, XK_t, togglebartitle, {0} },
++ { MODKEY, XK_s, togglebarstatus,{0} },
++ { MODKEY|ShiftMask, XK_t, togglebartags, {0} },
++ { MODKEY|ShiftMask, XK_s, togglebarlt, {0} },
++ { MODKEY|ShiftMask, XK_f, togglebarfloat, {0} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
+ { MODKEY, XK_comma, focusmon, {.i = -1 } },
+diff -up a/dwm.c b/dwm.c
+--- a/dwm.c 2022-10-04 19:38:18.000000000 +0200
++++ b/dwm.c 2022-10-22 14:41:29.903932288 +0200
+@@ -123,6 +123,11 @@ struct Monitor {
+ unsigned int sellt;
+ unsigned int tagset[2];
+ int showbar;
++ int showtitle;
++ int showtags;
++ int showlayout;
++ int showstatus;
++ int showfloating;
+ int topbar;
+ Client *clients;
+ Client *sel;
+@@ -211,6 +216,11 @@ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *m);
+ static void togglebar(const Arg *arg);
++static void togglebartags(const Arg *arg);
++static void togglebartitle(const Arg *arg);
++static void togglebarlt(const Arg *arg);
++static void togglebarstatus(const Arg *arg);
++static void togglebarfloat(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+@@ -435,16 +445,17 @@ buttonpress(XEvent *e)
+ if (ev->window == selmon->barwin) {
+ i = x = 0;
+ do
+- x += TEXTW(tags[i]);
++ if (selmon->showtags)
++ x += TEXTW(tags[i]);
+ while (ev->x >= x && ++i < LENGTH(tags));
+- if (i < LENGTH(tags)) {
++ if (i < LENGTH(tags) && selmon->showtags) {
+ click = ClkTagBar;
+ arg.ui = 1 << i;
+- } else if (ev->x < x + TEXTW(selmon->ltsymbol))
++ } else if (ev->x < x + TEXTW(selmon->ltsymbol) && selmon->showlayout)
+ click = ClkLtSymbol;
+- else if (ev->x > selmon->ww - (int)TEXTW(stext))
++ else if (ev->x > selmon->ww - (int)TEXTW(stext) && selmon->showstatus)
+ click = ClkStatusText;
+- else
++ else if (selmon->showtitle)
+ click = ClkWinTitle;
+ } else if ((c = wintoclient(ev->window))) {
+ focus(c);
+@@ -641,6 +652,11 @@ createmon(void)
+ m->mfact = mfact;
+ m->nmaster = nmaster;
+ m->showbar = showbar;
++ m->showtitle = showtitle;
++ m->showtags = showtags;
++ m->showlayout = showlayout;
++ m->showstatus = showstatus;
++ m->showfloating = showfloating;
+ m->topbar = topbar;
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
+@@ -709,7 +725,7 @@ drawbar(Monitor *m)
+ return;
+
+ /* draw status first so it can be overdrawn by tags later */
+- if (m == selmon) { /* status is only drawn on selected monitor */
++ if (m == selmon && selmon->showstatus) { /* status is only drawn on selected monitor */
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+ drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+@@ -717,29 +733,35 @@ drawbar(Monitor *m)
+
+ for (c = m->clients; c; c = c->next) {
+ occ |= c->tags;
+- if (c->isurgent)
++ if (c->isurgent && selmon->showtags)
+ urg |= c->tags;
+ }
+ x = 0;
+ for (i = 0; i < LENGTH(tags); i++) {
+- w = TEXTW(tags[i]);
+- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+- if (occ & 1 << i)
+- drw_rect(drw, x + boxs, boxs, boxw, boxw,
+- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+- urg & 1 << i);
+- x += w;
+- }
+- w = TEXTW(m->ltsymbol);
+- drw_setscheme(drw, scheme[SchemeNorm]);
+- x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
++ if (selmon->showtags) {
++ w = TEXTW(tags[i]);
++ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
++ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
++ if (occ & 1 << i && selmon->showfloating)
++ drw_rect(drw, x + boxs, boxs, boxw, boxw,
++ m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
++ urg & 1 << i);
++ x += w;
++ }
++ }
++
++ /* draw layout indicator if selmon->showlayout */
++ if (selmon->showlayout) {
++ w = TEXTW(m->ltsymbol);
++ drw_setscheme(drw, scheme[SchemeNorm]);
++ x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
++ }
+
+ if ((w = m->ww - tw - x) > bh) {
+- if (m->sel) {
++ if (m->sel && selmon->showtitle) {
+ drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+- if (m->sel->isfloating)
++ if (m->sel->isfloating && selmon->showfloating)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
+ } else {
+ drw_setscheme(drw, scheme[SchemeNorm]);
+@@ -1238,7 +1260,7 @@ propertynotify(XEvent *e)
+ }
+ if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
+ updatetitle(c);
+- if (c == c->mon->sel)
++ if (c == c->mon->sel && selmon->showtitle)
+ drawbar(c->mon);
+ }
+ if (ev->atom == netatom[NetWMWindowType])
+@@ -1704,6 +1726,41 @@ togglebar(const Arg *arg)
+ }
+
+ void
++togglebartags(const Arg *arg)
++{
++ selmon->showtags = !selmon->showtags;
++ arrange(selmon);
++}
++
++void
++togglebartitle(const Arg *arg)
++{
++ selmon->showtitle = !selmon->showtitle;
++ arrange(selmon);
++}
++
++void
++togglebarlt(const Arg *arg)
++{
++ selmon->showlayout = !selmon->showlayout;
++ arrange(selmon);
++}
++
++void
++togglebarstatus(const Arg *arg)
++{
++ selmon->showstatus = !selmon->showstatus;
++ arrange(selmon);
++}
++
++void
++togglebarfloat(const Arg *arg)
++{
++ selmon->showfloating = !selmon->showfloating;
++ arrange(selmon);
++}
++
++void
+ togglefloating(const Arg *arg)
+ {
+ if (!selmon->sel)
+@@ -1987,7 +2044,7 @@ updatesizehints(Client *c)
+ void
+ updatestatus(void)
+ {
+- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
++ if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)) && selmon->showstatus)
+ strcpy(stext, "dwm-"VERSION);
+ drawbar(selmon);
+ }
diff --git a/dwm/patches/dwm-borderrule-20231226-e7f651b.diff b/dwm/patches/dwm-borderrule-20231226-e7f651b.diff
new file mode 100644
index 0000000..6426ba5
--- /dev/null
+++ b/dwm/patches/dwm-borderrule-20231226-e7f651b.diff
@@ -0,0 +1,66 @@
+# From e7f651b1321747fb92521522f0aa07a01160d4af Mon Sep 17 00:00:00 2001
+# From: Jasper Shovelton <Beanie.github@proton.me>
+# Date: Tue, 26 Dec 2023 12:57:35 +0000
+# Subject: [PATCH] Add a `borderpx` value to `rules` in `config.def.h`.
+#
+# ---
+# config.def.h | 6 +++---
+# dwm.c | 5 ++++-
+# 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..bdddfa5 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -26,9 +26,9 @@ static const Rule rules[] = {
+ * WM_CLASS(STRING) = instance, class
+ * WM_NAME(STRING) = title
+ */
+- /* class instance title tags mask isfloating monitor */
+- { "Gimp", NULL, NULL, 0, 1, -1 },
+- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
++ /* class instance title tags mask isfloating monitor border width */
++ { "Gimp", NULL, NULL, 0, 1, -1, -1 },
++ { "Firefox", NULL, NULL, 1 << 8, 0, -1, 0 },
+ };
+
+ /* layout(s) */
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..48403c2 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -139,6 +139,7 @@ typedef struct {
+ unsigned int tags;
+ int isfloating;
+ int monitor;
++ int bw;
+ } Rule;
+
+ /* function declarations */
+@@ -287,6 +288,7 @@ applyrules(Client *c)
+ /* rule matching */
+ c->isfloating = 0;
+ c->tags = 0;
++ c->bw = borderpx;
+ XGetClassHint(dpy, c->win, &ch);
+ class = ch.res_class ? ch.res_class : broken;
+ instance = ch.res_name ? ch.res_name : broken;
+@@ -299,6 +301,8 @@ applyrules(Client *c)
+ {
+ c->isfloating = r->isfloating;
+ c->tags |= r->tags;
++ if (r->bw != -1)
++ c->bw = r->bw;
+ for (m = mons; m && m->num != r->monitor; m = m->next);
+ if (m)
+ c->mon = m;
+@@ -1059,7 +1063,6 @@ manage(Window w, XWindowAttributes *wa)
+ 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);
+- c->bw = borderpx;
+
+ wc.border_width = c->bw;
+ XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+--
+2.43.0
diff --git a/dwm/patches/dwm-bulkill-20231029-9f88553.diff b/dwm/patches/dwm-bulkill-20231029-9f88553.diff
new file mode 100644
index 0000000..d4e6bc9
--- /dev/null
+++ b/dwm/patches/dwm-bulkill-20231029-9f88553.diff
@@ -0,0 +1,85 @@
+# From 70a21457fdbcbcdf26efb1329dd29872b7fcd8e3 Mon Sep 17 00:00:00 2001
+# From: ysl2 <www.songli.yu@gmail.com>
+# Date: Sun, 29 Oct 2023 15:45:05 +0800
+# Subject: [PATCH] Give killclient an augument to control the beheviour: arg.ui
+# == 0 for normal kill current client; arg.ui == 1 for kill other clients in
+# current tag (except current focusing client); arg.ui == 2 for kill all
+# clients in current tag (include focusing client).
+#
+# ---
+# config.def.h | 2 ++
+# dwm.c | 30 ++++++++++++++++++++++++------
+# 2 files changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..d39e6dd 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -74,6 +74,8 @@ static const Key keys[] = {
+ { MODKEY, XK_Return, zoom, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY|ShiftMask, XK_c, killclient, {0} },
++ { MODKEY|ControlMask, XK_c, killclient, {.ui = 1} }, // kill unselect
++ { MODKEY|ShiftMask|ControlMask, XK_c, killclient, {.ui = 2} }, // killall
+ { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
+ { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..011744d 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -177,6 +177,7 @@ static void grabbuttons(Client *c, int focused);
+ static void grabkeys(void);
+ static void incnmaster(const Arg *arg);
+ static void keypress(XEvent *e);
++static void killthis(Client *c);
+ static void killclient(const Arg *arg);
+ static void manage(Window w, XWindowAttributes *wa);
+ static void mappingnotify(XEvent *e);
+@@ -1013,21 +1014,38 @@ keypress(XEvent *e)
+ }
+
+ void
+-killclient(const Arg *arg)
+-{
+- if (!selmon->sel)
+- return;
+- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
++killthis(Client *c) {
++ if (!sendevent(c, wmatom[WMDelete])) {
+ XGrabServer(dpy);
+ XSetErrorHandler(xerrordummy);
+ XSetCloseDownMode(dpy, DestroyAll);
+- XKillClient(dpy, selmon->sel->win);
++ XKillClient(dpy, c->win);
+ XSync(dpy, False);
+ XSetErrorHandler(xerror);
+ XUngrabServer(dpy);
+ }
+ }
+
++void
++killclient(const Arg *arg)
++{
++ Client *c;
++
++ if (!selmon->sel)
++ return;
++
++ if (!arg->ui || arg->ui == 0) {
++ killthis(selmon->sel);
++ return;
++ }
++
++ for (c = selmon->clients; c; c = c->next) {
++ if (!ISVISIBLE(c) || (arg->ui == 1 && c == selmon->sel))
++ continue;
++ killthis(c);
++ }
++}
++
+ void
+ manage(Window w, XWindowAttributes *wa)
+ {
+--
+2.20.1
diff --git a/dwm/patches/dwm-canfocusfloating-20210724-b914109.diff b/dwm/patches/dwm-canfocusfloating-20210724-b914109.diff
new file mode 100644
index 0000000..851e4ed
--- /dev/null
+++ b/dwm/patches/dwm-canfocusfloating-20210724-b914109.diff
@@ -0,0 +1,144 @@
+# From b9141091994ba657af534453ab913663a8258f9a Mon Sep 17 00:00:00 2001
+# From: oxinosg <georgios.oxinos.extern@elinvar.de>
+# Date: Sat, 24 Jul 2021 23:31:30 +0200
+# Subject: [PATCH] [dwm][cantogglefloating] patch that allows disabling focus on
+# floating clients
+#
+# ---
+# config.def.h | 1 +
+# dwm.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++----
+# 2 files changed, 63 insertions(+), 5 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..005fb5d 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -70,6 +70,7 @@ static Key keys[] = {
+ { MODKEY, XK_d, incnmaster, {.i = -1 } },
+ { MODKEY, XK_h, setmfact, {.f = -0.05} },
+ { MODKEY, XK_l, setmfact, {.f = +0.05} },
++ { MODKEY, XK_s, togglecanfocusfloating, {0} },
+ { MODKEY, XK_Return, zoom, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY|ShiftMask, XK_c, killclient, {0} },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..ae0a0ea 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -92,7 +92,7 @@ struct Client {
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh;
+ int bw, oldbw;
+ unsigned int tags;
+- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, cantfocus;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+@@ -191,6 +191,7 @@ 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 resetcanfocusfloating();
+ static void restack(Monitor *m);
+ static void run(void);
+ static void scan(void);
+@@ -211,6 +212,7 @@ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void togglecanfocusfloating(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -788,6 +790,8 @@ focus(Client *c)
+ if (selmon->sel && selmon->sel != c)
+ unfocus(selmon->sel, 0);
+ if (c) {
++ if (c->cantfocus)
++ return;
+ if (c->mon != selmon)
+ selmon = c->mon;
+ if (c->isurgent)
+@@ -837,16 +841,16 @@ focusstack(const Arg *arg)
+ if (!selmon->sel)
+ return;
+ if (arg->i > 0) {
+- for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
++ for (c = selmon->sel->next; c && (!ISVISIBLE(c) || c->cantfocus); c = c->next);
+ if (!c)
+- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
++ for (c = selmon->clients; c && (!ISVISIBLE(c) || c->cantfocus); c = c->next);
+ } else {
+ for (i = selmon->clients; i != selmon->sel; i = i->next)
+- if (ISVISIBLE(i))
++ if (ISVISIBLE(i) && !i->cantfocus)
+ c = i;
+ if (!c)
+ for (; i; i = i->next)
+- if (ISVISIBLE(i))
++ if (ISVISIBLE(i) && !i->cantfocus)
+ c = i;
+ }
+ if (c) {
+@@ -1716,6 +1720,59 @@ togglefloating(const Arg *arg)
+ if (selmon->sel->isfloating)
+ resize(selmon->sel, selmon->sel->x, selmon->sel->y,
+ selmon->sel->w, selmon->sel->h, 0);
++
++ resetcanfocusfloating();
++
++ arrange(selmon);
++}
++
++void
++resetcanfocusfloating()
++{
++ unsigned int i, n;
++ Client *c;
++
++ for (n = 0, c = selmon->clients; c; c = c->next, n++);
++ if (n == 0)
++ return;
++
++ for (i = 0, c = selmon->clients; c; c = c->next, i++)
++ if (c->isfloating)
++ c->cantfocus = 0;
++
++ arrange(selmon);
++}
++
++void
++togglecanfocusfloating(const Arg *arg)
++{
++ unsigned int n;
++ Client *c, *cf = NULL;
++
++ if (!selmon->sel)
++ return;
++
++ for (c = selmon->clients; c; c = c->next)
++ if (c->cantfocus == 1) {
++ cf = c;
++ }
++
++ if (cf) {
++ resetcanfocusfloating();
++ focus(cf);
++ } else {
++ for (n = 0, c = selmon->clients; c; c = c->next)
++ if (c->isfloating)
++ c->cantfocus = !c->cantfocus;
++ else
++ n++;
++
++ if (n && selmon->sel->isfloating) {
++ c = nexttiled(selmon->clients);
++ focus(c);
++ }
++ }
++
+ arrange(selmon);
+ }
+
+--
+2.27.0
diff --git a/dwm/patches/dwm-cfacts-vanitygaps-6.4_combo.diff b/dwm/patches/dwm-cfacts-vanitygaps-6.4_combo.diff
new file mode 100644
index 0000000..371fce0
--- /dev/null
+++ b/dwm/patches/dwm-cfacts-vanitygaps-6.4_combo.diff
@@ -0,0 +1,1018 @@
+diff --git a/config.def.h b/config.def.h
+index 9efa774..357dc6f 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,6 +3,11 @@
+ /* appearance */
+ static const unsigned int borderpx = 1; /* border pixel of windows */
+ static const unsigned int snap = 32; /* snap pixel */
++static const unsigned int gappih = 20; /* horiz inner gap between windows */
++static const unsigned int gappiv = 10; /* vert inner gap between windows */
++static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */
++static const unsigned int gappov = 30; /* vert outer gap between windows and screen edge */
++static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
+ static const int showbar = 1; /* 0 means no bar */
+ static const int topbar = 1; /* 0 means bottom bar */
+ static const char *fonts[] = { "monospace:size=10" };
+@@ -37,11 +42,26 @@ static const int nmaster = 1; /* number of clients in master area */
+ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
+ static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
+
++#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */
++#include "vanitygaps.c"
++
+ static const Layout layouts[] = {
+ /* symbol arrange function */
+ { "[]=", tile }, /* first entry is default */
+- { "><>", NULL }, /* no layout function means floating behavior */
+ { "[M]", monocle },
++ { "[@]", spiral },
++ { "[\\]", dwindle },
++ { "H[]", deck },
++ { "TTT", bstack },
++ { "===", bstackhoriz },
++ { "HHH", grid },
++ { "###", nrowgrid },
++ { "---", horizgrid },
++ { ":::", gaplessgrid },
++ { "|M|", centeredmaster },
++ { ">M>", centeredfloatingmaster },
++ { "><>", NULL }, /* no layout function means floating behavior */
++ { NULL, NULL },
+ };
+
+ /* key definitions */
+@@ -71,7 +91,26 @@ static const Key keys[] = {
+ { MODKEY, XK_d, incnmaster, {.i = -1 } },
+ { MODKEY, XK_h, setmfact, {.f = -0.05} },
+ { MODKEY, XK_l, setmfact, {.f = +0.05} },
++ { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} },
++ { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} },
++ { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} },
+ { MODKEY, XK_Return, zoom, {0} },
++ { MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } },
++ { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } },
++ { MODKEY|Mod4Mask, XK_0, togglegaps, {0} },
++ { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY|ShiftMask, XK_c, killclient, {0} },
+ { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..5bbd733 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -87,6 +87,7 @@ typedef struct Client Client;
+ struct Client {
+ char name[256];
+ float mina, maxa;
++ float cfact;
+ int x, y, w, h;
+ int oldx, oldy, oldw, oldh;
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
+@@ -119,6 +120,10 @@ struct Monitor {
+ int by; /* bar geometry */
+ int mx, my, mw, mh; /* screen size */
+ int wx, wy, ww, wh; /* window area */
++ int gappih; /* horizontal gap between windows */
++ int gappiv; /* vertical gap between windows */
++ int gappoh; /* horizontal outer gaps */
++ int gappov; /* vertical outer gaps */
+ unsigned int seltags;
+ unsigned int sellt;
+ unsigned int tagset[2];
+@@ -201,6 +206,7 @@ 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 setcfact(const Arg *arg);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
+ static void seturgent(Client *c, int urg);
+@@ -208,7 +214,6 @@ 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 tile(Monitor *m);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+ static void toggletag(const Arg *arg);
+@@ -641,6 +646,10 @@ createmon(void)
+ m->nmaster = nmaster;
+ m->showbar = showbar;
+ m->topbar = topbar;
++ m->gappih = gappih;
++ m->gappiv = gappiv;
++ m->gappoh = gappoh;
++ m->gappov = gappov;
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+@@ -1043,6 +1052,7 @@ manage(Window w, XWindowAttributes *wa)
+ c->w = c->oldw = wa->width;
+ c->h = c->oldh = wa->height;
+ c->oldbw = wa->border_width;
++ c->cfact = 1.0;
+
+ updatetitle(c);
+ if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
+@@ -1521,6 +1531,24 @@ setlayout(const Arg *arg)
+ drawbar(selmon);
+ }
+
++void
++setcfact(const Arg *arg) {
++ float f;
++ Client *c;
++
++ c = selmon->sel;
++
++ if(!arg || !c || !selmon->lt[selmon->sellt]->arrange)
++ return;
++ f = arg->f + c->cfact;
++ if(arg->f == 0.0)
++ f = 1.0;
++ else if(f < 0.25 || f > 4.0)
++ return;
++ c->cfact = f;
++ arrange(selmon);
++}
++
+ /* arg > 1.0 will set mfact absolutely */
+ void
+ setmfact(const Arg *arg)
+@@ -1684,34 +1712,6 @@ tagmon(const Arg *arg)
+ sendmon(selmon->sel, dirtomon(arg->i));
+ }
+
+-void
+-tile(Monitor *m)
+-{
+- unsigned int i, n, h, mw, my, ty;
+- Client *c;
+-
+- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+- if (n == 0)
+- return;
+-
+- if (n > m->nmaster)
+- mw = m->nmaster ? m->ww * m->mfact : 0;
+- else
+- mw = m->ww;
+- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+- if (i < m->nmaster) {
+- h = (m->wh - my) / (MIN(n, m->nmaster) - i);
+- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
+- if (my + HEIGHT(c) < m->wh)
+- my += HEIGHT(c);
+- } else {
+- h = (m->wh - ty) / (n - i);
+- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
+- if (ty + HEIGHT(c) < m->wh)
+- ty += HEIGHT(c);
+- }
+-}
+-
+ void
+ togglebar(const Arg *arg)
+ {
+diff --git a/vanitygaps.c b/vanitygaps.c
+new file mode 100644
+index 0000000..1a816b6
+--- /dev/null
++++ b/vanitygaps.c
+@@ -0,0 +1,822 @@
++/* Key binding functions */
++static void defaultgaps(const Arg *arg);
++static void incrgaps(const Arg *arg);
++static void incrigaps(const Arg *arg);
++static void incrogaps(const Arg *arg);
++static void incrohgaps(const Arg *arg);
++static void incrovgaps(const Arg *arg);
++static void incrihgaps(const Arg *arg);
++static void incrivgaps(const Arg *arg);
++static void togglegaps(const Arg *arg);
++/* Layouts (delete the ones you do not need) */
++static void bstack(Monitor *m);
++static void bstackhoriz(Monitor *m);
++static void centeredmaster(Monitor *m);
++static void centeredfloatingmaster(Monitor *m);
++static void deck(Monitor *m);
++static void dwindle(Monitor *m);
++static void fibonacci(Monitor *m, int s);
++static void grid(Monitor *m);
++static void nrowgrid(Monitor *m);
++static void spiral(Monitor *m);
++static void tile(Monitor *m);
++/* Internals */
++static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
++static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr);
++static void setgaps(int oh, int ov, int ih, int iv);
++
++/* Settings */
++#if !PERTAG_PATCH
++static int enablegaps = 1;
++#endif // PERTAG_PATCH
++
++void
++setgaps(int oh, int ov, int ih, int iv)
++{
++ if (oh < 0) oh = 0;
++ if (ov < 0) ov = 0;
++ if (ih < 0) ih = 0;
++ if (iv < 0) iv = 0;
++
++ selmon->gappoh = oh;
++ selmon->gappov = ov;
++ selmon->gappih = ih;
++ selmon->gappiv = iv;
++ arrange(selmon);
++}
++
++void
++togglegaps(const Arg *arg)
++{
++ #if PERTAG_PATCH
++ selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
++ #else
++ enablegaps = !enablegaps;
++ #endif // PERTAG_PATCH
++ arrange(NULL);
++}
++
++void
++defaultgaps(const Arg *arg)
++{
++ setgaps(gappoh, gappov, gappih, gappiv);
++}
++
++void
++incrgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh + arg->i,
++ selmon->gappov + arg->i,
++ selmon->gappih + arg->i,
++ selmon->gappiv + arg->i
++ );
++}
++
++void
++incrigaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh,
++ selmon->gappov,
++ selmon->gappih + arg->i,
++ selmon->gappiv + arg->i
++ );
++}
++
++void
++incrogaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh + arg->i,
++ selmon->gappov + arg->i,
++ selmon->gappih,
++ selmon->gappiv
++ );
++}
++
++void
++incrohgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh + arg->i,
++ selmon->gappov,
++ selmon->gappih,
++ selmon->gappiv
++ );
++}
++
++void
++incrovgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh,
++ selmon->gappov + arg->i,
++ selmon->gappih,
++ selmon->gappiv
++ );
++}
++
++void
++incrihgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh,
++ selmon->gappov,
++ selmon->gappih + arg->i,
++ selmon->gappiv
++ );
++}
++
++void
++incrivgaps(const Arg *arg)
++{
++ setgaps(
++ selmon->gappoh,
++ selmon->gappov,
++ selmon->gappih,
++ selmon->gappiv + arg->i
++ );
++}
++
++void
++getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
++{
++ unsigned int n, oe, ie;
++ #if PERTAG_PATCH
++ oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
++ #else
++ oe = ie = enablegaps;
++ #endif // PERTAG_PATCH
++ Client *c;
++
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
++ if (smartgaps && n == 1) {
++ oe = 0; // outer gaps disabled when only one client
++ }
++
++ *oh = m->gappoh*oe; // outer horizontal gap
++ *ov = m->gappov*oe; // outer vertical gap
++ *ih = m->gappih*ie; // inner horizontal gap
++ *iv = m->gappiv*ie; // inner vertical gap
++ *nc = n; // number of clients
++}
++
++void
++getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
++{
++ unsigned int n;
++ float mfacts = 0, sfacts = 0;
++ int mtotal = 0, stotal = 0;
++ Client *c;
++
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
++ if (n < m->nmaster)
++ mfacts += c->cfact;
++ else
++ sfacts += c->cfact;
++
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
++ if (n < m->nmaster)
++ mtotal += msize * (c->cfact / mfacts);
++ else
++ stotal += ssize * (c->cfact / sfacts);
++
++ *mf = mfacts; // total factor of master area
++ *sf = sfacts; // total factor of stack area
++ *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split
++ *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts stack split
++}
++
++/***
++ * Layouts
++ */
++
++/*
++ * Bottomstack layout + gaps
++ * https://dwm.suckless.org/patches/bottomstack/
++ */
++static void
++bstack(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ 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;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ sh = mh = m->wh - 2*oh;
++ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
++ sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
++
++ if (m->nmaster && n > m->nmaster) {
++ sh = (mh - ih) * (1 - m->mfact);
++ mh = mh - ih - sh;
++ sx = mx;
++ sy = my + mh + ih;
++ }
++
++ 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 * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
++ mx += WIDTH(c) + iv;
++ } else {
++ resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
++ sx += WIDTH(c) + iv;
++ }
++ }
++}
++
++static void
++bstackhoriz(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ 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;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ mh = m->wh - 2*oh;
++ sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
++ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
++ sw = m->ww - 2*ov;
++
++ if (m->nmaster && n > m->nmaster) {
++ sh = (mh - ih) * (1 - m->mfact);
++ mh = mh - ih - sh;
++ sy = my + mh + ih;
++ sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
++ }
++
++ getfacts(m, mw, 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 * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
++ mx += WIDTH(c) + iv;
++ } else {
++ resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
++ sy += HEIGHT(c) + ih;
++ }
++ }
++}
++
++/*
++ * Centred master layout + gaps
++ * https://dwm.suckless.org/patches/centeredmaster/
++ */
++void
++centeredmaster(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int lx = 0, ly = 0, lw = 0, lh = 0;
++ int rx = 0, ry = 0, rw = 0, rh = 0;
++ float mfacts = 0, lfacts = 0, rfacts = 0;
++ int mtotal = 0, ltotal = 0, rtotal = 0;
++ int mrest = 0, lrest = 0, rrest = 0;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ /* initialize areas */
++ mx = m->wx + ov;
++ my = m->wy + oh;
++ mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
++ mw = m->ww - 2*ov;
++ lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
++ rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
++
++ if (m->nmaster && n > m->nmaster) {
++ /* go mfact box in the center if more than nmaster clients */
++ if (n - m->nmaster > 1) {
++ /* ||<-S->|<---M--->|<-S->|| */
++ mw = (m->ww - 2*ov - 2*iv) * m->mfact;
++ lw = (m->ww - mw - 2*ov - 2*iv) / 2;
++ rw = (m->ww - mw - 2*ov - 2*iv) - lw;
++ mx += lw + iv;
++ } else {
++ /* ||<---M--->|<-S->|| */
++ mw = (mw - iv) * m->mfact;
++ lw = 0;
++ rw = m->ww - mw - iv - 2*ov;
++ }
++ lx = m->wx + ov;
++ ly = m->wy + oh;
++ rx = mx + mw + iv;
++ ry = m->wy + oh;
++ }
++
++ /* calculate facts */
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
++ if (!m->nmaster || n < m->nmaster)
++ mfacts += c->cfact;
++ else if ((n - m->nmaster) % 2)
++ lfacts += c->cfact; // total factor of left hand stack area
++ else
++ rfacts += c->cfact; // total factor of right hand stack area
++ }
++
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
++ if (!m->nmaster || n < m->nmaster)
++ mtotal += mh * (c->cfact / mfacts);
++ else if ((n - m->nmaster) % 2)
++ ltotal += lh * (c->cfact / lfacts);
++ else
++ rtotal += rh * (c->cfact / rfacts);
++
++ mrest = mh - mtotal;
++ lrest = lh - ltotal;
++ rrest = rh - rtotal;
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
++ if (!m->nmaster || i < m->nmaster) {
++ /* nmaster clients are stacked vertically, in the center of the screen */
++ resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
++ my += HEIGHT(c) + ih;
++ } else {
++ /* stack clients are stacked vertically */
++ if ((i - m->nmaster) % 2 ) {
++ resize(c, lx, ly, lw - (2*c->bw), lh * (c->cfact / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
++ ly += HEIGHT(c) + ih;
++ } else {
++ resize(c, rx, ry, rw - (2*c->bw), rh * (c->cfact / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
++ ry += HEIGHT(c) + ih;
++ }
++ }
++ }
++}
++
++void
++centeredfloatingmaster(Monitor *m)
++{
++ unsigned int i, n;
++ float mfacts, sfacts;
++ float mivf = 1.0; // master inner vertical gap factor
++ int oh, ov, ih, iv, mrest, srest;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int sx = 0, sy = 0, sh = 0, sw = 0;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ sh = mh = m->wh - 2*oh;
++ mw = m->ww - 2*ov - iv*(n - 1);
++ sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
++
++ if (m->nmaster && n > m->nmaster) {
++ mivf = 0.8;
++ /* go mfact box in the center if more than nmaster clients */
++ if (m->ww > m->wh) {
++ mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
++ mh = m->wh * 0.9;
++ } else {
++ mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
++ mh = m->wh * m->mfact;
++ }
++ mx = m->wx + (m->ww - mw) / 2;
++ my = m->wy + (m->wh - mh - 2*oh) / 2;
++
++ sx = m->wx + ov;
++ sy = m->wy + oh;
++ sh = m->wh - 2*oh;
++ }
++
++ 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) {
++ /* nmaster clients are stacked horizontally, in the center of the screen */
++ resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
++ mx += WIDTH(c) + iv*mivf;
++ } else {
++ /* stack clients are stacked horizontally */
++ resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
++ sx += WIDTH(c) + iv;
++ }
++}
++
++/*
++ * Deck layout + gaps
++ * https://dwm.suckless.org/patches/deck/
++ */
++void
++deck(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ 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;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
++ sw = mw = m->ww - 2*ov;
++
++ if (m->nmaster && n > m->nmaster) {
++ sw = (mw - iv) * (1 - m->mfact);
++ mw = mw - iv - sw;
++ sx = mx + mw + iv;
++ sh = m->wh - 2*oh;
++ }
++
++ getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
++
++ if (n - m->nmaster > 0) /* override layout symbol */
++ snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
++
++ 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 * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
++ my += HEIGHT(c) + ih;
++ } else {
++ resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
++ }
++}
++
++/*
++ * Fibonacci layout + gaps
++ * https://dwm.suckless.org/patches/fibonacci/
++ */
++void
++fibonacci(Monitor *m, int s)
++{
++ unsigned int i, n;
++ int nx, ny, nw, nh;
++ int oh, ov, ih, iv;
++ int nv, hrest = 0, wrest = 0, r = 1;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ nx = m->wx + ov;
++ ny = m->wy + oh;
++ nw = m->ww - 2*ov;
++ nh = m->wh - 2*oh;
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
++ if (r) {
++ if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
++ || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
++ r = 0;
++ }
++ if (r && i < n - 1) {
++ if (i % 2) {
++ nv = (nh - ih) / 2;
++ hrest = nh - 2*nv - ih;
++ nh = nv;
++ } else {
++ nv = (nw - iv) / 2;
++ wrest = nw - 2*nv - iv;
++ nw = nv;
++ }
++
++ if ((i % 4) == 2 && !s)
++ nx += nw + iv;
++ else if ((i % 4) == 3 && !s)
++ ny += nh + ih;
++ }
++
++ if ((i % 4) == 0) {
++ if (s) {
++ ny += nh + ih;
++ nh += hrest;
++ }
++ else {
++ nh -= hrest;
++ ny -= nh + ih;
++ }
++ }
++ else if ((i % 4) == 1) {
++ nx += nw + iv;
++ nw += wrest;
++ }
++ else if ((i % 4) == 2) {
++ ny += nh + ih;
++ nh += hrest;
++ if (i < n - 1)
++ nw += wrest;
++ }
++ else if ((i % 4) == 3) {
++ if (s) {
++ nx += nw + iv;
++ nw -= wrest;
++ } else {
++ nw -= wrest;
++ nx -= nw + iv;
++ nh += hrest;
++ }
++ }
++ if (i == 0) {
++ if (n != 1) {
++ nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
++ wrest = 0;
++ }
++ ny = m->wy + oh;
++ }
++ else if (i == 1)
++ nw = m->ww - nw - iv - 2*ov;
++ i++;
++ }
++
++ resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
++ }
++}
++
++void
++dwindle(Monitor *m)
++{
++ fibonacci(m, 1);
++}
++
++void
++spiral(Monitor *m)
++{
++ fibonacci(m, 0);
++}
++
++/*
++ * Gappless grid layout + gaps (ironically)
++ * https://dwm.suckless.org/patches/gaplessgrid/
++ */
++void
++gaplessgrid(Monitor *m)
++{
++ unsigned int i, n;
++ int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
++ int oh, ov, ih, iv;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &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 - 2*oh - ih * (rows - 1)) / rows;
++ cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
++ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
++ crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
++ x = m->wx + ov;
++ y = m->wy + oh;
++
++ 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 - 2*oh - ih * (rows - 1)) / rows;
++ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
++ }
++ resize(c,
++ x,
++ y + rn*(ch + ih) + 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 + ih + (cn < crest ? 1 : 0);
++ cn++;
++ }
++ }
++}
++
++/*
++ * Gridmode layout + gaps
++ * https://dwm.suckless.org/patches/gridmode/
++ */
++void
++grid(Monitor *m)
++{
++ unsigned int i, n;
++ int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
++ int oh, ov, ih, iv;
++ Client *c;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++
++ /* grid dimensions */
++ for (rows = 0; rows <= n/2; rows++)
++ if (rows*rows >= n)
++ break;
++ cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
++
++ /* window geoms (cell height/width) */
++ ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
++ cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
++ chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
++ cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
++ cc = i / rows;
++ cr = i % rows;
++ cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
++ cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
++ resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
++ }
++}
++
++/*
++ * Horizontal grid layout + gaps
++ * https://dwm.suckless.org/patches/horizgrid/
++ */
++void
++horizgrid(Monitor *m) {
++ Client *c;
++ unsigned int n, i;
++ int oh, ov, ih, iv;
++ int mx = 0, my = 0, mh = 0, mw = 0;
++ int sx = 0, sy = 0, sh = 0, sw = 0;
++ int ntop, nbottom = 1;
++ float mfacts = 0, sfacts = 0;
++ int mrest, srest, mtotal = 0, stotal = 0;
++
++ /* Count windows */
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ if (n <= 2)
++ ntop = n;
++ else {
++ ntop = n / 2;
++ nbottom = n - ntop;
++ }
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ sh = mh = m->wh - 2*oh;
++ sw = mw = m->ww - 2*ov;
++
++ if (n > ntop) {
++ sh = (mh - ih) / 2;
++ mh = mh - ih - sh;
++ sy = my + mh + ih;
++ mw = m->ww - 2*ov - iv * (ntop - 1);
++ sw = m->ww - 2*ov - iv * (nbottom - 1);
++ }
++
++ /* calculate facts */
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ if (i < ntop)
++ mfacts += c->cfact;
++ else
++ sfacts += c->cfact;
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ if (i < ntop)
++ mtotal += mh * (c->cfact / mfacts);
++ else
++ stotal += sw * (c->cfact / sfacts);
++
++ mrest = mh - mtotal;
++ srest = sw - stotal;
++
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ if (i < ntop) {
++ resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
++ mx += WIDTH(c) + iv;
++ } else {
++ resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
++ sx += WIDTH(c) + iv;
++ }
++}
++
++/*
++ * nrowgrid layout + gaps
++ * https://dwm.suckless.org/patches/nrowgrid/
++ */
++void
++nrowgrid(Monitor *m)
++{
++ unsigned int n;
++ int ri = 0, ci = 0; /* counters */
++ int oh, ov, ih, iv; /* vanitygap settings */
++ unsigned int cx, cy, cw, ch; /* client geometry */
++ unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */
++ unsigned int cols, rows = m->nmaster + 1;
++ Client *c;
++
++ /* count clients */
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++
++ /* nothing to do here */
++ if (n == 0)
++ return;
++
++ /* force 2 clients to always split vertically */
++ if (FORCE_VSPLIT && n == 2)
++ rows = 1;
++
++ /* never allow empty rows */
++ if (n < rows)
++ rows = n;
++
++ /* define first row */
++ cols = n / rows;
++ uc = cols;
++ cy = m->wy + oh;
++ ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
++ uh = ch;
++
++ for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
++ if (ci == cols) {
++ uw = 0;
++ ci = 0;
++ ri++;
++
++ /* next row */
++ cols = (n - uc) / (rows - ri);
++ uc += cols;
++ cy = m->wy + oh + uh + ih;
++ uh += ch + ih;
++ }
++
++ cx = m->wx + ov + uw;
++ cw = (m->ww - 2*ov - uw) / (cols - ci);
++ uw += cw + iv;
++
++ resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
++ }
++}
++
++/*
++ * Default tile layout + gaps
++ */
++static void
++tile(Monitor *m)
++{
++ unsigned int i, n;
++ int oh, ov, ih, iv;
++ 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;
++
++ getgaps(m, &oh, &ov, &ih, &iv, &n);
++ if (n == 0)
++ return;
++
++ sx = mx = m->wx + ov;
++ sy = my = m->wy + oh;
++ mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
++ sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
++ sw = mw = m->ww - 2*ov;
++
++ if (m->nmaster && n > m->nmaster) {
++ sw = (mw - iv) * (1 - m->mfact);
++ mw = mw - iv - sw;
++ sx = mx + mw + iv;
++ }
++
++ 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 * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
++ my += HEIGHT(c) + ih;
++ } else {
++ resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
++ sy += HEIGHT(c) + ih;
++ }
++}
+\ No newline at end of file
diff --git a/dwm/patches/dwm-clientopacity-6.4.diff b/dwm/patches/dwm-clientopacity-6.4.diff
new file mode 100644
index 0000000..4564e08
--- /dev/null
+++ b/dwm/patches/dwm-clientopacity-6.4.diff
@@ -0,0 +1,274 @@
+# From 10dd5df95f551d81d0a814dcdb2bde20e405fb91 Mon Sep 17 00:00:00 2001
+# From: sympodius <mail@sympodius.net>
+# Date: Mon, 13 Mar 2023 16:28:16 +0000
+# Subject: [PATCH] [dwm][patch][clientopacity] Adds opacity on a per client
+# basis
+#
+# ---
+# config.def.h | 80 ++++++++++++++++++++++++++++------------------------
+# dwm.c | 61 ++++++++++++++++++++++++++++++++++++++-
+# 2 files changed, 103 insertions(+), 38 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..9ca812d 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -5,6 +5,8 @@ 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 double activeopacity = 0.9f; /* Window opacity when it's focused (0 <= opacity <= 1) */
++static const double inactiveopacity = 0.7f; /* Window opacity when it's inactive (0 <= opacity <= 1) */
+ static const char *fonts[] = { "monospace:size=10" };
+ static const char dmenufont[] = "monospace:size=10";
+ static const char col_gray1[] = "#222222";
+@@ -26,9 +28,9 @@ static const Rule rules[] = {
+ * WM_CLASS(STRING) = instance, class
+ * WM_NAME(STRING) = title
+ */
+- /* class instance title tags mask isfloating monitor */
+- { "Gimp", NULL, NULL, 0, 1, -1 },
+- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
++ /* class instance title tags mask isfloating focusopacity unfocusopacity monitor */
++ { "Gimp", NULL, NULL, 0, 1, 1.0, inactiveopacity, -1 },
++ { "Firefox", NULL, NULL, 1 << 8, 0, activeopacity, inactiveopacity, -1 },
+ };
+
+ /* layout(s) */
+@@ -61,40 +63,44 @@ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont,
+ static const char *termcmd[] = { "st", NULL };
+
+ 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} },
+- { MODKEY, XK_j, focusstack, {.i = +1 } },
+- { MODKEY, XK_k, focusstack, {.i = -1 } },
+- { 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, 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_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 } },
+- 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)
+- { MODKEY|ShiftMask, XK_q, quit, {0} },
++ /* modifier key function argument */
++ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
++ { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
++ { MODKEY, XK_b, togglebar, {0} },
++ { MODKEY, XK_j, focusstack, {.i = +1 } },
++ { MODKEY, XK_k, focusstack, {.i = -1 } },
++ { 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, 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_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 } },
++ { MODKEY|ShiftMask, XK_a, changefocusopacity, {.f = +0.025}},
++ { MODKEY|ShiftMask, XK_s, changefocusopacity, {.f = -0.025}},
++ { MODKEY|ShiftMask, XK_z, changeunfocusopacity, {.f = +0.025}},
++ { MODKEY|ShiftMask, XK_x, changeunfocusopacity, {.f = -0.025}},
++ 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)
++ { MODKEY|ShiftMask, XK_q, quit, {0} },
+ };
+
+ /* button definitions */
+diff --git a/dwm.c b/dwm.c
+index c2bd871..71cf33c 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -62,7 +62,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+ enum { SchemeNorm, SchemeSel }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
++ NetWMWindowTypeDialog, NetClientList, NetWMWindowsOpacity, NetLast }; /* EWMH atoms */
+ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
+ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
+ ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+@@ -95,6 +95,8 @@ struct Client {
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+ Client *next;
+ Client *snext;
++ double opacity;
++ double unfocusopacity;
+ Monitor *mon;
+ Window win;
+ };
+@@ -138,6 +140,8 @@ typedef struct {
+ const char *title;
+ unsigned int tags;
+ int isfloating;
++ double opacity;
++ double unfocusopacity;
+ int monitor;
+ } Rule;
+
+@@ -149,6 +153,8 @@ static void arrangemon(Monitor *m);
+ static void attach(Client *c);
+ static void attachstack(Client *c);
+ static void buttonpress(XEvent *e);
++static void changefocusopacity(const Arg *arg);
++static void changeunfocusopacity(const Arg *arg);
+ static void checkotherwm(void);
+ static void cleanup(void);
+ static void cleanupmon(Monitor *mon);
+@@ -185,6 +191,7 @@ static void monocle(Monitor *m);
+ static void motionnotify(XEvent *e);
+ static void movemouse(const Arg *arg);
+ static Client *nexttiled(Client *c);
++static void opacity(Client *c, double opacity);
+ static void pop(Client *c);
+ static void propertynotify(XEvent *e);
+ static void quit(const Arg *arg);
+@@ -287,6 +294,8 @@ applyrules(Client *c)
+ /* rule matching */
+ c->isfloating = 0;
+ c->tags = 0;
++ c->opacity = activeopacity;
++ c->unfocusopacity = inactiveopacity;
+ XGetClassHint(dpy, c->win, &ch);
+ class = ch.res_class ? ch.res_class : broken;
+ instance = ch.res_name ? ch.res_name : broken;
+@@ -299,6 +308,8 @@ applyrules(Client *c)
+ {
+ c->isfloating = r->isfloating;
+ c->tags |= r->tags;
++ c->opacity = r->opacity;
++ c->unfocusopacity = r->unfocusopacity;
+ for (m = mons; m && m->num != r->monitor; m = m->next);
+ if (m)
+ c->mon = m;
+@@ -457,6 +468,36 @@ buttonpress(XEvent *e)
+ buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
+ }
+
++void
++changefocusopacity(const Arg *arg)
++{
++ if (!selmon->sel)
++ return;
++ selmon->sel->opacity+=arg->f;
++ if(selmon->sel->opacity > 1.0)
++ selmon->sel->opacity = 1.0;
++
++ if(selmon->sel->opacity < 0.1)
++ selmon->sel->opacity = 0.1;
++
++ opacity(selmon->sel, selmon->sel->opacity);
++}
++
++void
++changeunfocusopacity(const Arg *arg)
++{
++ if (!selmon->sel)
++ return;
++ selmon->sel->unfocusopacity+=arg->f;
++ if(selmon->sel->unfocusopacity > 1.0)
++ selmon->sel->unfocusopacity = 1.0;
++
++ if(selmon->sel->unfocusopacity < 0.1)
++ selmon->sel->unfocusopacity = 0.1;
++
++ opacity(selmon->sel, selmon->sel->unfocusopacity);
++}
++
+ void
+ checkotherwm(void)
+ {
+@@ -803,6 +844,8 @@ focus(Client *c)
+ grabbuttons(c, 1);
+ XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
+ setfocus(c);
++ c->opacity = MIN(1.0, MAX(0, c->opacity));
++ opacity(c, c->opacity);
+ } else {
+ XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+ XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
+@@ -1052,6 +1095,7 @@ manage(Window w, XWindowAttributes *wa)
+ c->mon = selmon;
+ applyrules(c);
+ }
++ opacity(c, c->opacity);
+
+ if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
+ c->x = c->mon->wx + c->mon->ww - WIDTH(c);
+@@ -1209,6 +1253,18 @@ nexttiled(Client *c)
+ return c;
+ }
+
++void
++opacity(Client *c, double opacity)
++{
++ if(opacity > 0 && opacity < 1) {
++ unsigned long real_opacity[] = { opacity * 0xffffffff };
++ XChangeProperty(dpy, c->win, netatom[NetWMWindowsOpacity], XA_CARDINAL,
++ 32, PropModeReplace, (unsigned char *)real_opacity,
++ 1);
++ } else
++ XDeleteProperty(dpy, c->win, netatom[NetWMWindowsOpacity]);
++}
++
+ void
+ pop(Client *c)
+ {
+@@ -1579,6 +1635,7 @@ setup(void)
+ netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
+ netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+ netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
++ netatom[NetWMWindowsOpacity] = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
+ /* init cursors */
+ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
+ cursor[CurResize] = drw_cur_create(drw, XC_sizing);
+@@ -1760,6 +1817,8 @@ unfocus(Client *c, int setfocus)
+ if (!c)
+ return;
+ grabbuttons(c, 0);
++ c->unfocusopacity = MIN(1.0, MAX(0, c->unfocusopacity));
++ opacity(c, c->unfocusopacity);
+ XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
+ if (setfocus) {
+ XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+--
+2.39.2
diff --git a/dwm/patches/dwm-clientresizehints-6.5.diff b/dwm/patches/dwm-clientresizehints-6.5.diff
new file mode 100644
index 0000000..8c35e8b
--- /dev/null
+++ b/dwm/patches/dwm-clientresizehints-6.5.diff
@@ -0,0 +1,75 @@
+# From b2de13e11e7b4d67b4982ef51befa87ed9202080 Mon Sep 17 00:00:00 2001
+# From: Fred Frey <fred@fpf3.net>
+# Date: Sun, 22 Sep 2024 16:09:53 -0400
+# Subject: [PATCH] implement per-client resizehints
+#
+# ---
+# config.def.h | 6 +++---
+# dwm.c | 7 +++++--
+# 2 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..67e7a9c 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -26,9 +26,9 @@ static const Rule rules[] = {
+ * WM_CLASS(STRING) = instance, class
+ * WM_NAME(STRING) = title
+ */
+- /* class instance title tags mask isfloating monitor */
+- { "Gimp", NULL, NULL, 0, 1, -1 },
+- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
++ /* class instance title tags mask isfloating monitor resizehints */
++ { "Gimp", NULL, NULL, 0, 1, -1, 1},
++ { "Firefox", NULL, NULL, 1 << 8, 0, -1, 1},
+ };
+
+ /* layout(s) */
+diff --git a/dwm.c b/dwm.c
+index 67c6b2b..f179b4c 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -92,7 +92,7 @@ struct Client {
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
+ int bw, oldbw;
+ unsigned int tags;
+- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, resizehints;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+@@ -139,6 +139,7 @@ typedef struct {
+ unsigned int tags;
+ int isfloating;
+ int monitor;
++ int resizehints;
+ } Rule;
+
+ /* function declarations */
+@@ -299,6 +300,7 @@ applyrules(Client *c)
+ {
+ c->isfloating = r->isfloating;
+ c->tags |= r->tags;
++ c->resizehints = r->resizehints;
+ for (m = mons; m && m->num != r->monitor; m = m->next);
+ if (m)
+ c->mon = m;
+@@ -343,7 +345,7 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
+ *h = bh;
+ if (*w < bh)
+ *w = bh;
+- if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
++ if (c->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 */
+@@ -1043,6 +1045,7 @@ manage(Window w, XWindowAttributes *wa)
+ c->w = c->oldw = wa->width;
+ c->h = c->oldh = wa->height;
+ c->oldbw = wa->border_width;
++ c->resizehints = resizehints;
+
+ updatetitle(c);
+ if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
+--
+2.46.0
diff --git a/dwm/patches/dwm-colorbar-6.3.diff b/dwm/patches/dwm-colorbar-6.3.diff
new file mode 100644
index 0000000..976a2e5
--- /dev/null
+++ b/dwm/patches/dwm-colorbar-6.3.diff
@@ -0,0 +1,85 @@
+# From 647a2a56cf7cab6dea868f9800671770940ce3c3 Mon Sep 17 00:00:00 2001
+# From: Alessandro Sisto <alessandro.sisto@studioform.net>
+# Date: Sun, 5 Jun 2022 12:03:43 +0200
+# Subject: [PATCH] colorbar
+#
+# ---
+# config.def.h | 6 +++++-
+# dwm.c | 12 ++++++------
+# 2 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index a2ac963..56bc324 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -16,6 +16,11 @@ static const char *colors[][3] = {
+ /* fg bg border */
+ [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+ [SchemeSel] = { col_gray4, col_cyan, col_cyan },
++ [SchemeStatus] = { col_gray3, col_gray1, "#000000" }, // Statusbar right {text,background,not used but cannot be empty}
++ [SchemeTagsSel] = { col_gray4, col_cyan, "#000000" }, // Tagbar left selected {text,background,not used but cannot be empty}
++ [SchemeTagsNorm] = { col_gray3, col_gray1, "#000000" }, // Tagbar left unselected {text,background,not used but cannot be empty}
++ [SchemeInfoSel] = { col_gray4, col_cyan, "#000000" }, // infobar middle selected {text,background,not used but cannot be empty}
++ [SchemeInfoNorm] = { col_gray3, col_gray1, "#000000" }, // infobar middle unselected {text,background,not used but cannot be empty}
+ };
+
+ /* tagging */
+@@ -113,4 +118,3 @@ static Button buttons[] = {
+ { ClkTagBar, MODKEY, Button1, tag, {0} },
+ { ClkTagBar, MODKEY, Button3, toggletag, {0} },
+ };
+-
+diff --git a/dwm.c b/dwm.c
+index a96f33c..0eaa4cd 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -59,7 +59,7 @@
+
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+-enum { SchemeNorm, SchemeSel }; /* color schemes */
++enum { SchemeNorm, SchemeSel, SchemeStatus, SchemeTagsSel, SchemeTagsNorm, SchemeInfoSel, SchemeInfoNorm }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+@@ -707,7 +707,7 @@ drawbar(Monitor *m)
+
+ /* draw status first so it can be overdrawn by tags later */
+ if (m == selmon) { /* status is only drawn on selected monitor */
+- drw_setscheme(drw, scheme[SchemeNorm]);
++ drw_setscheme(drw, scheme[SchemeStatus]);
+ tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+ drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+ }
+@@ -720,7 +720,7 @@ drawbar(Monitor *m)
+ x = 0;
+ for (i = 0; i < LENGTH(tags); i++) {
+ w = TEXTW(tags[i]);
+- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
++ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel : SchemeTagsNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+ if (occ & 1 << i)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw,
+@@ -729,17 +729,17 @@ drawbar(Monitor *m)
+ x += w;
+ }
+ w = blw = TEXTW(m->ltsymbol);
+- drw_setscheme(drw, scheme[SchemeNorm]);
++ drw_setscheme(drw, scheme[SchemeTagsNorm]);
+ x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
+
+ if ((w = m->ww - tw - x) > bh) {
+ if (m->sel) {
+- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
++ drw_setscheme(drw, scheme[m == selmon ? SchemeInfoSel : SchemeInfoNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+ if (m->sel->isfloating)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
+ } else {
+- drw_setscheme(drw, scheme[SchemeNorm]);
++ drw_setscheme(drw, scheme[SchemeInfoNorm]);
+ drw_rect(drw, x, 0, w, bh, 1, 1);
+ }
+ }
+--
+2.36.1
diff --git a/dwm/patches/dwm-exresize-r1606.diff b/dwm/patches/dwm-exresize-r1606.diff
new file mode 100644
index 0000000..dcc93c0
--- /dev/null
+++ b/dwm/patches/dwm-exresize-r1606.diff
@@ -0,0 +1,372 @@
+diff --git a/config.def.h b/config.def.h
+index 7fb4d82..959a119 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -88,6 +88,33 @@ static Key keys[] = {
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
++
++ { MODKEY, XK_KP_7, explace, {.ui = EX_NW }},
++ { MODKEY, XK_KP_8, explace, {.ui = EX_N }},
++ { MODKEY, XK_KP_9, explace, {.ui = EX_NE }},
++ { MODKEY, XK_KP_4, explace, {.ui = EX_W }},
++ { MODKEY, XK_KP_5, explace, {.ui = EX_C }},
++ { MODKEY, XK_KP_6, explace, {.ui = EX_E }},
++ { MODKEY, XK_KP_1, explace, {.ui = EX_SW }},
++ { MODKEY, XK_KP_2, explace, {.ui = EX_S }},
++ { MODKEY, XK_KP_3, explace, {.ui = EX_SE }},
++
++ { MODKEY|ShiftMask, XK_KP_8, exresize, {.v = (int []){ 0, 25 }}},
++ { MODKEY|ShiftMask, XK_KP_2, exresize, {.v = (int []){ 0, -25 }}},
++ { MODKEY|ShiftMask, XK_KP_6, exresize, {.v = (int []){ 25, 0 }}},
++ { MODKEY|ShiftMask, XK_KP_4, exresize, {.v = (int []){ -25, 0 }}},
++ { MODKEY|ShiftMask, XK_KP_5, exresize, {.v = (int []){ 25, 25 }}},
++ { MODKEY|ShiftMask|ControlMask, XK_KP_5, exresize, {.v = (int []){ -25, -25 }}},
++
++ { MODKEY|ControlMask, XK_KP_6, togglehorizontalexpand, {.i = +1} },
++ { MODKEY|ControlMask, XK_KP_3, togglehorizontalexpand, {.i = 0} },
++ { MODKEY|ControlMask, XK_KP_4, togglehorizontalexpand, {.i = -1} },
++ { MODKEY|ControlMask, XK_KP_8, toggleverticalexpand, {.i = +1} },
++ { MODKEY|ControlMask, XK_KP_1, toggleverticalexpand, {.i = 0} },
++ { MODKEY|ControlMask, XK_KP_2, toggleverticalexpand, {.i = -1} },
++ { MODKEY|ControlMask, XK_KP_9, togglemaximize, {.i = -1} },
++ { MODKEY|ControlMask, XK_KP_7, togglemaximize, {.i = +1} },
++ { MODKEY|ControlMask, XK_KP_5, togglemaximize, {.i = 0} },
+ };
+
+ /* button definitions */
+diff --git a/dwm.c b/dwm.c
+index 4986b07..8fc0c57 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -89,11 +89,14 @@ 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 */
+ int oldx, oldy, oldw, oldh;
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh;
+ int bw, oldbw;
+ unsigned int tags;
+- Bool isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ unsigned char expandmask;
++ int expandx1, expandy1, expandx2, expandy2;
++ Bool wasfloating, isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+@@ -1132,8 +1135,14 @@ manage(Window w, XWindowAttributes *wa) {
+ updatewindowtype(c);
+ updatesizehints(c);
+ updatewmhints(c);
++ c->sfx = c->x;
++ c->sfy = c->y;
++ c->sfw = c->w;
++ c->sfh = c->h;
+ XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
+ grabbuttons(c, False);
++ c->wasfloating = False;
++ c->expandmask = 0;
+ if(!c->isfloating)
+ c->isfloating = c->oldstate = trans != None || c->isfixed;
+ if(c->isfloating)
+@@ -1234,8 +1243,9 @@ movemouse(const Arg *arg) {
+ case MotionNotify:
+ nx = ocx + (ev.xmotion.x - x);
+ ny = ocy + (ev.xmotion.y - y);
+- if(nx >= selmon->wx && nx <= selmon->wx + selmon->ww
+- && ny >= selmon->wy && ny <= selmon->wy + selmon->wh) {
++ if ((m = recttomon(nx, ny, c->w, c->h))) {
++ if (m != selmon)
++ sendmon(c, m);
+ if(abs(selmon->wx - nx) < snap)
+ nx = selmon->wx;
+ else if(abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
+@@ -1343,6 +1353,7 @@ resizeclient(Client *c, int x, int y, int w, int h) {
+ c->oldy = c->y; c->y = wc.y = y;
+ c->oldw = c->w; c->w = wc.width = w;
+ c->oldh = c->h; c->h = wc.height = h;
++ c->expandmask = 0;
+ wc.border_width = c->bw;
+ XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
+ configure(c);
+@@ -1379,9 +1390,9 @@ resizemouse(const Arg *arg) {
+ case MotionNotify:
+ nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
+ nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 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 ((m = recttomon(c->x, c->y, nw, nh))) {
++ if (m != selmon)
++ sendmon(c, m);
+ if(!c->isfloating && selmon->lt[selmon->sellt]->arrange
+ && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
+ togglefloating(NULL);
+@@ -1463,6 +1474,7 @@ scan(void) {
+
+ void
+ sendmon(Client *c, Monitor *m) {
++ Monitor *oldm = selmon;
+ if(c->mon == m)
+ return;
+ unfocus(c, True);
+@@ -1472,8 +1484,11 @@ sendmon(Client *c, Monitor *m) {
+ c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
+ attach(c);
+ attachstack(c);
+- focus(NULL);
+- arrange(NULL);
++ if (oldm != m)
++ arrange(oldm);
++ arrange(m);
++ focus(c);
++ restack(m);
+ }
+
+ void
+@@ -1549,8 +1564,18 @@ setfullscreen(Client *c, Bool fullscreen) {
+
+ void
+ setlayout(const Arg *arg) {
+- if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
++ if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) {
+ selmon->sellt ^= 1;
++ if (!selmon->lt[selmon->sellt]->arrange) {
++ for (Client *c = selmon->clients ; c ; c = c->next) {
++ if(!c->isfloating) {
++ /*restore last known float dimensions*/
++ resize(c, selmon->mx + c->sfx, selmon->my + c->sfy,
++ c->sfw, c->sfh, False);
++ }
++ }
++ }
++ }
+ if(arg && arg->v)
+ selmon->lt[selmon->sellt] = (Layout *)arg->v;
+ strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
+@@ -1732,9 +1757,19 @@ togglefloating(const Arg *arg) {
+ if(selmon->sel->isfullscreen) /* no support for fullscreen windows */
+ return;
+ selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
+- if(selmon->sel->isfloating)
+- resize(selmon->sel, selmon->sel->x, selmon->sel->y,
+- selmon->sel->w, selmon->sel->h, False);
++ if(selmon->sel->isfloating) {
++ /*restore last known float dimensions*/
++ resize(selmon->sel, selmon->mx + selmon->sel->sfx, selmon->my + selmon->sel->sfy,
++ selmon->sel->sfw, selmon->sel->sfh, False);
++ } else {
++ if (selmon->sel->isfullscreen)
++ setfullscreen(selmon->sel, False);
++ /*save last known float dimensions*/
++ selmon->sel->sfx = selmon->sel->x - selmon->mx;
++ selmon->sel->sfy = selmon->sel->y - selmon->my;
++ selmon->sel->sfw = selmon->sel->w;
++ selmon->sel->sfh = selmon->sel->h;
++ }
+ arrange(selmon);
+ }
+
+diff --git a/exresize.c b/exresize.c
+new file mode 100644
+index 0000000..2343ffe
+--- /dev/null
++++ b/exresize.c
+@@ -0,0 +1,195 @@
++#define EXPAND_LEFT (1 << 0)
++#define EXPAND_RIGHT (1 << 2)
++#define EXPAND_UP (1 << 4)
++#define EXPAND_DOWN (1 << 6)
++
++#define IS_SET(q, w) ((q & w) != 0)
++#define IS_FORCED(q, w) IS_SET((q << 1), w)
++
++#define EXPANDALL (EXPAND_LEFT | EXPAND_RIGHT | EXPAND_UP | EXPAND_DOWN)
++#define UNEXPAND (EXPANDALL << 1) // Force all directions to 0
++#define FORCE_EXPANDALL ~0 // Force expand in all directions
++
++enum { EX_NW, EX_N, EX_NE, EX_W, EX_C, EX_E, EX_SW, EX_S, EX_SE };
++
++void expand(unsigned char mask);
++
++void togglemaximize(const Arg *arg);
++void toggleverticalexpand(const Arg *arg);
++void togglehorizontalexpand(const Arg *arg);
++void exresize(const Arg *arg);
++void explace(const Arg *arg);
++
++void
++exresize(const Arg *arg) {
++ Client *c;
++ int x, y, nx, ny, nw, nh;
++ c = selmon->sel;
++
++ if (!c || !arg) return;
++ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
++ togglefloating(NULL);
++ if (c->expandmask != 0)
++ expand(UNEXPAND);
++
++ x = ((int *)arg->v)[0];
++ y = ((int *)arg->v)[1];
++
++ nw = MIN(selmon->ww - c->bw*2, c->w + x);
++ nh = MIN(selmon->wh - c->bw*2, c->h + y);
++ nx = c->x - x/2;
++ ny = c->y - y/2;
++
++ if (!((abs(c->x + c->w/2 - (selmon->wx + selmon->ww/2)) < snap))) {
++ if ((nw == selmon->ww) ||
++ (nx < selmon->wx) ||
++ (abs(selmon->wx - c->x) < snap))
++ nx = selmon->wx;
++ else if ((nx+nw > (selmon->wx + selmon->ww)) ||
++ (abs((selmon->wx + selmon->ww) - (c->x + c->w)) < snap))
++ nx = (selmon->wx + selmon->ww) - nw - c->bw*2;
++ } else
++ nx = selmon->wx + selmon->ww/2 - nw/2;
++
++ if (!((abs(c->y + c->h/2 - (selmon->wy + selmon->wh/2)) < snap))) {
++
++ if ((nh == selmon->wh) ||
++ (ny < selmon->wy) ||
++ (abs(selmon->wy - c->y) < snap))
++ ny = selmon->wy;
++ else if ((ny+nh > (selmon->wy + selmon->wh)) ||
++ (abs((selmon->wy + selmon->wh) - (c->y + c->h)) < snap))
++ ny = (selmon->wy + selmon->wh) - nh - c->bw*2;
++ } else
++ ny = selmon->wy + selmon->wh/2 - nh/2;
++
++
++ resizeclient(c, nx, ny, MAX(nw, 32), MAX(nh, 32));
++ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
++}
++
++void
++explace(const Arg *arg) {
++ Client *c;
++ int nx, ny;
++
++ c = selmon->sel;
++ if (!c || (arg->ui >= 9)) return;
++ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
++ togglefloating(NULL);
++
++ nx = (arg->ui % 3) - 1;
++ ny = (arg->ui / 3) - 1;
++
++ if (nx < 0) nx = selmon->wx;
++ else if (nx > 0) nx = selmon->wx + selmon->ww - c->w - c->bw*2;
++ else nx = selmon->wx + selmon->ww/2 - c->w/2;
++
++ if (ny < 0) ny = selmon->wy;
++ else if (ny > 0) ny = selmon->wy + selmon->wh - c->h - c->bw*2;
++ else ny = selmon->wy + selmon->wh/2 - c->h/2;
++
++ resize(c, nx, ny, c->w, c->h, 0);
++ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
++}
++
++int
++calculate_expand(unsigned char mask, unsigned char curmask,
++ unsigned char *newmask, unsigned char key,
++ int *reset_value, int new_reset_value,
++ int max_value, int old_value) {
++ if (IS_SET(key, mask) ||
++ (IS_SET(key, curmask) && (!IS_SET(key, mask) && IS_FORCED(key, mask))) ||
++ (!IS_SET(key, curmask) && (IS_SET(key, mask) && IS_FORCED(key, mask)))) {
++
++ if (IS_SET(key, mask) && (!IS_SET(key,curmask) || IS_FORCED(key,mask)))
++ {
++ if (!IS_SET(key, curmask))
++ *reset_value = new_reset_value;
++ *newmask |= key;
++ return max_value;
++ } else if ((IS_SET(key,curmask) && IS_SET(key, mask)) ||
++ (!IS_SET(key, mask) && IS_FORCED(key, mask))) {
++ *newmask &= ~key;
++ return *reset_value;
++ } else {
++ *newmask &= ~key;
++ return old_value;
++ }
++ } else
++ return new_reset_value;
++}
++
++void
++expand(unsigned char mask) {
++ XEvent ev;
++ int nx1, ny1, nx2, ny2;
++ unsigned char curmask;
++ unsigned char newmask;
++
++ if(!selmon->sel || selmon->sel->isfixed)
++ return;
++ XRaiseWindow(dpy, selmon->sel->win);
++ newmask = curmask = selmon->sel->expandmask;
++
++ if (curmask == 0) {
++ if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating)
++ selmon->sel->wasfloating = 0;
++ else {
++ togglefloating(NULL);
++ selmon->sel->wasfloating = 0;
++ }
++ }
++
++ nx1 = calculate_expand(mask, curmask, &newmask,
++ EXPAND_LEFT, &selmon->sel->expandx1,
++ selmon->sel->x,
++ selmon->wx,
++ selmon->sel->oldx);
++ nx2 = calculate_expand(mask, curmask, &newmask,
++ EXPAND_RIGHT, &selmon->sel->expandx2,
++ selmon->sel->x + selmon->sel->w,
++ selmon->wx + selmon->ww - 2*borderpx,
++ selmon->sel->oldw + selmon->sel->x);
++ ny1 = calculate_expand(mask, curmask, &newmask,
++ EXPAND_UP, &selmon->sel->expandy1,
++ selmon->sel->y,
++ selmon->wy,
++ selmon->sel->oldy);
++ ny2 = calculate_expand(mask, curmask, &newmask,
++ EXPAND_DOWN, &selmon->sel->expandy2,
++ selmon->sel->y + selmon->sel->h,
++ selmon->wy + selmon->wh - 2*borderpx,
++ selmon->sel->oldh + selmon->sel->y);
++
++
++ resizeclient(selmon->sel, nx1, ny1, MAX(nx2-nx1, 32), MAX(ny2-ny1, 32));
++
++ if ((newmask == 0) && (!selmon->sel->wasfloating))
++ togglefloating(NULL);
++ selmon->sel->expandmask = newmask;
++ drawbar(selmon);
++ while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
++}
++
++void
++togglemaximize(const Arg *arg) {
++ if (arg->i > 0) expand(FORCE_EXPANDALL);
++ else if (arg->i < 0) expand(UNEXPAND);
++ else expand(EXPANDALL);
++}
++
++void
++toggleverticalexpand(const Arg *arg) {
++ if (arg->i < 0) expand(EXPAND_DOWN);
++ else if (arg->i > 0) expand(EXPAND_UP);
++ else expand(EXPAND_DOWN | EXPAND_UP);
++}
++
++void
++togglehorizontalexpand(const Arg *arg) {
++ if (arg->i < 0) expand(EXPAND_LEFT);
++ else if (arg->i > 0) expand(EXPAND_RIGHT);
++ else expand(EXPAND_LEFT | EXPAND_RIGHT);
++}
++
diff --git a/dwm/patches/dwm-float-border-color-20231008-3a7ea45f.diff b/dwm/patches/dwm-float-border-color-20231008-3a7ea45f.diff
new file mode 100644
index 0000000..dc1106b
--- /dev/null
+++ b/dwm/patches/dwm-float-border-color-20231008-3a7ea45f.diff
@@ -0,0 +1,108 @@
+# From 5f6716fa3fb7e28e6592872ce3de32b7aa0965a7 Mon Sep 17 00:00:00 2001
+# From: glpzzz <glpz@daxslab.com>
+# Date: Sun, 8 Oct 2023 16:44:37 -0400
+# Subject: [PATCH] set the custom colored floating border on unfocus too.
+#
+# ---
+# config.def.h | 8 ++++----
+# dwm.c | 24 ++++++++++++++++++++----
+# 2 files changed, 24 insertions(+), 8 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..ce68d1e 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -12,10 +12,10 @@ static const char col_gray2[] = "#444444";
+ static const char col_gray3[] = "#bbbbbb";
+ static const char col_gray4[] = "#eeeeee";
+ static const char col_cyan[] = "#005577";
+-static const char *colors[][3] = {
+- /* fg bg border */
+- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
++static const char *colors[][4] = {
++ /* fg bg border float */
++ [SchemeNorm] = { col_gray3, col_gray1, col_gray2, col_gray2 },
++ [SchemeSel] = { col_gray4, col_cyan, col_gray2, col_cyan },
+ };
+
+ /* tagging */
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..4182083 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -56,6 +56,7 @@
+ #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
+ #define TAGMASK ((1 << LENGTH(tags)) - 1)
+ #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
++#define ColFloat 3
+
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+@@ -801,7 +802,10 @@ focus(Client *c)
+ detachstack(c);
+ attachstack(c);
+ grabbuttons(c, 1);
+- XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
++ 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, root, RevertToPointerRoot, CurrentTime);
+@@ -1063,7 +1067,10 @@ manage(Window w, XWindowAttributes *wa)
+
+ wc.border_width = c->bw;
+ XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+- XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
++ 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 */
+ updatewindowtype(c);
+ updatesizehints(c);
+@@ -1074,6 +1081,8 @@ manage(Window w, XWindowAttributes *wa)
+ c->isfloating = c->oldstate = trans != None || c->isfixed;
+ if (c->isfloating)
+ XRaiseWindow(dpy, c->win);
++ if(c->isfloating)
++ XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColFloat].pixel);
+ attach(c);
+ attachstack(c);
+ XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
+@@ -1586,7 +1595,7 @@ setup(void)
+ /* init appearance */
+ scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
+ for (i = 0; i < LENGTH(colors); i++)
+- scheme[i] = drw_scm_create(drw, colors[i], 3);
++ scheme[i] = drw_scm_create(drw, colors[i], 4);
+ /* init bars */
+ updatebars();
+ updatestatus();
+@@ -1730,6 +1739,10 @@ togglefloating(const Arg *arg)
+ return;
+ selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
+ if (selmon->sel->isfloating)
++ XSetWindowBorder(dpy, selmon->sel->win, scheme[SchemeSel][ColFloat].pixel);
++ else
++ XSetWindowBorder(dpy, selmon->sel->win, scheme[SchemeSel][ColBorder].pixel);
++ if(selmon->sel->isfloating)
+ resize(selmon->sel, selmon->sel->x, selmon->sel->y,
+ selmon->sel->w, selmon->sel->h, 0);
+ arrange(selmon);
+@@ -1768,7 +1781,10 @@ unfocus(Client *c, int setfocus)
+ if (!c)
+ return;
+ grabbuttons(c, 0);
+- XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
++ 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]);
+--
+2.39.2
diff --git a/dwm/patches/dwm-floatborderwidth-6.3.diff b/dwm/patches/dwm-floatborderwidth-6.3.diff
new file mode 100644
index 0000000..d41bed2
--- /dev/null
+++ b/dwm/patches/dwm-floatborderwidth-6.3.diff
@@ -0,0 +1,68 @@
+# From 54b88e6663364d561fc0feb3ea9d4c79c0f4e3b0 Mon Sep 17 00:00:00 2001
+# From: Dylan Cairns-Howarth <dairnarth@dylancairns.co.uk>
+# Date: Sun, 20 Feb 2022 07:48:59 +0000
+# Subject: [PATCH] Floating Windows have seperate border width
+#
+# This dwm patch adds the int fborderpx to config.def.h that assigns a
+# border width to floating windows.
+#
+# By default, this patch sets borderpx to 0 and fborderpx to 1 (no borders
+# for tiled windows and a 1px border for floating windows).
+# ---
+# config.def.h | 4 ++--
+# dwm.c | 13 +++++++++++--
+# 2 files changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index a2ac963..ce35589 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -1,7 +1,8 @@
+ /* See LICENSE file for copyright and license details. */
+
+ /* appearance */
+-static const unsigned int borderpx = 1; /* border pixel of windows */
++static const unsigned int borderpx = 0; /* border pixel of windows */
++static const unsigned int fborderpx = 1; /* border pixel of floating 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 */
+@@ -113,4 +114,3 @@ static Button buttons[] = {
+ { ClkTagBar, MODKEY, Button1, tag, {0} },
+ { ClkTagBar, MODKEY, Button3, toggletag, {0} },
+ };
+-
+diff --git a/dwm.c b/dwm.c
+index a96f33c..a63e9cd 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -1052,6 +1052,8 @@ manage(Window w, XWindowAttributes *wa)
+ c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
+ && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
+ c->bw = borderpx;
++ if (c->isfloating)
++ c->bw = fborderpx;
+
+ wc.border_width = c->bw;
+ XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+@@ -1719,9 +1721,16 @@ togglefloating(const Arg *arg)
+ if (selmon->sel->isfullscreen) /* no support for fullscreen windows */
+ return;
+ selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
+- if (selmon->sel->isfloating)
++ if (selmon->sel->isfloating) {
++ selmon->sel->bw = fborderpx;
++ configure(selmon->sel);
++ int borderdiff = (fborderpx - borderpx) * 2;
+ resize(selmon->sel, selmon->sel->x, selmon->sel->y,
+- selmon->sel->w, selmon->sel->h, 0);
++ selmon->sel->w - borderdiff, selmon->sel->h - borderdiff, 0);
++ } else {
++ selmon->sel->bw = borderpx;
++ configure(selmon->sel);
++ }
+ arrange(selmon);
+ }
+
+--
+2.35.1
diff --git a/dwm/patches/dwm-focusmaster-return-6.2.diff b/dwm/patches/dwm-focusmaster-return-6.2.diff
new file mode 100644
index 0000000..9a02054
--- /dev/null
+++ b/dwm/patches/dwm-focusmaster-return-6.2.diff
@@ -0,0 +1,89 @@
+# From 8f662e7a556f94bda83ec724fb036e15b2badaac Mon Sep 17 00:00:00 2001
+# From: Jack Bird <jack.bird@durham.ac.uk>
+# Date: Fri, 27 Aug 2021 01:14:44 +0100
+# Subject: [PATCH] 6.2 focusmaster return
+#
+# ---
+# dwm.c | 39 +++++++++++++++++++++++++++++++++++++++
+# 1 file changed, 39 insertions(+)
+
+diff --git a/dwm.c b/dwm.c
+index 4465af1..5219cbd 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -127,6 +127,7 @@ struct Monitor {
+ Client *clients;
+ Client *sel;
+ Client *stack;
++ Client *tagmarked[32];
+ Monitor *next;
+ Window barwin;
+ const Layout *lt[2];
+@@ -167,6 +168,7 @@ static void enternotify(XEvent *e);
+ static void expose(XEvent *e);
+ static void focus(Client *c);
+ static void focusin(XEvent *e);
++static void focusmaster(const Arg *arg);
+ static void focusmon(const Arg *arg);
+ static void focusstack(const Arg *arg);
+ static int getrootptr(int *x, int *y);
+@@ -659,6 +661,10 @@ detach(Client *c)
+ {
+ Client **tc;
+
++ for (int i = 1; i < LENGTH(tags); i++)
++ if (c == c->mon->tagmarked[i])
++ c->mon->tagmarked[i] = NULL;
++
+ for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
+ *tc = c->next;
+ }
+@@ -815,6 +821,34 @@ focusin(XEvent *e)
+ setfocus(selmon->sel);
+ }
+
++void
++focusmaster(const Arg *arg)
++{
++ Client *master;
++
++ if (selmon->nmaster > 1)
++ return;
++ if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
++ return;
++
++ master = nexttiled(selmon->clients);
++
++ if (!master)
++ return;
++
++ int i;
++ for (i = 0; !(selmon->tagset[selmon->seltags] & 1 << i); i++);
++ i++;
++
++ if (selmon->sel == master) {
++ if (selmon->tagmarked[i] && ISVISIBLE(selmon->tagmarked[i]))
++ focus(selmon->tagmarked[i]);
++ } else {
++ selmon->tagmarked[i] = selmon->sel;
++ focus(master);
++ }
++}
++
+ void
+ focusmon(const Arg *arg)
+ {
+@@ -1202,6 +1236,11 @@ nexttiled(Client *c)
+ void
+ pop(Client *c)
+ {
++ int i;
++ for (i = 0; !(selmon->tagset[selmon->seltags] & 1 << i); i++);
++ i++;
++
++ c->mon->tagmarked[i] = nexttiled(c->mon->clients);
+ detach(c);
+ attach(c);
+ focus(c);
+--
+2.33.0
diff --git a/dwm/patches/dwm-gestures-6.4.diff b/dwm/patches/dwm-gestures-6.4.diff
new file mode 100644
index 0000000..d3ed528
--- /dev/null
+++ b/dwm/patches/dwm-gestures-6.4.diff
@@ -0,0 +1,126 @@
+diff -up a/config.def.h b/config.def.h
+--- a/config.def.h 2023-01-13 15:14:16.536118429 +0100
++++ b/config.def.h 2023-01-13 15:21:25.946360539 +0100
+@@ -78,6 +78,7 @@ static const Key keys[] = {
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_space, setlayout, {0} },
+ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
++ { MODKEY, XK_g, gesture, {0} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
+ { MODKEY, XK_comma, focusmon, {.i = -1 } },
+@@ -107,9 +108,21 @@ static const Button buttons[] = {
+ { ClkClientWin, MODKEY, Button1, movemouse, {0} },
+ { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
+ { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
++ { ClkClientWin, MODKEY|ShiftMask,Button3, gesture, {0} },
+ { ClkTagBar, 0, Button1, view, {0} },
+ { ClkTagBar, 0, Button3, toggleview, {0} },
+ { ClkTagBar, MODKEY, Button1, tag, {0} },
+ { ClkTagBar, MODKEY, Button3, toggletag, {0} },
+ };
+
++/* gestures
++ * u means up
++ * d means down
++ * l means left
++ * r means right
++ * ud means up and down
++ */
++static Gesture gestures[] = {
++ { "u", spawn, {.v = termcmd } },
++ { "d", spawn, {.v = dmenucmd } },
++};
+diff -up a/dwm.c b/dwm.c
+--- a/dwm.c 2023-01-13 15:14:16.536118429 +0100
++++ b/dwm.c 2023-01-13 15:14:41.094075080 +0100
+@@ -75,6 +75,12 @@ typedef union {
+ } Arg;
+
+ typedef struct {
++ char *gname;
++ void (*func)(const Arg *arg);
++ const Arg arg;
++} Gesture;
++
++typedef struct {
+ unsigned int click;
+ unsigned int mask;
+ unsigned int button;
+@@ -183,6 +189,7 @@ static void mappingnotify(XEvent *e);
+ static void maprequest(XEvent *e);
+ static void monocle(Monitor *m);
+ static void motionnotify(XEvent *e);
++static void gesture(const Arg *arg);
+ static void movemouse(const Arg *arg);
+ static Client *nexttiled(Client *c);
+ static void pop(Client *c);
+@@ -1134,6 +1141,68 @@ motionnotify(XEvent *e)
+ }
+
+ void
++gesture(const Arg *arg) {
++ int x, y, dx, dy, q;
++ int valid=0, listpos=0, gestpos=0, count=0;
++ char move, currGest[10];
++ XEvent ev;
++
++ if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
++ None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
++ return;
++ if(!getrootptr(&x, &y))
++ return;
++ do {
++ XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
++ switch (ev.type) {
++ case ConfigureRequest:
++ case Expose:
++ case MapRequest:
++ handler[ev.type](&ev);
++ break;
++ case MotionNotify:
++ if(count++ < 10)
++ break;
++ count = 0;
++ dx = ev.xmotion.x - x;
++ dy = ev.xmotion.y - y;
++ x = ev.xmotion.x;
++ y = ev.xmotion.y;
++
++ if( abs(dx)/(abs(dy)+1) == 0 )
++ move = dy<0?'u':'d';
++ else
++ move = dx<0?'l':'r';
++
++ if(move!=currGest[gestpos-1])
++ {
++ if(gestpos>9)
++ { ev.type++;
++ break;
++ }
++
++ currGest[gestpos] = move;
++ currGest[++gestpos] = '\0';
++
++ valid = 0;
++ for(q = 0; q<LENGTH(gestures); q++)
++ { if(!strcmp(currGest, gestures[q].gname))
++ { valid++;
++ listpos = q;
++ }
++ }
++ }
++
++ }
++ } while(ev.type != ButtonRelease);
++
++ if(valid)
++ gestures[listpos].func(&(gestures[listpos].arg));
++
++ XUngrabPointer(dpy, CurrentTime);
++}
++
++void
+ movemouse(const Arg *arg)
+ {
+ int x, y, ocx, ocy, nx, ny;
diff --git a/dwm/patches/dwm-hide_vacant_tags-6.4.diff b/dwm/patches/dwm-hide_vacant_tags-6.4.diff
new file mode 100644
index 0000000..42d9c05
--- /dev/null
+++ b/dwm/patches/dwm-hide_vacant_tags-6.4.diff
@@ -0,0 +1,48 @@
+:100644 100644 f1d86b2 0000000 M dwm.c
+
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..d41cc14 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -433,9 +433,15 @@ buttonpress(XEvent *e)
+ }
+ if (ev->window == selmon->barwin) {
+ i = x = 0;
+- do
++ unsigned int occ = 0;
++ for(c = m->clients; c; c=c->next)
++ occ |= c->tags == TAGMASK ? 0 : c->tags;
++ do {
++ /* Do not reserve space for vacant tags */
++ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
++ continue;
+ x += TEXTW(tags[i]);
+- while (ev->x >= x && ++i < LENGTH(tags));
++ } while (ev->x >= x && ++i < LENGTH(tags));
+ if (i < LENGTH(tags)) {
+ click = ClkTagBar;
+ arg.ui = 1 << i;
+@@ -715,19 +721,18 @@ drawbar(Monitor *m)
+ }
+
+ for (c = m->clients; c; c = c->next) {
+- occ |= c->tags;
++ occ |= c->tags == TAGMASK ? 0 : c->tags;
+ if (c->isurgent)
+ urg |= c->tags;
+ }
+ x = 0;
+ for (i = 0; i < LENGTH(tags); i++) {
++ /* Do not draw vacant tags */
++ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
++ continue;
+ w = TEXTW(tags[i]);
+ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+- if (occ & 1 << i)
+- drw_rect(drw, x + boxs, boxs, boxw, boxw,
+- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+- urg & 1 << i);
+ x += w;
+ }
+ w = TEXTW(m->ltsymbol);
diff --git a/dwm/patches/dwm-keychord-6.4.diff b/dwm/patches/dwm-keychord-6.4.diff
new file mode 100644
index 0000000..cd22e03
--- /dev/null
+++ b/dwm/patches/dwm-keychord-6.4.diff
@@ -0,0 +1,234 @@
+# From cb7ea178ac8e60cf123b333af64df8228762f669 Mon Sep 17 00:00:00 2001
+# From: =?UTF-8?q?Aaron=20Z=C3=BCger?= <contact@azureorange.xyz>
+# Date: Wed, 19 Jul 2023 14:17:39 +0200
+# Subject: [PATCH] Update dwm-keychord patch to comply with the changes in dwm
+# from version 6.2 to version 6.4. Namely changes in the grabkey function to
+# match the newer implementation of said function.
+#
+# ---
+# config.def.h | 81 ++++++++++++++++++++++++++--------------------------
+# dwm.c | 72 +++++++++++++++++++++++++++++++++++++---------
+# 2 files changed, 99 insertions(+), 54 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..49f0558 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -46,11 +46,11 @@ static const Layout layouts[] = {
+
+ /* 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 TAGKEYS(KEY,TAG) \
++ &((Keychord){1, {{MODKEY, KEY}}, view, {.ui = 1 << TAG} }), \
++ &((Keychord){1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }), \
++ &((Keychord){1, {{MODKEY|ShiftMask, KEY}}, tag, {.ui = 1 << TAG} }), \
++ &((Keychord){1, {{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 } }
+@@ -60,41 +60,42 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+ static const char *termcmd[] = { "st", NULL };
+
+-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} },
+- { MODKEY, XK_j, focusstack, {.i = +1 } },
+- { MODKEY, XK_k, focusstack, {.i = -1 } },
+- { 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, 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_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 } },
+- 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)
+- { MODKEY|ShiftMask, XK_q, quit, {0} },
++static Keychord *keychords[] = {
++ /* Keys function argument */
++ &((Keychord){1, {{MODKEY, XK_p}}, spawn, {.v = dmenucmd } }),
++ &((Keychord){1, {{MODKEY|ShiftMask, XK_Return}}, spawn, {.v = termcmd } }),
++ &((Keychord){2, {{MODKEY, XK_e}, {MODKEY, XK_e}}, spawn, {.v = termcmd } }),
++ &((Keychord){1, {{MODKEY, XK_b}}, togglebar, {0} }),
++ &((Keychord){1, {{MODKEY, XK_j}}, focusstack, {.i = +1 } }),
++ &((Keychord){1, {{MODKEY, XK_k}}, focusstack, {.i = -1 } }),
++ &((Keychord){1, {{MODKEY, XK_i}}, incnmaster, {.i = +1 } }),
++ &((Keychord){1, {{MODKEY, XK_d}}, incnmaster, {.i = -1 } }),
++ &((Keychord){1, {{MODKEY, XK_h}}, setmfact, {.f = -0.05} }),
++ &((Keychord){1, {{MODKEY, XK_l}}, setmfact, {.f = +0.05} }),
++ &((Keychord){1, {{MODKEY, XK_Return}}, zoom, {0} }),
++ &((Keychord){1, {{MODKEY, XK_Tab}}, view, {0} }),
++ &((Keychord){1, {{MODKEY|ShiftMask, XK_c}}, killclient, {0} }),
++ &((Keychord){1, {{MODKEY, XK_t}}, setlayout, {.v = &layouts[0]} }),
++ &((Keychord){1, {{MODKEY, XK_f}}, setlayout, {.v = &layouts[1]} }),
++ &((Keychord){1, {{MODKEY, XK_m}}, setlayout, {.v = &layouts[2]} }),
++ &((Keychord){1, {{MODKEY, XK_space}}, setlayout, {0} }),
++ &((Keychord){1, {{MODKEY|ShiftMask, XK_space}}, togglefloating, {0} }),
++ &((Keychord){1, {{MODKEY, XK_0}}, view, {.ui = ~0 } }),
++ &((Keychord){1, {{MODKEY|ShiftMask, XK_0}}, tag, {.ui = ~0 } }),
++ &((Keychord){1, {{MODKEY, XK_comma}}, focusmon, {.i = -1 } }),
++ &((Keychord){1, {{MODKEY, XK_period}}, focusmon, {.i = +1 } }),
++ &((Keychord){1, {{MODKEY|ShiftMask, XK_comma}}, tagmon, {.i = -1 } }),
++ &((Keychord){1, {{MODKEY|ShiftMask, XK_period}}, tagmon, {.i = +1 } }),
++ &((Keychord){1, {{MODKEY|ShiftMask, XK_q}}, quit, {0} }),
++ 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 */
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..e4885a4 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -102,9 +102,14 @@ struct Client {
+ typedef struct {
+ unsigned int mod;
+ KeySym keysym;
++} Key;
++
++typedef struct {
++ unsigned int n;
++ const Key keys[5];
+ void (*func)(const Arg *);
+ const Arg arg;
+-} Key;
++} Keychord;
+
+ typedef struct {
+ const char *symbol;
+@@ -267,6 +272,7 @@ static Display *dpy;
+ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
++unsigned int currentkey = 0;
+
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+@@ -954,7 +960,8 @@ grabkeys(void)
+ {
+ updatenumlockmask();
+ {
+- unsigned int i, j, k;
++ /* unsigned int i, j, k; */
++ unsigned int i, c, k;
+ unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
+ int start, end, skip;
+ KeySym *syms;
+@@ -964,15 +971,18 @@ grabkeys(void)
+ syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip);
+ if (!syms)
+ return;
++
+ for (k = start; k <= end; k++)
+- for (i = 0; i < LENGTH(keys); i++)
++ for (i = 0; i < LENGTH(keychords); i++)
+ /* skip modifier codes, we do that ourselves */
+- if (keys[i].keysym == syms[(k - start) * skip])
+- for (j = 0; j < LENGTH(modifiers); j++)
++ if (keychords[i]->keys[currentkey].keysym == syms[(k - start) * skip])
++ for (c = 0; c < LENGTH(modifiers); c++)
+ XGrabKey(dpy, k,
+- keys[i].mod | modifiers[j],
++ keychords[i]->keys[currentkey].mod | modifiers[c],
+ root, True,
+ GrabModeAsync, GrabModeAsync);
++ if(currentkey > 0)
++ XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Escape), AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
+ XFree(syms);
+ }
+ }
+@@ -999,17 +1009,51 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
+ void
+ keypress(XEvent *e)
+ {
+- unsigned int i;
++ /* unsigned int i; */
++ XEvent event = *e;
++ unsigned int ran = 0;
+ KeySym keysym;
+ XKeyEvent *ev;
+
+- ev = &e->xkey;
+- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
+- 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));
++ Keychord *arr1[sizeof(keychords) / sizeof(Keychord*)];
++ Keychord *arr2[sizeof(keychords) / sizeof(Keychord*)];
++ memcpy(arr1, keychords, sizeof(keychords));
++ Keychord **rpointer = arr1;
++ Keychord **wpointer = arr2;
++
++ size_t r = sizeof(keychords)/ sizeof(Keychord*);
++
++ while(1){
++ ev = &event.xkey;
++ keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
++ size_t w = 0;
++ for (int i = 0; i < r; i++){
++ if(keysym == (*(rpointer + i))->keys[currentkey].keysym
++ && CLEANMASK((*(rpointer + i))->keys[currentkey].mod) == CLEANMASK(ev->state)
++ && (*(rpointer + i))->func){
++ if((*(rpointer + i))->n == currentkey +1){
++ (*(rpointer + i))->func(&((*(rpointer + i))->arg));
++ ran = 1;
++ }else{
++ *(wpointer + w) = *(rpointer + i);
++ w++;
++ }
++ }
++ }
++ currentkey++;
++ if(w == 0 || ran == 1)
++ break;
++ grabkeys();
++ while (running && !XNextEvent(dpy, &event) && !ran)
++ if(event.type == KeyPress)
++ break;
++ r = w;
++ Keychord **holder = rpointer;
++ rpointer = wpointer;
++ wpointer = holder;
++ }
++ currentkey = 0;
++ grabkeys();
+ }
+
+ void
+--
+2.41.0
diff --git a/dwm/patches/dwm-layoutmenu-6.2.diff b/dwm/patches/dwm-layoutmenu-6.2.diff
new file mode 100644
index 0000000..9a2417e
--- /dev/null
+++ b/dwm/patches/dwm-layoutmenu-6.2.diff
@@ -0,0 +1,88 @@
+# From e45e286b3d639b90ef202996d87054cced1fd80e Mon Sep 17 00:00:00 2001
+# From: tdu <tdukv@protonmail.com>
+# Date: Mon, 31 Aug 2020 00:07:32 +0300
+# Subject: [PATCH] Right clicking the layout symbol opens an xmenu prompt to
+# select layout.
+#
+# Xmenu need to be installed for this to work.
+# Edit layoutmenu with the correct layout table, and place in PATH.
+# ---
+# config.def.h | 3 ++-
+# dwm.c | 19 +++++++++++++++++++
+# layoutmenu | 7 +++++++
+# 3 files changed, 28 insertions(+), 1 deletion(-)
+# create mode 100755 layoutmenu
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..c9e0833 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -58,6 +58,7 @@ static const Layout layouts[] = {
+ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+ static const char *termcmd[] = { "st", NULL };
++static const char *layoutmenu_cmd = "layoutmenu";
+
+ static Key keys[] = {
+ /* modifier key function argument */
+@@ -101,7 +102,7 @@ static Key keys[] = {
+ static Button buttons[] = {
+ /* click event mask button function argument */
+ { ClkLtSymbol, 0, Button1, setlayout, {0} },
+- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
++ { ClkLtSymbol, 0, Button3, layoutmenu, {0} },
+ { ClkWinTitle, 0, Button2, zoom, {0} },
+ { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
+ { ClkClientWin, MODKEY, Button1, movemouse, {0} },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..2508a0a 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -177,6 +177,7 @@ static void grabkeys(void);
+ static void incnmaster(const Arg *arg);
+ static void keypress(XEvent *e);
+ static void killclient(const Arg *arg);
++static void layoutmenu(const Arg *arg);
+ static void manage(Window w, XWindowAttributes *wa);
+ static void mappingnotify(XEvent *e);
+ static void maprequest(XEvent *e);
+@@ -1014,6 +1015,24 @@ killclient(const Arg *arg)
+ }
+ }
+
++void
++layoutmenu(const Arg *arg) {
++ FILE *p;
++ char c[3], *s;
++ int i;
++
++ if (!(p = popen(layoutmenu_cmd, "r")))
++ return;
++ s = fgets(c, sizeof(c), p);
++ pclose(p);
++
++ if (!s || *s == '\0' || c[0] == '\0')
++ return;
++
++ i = atoi(c);
++ setlayout(&((Arg) { .v = &layouts[i] }));
++}
++
+ void
+ manage(Window w, XWindowAttributes *wa)
+ {
+diff --git a/layoutmenu b/layoutmenu
+new file mode 100755
+index 0000000..1bf95f2
+--- /dev/null
++++ b/layoutmenu
+@@ -0,0 +1,7 @@
++#!/bin/sh
++
++cat <<EOF | xmenu
++[]= Tiled Layout 0
++><> Floating Layout 1
++[M] Monocle Layout 2
++EOF
+--
+2.28.0
diff --git a/dwm/patches/dwm-layoutscroll-6.2.diff b/dwm/patches/dwm-layoutscroll-6.2.diff
new file mode 100644
index 0000000..95e621d
--- /dev/null
+++ b/dwm/patches/dwm-layoutscroll-6.2.diff
@@ -0,0 +1,67 @@
+diff --git a/config.def.h b/config.def.h
+index 4c56466..11ee7b5 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -90,6 +90,8 @@ static Key keys[] = {
+ { MODKEY, XK_period, focusmon, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
++ { MODKEY|ShiftMask, XK_h, layoutscroll, {.i = -1 } },
++ { MODKEY|ShiftMask, XK_l, layoutscroll, {.i = +1 } },
+ TAGKEYS( XK_1, 0)
+ TAGKEYS( XK_2, 1)
+ TAGKEYS( XK_3, 2)
+diff --git a/dwm.c b/dwm.c
+index 1e37fcf..24effbc 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -148,6 +148,7 @@ struct Monitor {
+ Monitor *next;
+ Window barwin;
+ const Layout *lt[2];
++ int ltcur; /* current layout */
+ };
+
+ typedef struct {
+@@ -227,6 +228,7 @@ 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 layoutscroll(const Arg *arg);
+ static void setlayout(const Arg *arg);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
+@@ -725,6 +727,7 @@ createmon(void)
+ m->nmaster = nmaster;
+ m->showbar = showbar;
+ m->topbar = topbar;
++ m->ltcur = 0;
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+@@ -1667,6 +1670,25 @@ setfullscreen(Client *c, int fullscreen)
+ }
+ }
+
++void
++layoutscroll(const Arg *arg)
++{
++ if (!arg || !arg->i)
++ return;
++ int switchto = selmon->ltcur + arg->i;
++ int l = LENGTH(layouts);
++
++ if (switchto == l)
++ switchto = 0;
++ else if(switchto < 0)
++ switchto = l - 1;
++
++ selmon->ltcur = switchto;
++ Arg arg2 = {.v= &layouts[switchto] };
++ setlayout(&arg2);
++
++}
++
+ void
+ setlayout(const Arg *arg)
+ {
diff --git a/dwm/patches/dwm-mark-new-6.2.diff b/dwm/patches/dwm-mark-new-6.2.diff
new file mode 100644
index 0000000..711c3fd
--- /dev/null
+++ b/dwm/patches/dwm-mark-new-6.2.diff
@@ -0,0 +1,247 @@
+# From 753860d3435e2968358f2bf8daf70bf625fe75fe Mon Sep 17 00:00:00 2001
+# From: Kajetan Puchalski <kajetan.puchalski@tuta.io>
+# Date: Mon, 5 Oct 2020 11:04:31 +0100
+# Subject: [PATCH] Updated Mark patch to work with 6.2
+#
+# ---
+# config.def.h | 14 +++++--
+# drw.h | 2 +-
+# dwm.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
+# 3 files changed, 118 insertions(+), 9 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 3858d75..a416c97 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -12,10 +12,13 @@ static const char col_gray2[] = "#444444";
+ static const char col_gray3[] = "#bbbbbb";
+ static const char col_gray4[] = "#eeeeee";
+ static const char col_cyan[] = "#005577";
+-static const char *colors[][3] = {
+- /* fg bg border */
+- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
++static const char normmarkcolor[] = "#775500"; /*border color for marked client*/
++static const char selmarkcolor[] = "#775577"; /*border color for marked client on focus*/
++
++static const char *colors[][4] = {
++ /* fg bg border mark */
++ [SchemeNorm] = { col_gray3, col_gray1, col_gray2, normmarkcolor },
++ [SchemeSel] = { col_gray4, col_cyan, col_cyan, selmarkcolor },
+ };
+
+ /* tagging */
+@@ -94,6 +97,9 @@ static Key keys[] = {
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY, XK_semicolon, togglemark, {0} },
++ { MODKEY, XK_o, swapfocus, {0} },
++ { MODKEY, XK_u, swapclient, {0} },
+ };
+
+ /* button definitions */
+diff --git a/drw.h b/drw.h
+index 4bcd5ad..97aae99 100644
+--- a/drw.h
++++ b/drw.h
+@@ -12,7 +12,7 @@ typedef struct Fnt {
+ struct Fnt *next;
+ } Fnt;
+
+-enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
++enum { ColFg, ColBg, ColBorder, ColMark }; /* Clr scheme index */
+ typedef XftColor Clr;
+
+ typedef struct {
+diff --git a/dwm.c b/dwm.c
+index 664c527..195b8eb 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -201,17 +201,21 @@ 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 setmark(Client *c);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
++static void swapclient(const Arg *arg);
++static void swapfocus(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void togglemark(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -268,6 +272,7 @@ static Display *dpy;
+ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
++static Client *mark;
+
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+@@ -796,7 +801,10 @@ focus(Client *c)
+ detachstack(c);
+ attachstack(c);
+ grabbuttons(c, 1);
+- XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
++ if (c == mark)
++ XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColMark].pixel);
++ else
++ XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
+ setfocus(c);
+ } else {
+ XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+@@ -1052,7 +1060,10 @@ manage(Window w, XWindowAttributes *wa)
+
+ wc.border_width = c->bw;
+ XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+- XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
++ if (c == mark)
++ XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColMark].pixel);
++ else
++ XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
+ configure(c); /* propagates border_width, if size doesn't change */
+ updatewindowtype(c);
+ updatesizehints(c);
+@@ -1512,6 +1523,23 @@ setlayout(const Arg *arg)
+ drawbar(selmon);
+ }
+
++void
++setmark(Client *c)
++{
++ if (c == mark)
++ return;
++ if (mark) {
++ XSetWindowBorder(dpy, mark->win, scheme[mark == selmon->sel
++ ? SchemeSel : SchemeNorm][ColBorder].pixel);
++ mark = 0;
++ }
++ if (c) {
++ XSetWindowBorder(dpy, c->win, scheme[c == selmon->sel
++ ? SchemeSel : SchemeNorm][ColMark].pixel);
++ mark = c;
++ }
++}
++
+ /* arg > 1.0 will set mfact absolutely */
+ void
+ setmfact(const Arg *arg)
+@@ -1570,7 +1598,7 @@ setup(void)
+ /* init appearance */
+ scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
+ for (i = 0; i < LENGTH(colors); i++)
+- scheme[i] = drw_scm_create(drw, colors[i], 3);
++ scheme[i] = drw_scm_create(drw, colors[i], 4);
+ /* init bars */
+ updatebars();
+ updatestatus();
+@@ -1653,6 +1681,75 @@ spawn(const Arg *arg)
+ }
+ }
+
++void
++swapclient(const Arg *arg)
++{
++ Client *s, *m, t;
++
++ if (!mark || !selmon->sel || mark == selmon->sel
++ || !selmon->lt[selmon->sellt]->arrange)
++ return;
++ s = selmon->sel;
++ m = mark;
++ t = *s;
++ strcpy(s->name, m->name);
++ s->win = m->win;
++ s->x = m->x;
++ s->y = m->y;
++ s->w = m->w;
++ s->h = m->h;
++
++ m->win = t.win;
++ strcpy(m->name, t.name);
++ m->x = t.x;
++ m->y = t.y;
++ m->w = t.w;
++ m->h = t.h;
++
++ selmon->sel = m;
++ mark = s;
++ focus(s);
++ setmark(m);
++
++ arrange(s->mon);
++ if (s->mon != m->mon) {
++ arrange(m->mon);
++ }
++}
++
++void
++swapfocus(const Arg *arg)
++{
++ Client *t;
++
++ if (!selmon->sel || !mark || selmon->sel == mark)
++ return;
++ t = selmon->sel;
++ if (mark->mon != selmon) {
++ unfocus(selmon->sel, 0);
++ selmon = mark->mon;
++ }
++ if (ISVISIBLE(mark)) {
++ focus(mark);
++ restack(selmon);
++ } else {
++ selmon->seltags ^= 1;
++ selmon->tagset[selmon->seltags] = mark->tags;
++ focus(mark);
++ arrange(selmon);
++ }
++ setmark(t);
++}
++
++void
++togglemark(const Arg *arg)
++{
++ if (!selmon->sel)
++ return;
++ setmark(selmon->sel == mark ? 0 : selmon->sel);
++}
++
++
+ void
+ tag(const Arg *arg)
+ {
+@@ -1755,7 +1852,10 @@ unfocus(Client *c, int setfocus)
+ if (!c)
+ return;
+ grabbuttons(c, 0);
+- XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
++ if (c == mark)
++ XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColMark].pixel);
++ else
++ XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
+ if (setfocus) {
+ XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+ XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
+@@ -1768,6 +1868,9 @@ unmanage(Client *c, int destroyed)
+ Monitor *m = c->mon;
+ XWindowChanges wc;
+
++ if (c == mark)
++ setmark(0);
++
+ detach(c);
+ detachstack(c);
+ if (!destroyed) {
+--
+2.28.0
diff --git a/dwm/patches/dwm-movecenter-6.5.diff b/dwm/patches/dwm-movecenter-6.5.diff
new file mode 100644
index 0000000..b24977a
--- /dev/null
+++ b/dwm/patches/dwm-movecenter-6.5.diff
@@ -0,0 +1,41 @@
+diff --git a/config.def.h b/config.def.h
+index 9efa774..89a958a 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -85,6 +85,7 @@ static const Key keys[] = {
+ { MODKEY, XK_period, focusmon, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
++ { MODKEY, XK_x, movecenter, {0} },
+ TAGKEYS( XK_1, 0)
+ TAGKEYS( XK_2, 1)
+ TAGKEYS( XK_3, 2)
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..ad534ad 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -184,6 +184,7 @@ static void maprequest(XEvent *e);
+ static void monocle(Monitor *m);
+ static void motionnotify(XEvent *e);
+ static void movemouse(const Arg *arg);
++static void movecenter(const Arg *arg);
+ static Client *nexttiled(Client *c);
+ static void pop(Client *c);
+ static void propertynotify(XEvent *e);
+@@ -1202,6 +1203,16 @@ movemouse(const Arg *arg)
+ }
+ }
+
++void
++movecenter(const Arg *arg)
++{
++ if (selmon->sel) {
++ selmon->sel->x = selmon->sel->mon->mx + (selmon->sel->mon->mw - WIDTH(selmon->sel)) / 2;
++ selmon->sel->y = selmon->sel->mon->my + (selmon->sel->mon->mh - HEIGHT(selmon->sel)) / 2;
++ arrange(selmon);
++ }
++}
++
+ Client *
+ nexttiled(Client *c)
+ {
diff --git a/dwm/patches/dwm-multimon-1-monitor_marker-6.4.diff b/dwm/patches/dwm-multimon-1-monitor_marker-6.4.diff
new file mode 100644
index 0000000..ea4b851
--- /dev/null
+++ b/dwm/patches/dwm-multimon-1-monitor_marker-6.4.diff
@@ -0,0 +1,194 @@
+# From c13f9b5a379422525ec7f714d83a1cbb0e3251c2 Mon Sep 17 00:00:00 2001
+# From: "Gary B. Genett" <me@garybgenett.net>
+# Date: Sun, 19 Feb 2023 08:56:42 -0800
+# Subject: added monitor marker to bar
+# MIME-Version: 1.0
+# Content-Type: multipart/mixed; boundary="------------2.37.4"
+#
+# This is a multi-part message in MIME format.
+# --------------2.37.4
+# Content-Type: text/plain; charset=UTF-8; format=fixed
+# Content-Transfer-Encoding: 8bit
+#
+# ---
+# config.def.h | 2 ++
+# dwm.c | 12 +++++++++++-
+# 2 files changed, 13 insertions(+), 1 deletion(-)
+#
+#
+# --------------2.37.4
+# Content-Type: text/x-patch; name="0001-added-monitor-marker-to-bar.patch"
+# Content-Transfer-Encoding: 8bit
+# Content-Disposition: attachment; filename="0001-added-monitor-marker-to-bar.patch"
+
+diff --git a/config.def.h b/config.def.h
+index 9efa7744b39c8b0ff0cf09a504a2539910c2881c..9d549ce8628e1a7769ee2a3d5c0a4c6d56ce6931 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -96,20 +96,22 @@ static const Key keys[] = {
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
+ };
+
+ /* 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]} },
++ { ClkMonNum, 0, Button1, focusmon, {.i = +1} },
++ { ClkMonNum, 0, Button3, focusmon, {.i = -1} },
+ { 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} },
+ };
+diff --git a/dwm.c b/dwm.c
+index c2bd8710544eb4b4e7eaa4a1307e1f1dfd8d16ba..bc5160a7d46ab07da82f0595abb7700debb2b891 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -57,21 +57,21 @@
+ #define TAGMASK ((1 << LENGTH(tags)) - 1)
+ #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+ enum { SchemeNorm, SchemeSel }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
+-enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
++enum { ClkTagBar, ClkLtSymbol, ClkMonNum, ClkStatusText, ClkWinTitle,
+ ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+
+ typedef union {
+ int i;
+ unsigned int ui;
+ float f;
+ const void *v;
+ } Arg;
+
+ typedef struct {
+@@ -106,20 +106,21 @@ typedef struct {
+ const Arg arg;
+ } Key;
+
+ typedef struct {
+ const char *symbol;
+ void (*arrange)(Monitor *);
+ } Layout;
+
+ struct Monitor {
+ char ltsymbol[16];
++ char monmark[16];
+ float mfact;
+ int nmaster;
+ int num;
+ int by; /* bar geometry */
+ 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;
+@@ -434,20 +435,22 @@ buttonpress(XEvent *e)
+ if (ev->window == selmon->barwin) {
+ i = x = 0;
+ do
+ x += TEXTW(tags[i]);
+ while (ev->x >= x && ++i < LENGTH(tags));
+ if (i < LENGTH(tags)) {
+ click = ClkTagBar;
+ arg.ui = 1 << i;
+ } else if (ev->x < x + TEXTW(selmon->ltsymbol))
+ click = ClkLtSymbol;
++ else if (ev->x < x + TEXTW(selmon->ltsymbol) + TEXTW(selmon->monmark))
++ click = ClkMonNum;
+ else if (ev->x > selmon->ww - (int)TEXTW(stext))
+ click = ClkStatusText;
+ else
+ click = ClkWinTitle;
+ } else if ((c = wintoclient(ev->window))) {
+ focus(c);
+ restack(selmon);
+ XAllowEvents(dpy, ReplayPointer, CurrentTime);
+ click = ClkClientWin;
+ }
+@@ -637,20 +640,22 @@ createmon(void)
+
+ m = ecalloc(1, sizeof(Monitor));
+ m->tagset[0] = m->tagset[1] = 1;
+ m->mfact = mfact;
+ m->nmaster = nmaster;
+ m->showbar = showbar;
+ m->topbar = topbar;
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
++ /* this is actually set in updategeom, to avoid a race condition */
++// snprintf(m->monmark, sizeof(m->monmark), "(%d)", m->num);
+ return m;
+ }
+
+ void
+ destroynotify(XEvent *e)
+ {
+ Client *c;
+ XDestroyWindowEvent *ev = &e->xdestroywindow;
+
+ if ((c = wintoclient(ev->window)))
+@@ -726,20 +731,23 @@ drawbar(Monitor *m)
+ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+ if (occ & 1 << i)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw,
+ m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+ urg & 1 << i);
+ x += w;
+ }
+ w = TEXTW(m->ltsymbol);
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
++ w = TEXTW(m->monmark);
++ drw_setscheme(drw, scheme[SchemeNorm]);
++ x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->monmark, 0);
+
+ if ((w = m->ww - tw - x) > bh) {
+ if (m->sel) {
+ drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+ if (m->sel->isfloating)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
+ } else {
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, x, 0, w, bh, 1, 1);
+@@ -1886,20 +1894,22 @@ updategeom(void)
+ 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;
++ /* this is ugly, but it is a race condition otherwise */
++ snprintf(m->monmark, sizeof(m->monmark), "(%d)", m->num);
+ 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)) {
+
+--------------2.37.4--
diff --git a/dwm/patches/dwm-multimon-2-unified_view-6.4.diff b/dwm/patches/dwm-multimon-2-unified_view-6.4.diff
new file mode 100644
index 0000000..9815e92
--- /dev/null
+++ b/dwm/patches/dwm-multimon-2-unified_view-6.4.diff
@@ -0,0 +1,181 @@
+# From 96ebf3ddfad143aec93a7d2aa212389121ccae41 Mon Sep 17 00:00:00 2001
+# From: "Gary B. Genett" <me@garybgenett.net>
+# Date: Sun, 19 Feb 2023 08:57:30 -0800
+# Subject: added n*view wrappers, for unified multi-monitor
+# MIME-Version: 1.0
+# Content-Type: multipart/mixed; boundary="------------2.37.4"
+#
+# This is a multi-part message in MIME format.
+# --------------2.37.4
+# Content-Type: text/plain; charset=UTF-8; format=fixed
+# Content-Transfer-Encoding: 8bit
+#
+# ---
+# config.def.h | 5 +++++
+# dwm.c | 26 ++++++++++++++++++++++++++
+# 2 files changed, 31 insertions(+)
+#
+#
+# --------------2.37.4
+# Content-Type: text/x-patch; name="0002-added-n-view-wrappers-for-unified-multi-monitor.patch"
+# Content-Transfer-Encoding: 8bit
+# Content-Disposition: attachment; filename="0002-added-n-view-wrappers-for-unified-multi-monitor.patch"
+
+diff --git a/config.def.h b/config.def.h
+index 9d549ce8628e1a7769ee2a3d5c0a4c6d56ce6931..c59d27597a62ddf884baacded2830a318db1b45c 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -38,24 +38,27 @@ static const int resizehints = 1; /* 1 means respect size hints in tiled resi
+ 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 */
+ { "[M]", monocle },
+ };
+
+ /* key definitions */
++#define WINKEY Mod4Mask
+ #define MODKEY Mod1Mask
+ #define TAGKEYS(KEY,TAG) \
+ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
+ { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
++ { MODKEY|WINKEY, KEY, nview, {.ui = 1 << TAG} }, \
++ { MODKEY|WINKEY|ControlMask, KEY, ntoggleview, {.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 char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+ static const char *termcmd[] = { "st", NULL };
+@@ -105,14 +108,16 @@ static const Button buttons[] = {
+ { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkMonNum, 0, Button1, focusmon, {.i = +1} },
+ { ClkMonNum, 0, Button3, focusmon, {.i = -1} },
+ { 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|WINKEY, Button1, nview, {0} },
++ { ClkTagBar, MODKEY|WINKEY, Button3, ntoggleview, {0} },
+ { ClkTagBar, MODKEY, Button1, tag, {0} },
+ { ClkTagBar, MODKEY, Button3, toggletag, {0} },
+ };
+
+diff --git a/dwm.c b/dwm.c
+index bc5160a7d46ab07da82f0595abb7700debb2b891..2cf8d78c22c64ff26eda6195b6bd503f213a4d5f 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -206,34 +206,36 @@ static void setmfact(const Arg *arg);
+ static void setup(void);
+ static void seturgent(Client *c, int urg);
+ 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 tile(Monitor *m);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+ static void toggletag(const Arg *arg);
++static void ntoggleview(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+ 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 updatewindowtype(Client *c);
+ static void updatewmhints(Client *c);
++static void nview(const Arg *arg);
+ 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);
+
+ /* variables */
+ static const char broken[] = "broken";
+@@ -1743,20 +1745,32 @@ toggletag(const Arg *arg)
+ if (!selmon->sel)
+ return;
+ newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
+ if (newtags) {
+ selmon->sel->tags = newtags;
+ focus(NULL);
+ arrange(selmon);
+ }
+ }
+
++void
++ntoggleview(const Arg *arg)
++{
++ const Arg n = {.i = +1};
++ const int mon = selmon->num;
++ do {
++ focusmon(&n);
++ toggleview(arg);
++ }
++ while (selmon->num != mon);
++}
++
+ void
+ toggleview(const Arg *arg)
+ {
+ unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
+
+ if (newtagset) {
+ selmon->tagset[selmon->seltags] = newtagset;
+ focus(NULL);
+ arrange(selmon);
+ }
+@@ -2045,20 +2059,32 @@ updatewmhints(Client *c)
+ } else
+ c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0;
+ if (wmh->flags & InputHint)
+ c->neverfocus = !wmh->input;
+ else
+ c->neverfocus = 0;
+ XFree(wmh);
+ }
+ }
+
++void
++nview(const Arg *arg)
++{
++ const Arg n = {.i = +1};
++ const int mon = selmon->num;
++ do {
++ focusmon(&n);
++ view(arg);
++ }
++ while (selmon->num != mon);
++}
++
+ 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;
+ focus(NULL);
+ arrange(selmon);
+
+--------------2.37.4--
diff --git a/dwm/patches/dwm-multimon-4-status_all-6.4.diff b/dwm/patches/dwm-multimon-4-status_all-6.4.diff
new file mode 100644
index 0000000..5059958
--- /dev/null
+++ b/dwm/patches/dwm-multimon-4-status_all-6.4.diff
@@ -0,0 +1,102 @@
+# From 34d7ca93ff7fff443f9cf0ce6ba6da6acbcfe06c Mon Sep 17 00:00:00 2001
+# From: "Gary B. Genett" <me@garybgenett.net>
+# Date: Sun, 19 Feb 2023 08:59:36 -0800
+# Subject: added statusall toggle
+# MIME-Version: 1.0
+# Content-Type: multipart/mixed; boundary="------------2.37.4"
+#
+# This is a multi-part message in MIME format.
+# --------------2.37.4
+# Content-Type: text/plain; charset=UTF-8; format=fixed
+# Content-Transfer-Encoding: 8bit
+#
+# ---
+# config.def.h | 1 +
+# dwm.c | 4 ++--
+# 2 files changed, 3 insertions(+), 2 deletions(-)
+#
+#
+# --------------2.37.4
+# Content-Type: text/x-patch; name="0004-added-statusall-toggle.patch"
+# Content-Transfer-Encoding: 8bit
+# Content-Disposition: attachment; filename="0004-added-statusall-toggle.patch"
+
+diff --git a/config.def.h b/config.def.h
+index a664c793845c4c7c0ebe8ac69c96885c76193819..fcfe8245a438686f276ffc9a4df17695382ed58b 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -29,20 +29,21 @@ static const Rule rules[] = {
+ /* class instance title tags mask isfloating monitor */
+ { "Gimp", NULL, NULL, 0, 1, -1 },
+ { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
+ };
+
+ /* 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 nviews = 3; /* mask of tags highlighted by default (tags 1-4) */
+ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
++static const int statusall = 1; /* 1 means status is shown in all bars, not just active monitor */
+ static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
+
+ static const float facts[1]; //static const float facts[] = { 0, 0.5 }; // = mfact // 50%
+ static const int masters[1]; //static const int masters[] = { 0, -1 }; // = nmaster // vertical stacking (for rotated monitor)
+ static const int views[1]; //static const int views[] = { 0, ~0 }; // = nviews // all tags
+ /* invert tags after nviews */ /* array dimentions can both be as big as needed */ // final highlighted tags
+ static const int toggles[1][1]; //static const int toggles[2][2] = { {0,8}, {~0,~0} }; // 2-4+9 // all (leave as views above)
+ static const int toggles[1][1] = {{~0}};
+
+ static const Layout layouts[] = {
+ /* symbol arrange function */
+diff --git a/dwm.c b/dwm.c
+index 93da0f4565d7a17ef96a1b167cfcb2c9f0ac6ad3..77ff310e03edbf42ac2dd55471962ce259b63071 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -709,21 +709,21 @@ drawbar(Monitor *m)
+ int x, w, tw = 0;
+ int boxs = drw->fonts->h / 9;
+ int boxw = drw->fonts->h / 6 + 2;
+ unsigned int i, occ = 0, urg = 0;
+ Client *c;
+
+ if (!m->showbar)
+ return;
+
+ /* draw status first so it can be overdrawn by tags later */
+- if (m == selmon) { /* status is only drawn on selected monitor */
++ if (m == selmon || statusall) { /* status is only drawn on selected monitor */
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+ drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+ }
+
+ for (c = m->clients; c; c = c->next) {
+ occ |= c->tags;
+ if (c->isurgent)
+ urg |= c->tags;
+ }
+@@ -2017,21 +2017,21 @@ updatesizehints(Client *c)
+ c->maxa = c->mina = 0.0;
+ c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh);
+ c->hintsvalid = 1;
+ }
+
+ void
+ updatestatus(void)
+ {
+ if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
+ strcpy(stext, "dwm-"VERSION);
+- drawbar(selmon);
++ statusall ? drawbars() : drawbar(selmon);
+ }
+
+ 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);
+ }
+
+--------------2.37.4--
diff --git a/dwm/patches/dwm-multimon-6-swap_focus-6.4.diff b/dwm/patches/dwm-multimon-6-swap_focus-6.4.diff
new file mode 100644
index 0000000..9bd091a
--- /dev/null
+++ b/dwm/patches/dwm-multimon-6-swap_focus-6.4.diff
@@ -0,0 +1,185 @@
+# From de73c72af0250f56f9ac30a5c3f4520da250282a Mon Sep 17 00:00:00 2001
+# From: "Gary B. Genett" <me@garybgenett.net>
+# Date: Sun, 19 Feb 2023 09:40:00 -0800
+# Subject: patches/swapfocus: dwm-swapfocus-20160731-56a31dc.diff
+# MIME-Version: 1.0
+# Content-Type: multipart/mixed; boundary="------------2.37.4"
+#
+# This is a multi-part message in MIME format.
+# --------------2.37.4
+# Content-Type: text/plain; charset=UTF-8; format=fixed
+# Content-Transfer-Encoding: 8bit
+#
+#
+# modified from sites: 38b351cf3689ff3fa4845d35ce9894fd9253dbb8
+# ---
+# config.def.h | 1 +
+# dwm.c | 19 ++++++++++++++++++-
+# 2 files changed, 19 insertions(+), 1 deletion(-)
+#
+#
+# --------------2.37.4
+# Content-Type: text/x-patch; name="0006-patches-swapfocus-dwm-swapfocus-20160731-56a31dc.dif.patch"
+# Content-Transfer-Encoding: 8bit
+# Content-Disposition: attachment; filename="0006-patches-swapfocus-dwm-swapfocus-20160731-56a31dc.dif.patch"
+
+diff --git a/config.def.h b/config.def.h
+index fd00f7080db9271912d0e4352434739d3c08e1b3..9a1118791c3a2f875b58bf3979db5074416b8634 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -79,20 +79,21 @@ static const Key keys[] = {
+ { MODKEY, XK_j, focusstack, {.i = +1 } },
+ { MODKEY, XK_k, focusstack, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_j, pushdown, {0} },
+ { MODKEY|ShiftMask, XK_k, pushup, {0} },
+ { 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_Tab, swapfocus, {0} },
+ { MODKEY|ShiftMask, XK_c, killclient, {0} },
+ { 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_0, view, {.ui = ~0 } },
+ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
+ { MODKEY, XK_comma, focusmon, {.i = -1 } },
+ { MODKEY, XK_period, focusmon, {.i = +1 } },
+diff --git a/dwm.c b/dwm.c
+index 5aa229611a27b8aa943308314b494c10e2364137..ac52b8c25991a073db15b55fae774e9c47a05708 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -203,20 +203,21 @@ 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 showhide(Client *c);
+ static void spawn(const Arg *arg);
++static void swapfocus(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *m);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void ntoggleview(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+ static void unmanage(Client *c, int destroyed);
+@@ -235,20 +236,21 @@ static void nview(const Arg *arg);
+ 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);
+ static void reset_view(const Arg *arg);
+
+ /* variables */
++static Client *prevclient = NULL;
+ static const char broken[] = "broken";
+ static char stext[256];
+ static int screen;
+ static int sw, sh; /* X display screen geometry width, height */
+ static int bh; /* bar height */
+ static int lrpad; /* sum of left and right padding for text */
+ static int (*xerrorxlib)(Display *, XErrorEvent *);
+ static unsigned int numlockmask = 0;
+ static void (*handler[LASTEvent]) (XEvent *) = {
+ [ButtonPress] = buttonpress,
+@@ -1721,20 +1723,32 @@ spawn(const Arg *arg)
+ dmenumon[0] = '0' + selmon->num;
+ if (fork() == 0) {
+ if (dpy)
+ close(ConnectionNumber(dpy));
+ setsid();
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]);
+ }
+ }
+
++void
++swapfocus(const Arg *arg)
++{
++ Client *c;
++
++ for(c = selmon->clients; c && c != prevclient; c = c->next) ;
++ if(c == prevclient) {
++ focus(prevclient);
++ restack(prevclient->mon);
++ }
++}
++
+ void
+ tag(const Arg *arg)
+ {
+ if (selmon->sel && arg->ui & TAGMASK) {
+ selmon->sel->tags = arg->ui & TAGMASK;
+ focus(NULL);
+ arrange(selmon);
+ }
+ }
+
+@@ -1834,20 +1848,21 @@ toggleview(const Arg *arg)
+ focus(NULL);
+ arrange(selmon);
+ }
+ }
+
+ void
+ unfocus(Client *c, int setfocus)
+ {
+ if (!c)
+ return;
++ prevclient = c;
+ grabbuttons(c, 0);
+ 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)
+@@ -2213,25 +2228,27 @@ 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;
++ prevclient = nexttiled(selmon->clients);
+
+ if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating)
+ return;
+ if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next)))
+- return;
++ if (!c || !(c = prevclient = nexttiled(c->next)))
++ return;
+ pop(c);
+ }
+
+ void
+ reset_view(const Arg *arg) {
+ const int mon = selmon->num;
+ Arg n = {.i = +1}; // focusmon(next monitor)
+ Arg m = {.f = 0}; // mfact -> facts[]
+ Arg i = {.i = 0}; // nmaster -> masters[]
+ Arg v = {.ui = 0}; // nviews -> views[]
+
+--------------2.37.4--
diff --git a/dwm/patches/dwm-multimon-7-focus_on_active-6.4.diff b/dwm/patches/dwm-multimon-7-focus_on_active-6.4.diff
new file mode 100644
index 0000000..958ae04
--- /dev/null
+++ b/dwm/patches/dwm-multimon-7-focus_on_active-6.4.diff
@@ -0,0 +1,59 @@
+# From ef123521987ec72df95a05542f6558999b673863 Mon Sep 17 00:00:00 2001
+# From: "Gary B. Genett" <me@garybgenett.net>
+# Date: Sun, 19 Feb 2023 09:09:23 -0800
+# Subject: patches/focusonnetactive: dwm-focusonnetactive-6.2.diff
+# MIME-Version: 1.0
+# Content-Type: multipart/mixed; boundary="------------2.37.4"
+#
+# This is a multi-part message in MIME format.
+# --------------2.37.4
+# Content-Type: text/plain; charset=UTF-8; format=fixed
+# Content-Transfer-Encoding: 8bit
+#
+#
+# modified from sites: 38b351cf3689ff3fa4845d35ce9894fd9253dbb8
+# used old dwm code instead: bb3bd6fec37174e8d4bb9457ca815c00609e5157
+# ---
+# dwm.c | 7 +++++--
+# 1 file changed, 5 insertions(+), 2 deletions(-)
+#
+#
+# --------------2.37.4
+# Content-Type: text/x-patch; name="0007-patches-focusonnetactive-dwm-focusonnetactive-6.2.di.patch"
+# Content-Transfer-Encoding: 8bit
+# Content-Disposition: attachment; filename="0007-patches-focusonnetactive-dwm-focusonnetactive-6.2.di.patch"
+
+diff --git a/dwm.c b/dwm.c
+index ac52b8c25991a073db15b55fae774e9c47a05708..3294c2fe53785473397b6e978c79a704cb7e8f25 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -530,22 +530,25 @@ clientmessage(XEvent *e)
+ 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);
++ if (!ISVISIBLE(c)) {
++ c->mon->seltags ^= 1;
++ c->mon->tagset[c->mon->seltags] = c->tags;
++ }
++ pop(c);
+ }
+ }
+
+ void
+ configure(Client *c)
+ {
+ XConfigureEvent ce;
+
+ ce.type = ConfigureNotify;
+ ce.display = dpy;
+
+--------------2.37.4--
diff --git a/dwm/patches/dwm-multiple-dynamic-scratchpads.diff b/dwm/patches/dwm-multiple-dynamic-scratchpads.diff
new file mode 100644
index 0000000..22d0000
--- /dev/null
+++ b/dwm/patches/dwm-multiple-dynamic-scratchpads.diff
@@ -0,0 +1,207 @@
+diff --git a/config.def.h b/config.def.h
+index a2ac963..1c82453 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -95,6 +95,13 @@ static Key keys[] = {
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY, XK_s, scratchpad_show, {.i = 1} },
++ { MODKEY, XK_y, scratchpad_show, {.i = 2} },
++ { MODKEY, XK_u, scratchpad_show, {.i = 3} },
++ { MODKEY|ShiftMask, XK_s, scratchpad_hide, {.i = 1} },
++ { MODKEY|ShiftMask, XK_y, scratchpad_hide, {.i = 2} },
++ { MODKEY|ShiftMask, XK_u, scratchpad_hide, {.i = 3} },
++ { MODKEY|ShiftMask, XK_r, scratchpad_remove, {0} },
+ };
+
+ /* button definitions */
+diff --git a/dwm.c b/dwm.c
+index 5f16260..202038f 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -195,6 +195,11 @@ static void resizemouse(const Arg *arg);
+ static void restack(Monitor *m);
+ static void run(void);
+ static void scan(void);
++static void scratchpad_hide();
++static void scratchpad_remove();
++static void scratchpad_show();
++static void scratchpad_show_client(Client *c);
++static void scratchpad_show_first(int scratchNum);
+ static int sendevent(Client *c, Atom proto);
+ static void sendmon(Client *c, Monitor *m);
+ static void setclientstate(Client *c, long state);
+@@ -269,11 +274,19 @@ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
+
++/* scratchpad */
++#define SCRATCHPAD_MASK_1 (1u << sizeof tags / sizeof * tags)
++#define SCRATCHPAD_MASK_2 (1u << (sizeof tags / sizeof * tags + 1))
++#define SCRATCHPAD_MASK_3 (1u << (sizeof tags / sizeof * tags + 2))
++static int scratchpad_hide_flag = 0;
++static Client *scratchpad_last_showed_1 = NULL;
++static Client *scratchpad_last_showed_2 = NULL;
++static Client *scratchpad_last_showed_3 = NULL;
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+-struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
++struct NumTags { char limitexceeded[LENGTH(tags) > 28 ? -1 : 1]; };
+
+ /* function implementations */
+ void
+@@ -309,7 +322,9 @@ applyrules(Client *c)
+ XFree(ch.res_class);
+ if (ch.res_name)
+ XFree(ch.res_name);
++ if(c->tags != SCRATCHPAD_MASK_1 && c->tags != SCRATCHPAD_MASK_2 && c->tags != SCRATCHPAD_MASK_3) {
+ c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
++ }
+ }
+
+ int
+@@ -1412,6 +1427,124 @@ scan(void)
+ }
+ }
+
++static void scratchpad_hide(const Arg *arg) {
++ if(scratchpad_hide_flag < 4) {
++ if(arg->i == 1) {
++ if(selmon->sel) {
++ selmon->sel->tags = SCRATCHPAD_MASK_1;
++ selmon->sel->isfloating = 1;
++ focus(NULL);
++ arrange(selmon);
++ scratchpad_hide_flag++;
++ }
++ }
++ else if(arg->i == 2) {
++ if(selmon->sel) {
++ selmon->sel->tags = SCRATCHPAD_MASK_2;
++ selmon->sel->isfloating = 1;
++ focus(NULL);
++ arrange(selmon);
++ scratchpad_hide_flag++;
++ }
++ }
++ else if(arg->i == 3) {
++ if(selmon->sel) {
++ selmon->sel->tags = SCRATCHPAD_MASK_3;
++ selmon->sel->isfloating = 1;
++ focus(NULL);
++ arrange(selmon);
++ scratchpad_hide_flag++;
++ }
++ }
++ }
++}
++
++static void scratchpad_remove() {
++ if(selmon->sel && (scratchpad_last_showed_1 != NULL || scratchpad_last_showed_2 != NULL ||scratchpad_last_showed_3 != NULL) && (selmon->sel == scratchpad_last_showed_1 || selmon->sel == scratchpad_last_showed_2 || selmon->sel == scratchpad_last_showed_3)) {
++ if(scratchpad_last_showed_1 == selmon->sel) {
++ scratchpad_last_showed_1 = NULL;
++ scratchpad_hide_flag--;
++ }
++ else if(scratchpad_last_showed_2 == selmon->sel) {
++ scratchpad_last_showed_2 = NULL;
++ scratchpad_hide_flag--;
++ }
++ else if(scratchpad_last_showed_3 == selmon->sel) {
++ scratchpad_last_showed_3 = NULL;
++ scratchpad_hide_flag--;
++ }
++ }
++}
++
++static void scratchpad_show(const Arg *arg) {
++ if(arg->i == 1) {
++ if(scratchpad_last_showed_1 == NULL) {
++ scratchpad_show_first(arg->i);
++ }
++ else {
++ if(scratchpad_last_showed_1->tags != SCRATCHPAD_MASK_1) {
++ scratchpad_last_showed_1->tags = SCRATCHPAD_MASK_1;
++ focus(NULL);
++ arrange(selmon);
++ }
++ else {
++ scratchpad_show_first(arg->i);
++ }
++ }
++ }
++ else if(arg->i == 2) {
++ if(scratchpad_last_showed_2 == NULL) {
++ scratchpad_show_first(arg->i);
++ }
++ else {
++ if(scratchpad_last_showed_2->tags != SCRATCHPAD_MASK_2) {
++ scratchpad_last_showed_2->tags = SCRATCHPAD_MASK_2;
++ focus(NULL);
++ arrange(selmon);
++ }
++ else {
++ scratchpad_show_first(arg->i);
++ }
++ }
++ }
++ else if(arg->i == 3) {
++ if(scratchpad_last_showed_3 == NULL) {
++ scratchpad_show_first(arg->i);
++ }
++ else {
++ if(scratchpad_last_showed_3->tags != SCRATCHPAD_MASK_3) {
++ scratchpad_last_showed_3->tags = SCRATCHPAD_MASK_3;
++ focus(NULL);
++ arrange(selmon);
++ }
++ else {
++ scratchpad_show_first(arg->i);
++ }
++ }
++ }
++}
++
++static void scratchpad_show_client(Client *c) {
++ c->tags = selmon->tagset[selmon->seltags];
++ focus(c);
++ arrange(selmon);
++}
++
++static void scratchpad_show_first(int scratchNum) {
++ for(Client *c = selmon->clients; c !=NULL; c = c->next) {
++ if(c->tags == SCRATCHPAD_MASK_1 && scratchNum == 1) {
++ scratchpad_last_showed_1 = c;
++ scratchpad_show_client(c);
++ } else if(c->tags == SCRATCHPAD_MASK_2 && scratchNum == 2) {
++ scratchpad_last_showed_2 = c;
++ scratchpad_show_client(c);
++ } else if(c->tags == SCRATCHPAD_MASK_3 && scratchNum == 3) {
++ scratchpad_last_showed_3 = c;
++ scratchpad_show_client(c);
++ }
++ }
++}
++
+ void
+ sendmon(Client *c, Monitor *m)
+ {
+@@ -1785,6 +1918,16 @@ unmanage(Client *c, int destroyed)
+ XSetErrorHandler(xerror);
+ XUngrabServer(dpy);
+ }
++ if(scratchpad_last_showed_1 == c) {
++ scratchpad_last_showed_1 = NULL;
++ }
++ if(scratchpad_last_showed_2 == c) {
++ scratchpad_last_showed_2 = NULL;
++ }
++ if(scratchpad_last_showed_3 == c) {
++ scratchpad_last_showed_3 = NULL;
++ }
++
+ free(c);
+ focus(NULL);
+ updateclientlist();
diff --git a/dwm/patches/dwm-pertag_with_sel-20231003-9f88553.diff b/dwm/patches/dwm-pertag_with_sel-20231003-9f88553.diff
new file mode 100644
index 0000000..70e3b5d
--- /dev/null
+++ b/dwm/patches/dwm-pertag_with_sel-20231003-9f88553.diff
@@ -0,0 +1,214 @@
+# From b47a32da69a1bb6f60b9c81619f3e504278cc780 Mon Sep 17 00:00:00 2001
+# From: Leonardo-Boss <70913810+Leonardo-Boss@users.noreply.github.com>
+# Date: Tue, 3 Oct 2023 12:33:58 -0300
+# Subject: [PATCH] pertag with last selection
+#
+# ---
+# dwm.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
+# 1 file changed, 90 insertions(+), 7 deletions(-)
+
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..0e4d444 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -111,6 +111,7 @@ typedef struct {
+ void (*arrange)(Monitor *);
+ } Layout;
+
++typedef struct Pertag Pertag;
+ struct Monitor {
+ char ltsymbol[16];
+ float mfact;
+@@ -130,6 +131,7 @@ struct Monitor {
+ Monitor *next;
+ Window barwin;
+ const Layout *lt[2];
++ Pertag *pertag;
+ };
+
+ typedef struct {
+@@ -271,6 +273,16 @@ static Window root, wmcheckwin;
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+
++struct Pertag {
++ unsigned int curtag, prevtag; /* current and previous tag */
++ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
++ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
++ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
++ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
++ int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
++ Client *sel[LENGTH(tags) + 1]; /* selected client */
++};
++
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+
+@@ -634,6 +646,7 @@ Monitor *
+ createmon(void)
+ {
+ Monitor *m;
++ unsigned int i;
+
+ m = ecalloc(1, sizeof(Monitor));
+ m->tagset[0] = m->tagset[1] = 1;
+@@ -644,6 +657,20 @@ createmon(void)
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
++ m->pertag = ecalloc(1, sizeof(Pertag));
++ m->pertag->curtag = m->pertag->prevtag = 1;
++
++ for (i = 0; i <= LENGTH(tags); i++) {
++ m->pertag->nmasters[i] = m->nmaster;
++ m->pertag->mfacts[i] = m->mfact;
++
++ m->pertag->ltidxs[i][0] = m->lt[0];
++ m->pertag->ltidxs[i][1] = m->lt[1];
++ m->pertag->sellts[i] = m->sellt;
++
++ m->pertag->showbars[i] = m->showbar;
++ }
++
+ return m;
+ }
+
+@@ -808,6 +835,7 @@ focus(Client *c)
+ XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
+ }
+ selmon->sel = c;
++ selmon->pertag->sel[selmon->pertag->curtag] = c;
+ drawbars();
+ }
+
+@@ -980,7 +1008,7 @@ grabkeys(void)
+ void
+ incnmaster(const Arg *arg)
+ {
+- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
+ arrange(selmon);
+ }
+
+@@ -1511,9 +1539,9 @@ void
+ setlayout(const Arg *arg)
+ {
+ if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
+- selmon->sellt ^= 1;
++ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
+ if (arg && arg->v)
+- selmon->lt[selmon->sellt] = (Layout *)arg->v;
++ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
+ strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
+ if (selmon->sel)
+ arrange(selmon);
+@@ -1532,7 +1560,7 @@ setmfact(const Arg *arg)
+ f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
+ if (f < 0.05 || f > 0.95)
+ return;
+- selmon->mfact = f;
++ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
+ arrange(selmon);
+ }
+
+@@ -1715,7 +1743,7 @@ tile(Monitor *m)
+ void
+ togglebar(const Arg *arg)
+ {
+- selmon->showbar = !selmon->showbar;
++ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
+ updatebarpos(selmon);
+ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+ arrange(selmon);
+@@ -1754,9 +1782,33 @@ 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->prevtag = selmon->pertag->curtag;
++ selmon->pertag->curtag = 0;
++ }
++
++ /* test if the user did not select the same tag */
++ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
++ selmon->pertag->prevtag = selmon->pertag->curtag;
++ 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];
++
++ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
++ togglebar(NULL);
++
+ focus(NULL);
+ arrange(selmon);
+ }
+@@ -1778,9 +1830,14 @@ unfocus(Client *c, int setfocus)
+ void
+ unmanage(Client *c, int destroyed)
+ {
++ int i;
+ Monitor *m = c->mon;
+ XWindowChanges wc;
+
++ for (i = 0; i < LENGTH(tags) + 1; i++)
++ if (c->mon->pertag->sel[i] == c)
++ c->mon->pertag->sel[i] = NULL;
++
+ detach(c);
+ detachstack(c);
+ if (!destroyed) {
+@@ -2053,12 +2110,38 @@ updatewmhints(Client *c)
+ void
+ view(const Arg *arg)
+ {
++ int i;
++ unsigned int tmptag;
++
+ if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+ return;
+ selmon->seltags ^= 1; /* toggle sel tagset */
+- if (arg->ui & TAGMASK)
++ if (arg->ui & TAGMASK) {
+ selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
+- focus(NULL);
++ selmon->pertag->prevtag = selmon->pertag->curtag;
++
++ if (arg->ui == ~0)
++ selmon->pertag->curtag = 0;
++ else {
++ for (i = 0; !(arg->ui & 1 << i); i++) ;
++ selmon->pertag->curtag = i + 1;
++ }
++ } else {
++ tmptag = selmon->pertag->prevtag;
++ selmon->pertag->prevtag = selmon->pertag->curtag;
++ selmon->pertag->curtag = tmptag;
++ }
++
++ 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];
++
++ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
++ togglebar(NULL);
++
++ focus(selmon->pertag->sel[selmon->pertag->curtag]);
+ arrange(selmon);
+ }
+
+--
+2.41.0
diff --git a/dwm/patches/dwm-preserveonrestart-6.3.diff b/dwm/patches/dwm-preserveonrestart-6.3.diff
new file mode 100644
index 0000000..9fed4d8
--- /dev/null
+++ b/dwm/patches/dwm-preserveonrestart-6.3.diff
@@ -0,0 +1,118 @@
+# From 713fa8650f5a20006451ebcccf57a4512e83bae8 Mon Sep 17 00:00:00 2001
+# From: Arda Atci <arda@phytech.io>
+# Date: Wed, 18 May 2022 17:23:16 +0300
+# Subject: [PATCH] preserve clients on old tags when renewing dwm
+#
+# By default, when dwm is recompiled-restarted all clients will
+# lose it's current tag and collapse to first tag. This patch preserves
+# clients on old tags, however note that layout order is not preserved.
+#
+# ---
+# dwm.c | 38 +++++++++++++++++++++++++++++++++++++-
+# 1 file changed, 37 insertions(+), 1 deletion(-)
+
+diff --git a/dwm.c b/dwm.c
+index a96f33c..a12e0bd 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -62,7 +62,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+ enum { SchemeNorm, SchemeSel }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
++ NetWMWindowTypeDialog, NetClientList, NetClientInfo, NetLast }; /* EWMH atoms */
+ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
+ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
+ ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+@@ -198,6 +198,7 @@ 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 setclienttagprop(Client *c);
+ static void setfocus(Client *c);
+ static void setfullscreen(Client *c, int fullscreen);
+ static void setlayout(const Arg *arg);
+@@ -1060,6 +1061,26 @@ manage(Window w, XWindowAttributes *wa)
+ updatewindowtype(c);
+ updatesizehints(c);
+ updatewmhints(c);
++ {
++ int format;
++ unsigned long *data, n, extra;
++ Monitor *m;
++ Atom atom;
++ if (XGetWindowProperty(dpy, c->win, netatom[NetClientInfo], 0L, 2L, False, XA_CARDINAL,
++ &atom, &format, &n, &extra, (unsigned char **)&data) == Success && n == 2) {
++ c->tags = *data;
++ for (m = mons; m; m = m->next) {
++ if (m->num == *(data+1)) {
++ c->mon = m;
++ break;
++ }
++ }
++ }
++ if (n > 0)
++ XFree(data);
++ }
++ setclienttagprop(c);
++
+ XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
+ grabbuttons(c, 0);
+ if (!c->isfloating)
+@@ -1423,6 +1444,7 @@ sendmon(Client *c, Monitor *m)
+ c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
+ attach(c);
+ attachstack(c);
++ setclienttagprop(c);
+ focus(NULL);
+ arrange(NULL);
+ }
+@@ -1566,6 +1588,7 @@ setup(void)
+ netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
+ netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+ netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
++ netatom[NetClientInfo] = XInternAtom(dpy, "_NET_CLIENT_INFO", False);
+ /* init cursors */
+ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
+ cursor[CurResize] = drw_cur_create(drw, XC_sizing);
+@@ -1589,6 +1612,7 @@ setup(void)
+ XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
+ PropModeReplace, (unsigned char *) netatom, NetLast);
+ XDeleteProperty(dpy, root, netatom[NetClientList]);
++ XDeleteProperty(dpy, root, netatom[NetClientInfo]);
+ /* select events */
+ wa.cursor = cursor[CurNormal]->cursor;
+ wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
+@@ -1656,11 +1680,22 @@ spawn(const Arg *arg)
+ }
+ }
+
++void
++setclienttagprop(Client *c)
++{
++ long data[] = { (long) c->tags, (long) c->mon->num };
++ XChangeProperty(dpy, c->win, netatom[NetClientInfo], XA_CARDINAL, 32,
++ PropModeReplace, (unsigned char *) data, 2);
++}
++
+ void
+ tag(const Arg *arg)
+ {
++ Client *c;
+ if (selmon->sel && arg->ui & TAGMASK) {
++ c = selmon->sel;
+ selmon->sel->tags = arg->ui & TAGMASK;
++ setclienttagprop(c);
+ focus(NULL);
+ arrange(selmon);
+ }
+@@ -1735,6 +1770,7 @@ toggletag(const Arg *arg)
+ newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
+ if (newtags) {
+ selmon->sel->tags = newtags;
++ setclienttagprop(selmon->sel);
+ focus(NULL);
+ arrange(selmon);
+ }
+--
+2.36.1
diff --git a/dwm/patches/dwm-preventfocusshift-20240831-6.5.diff b/dwm/patches/dwm-preventfocusshift-20240831-6.5.diff
new file mode 100644
index 0000000..a779208
--- /dev/null
+++ b/dwm/patches/dwm-preventfocusshift-20240831-6.5.diff
@@ -0,0 +1,24 @@
+# From 554f5a8a2205a7c52280babf5685462d8991b038 Mon Sep 17 00:00:00 2001
+# From: Suleyman Farajli <suleyman@farajli.net>
+# Date: Sat, 31 Aug 2024 13:34:58 +0400
+# Subject: [PATCH] prevent focus shifting when a window is spawned in fullscreen
+#
+# ---
+# dwm.c | 2 ++
+# 1 file changed, 2 insertions(+)
+
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..31b5d07 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -1080,6 +1080,8 @@ manage(Window w, XWindowAttributes *wa)
+ (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(selmon->sel && selmon->sel->isfullscreen && !c->isfloating)
++ setfullscreen(selmon->sel, 0);
+ if (c->mon == selmon)
+ unfocus(selmon->sel, 0);
+ c->mon->sel = c;
+--
+2.44.2
diff --git a/dwm/patches/dwm-refreshrate-20230826-9554a10.diff b/dwm/patches/dwm-refreshrate-20230826-9554a10.diff
new file mode 100644
index 0000000..aa93b19
--- /dev/null
+++ b/dwm/patches/dwm-refreshrate-20230826-9554a10.diff
@@ -0,0 +1,55 @@
+# From 9554a109e240789f76f0ece3e62f9014ceb8a4bc Mon Sep 17 00:00:00 2001
+# From: sewn <sewn@disroot.org>
+# Date: Sat, 26 Aug 2023 22:57:51 +0300
+# Subject: [PATCH] dwm: remove resize/move limitation
+#
+# we have modern machines, and we have high refresh rate monitors;
+# this makes resizing and moving windows have no limit when refreshing.
+# ---
+# dwm.c | 10 ----------
+# 1 file changed, 10 deletions(-)
+
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..4c00cbe 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -1149,7 +1149,6 @@ movemouse(const Arg *arg)
+ Client *c;
+ Monitor *m;
+ XEvent ev;
+- Time lasttime = 0;
+
+ if (!(c = selmon->sel))
+ return;
+@@ -1172,10 +1171,6 @@ movemouse(const Arg *arg)
+ 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)
+@@ -1304,7 +1299,6 @@ resizemouse(const Arg *arg)
+ Client *c;
+ Monitor *m;
+ XEvent ev;
+- Time lasttime = 0;
+
+ if (!(c = selmon->sel))
+ return;
+@@ -1326,10 +1320,6 @@ resizemouse(const Arg *arg)
+ handler[ev.type](&ev);
+ break;
+ case MotionNotify:
+- if ((ev.xmotion.time - lasttime) <= (1000 / 60))
+- continue;
+- lasttime = ev.xmotion.time;
+-
+ nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
+ nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
+ if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
+--
+2.42.0
diff --git a/dwm/patches/dwm-resetlayout-6.2.diff b/dwm/patches/dwm-resetlayout-6.2.diff
new file mode 100644
index 0000000..e3cd587
--- /dev/null
+++ b/dwm/patches/dwm-resetlayout-6.2.diff
@@ -0,0 +1,64 @@
+# From 4df827a2ec7820f41bdb8576cc39b55fbf35be44 Mon Sep 17 00:00:00 2001
+# From: Jack Bird <jack.bird@durham.ac.uk>
+# Date: Mon, 16 Aug 2021 23:25:16 +0100
+# Subject: [PATCH] Patch applies cleanly
+#
+# ---
+# config.def.h | 1 +
+# dwm.c | 15 +++++++++++++++
+# 2 files changed, 16 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..5d118cf 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -70,6 +70,7 @@ static Key keys[] = {
+ { MODKEY, XK_d, incnmaster, {.i = -1 } },
+ { MODKEY, XK_h, setmfact, {.f = -0.05} },
+ { MODKEY, XK_l, setmfact, {.f = +0.05} },
++ { MODKEY, XK_r, resetlayout, {0} },
+ { MODKEY, XK_Return, zoom, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY|ShiftMask, XK_c, killclient, {0} },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..77727ea 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -188,6 +188,7 @@ static void pop(Client *);
+ static void propertynotify(XEvent *e);
+ static void quit(const Arg *arg);
+ static Monitor *recttomon(int x, int y, int w, int h);
++static void resetlayout(const Arg *arg);
+ 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);
+@@ -1265,6 +1266,16 @@ recttomon(int x, int y, int w, int h)
+ return r;
+ }
+
++void
++resetlayout(const Arg *arg)
++{
++ Arg default_layout = {.v = &layouts[0]};
++ Arg default_mfact = {.f = mfact + 1};
++
++ setlayout(&default_layout);
++ setmfact(&default_mfact);
++}
++
+ void
+ resize(Client *c, int x, int y, int w, int h, int interact)
+ {
+@@ -1282,6 +1293,10 @@ resizeclient(Client *c, int x, int y, int w, int h)
+ c->oldw = c->w; c->w = wc.width = w;
+ c->oldh = c->h; c->h = wc.height = h;
+ wc.border_width = c->bw;
++
++ if ((nexttiled(c->mon->clients) == c) && !(nexttiled(c->next)))
++ resetlayout(NULL);
++
+ XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
+ configure(c);
+ XSync(dpy, False);
+--
+2.32.0
diff --git a/dwm/patches/dwm-resetnmaster-pertag-6.3.diff b/dwm/patches/dwm-resetnmaster-pertag-6.3.diff
new file mode 100644
index 0000000..a3d12c0
--- /dev/null
+++ b/dwm/patches/dwm-resetnmaster-pertag-6.3.diff
@@ -0,0 +1,36 @@
+diff -r -u a/config.def.h b/config.def.h
+--- a/config.def.h 2022-01-07 06:42:18.000000000 -0500
++++ b/config.def.h 2022-01-23 16:03:42.521951418 -0500
+@@ -69,6 +69,7 @@
+ { MODKEY, XK_k, focusstack, {.i = -1 } },
+ { MODKEY, XK_i, incnmaster, {.i = +1 } },
+ { MODKEY, XK_d, incnmaster, {.i = -1 } },
++ { MODKEY, XK_o, resetnmaster, {0} },
+ { MODKEY, XK_h, setmfact, {.f = -0.05} },
+ { MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY, XK_Return, zoom, {0} },
+diff -r -u a/dwm.c b/dwm.c
+--- a/dwm.c 2022-01-23 16:06:01.221948285 -0500
++++ b/dwm.c 2022-01-23 16:05:35.949948855 -0500
+@@ -191,6 +191,7 @@
+ static void propertynotify(XEvent *e);
+ static void quit(const Arg *arg);
+ static Monitor *recttomon(int x, int y, int w, int h);
++static void resetnmaster(const Arg *arg);
+ 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);
+@@ -1296,6 +1297,13 @@
+ }
+
+ void
++resetnmaster(const Arg *arg)
++{
++ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = 1;
++ arrange(selmon);
++}
++
++void
+ resize(Client *c, int x, int y, int w, int h, int interact)
+ {
+ if (applysizehints(c, &x, &y, &w, &h, interact))
diff --git a/dwm/patches/dwm-resizehere-20230824-e81f17d.diff b/dwm/patches/dwm-resizehere-20230824-e81f17d.diff
new file mode 100644
index 0000000..2e353f1
--- /dev/null
+++ b/dwm/patches/dwm-resizehere-20230824-e81f17d.diff
@@ -0,0 +1,60 @@
+# From d2824944615917697c18555a397bf84f2249a722 Mon Sep 17 00:00:00 2001
+# From: =?UTF-8?q?Gutyina=20Gerg=C5=91?= <gutyina.gergo.2@gmail.com>
+# Date: Thu, 24 Aug 2023 15:06:56 +0200
+# Subject: [PATCH] Resize clients without wrapping the pointer
+#
+# ---
+# dwm.c | 14 +++++++-------
+# 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/dwm.c b/dwm.c
+index f1d86b2..8c661a2 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -1300,7 +1300,7 @@ resizeclient(Client *c, int x, int y, int w, int h)
+ void
+ resizemouse(const Arg *arg)
+ {
+- int ocx, ocy, nw, nh;
++ int x, y, ocw, och, nw, nh;
+ Client *c;
+ Monitor *m;
+ XEvent ev;
+@@ -1311,12 +1311,13 @@ resizemouse(const Arg *arg)
+ if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
+ return;
+ restack(selmon);
+- ocx = c->x;
+- ocy = c->y;
++ ocw = c->w;
++ och = c->h;
+ if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
+ None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
+ return;
+- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
++ if(!getrootptr(&x, &y))
++ return;
+ do {
+ XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
+ switch(ev.type) {
+@@ -1330,8 +1331,8 @@ resizemouse(const Arg *arg)
+ continue;
+ lasttime = ev.xmotion.time;
+
+- nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
+- nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
++ nw = MAX(ocw + (ev.xmotion.x - x), 1);
++ nh = MAX(och + (ev.xmotion.y - y), 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)
+ {
+@@ -1344,7 +1345,6 @@ resizemouse(const Arg *arg)
+ break;
+ }
+ } while (ev.type != ButtonRelease);
+- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+ XUngrabPointer(dpy, CurrentTime);
+ while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+ if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
+--
+2.41.0
diff --git a/dwm/patches/dwm-restartsig-20180523-6.2.diff b/dwm/patches/dwm-restartsig-20180523-6.2.diff
new file mode 100644
index 0000000..5aa979b
--- /dev/null
+++ b/dwm/patches/dwm-restartsig-20180523-6.2.diff
@@ -0,0 +1,138 @@
+# From 2991f37f0aaf44b9f9b11e7893ff0af8eb88f649 Mon Sep 17 00:00:00 2001
+# From: Christopher Drelich <cd@cdrakka.com>
+# Date: Wed, 23 May 2018 22:50:38 -0400
+# Subject: [PATCH] Modifies quit to handle restarts and adds SIGHUP and SIGTERM
+# handlers.
+#
+# Modified quit() to restart if it receives arg .i = 1
+# MOD+CTRL+SHIFT+Q was added to confid.def.h to do just that.
+#
+# Signal handlers were handled for SIGHUP and SIGTERM.
+# If dwm receives these signals it calls quit() with
+# arg .i = to 1 or 0, respectively.
+#
+# To restart dwm:
+# MOD+CTRL+SHIFT+Q
+# or
+# kill -HUP dwmpid
+#
+# To quit dwm cleanly:
+# MOD+SHIFT+Q
+# or
+# kill -TERM dwmpid
+# ---
+# config.def.h | 1 +
+# dwm.1 | 10 ++++++++++
+# dwm.c | 22 ++++++++++++++++++++++
+# 3 files changed, 33 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index a9ac303..e559429 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -94,6 +94,7 @@ static Key keys[] = {
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} },
+ };
+
+ /* button definitions */
+diff --git a/dwm.1 b/dwm.1
+index 13b3729..36a331c 100644
+--- a/dwm.1
++++ b/dwm.1
+@@ -142,6 +142,9 @@ Add/remove all windows with nth tag to/from the view.
+ .TP
+ .B Mod1\-Shift\-q
+ Quit dwm.
++.TP
++.B Mod1\-Control\-Shift\-q
++Restart dwm.
+ .SS Mouse commands
+ .TP
+ .B Mod1\-Button1
+@@ -155,6 +158,13 @@ Resize focused window while dragging. Tiled windows will be toggled to the float
+ .SH CUSTOMIZATION
+ dwm is customized by creating a custom config.h and (re)compiling the source
+ code. This keeps it fast, secure and simple.
++.SH SIGNALS
++.TP
++.B SIGHUP - 1
++Restart the dwm process.
++.TP
++.B SIGTERM - 15
++Cleanly terminate the dwm process.
+ .SH SEE ALSO
+ .BR dmenu (1),
+ .BR st (1)
+diff --git a/dwm.c b/dwm.c
+index bb95e26..286eecd 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -205,6 +205,8 @@ static void setup(void);
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
++static void sighup(int unused);
++static void sigterm(int unused);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+@@ -260,6 +262,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
+ [UnmapNotify] = unmapnotify
+ };
+ static Atom wmatom[WMLast], netatom[NetLast];
++static int restart = 0;
+ static int running = 1;
+ static Cur *cursor[CurLast];
+ static Clr **scheme;
+@@ -1248,6 +1251,7 @@ propertynotify(XEvent *e)
+ void
+ quit(const Arg *arg)
+ {
++ if(arg->i) restart = 1;
+ running = 0;
+ }
+
+@@ -1536,6 +1540,9 @@ setup(void)
+ /* clean up any zombies immediately */
+ sigchld(0);
+
++ signal(SIGHUP, sighup);
++ signal(SIGTERM, sigterm);
++
+ /* init screen */
+ screen = DefaultScreen(dpy);
+ sw = DisplayWidth(dpy, screen);
+@@ -1637,6 +1644,20 @@ sigchld(int unused)
+ }
+
+ void
++sighup(int unused)
++{
++ Arg a = {.i = 1};
++ quit(&a);
++}
++
++void
++sigterm(int unused)
++{
++ Arg a = {.i = 0};
++ quit(&a);
++}
++
++void
+ spawn(const Arg *arg)
+ {
+ if (arg->v == dmenucmd)
+@@ -2139,6 +2160,7 @@ main(int argc, char *argv[])
+ setup();
+ scan();
+ run();
++ if(restart) execvp(argv[0], argv);
+ cleanup();
+ XCloseDisplay(dpy);
+ return EXIT_SUCCESS;
+--
+2.7.4
diff --git a/dwm/patches/dwm-scratchpads-20200414-728d397b.diff b/dwm/patches/dwm-scratchpads-20200414-728d397b.diff
new file mode 100644
index 0000000..050e367
--- /dev/null
+++ b/dwm/patches/dwm-scratchpads-20200414-728d397b.diff
@@ -0,0 +1,198 @@
+# From 728d397b21982af88737277fd9d6939a7b558786 Mon Sep 17 00:00:00 2001
+# From: Christian Tenllado <ctenllado@gmail.com>
+# Date: Tue, 14 Apr 2020 23:31:15 +0200
+# Subject: [PATCH] Multiple scratchpads
+#
+# This patch enables multiple scratchpads, each with one asigned window.
+# This enables the same scratchpad workflow that you have in i3.
+#
+# Scratchpads are implemented as special tags, whose mask does not
+# apply to new spawned windows. To assign a window to a scratchpad you
+# have to set up a rule, as you do with regular tags.
+#
+# Windows tagged with scratchpad tags can be set floating or not in the
+# rules array. Most users would probably want them floating (i3 style),
+# but having them tiled does also perfectly work and might fit better the
+# DWM approach. In case they are set floating, the patch moves them to the
+# center of the screen whenever they are shown. The patch can easily be
+# modified to make this last feature configurable in the rules array (see
+# the center patch).
+#
+# The togglescratch function, borrowed from the previous scratchpad patch
+# and slightly modified, can be used to spawn a registered scratchpad
+# process or toggle its view. This function looks for a window tagged with
+# the selected scratchpad tag. If it is found its view is toggled. If it is
+# not found the corresponding registered command is spawned. The
+# config.def.h shows three examples of its use to spawn a terminal in the
+# first scratchpad tag, a second terminal running ranger on the second
+# scratchpad tag and the keepassxc application to manage passwords on a
+# third scratchpad tag.
+#
+# If you prefer to spawn your scratchpad applications from the startup
+# script, you might opt for binding keys to toggleview instead, as
+# scratchpads are just special tags (you may even extend the TAGKEYS macro
+# to generalize the key bindings).
+# ---
+# config.def.h | 28 ++++++++++++++++++++++++----
+# dwm.c | 43 +++++++++++++++++++++++++++++++++++++++++--
+# 2 files changed, 65 insertions(+), 6 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..06265e1 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -18,17 +18,33 @@ static const char *colors[][3] = {
+ [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ };
+
++typedef struct {
++ const char *name;
++ const void *cmd;
++} Sp;
++const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL };
++const char *spcmd2[] = {"st", "-n", "spfm", "-g", "144x41", "-e", "ranger", NULL };
++const char *spcmd3[] = {"keepassxc", NULL };
++static Sp scratchpads[] = {
++ /* name cmd */
++ {"spterm", spcmd1},
++ {"spranger", spcmd2},
++ {"keepassxc", spcmd3},
++};
++
+ /* tagging */
+ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+-
+ static const Rule rules[] = {
+ /* xprop(1):
+ * WM_CLASS(STRING) = instance, class
+ * WM_NAME(STRING) = title
+ */
+ /* class instance title tags mask isfloating monitor */
+- { "Gimp", NULL, NULL, 0, 1, -1 },
+- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
++ { "Gimp", NULL, NULL, 0, 1, -1 },
++ { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
++ { NULL, "spterm", NULL, SPTAG(0), 1, -1 },
++ { NULL, "spfm", NULL, SPTAG(1), 1, -1 },
++ { NULL, "keepassxc", NULL, SPTAG(2), 0, -1 },
+ };
+
+ /* layout(s) */
+@@ -59,6 +75,7 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+ static const char *termcmd[] = { "st", NULL };
+
++
+ static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+@@ -84,6 +101,9 @@ static Key keys[] = {
+ { MODKEY, XK_period, focusmon, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
++ { MODKEY, XK_y, togglescratch, {.ui = 0 } },
++ { MODKEY, XK_u, togglescratch, {.ui = 1 } },
++ { MODKEY, XK_x, togglescratch, {.ui = 2 } },
+ TAGKEYS( XK_1, 0)
+ TAGKEYS( XK_2, 1)
+ TAGKEYS( XK_3, 2)
+@@ -106,7 +126,7 @@ static Button buttons[] = {
+ { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
+ { ClkClientWin, MODKEY, Button1, movemouse, {0} },
+ { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
+- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
++ { ClkClientWin, MODKEY, Button1, resizemouse, {0} },
+ { ClkTagBar, 0, Button1, view, {0} },
+ { ClkTagBar, 0, Button3, toggleview, {0} },
+ { ClkTagBar, MODKEY, Button1, tag, {0} },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..646aa1a 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -54,7 +54,10 @@
+ #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X) ((X)->w + 2 * (X)->bw)
+ #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
+-#define TAGMASK ((1 << LENGTH(tags)) - 1)
++#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads))
++#define TAGMASK ((1 << NUMTAGS) - 1)
++#define SPTAG(i) ((1 << LENGTH(tags)) << (i))
++#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags))
+ #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+
+ /* enums */
+@@ -211,6 +214,7 @@ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void togglescratch(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -299,6 +303,11 @@ applyrules(Client *c)
+ {
+ c->isfloating = r->isfloating;
+ c->tags |= r->tags;
++ if ((r->tags & SPTAGMASK) && r->isfloating) {
++ c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
++ c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
++ }
++
+ for (m = mons; m && m->num != r->monitor; m = m->next);
+ if (m)
+ c->mon = m;
+@@ -308,7 +317,7 @@ applyrules(Client *c)
+ 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];
++ c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : (c->mon->tagset[c->mon->seltags] & ~SPTAGMASK);
+ }
+
+ int
+@@ -1616,6 +1625,10 @@ showhide(Client *c)
+ if (!c)
+ return;
+ if (ISVISIBLE(c)) {
++ if ((c->tags & SPTAGMASK) && c->isfloating) {
++ c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
++ c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
++ }
+ /* show clients top down */
+ XMoveWindow(dpy, c->win, c->x, c->y);
+ if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
+@@ -1719,6 +1732,32 @@ togglefloating(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++togglescratch(const Arg *arg)
++{
++ Client *c;
++ unsigned int found = 0;
++ unsigned int scratchtag = SPTAG(arg->ui);
++ Arg sparg = {.v = scratchpads[arg->ui].cmd};
++
++ for (c = selmon->clients; c && !(found = c->tags & scratchtag); c = c->next);
++ if (found) {
++ unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag;
++ if (newtagset) {
++ selmon->tagset[selmon->seltags] = newtagset;
++ focus(NULL);
++ arrange(selmon);
++ }
++ if (ISVISIBLE(c)) {
++ focus(c);
++ restack(selmon);
++ }
++ } else {
++ selmon->tagset[selmon->seltags] |= scratchtag;
++ spawn(&sparg);
++ }
++}
++
+ void
+ toggletag(const Arg *arg)
+ {
+--
+2.20.1
diff --git a/dwm/patches/dwm-sendmoncenter-20210805-138b405f.diff b/dwm/patches/dwm-sendmoncenter-20210805-138b405f.diff
new file mode 100644
index 0000000..3efdca4
--- /dev/null
+++ b/dwm/patches/dwm-sendmoncenter-20210805-138b405f.diff
@@ -0,0 +1,27 @@
+# From 449324adbe53240a734cb5f8f72763bb3419829a Mon Sep 17 00:00:00 2001
+# From: Rizqi Nur Assyaufi <bandithijo@gmail.com>
+# Date: Sat, 5 Aug 2021 00:04:32 +0800
+# Subject: [PATCH] [sendmoncenter] Send floating window to another monitor will
+# centered
+#
+# This patch will allows you to send floating window client to another monitor
+# will be centered position.
+# ---
+# dwm.c | 2 ++
+# 1 file changed, 2 insertions(+)
+
+diff --git a/dwm.c b/dwm.c
+index 5e4d494..c20023e 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -1418,6 +1418,8 @@ sendmon(Client *c, Monitor *m)
+ detachstack(c);
+ c->mon = m;
+ c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
++ c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
++ c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
+ attach(c);
+ attachstack(c);
+ focus(NULL);
+--
+2.31.1
diff --git a/dwm/patches/dwm-setborderpx-6.2.diff b/dwm/patches/dwm-setborderpx-6.2.diff
new file mode 100644
index 0000000..6a82087
--- /dev/null
+++ b/dwm/patches/dwm-setborderpx-6.2.diff
@@ -0,0 +1,90 @@
+diff -up a/config.def.h b/config.def.h
+--- a/config.def.h 2020-05-12 02:17:20.070933833 +0200
++++ b/config.def.h 2020-05-13 03:27:51.018695798 +0200
+@@ -84,6 +84,9 @@ static Key keys[] = {
+ { MODKEY, XK_period, focusmon, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
++ { MODKEY|ShiftMask, XK_minus, setborderpx, {.i = -1 } },
++ { MODKEY|ShiftMask, XK_plus, setborderpx, {.i = +1 } },
++ { MODKEY|ShiftMask, XK_numbersign, setborderpx, {.i = 0 } },
+ TAGKEYS( XK_1, 0)
+ TAGKEYS( XK_2, 1)
+ TAGKEYS( XK_3, 2)
+diff -up a/dwm.c b/dwm.c
+--- a/dwm.c 2020-05-12 02:17:20.070933833 +0200
++++ b/dwm.c 2020-05-14 00:17:35.047919771 +0200
+@@ -119,6 +119,7 @@ struct Monitor {
+ int by; /* bar geometry */
+ int mx, my, mw, mh; /* screen size */
+ int wx, wy, ww, wh; /* window area */
++ unsigned int borderpx;
+ unsigned int seltags;
+ unsigned int sellt;
+ unsigned int tagset[2];
+@@ -196,6 +197,7 @@ static void run(void);
+ static void scan(void);
+ static int sendevent(Client *c, Atom proto);
+ static void sendmon(Client *c, Monitor *m);
++static void setborderpx(const Arg *arg);
+ static void setclientstate(Client *c, long state);
+ static void setfocus(Client *c);
+ static void setfullscreen(Client *c, int fullscreen);
+@@ -638,6 +640,7 @@ createmon(void)
+ m->nmaster = nmaster;
+ m->showbar = showbar;
+ m->topbar = topbar;
++ m->borderpx = borderpx;
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+@@ -1047,7 +1050,7 @@ manage(Window w, XWindowAttributes *wa)
+ /* only fix client y-offset, if the client center might cover the bar */
+ c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
+ && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
+- c->bw = borderpx;
++ c->bw = c->mon->borderpx;
+
+ wc.border_width = c->bw;
+ XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+@@ -1424,6 +1427,40 @@ sendmon(Client *c, Monitor *m)
+ }
+
+ void
++setborderpx(const Arg *arg)
++{
++ Client *c;
++ int prev_borderpx = selmon->borderpx;
++
++ if (arg->i == 0)
++ selmon->borderpx = borderpx;
++ else if (selmon->borderpx + arg->i < 0)
++ selmon->borderpx = 0;
++ else
++ selmon->borderpx += arg->i;
++
++ for (c = selmon->clients; c; c = c->next)
++ {
++ if (c->bw + arg->i < 0)
++ c->bw = selmon->borderpx = 0;
++ else
++ c->bw = selmon->borderpx;
++ if (c->isfloating || !selmon->lt[selmon->sellt]->arrange)
++ {
++ if (arg->i != 0 && prev_borderpx + arg->i >= 0)
++ resize(c, c->x, c->y, c->w-(arg->i*2), c->h-(arg->i*2), 0);
++ else if (arg->i != 0)
++ resizeclient(c, c->x, c->y, c->w, c->h);
++ else if (prev_borderpx > borderpx)
++ resize(c, c->x, c->y, c->w + 2*(prev_borderpx - borderpx), c->h + 2*(prev_borderpx - borderpx), 0);
++ else if (prev_borderpx < borderpx)
++ resize(c, c->x, c->y, c->w-2*(borderpx - prev_borderpx), c->h-2*(borderpx - prev_borderpx), 0);
++ }
++ }
++ arrange(selmon);
++}
++
++void
+ setclientstate(Client *c, long state)
+ {
+ long data[] = { state, None };
diff --git a/dwm/patches/dwm-shift-tools-6.2.diff b/dwm/patches/dwm-shift-tools-6.2.diff
new file mode 100644
index 0000000..e9b9803
--- /dev/null
+++ b/dwm/patches/dwm-shift-tools-6.2.diff
@@ -0,0 +1,55 @@
+# From d57c8508c9f26be40667d402a2daaa2b27ae759f Mon Sep 17 00:00:00 2001
+# From: explosion-mental <explosion0mental@gmail.com>
+# Date: Wed, 11 Aug 2021 21:05:44 -0500
+# Subject: [PATCH] shift-tools-scratchpads - shifttag, moves the current selected client to
+# the adjacent tag - shifttagclients, moves the current selected client to the
+# adjacent tag that has at least one client else acts as shifttag -
+# shiftview, view adjacent tag - shiftviewclients, view the closes tag that has
+# a client. If none acts as shiftview - shiftboth, shifttag and shiftview.
+# Basically moves the window to the next/prev tag and follows it. -
+# shiftswaptags, its a shift implementation on the swaptags function (see
+# https://github.com/moizifty/DWM-Build/blob/65379c62640788881486401a0d8c79333751b02f/config.h#L48
+# for more details), which in short 'swaps tags' (swaps all clients with
+# the clients on the adjacent tag). A pretty useful example of this is
+# chosing a tag empty and sending all your clients to that tag. - swapfunction
+# is the 'helper' function for the shiftswaptags. remember that these functions
+# **shift**, which means you can go from tag 1 to 9 or 9 to 1. Also remember
+# that the default argument is 1 and you can change it.
+#
+# ---
+# config.def.h | 9 ++++
+# shift-tools-scratchpads.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++
+# 2 files changed, 144 insertions(+)
+# create mode 100644 shift-tools-scratchpads.c
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..1390d17 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -58,9 +58,14 @@ static const Layout layouts[] = {
+ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+ static const char *termcmd[] = { "st", NULL };
++#include "shift-tools-scratchpads.c"
+
+ static Key keys[] = {
+ /* modifier key function argument */
++ { MODKEY, XK_o, shiftviewclients, { .i = +1 } },
++ { MODKEY|ShiftMask, XK_o, shiftview, { .i = +1 } },
++ { MODKEY|ShiftMask, XK_i, shiftview, { .i = -1 } },
++ { MODKEY, XK_i, shiftviewclients, { .i = -1 } },
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+ { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
+ { MODKEY, XK_b, togglebar, {0} },
+@@ -69,6 +74,10 @@ static Key keys[] = {
+ { MODKEY, XK_i, incnmaster, {.i = +1 } },
+ { MODKEY, XK_d, incnmaster, {.i = -1 } },
+ { MODKEY, XK_h, setmfact, {.f = -0.05} },
++ { MODKEY|ShiftMask, XK_h, shiftboth, { .i = -1 } },
++ { MODKEY|ControlMask, XK_h, shiftswaptags, { .i = -1 } },
++ { MODKEY|ControlMask, XK_l, shiftswaptags, { .i = +1 } },
++ { MODKEY|ShiftMask, XK_l, shiftboth, { .i = +1 } },
+ { MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY, XK_Return, zoom, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+2.32.0
diff --git a/dwm/patches/dwm-showselmon-6.2.diff b/dwm/patches/dwm-showselmon-6.2.diff
new file mode 100644
index 0000000..bbf837e
--- /dev/null
+++ b/dwm/patches/dwm-showselmon-6.2.diff
@@ -0,0 +1,46 @@
+diff -up a/config.def.h b/config.def.h
+--- a/config.def.h 2020-07-04 13:56:23.316739958 +0200
++++ b/config.def.h 2020-07-04 13:57:58.020554340 +0200
+@@ -15,6 +15,7 @@ static const char col_cyan[] = "#
+ static const char *colors[][3] = {
+ /* fg bg border */
+ [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
++ [SchemeInv] = { col_gray1, col_gray3, col_gray2 },
+ [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ };
+
+diff -up a/dwm.c b/dwm.c
+--- a/dwm.c 2020-07-04 13:56:23.316739958 +0200
++++ b/dwm.c 2020-07-04 14:14:54.124590755 +0200
+@@ -59,7 +59,7 @@
+
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+-enum { SchemeNorm, SchemeSel }; /* color schemes */
++enum { SchemeNorm, SchemeInv, SchemeSel }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+@@ -716,7 +716,12 @@ drawbar(Monitor *m)
+ x = 0;
+ for (i = 0; i < LENGTH(tags); i++) {
+ w = TEXTW(tags[i]);
+- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
++ if (m == selmon) {
++ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
++ }
++ else {
++ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeInv : SchemeNorm]);
++ }
+ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+ if (occ & 1 << i)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw,
+@@ -730,7 +735,7 @@ drawbar(Monitor *m)
+
+ if ((w = m->ww - sw - x) > bh) {
+ if (m->sel) {
+- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
++ drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeInv]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+ if (m->sel->isfloating)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
diff --git a/dwm/patches/dwm-spawntag-6.2.diff b/dwm/patches/dwm-spawntag-6.2.diff
new file mode 100644
index 0000000..9dba2da
--- /dev/null
+++ b/dwm/patches/dwm-spawntag-6.2.diff
@@ -0,0 +1,84 @@
+# From abace8a090f579a9bd2513e78e0ebe9d9fa1e0bb Mon Sep 17 00:00:00 2001
+# From: Piyush Pangtey <gokuvsvegita@gmail.com>
+# Date: Wed, 19 May 2021 19:27:34 +0530
+# Subject: [PATCH] [Feature] spawntag
+#
+# spawn application whenever a tag is middle clicked
+# ---
+# config.def.h | 16 ++++++++++++++++
+# dwm.c | 14 ++++++++++++++
+# 2 files changed, 30 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..442b556 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -54,11 +54,26 @@ static const Layout layouts[] = {
+ /* helper for spawning shell commands in the pre dwm-5.0 fashion */
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+
++/* helper for launching gtk application */
++#define GTKCMD(cmd) { .v = (const char*[]){ "/usr/bin/gtk-launch", cmd, NULL } }
++
+ /* commands */
+ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+ static const char *termcmd[] = { "st", NULL };
+
++static const Arg tagexec[] = {
++ { .v = termcmd },
++ { .v = termcmd },
++ { .v = termcmd },
++ { .v = termcmd },
++ { .v = termcmd },
++ { .v = termcmd },
++ { .v = termcmd },
++ { .v = termcmd },
++ { .v = termcmd }
++};
++
+ static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+@@ -108,6 +123,7 @@ static Button buttons[] = {
+ { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
+ { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
+ { ClkTagBar, 0, Button1, view, {0} },
++ { ClkTagBar, 0, Button2, spawntag, {0} },
+ { ClkTagBar, 0, Button3, toggleview, {0} },
+ { ClkTagBar, MODKEY, Button1, tag, {0} },
+ { ClkTagBar, MODKEY, Button3, toggletag, {0} },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..89b3220 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -207,6 +207,7 @@ static void showhide(Client *c);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
++static void spawntag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+@@ -1662,6 +1663,19 @@ tag(const Arg *arg)
+ }
+ }
+
++void
++spawntag(const Arg *arg)
++{
++ if (arg->ui & TAGMASK) {
++ for (int i = LENGTH(tags); i >= 0; i--) {
++ if (arg->ui & 1<<i) {
++ spawn(&tagexec[i]);
++ return;
++ }
++ }
++ }
++}
++
+ void
+ tagmon(const Arg *arg)
+ {
+--
+2.31.1
diff --git a/dwm/patches/dwm-stacker-6.2.diff b/dwm/patches/dwm-stacker-6.2.diff
new file mode 100644
index 0000000..91837f0
--- /dev/null
+++ b/dwm/patches/dwm-stacker-6.2.diff
@@ -0,0 +1,196 @@
+# From d04f2d00688c8b0969d4f10f460c980dd91dac37 Mon Sep 17 00:00:00 2001
+# From: MLquest8 <miskuzius@gmail.com>
+# Date: Fri, 12 Jun 2020 16:04:18 +0400
+# Subject: [PATCH] stacker updated for version 6.2
+#
+# ---
+# config.def.h | 14 +++++++--
+# dwm.c | 88 ++++++++++++++++++++++++++++++++++++++++------------
+# 2 files changed, 80 insertions(+), 22 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..d28f8fc 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -50,6 +50,14 @@ static const Layout layouts[] = {
+ { 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_grave, ACTION##stack, {.i = PREVSEL } }, \
++ { MOD, XK_q, ACTION##stack, {.i = 0 } }, \
++ { MOD, XK_a, ACTION##stack, {.i = 1 } }, \
++ { MOD, XK_z, ACTION##stack, {.i = 2 } }, \
++ { MOD, XK_x, ACTION##stack, {.i = -1 } },
+
+ /* helper for spawning shell commands in the pre dwm-5.0 fashion */
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+@@ -64,8 +72,8 @@ static Key keys[] = {
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+ { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
+ { MODKEY, XK_b, togglebar, {0} },
+- { MODKEY, XK_j, focusstack, {.i = +1 } },
+- { MODKEY, XK_k, focusstack, {.i = -1 } },
++ 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} },
+@@ -93,7 +101,7 @@ static Key keys[] = {
+ TAGKEYS( XK_7, 6)
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+- { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY|ShiftMask, XK_BackSpace, quit, {0} },
+ };
+
+ /* button definitions */
+diff --git a/dwm.c b/dwm.c
+index 9fd0286..6c302c3 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -47,15 +47,21 @@
+ /* macros */
+ #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
+ #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
++#define GETINC(X) ((X) - 2000)
++#define INC(X) ((X) + 2000)
+ #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 ISINC(X) ((X) > 1000 && (X) < 3000)
+ #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
++#define PREVSEL 3000
+ #define LENGTH(X) (sizeof X / sizeof X[0])
++#define MOD(N,M) ((N)%(M) < 0 ? (N)%(M) + (M) : (N)%(M))
+ #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X) ((X)->w + 2 * (X)->bw)
+ #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
+ #define TAGMASK ((1 << LENGTH(tags)) - 1)
+ #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
++#define TRUNC(X,A,B) (MAX((A), MIN((X), (B))))
+
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+@@ -187,6 +193,7 @@ static void movemouse(const Arg *arg);
+ static Client *nexttiled(Client *c);
+ static void pop(Client *);
+ static void propertynotify(XEvent *e);
++static void pushstack(const Arg *arg);
+ 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);
+@@ -207,6 +214,7 @@ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
++static int stackpos(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+@@ -833,27 +841,16 @@ focusmon(const Arg *arg)
+ void
+ focusstack(const Arg *arg)
+ {
+- Client *c = NULL, *i;
++ int i = stackpos(arg);
++ Client *c, *p;
+
+- if (!selmon->sel)
++ if(i < 0)
+ return;
+- if (arg->i > 0) {
+- for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
+- if (!c)
+- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
+- } else {
+- for (i = selmon->clients; i != selmon->sel; i = i->next)
+- if (ISVISIBLE(i))
+- c = i;
+- if (!c)
+- for (; i; i = i->next)
+- if (ISVISIBLE(i))
+- c = i;
+- }
+- if (c) {
+- focus(c);
+- restack(selmon);
+- }
++
++ 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);
+ }
+
+ Atom
+@@ -1246,6 +1243,29 @@ propertynotify(XEvent *e)
+ }
+ }
+
++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);
++}
++
+ void
+ quit(const Arg *arg)
+ {
+@@ -1653,6 +1673,36 @@ spawn(const Arg *arg)
+ }
+ }
+
++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;
++}
++
+ void
+ tag(const Arg *arg)
+ {
+--
+2.26.2
diff --git a/dwm/patches/dwm-stairs-fullgaps-20220430-8b48e30.diff b/dwm/patches/dwm-stairs-fullgaps-20220430-8b48e30.diff
new file mode 100644
index 0000000..75b47fd
--- /dev/null
+++ b/dwm/patches/dwm-stairs-fullgaps-20220430-8b48e30.diff
@@ -0,0 +1,98 @@
+# From 2004db267a9478918699961ab2f3579c2c8113fb Mon Sep 17 00:00:00 2001
+# From: Ehsan Ghorbannezhad <ehsan@disroot.org>
+# Date: Sat, 30 Apr 2022 02:48:58 +0430
+# Subject: [PATCH] add the stairs layout with fullgaps support
+#
+# ---
+# config.def.h | 5 +++++
+# dwm.c | 38 ++++++++++++++++++++++++++++++++++++++
+# 2 files changed, 43 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index 5b0d4de..c0f24f4 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -6,6 +6,9 @@ static const unsigned int gappx = 5; /* gaps between 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 unsigned int stairpx = 20; /* depth of the stairs layout */
++static const int stairdirection = 1; /* 0: left-aligned, 1: right-aligned */
++static const int stairsamesize = 1; /* 1 means shrink all the staired windows to the same size */
+ static const char *fonts[] = { "monospace:size=10" };
+ static const char dmenufont[] = "monospace:size=10";
+ static const char col_gray1[] = "#222222";
+@@ -43,6 +46,7 @@ static const Layout layouts[] = {
+ { "[]=", tile }, /* first entry is default */
+ { "><>", NULL }, /* no layout function means floating behavior */
+ { "[M]", monocle },
++ { "[S]", stairs },
+ };
+
+ /* key definitions */
+@@ -78,6 +82,7 @@ static Key keys[] = {
+ { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
+ { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
++ { MODKEY, XK_s, setlayout, {.v = &layouts[3]} },
+ { MODKEY, XK_space, setlayout, {0} },
+ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+diff --git a/dwm.c b/dwm.c
+index 5b7348c..2c5380f 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -209,6 +209,7 @@ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
++static void stairs(Monitor *m);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+@@ -1672,6 +1673,43 @@ spawn(const Arg *arg)
+ }
+ }
+
++void
++stairs(Monitor *m)
++{
++ unsigned int i, n, h, mw, my;
++ unsigned int ox, oy, ow, oh; /* stair offset values */
++ Client *c;
++
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
++ if (n == 0)
++ return;
++
++ if (n > m->nmaster)
++ mw = m->nmaster ? m->ww * m->mfact : 0;
++ else
++ mw = m->ww - m->gappx;
++
++ for (i = 0, my = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
++ if (i < m->nmaster) {
++ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx;
++ resize(c, m->wx + m->gappx, m->wy + my, mw - (2 * c->bw) - m->gappx, h - (2 * c->bw), 0);
++ if (my + HEIGHT(c) + m->gappx < m->wh)
++ my += HEIGHT(c) + m->gappx;
++ } else {
++ oy = i - m->nmaster;
++ ox = stairdirection ? n - i - 1 : (stairsamesize ? i - m->nmaster : 0);
++ ow = stairsamesize ? n - m->nmaster - 1 : n - i - 1;
++ oh = stairsamesize ? ow : i - m->nmaster;
++ resize(c,
++ m->wx + mw + (ox * stairpx) + m->gappx,
++ m->wy + (oy * stairpx) + m->gappx,
++ m->ww - mw - (2 * c->bw) - (ow * stairpx) - (2 * m->gappx),
++ m->wh - (2 * c->bw) - (oh * stairpx) - (2 * m->gappx),
++ 0);
++ }
++ }
++}
++
+ void
+ tag(const Arg *arg)
+ {
+--
+2.36.0
diff --git a/dwm/patches/dwm-statuscmd-20241009-8933ebc.diff b/dwm/patches/dwm-statuscmd-20241009-8933ebc.diff
new file mode 100644
index 0000000..4e68a8a
--- /dev/null
+++ b/dwm/patches/dwm-statuscmd-20241009-8933ebc.diff
@@ -0,0 +1,219 @@
+# From ca2a2e6386a746ebfc3480787e5d99da11e7abee Mon Sep 17 00:00:00 2001
+# From: Justinas Grigas <dev@jstnas.com>
+# Date: Wed, 9 Oct 2024 01:00:20 +0100
+# Subject: [PATCH] [dwm][statuscmd] better click regions
+#
+# The main improvement of this patch over the previous version 20210405 is that
+# the click region now ends on a matching signal raw byte.
+#
+# The matching byte is optional, and without it dwm will behave as before.
+#
+# To take advantage of this feature, scripts need to be modified to print the raw
+# byte at the end as well.
+#
+# In addition, this patch cleanly applies onto master branch.
+# ---
+# config.def.h | 6 ++-
+# dwm.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++---
+# 2 files changed, 104 insertions(+), 6 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..d008275 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -55,6 +55,8 @@ static const Layout layouts[] = {
+ /* helper for spawning shell commands in the pre dwm-5.0 fashion */
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+
++#define STATUSBAR "dwmblocks"
++
+ /* commands */
+ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+@@ -104,7 +106,9 @@ static const Button buttons[] = {
+ { ClkLtSymbol, 0, Button1, setlayout, {0} },
+ { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
+ { ClkWinTitle, 0, Button2, zoom, {0} },
+- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
++ { 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} },
+diff --git a/dwm.c b/dwm.c
+index 1443802..94ee0c7 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -171,6 +171,7 @@ static void focusstack(const Arg *arg);
+ static Atom getatomprop(Client *c, Atom prop);
+ static int getrootptr(int *x, int *y);
+ static long getstate(Window w);
++static pid_t getstatusbarpid();
+ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
+ static void grabbuttons(Client *c, int focused);
+ static void grabkeys(void);
+@@ -204,6 +205,7 @@ static void setmfact(const Arg *arg);
+ static void setup(void);
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
++static void sigstatusbar(const Arg *arg);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+@@ -236,6 +238,9 @@ static void zoom(const Arg *arg);
+ /* variables */
+ static const char broken[] = "broken";
+ static char stext[256];
++static int statusw;
++static int statussig;
++static pid_t statuspid = -1;
+ static int screen;
+ static int sw, sh; /* X display screen geometry width, height */
+ static int bh; /* bar height */
+@@ -422,6 +427,7 @@ buttonpress(XEvent *e)
+ Client *c;
+ Monitor *m;
+ XButtonPressedEvent *ev = &e->xbutton;
++ char *text, *s, ch;
+
+ click = ClkRootWin;
+ /* focus monitor if necessary */
+@@ -440,9 +446,27 @@ buttonpress(XEvent *e)
+ arg.ui = 1 << i;
+ } else if (ev->x < x + TEXTW(selmon->ltsymbol))
+ click = ClkLtSymbol;
+- else if (ev->x > selmon->ww - (int)TEXTW(stext))
++ else if (ev->x > selmon->ww - statusw) {
++ x = selmon->ww - statusw;
+ click = ClkStatusText;
+- else
++ statussig = 0;
++ for (text = s = stext; *s && x <= ev->x; s++) {
++ if ((unsigned char)(*s) < ' ') {
++ ch = *s;
++ *s = '\0';
++ x += TEXTW(text) - lrpad;
++ *s = ch;
++ text = s + 1;
++ if (x >= ev->x)
++ break;
++ /* reset on matching signal raw byte */
++ if (ch == statussig)
++ statussig = 0;
++ else
++ statussig = ch;
++ }
++ }
++ } else
+ click = ClkWinTitle;
+ } else if ((c = wintoclient(ev->window))) {
+ focus(c);
+@@ -708,9 +732,24 @@ drawbar(Monitor *m)
+
+ /* draw status first so it can be overdrawn by tags later */
+ if (m == selmon) { /* status is only drawn on selected monitor */
++ char *text, *s, ch;
+ drw_setscheme(drw, scheme[SchemeNorm]);
+- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
++
++ x = 0;
++ for (text = s = stext; *s; s++) {
++ if ((unsigned char)(*s) < ' ') {
++ ch = *s;
++ *s = '\0';
++ tw = TEXTW(text) - lrpad;
++ drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0);
++ x += tw;
++ *s = ch;
++ text = s + 1;
++ }
++ }
++ tw = TEXTW(text) - lrpad + 2;
++ drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0);
++ tw = statusw;
+ }
+
+ for (c = m->clients; c; c = c->next) {
+@@ -876,6 +915,30 @@ getatomprop(Client *c, Atom prop)
+ return atom;
+ }
+
++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("pidof -s "STATUSBAR, "r")))
++ return -1;
++ fgets(buf, sizeof(buf), fp);
++ pclose(fp);
++ return strtol(buf, NULL, 10);
++}
++
+ int
+ getrootptr(int *x, int *y)
+ {
+@@ -1643,6 +1706,20 @@ showhide(Client *c)
+ }
+ }
+
++void
++sigstatusbar(const Arg *arg)
++{
++ union sigval sv;
++
++ if (!statussig)
++ return;
++ sv.sival_int = arg->i;
++ if ((statuspid = getstatusbarpid()) <= 0)
++ return;
++
++ sigqueue(statuspid, SIGRTMIN+statussig, sv);
++}
++
+ void
+ spawn(const Arg *arg)
+ {
+@@ -2004,8 +2081,25 @@ updatesizehints(Client *c)
+ void
+ updatestatus(void)
+ {
+- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
++ if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) {
+ strcpy(stext, "dwm-"VERSION);
++ statusw = TEXTW(stext) - lrpad + 2;
++ } else {
++ char *text, *s, ch;
++
++ statusw = 0;
++ for (text = s = stext; *s; s++) {
++ if ((unsigned char)(*s) < ' ') {
++ ch = *s;
++ *s = '\0';
++ statusw += TEXTW(text) - lrpad;
++ *s = ch;
++ text = s + 1;
++ }
++ }
++ statusw += TEXTW(text) - lrpad + 2;
++
++ }
+ drawbar(selmon);
+ }
+
+--
+2.46.2
diff --git a/dwm/patches/dwm-sticky-6.5.diff b/dwm/patches/dwm-sticky-6.5.diff
new file mode 100644
index 0000000..50a4066
--- /dev/null
+++ b/dwm/patches/dwm-sticky-6.5.diff
@@ -0,0 +1,145 @@
+# From 60f7034ca1573e10cf9e005e2ef5a44e6b76ea9b Mon Sep 17 00:00:00 2001
+# From: elbachir-one <bachiralfa@gmail.com>
+# Date: Fri, 27 Sep 2024 12:35:36 +0100
+# Subject: [PATCH] Added the missing keybinding
+#
+# ---
+# config.def.h | 1 +
+# dwm.c | 43 ++++++++++++++++++++++++++++++++++++++++---
+# 2 files changed, 41 insertions(+), 3 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..55c0a6c 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -95,6 +95,7 @@ static const Key keys[] = {
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY, XK_s, togglesticky, {0} },
+ };
+
+ /* button definitions */
+diff --git a/dwm.c b/dwm.c
+index 67c6b2b..e8ed755 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -49,7 +49,7 @@
+ #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 ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky)
+ #define LENGTH(X) (sizeof X / sizeof X[0])
+ #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X) ((X)->w + 2 * (X)->bw)
+@@ -61,7 +61,7 @@
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+ enum { SchemeNorm, SchemeSel }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+- NetWMFullscreen, NetActiveWindow, NetWMWindowType,
++ NetWMFullscreen, NetWMSticky, NetActiveWindow, NetWMWindowType,
+ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
+ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
+@@ -92,7 +92,7 @@ struct Client {
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
+ int bw, oldbw;
+ unsigned int tags;
+- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+@@ -200,6 +200,7 @@ 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 setsticky(Client *c, int sticky);
+ static void setlayout(const Arg *arg);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
+@@ -211,6 +212,7 @@ static void tagmon(const Arg *arg);
+ static void tile(Monitor *m);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void togglesticky(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -525,6 +527,10 @@ clientmessage(XEvent *e)
+ || 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)));
++
++ if (cme->data.l[1] == netatom[NetWMSticky]
++ || cme->data.l[2] == netatom[NetWMSticky])
++ setsticky(c, (cme->data.l[0] == 1 || (cme->data.l[0] == 2 && !c->issticky)));
+ } else if (cme->message_type == netatom[NetActiveWindow]) {
+ if (c != selmon->sel && !c->isurgent)
+ seturgent(c, 1);
+@@ -1507,6 +1513,23 @@ setfullscreen(Client *c, int fullscreen)
+ }
+ }
+
++void
++ setsticky(Client *c, int sticky)
++ {
++
++ if(sticky && !c->issticky) {
++ XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
++ PropModeReplace, (unsigned char *) &netatom[NetWMSticky], 1);
++ c->issticky = 1;
++ } else if(!sticky && c->issticky){
++ XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
++ PropModeReplace, (unsigned char *)0, 0);
++ c->issticky = 0;
++ arrange(c->mon);
++ }
++ }
++
++
+ void
+ setlayout(const Arg *arg)
+ {
+@@ -1576,6 +1599,7 @@ setup(void)
+ 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[NetWMSticky] = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False);
+ netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
+ netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+ netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+@@ -1735,6 +1759,15 @@ togglefloating(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++togglesticky(const Arg *arg)
++{
++ if (!selmon->sel)
++ return;
++ setsticky(selmon->sel, !selmon->sel->issticky);
++ arrange(selmon);
++}
++
+ void
+ toggletag(const Arg *arg)
+ {
+@@ -2027,6 +2060,9 @@ updatewindowtype(Client *c)
+
+ if (state == netatom[NetWMFullscreen])
+ setfullscreen(c, 1);
++ if (state == netatom[NetWMSticky]) {
++ setsticky(c, 1);
++ }
+ if (wtype == netatom[NetWMWindowTypeDialog])
+ c->isfloating = 1;
+ }
+@@ -2163,3 +2199,4 @@ main(int argc, char *argv[])
+ XCloseDisplay(dpy);
+ return EXIT_SUCCESS;
+ }
++
+--
+2.46.0
diff --git a/dwm/patches/dwm-stickyindicator-6.2.diff b/dwm/patches/dwm-stickyindicator-6.2.diff
new file mode 100644
index 0000000..8b6ec41
--- /dev/null
+++ b/dwm/patches/dwm-stickyindicator-6.2.diff
@@ -0,0 +1,65 @@
+diff -pu dwm.stickypatch/config.def.h dwm.stickyindicator/config.def.h
+--- dwm.stickypatch/config.def.h 2021-02-28 23:51:25.118904642 -0600
++++ dwm.stickyindicator/config.def.h 2021-03-15 20:19:53.533323727 -0500
+@@ -17,6 +17,8 @@ static const char *colors[][3] = {
+ [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+ [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ };
++static const XPoint stickyicon[] = { {0,0}, {4,0}, {4,8}, {2,6}, {0,8}, {0,0} }; /* represents the icon as an array of vertices */
++static const XPoint stickyiconbb = {4,8}; /* defines the bottom right corner of the polygon's bounding box (speeds up scaling) */
+
+ /* tagging */
+ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+diff -pu dwm.stickypatch/drw.c dwm.stickyindicator/drw.c
+--- dwm.stickypatch/drw.c 2021-02-28 23:51:06.992237482 -0600
++++ dwm.stickyindicator/drw.c 2021-03-15 20:19:19.499990633 -0500
+@@ -248,6 +248,26 @@ drw_rect(Drw *drw, int x, int y, unsigne
+ XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
+ }
+
++void
++drw_polygon(Drw *drw, int x, int y, int ow, int oh, int sw, int sh, const XPoint *points, int npoints, int shape, int filled) /* wrapper function to scale and draw a polygon with X11 */
++{
++ if (!drw || !drw->scheme)
++ return;
++ XSetForeground(drw->dpy, drw->gc, drw->scheme[ColFg].pixel);
++ if (!filled) { /* reduces the scaled width and height by 1 when drawing the outline to compensate for X11 drawing the line 1 pixel over */
++ sw -= 1;
++ sh -= 1;
++ }
++ XPoint scaledpoints[npoints];
++ memcpy(scaledpoints, points, npoints);
++ for (int v = 0; v < npoints; v++)
++ scaledpoints[v] = (XPoint){ .x = points[v].x * sw / ow + x, .y = points[v].y * sh / oh + y };
++ if (filled)
++ XFillPolygon(drw->dpy, drw->drawable, drw->gc, scaledpoints, npoints, shape, CoordModeOrigin); /* Change shape to 'Convex' or 'Complex' in dwm.c if the shape is not 'Nonconvex' */
++ else
++ XDrawLines(drw->dpy, drw->drawable, drw->gc, scaledpoints, npoints, CoordModeOrigin);
++}
++
+ int
+ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
+ {
+diff -pu dwm.stickypatch/drw.h dwm.stickyindicator/drw.h
+--- dwm.stickypatch/drw.h 2021-02-28 23:51:06.992237482 -0600
++++ dwm.stickyindicator/drw.h 2021-03-01 01:34:02.739074730 -0600
+@@ -51,6 +51,7 @@ 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);
++void drw_polygon(Drw *drw, int x, int y, int ow, int oh, int sw, int sh, const XPoint *points, int npoints, int shape, int filled);
+ int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
+
+ /* Map functions */
+diff -pu dwm.stickypatch/dwm.c dwm.stickyindicator/dwm.c
+--- dwm.stickypatch/dwm.c 2021-02-28 23:51:25.118904642 -0600
++++ dwm.stickyindicator/dwm.c 2021-03-15 20:12:32.063326766 -0500
+@@ -736,6 +736,8 @@ drawbar(Monitor *m)
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+ if (m->sel->isfloating)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
++ if (m->sel->issticky)
++ drw_polygon(drw, x + boxs, m->sel->isfloating ? boxs * 2 + boxw : boxs, stickyiconbb.x, stickyiconbb.y, boxw, boxw * stickyiconbb.y / stickyiconbb.x, stickyicon, LENGTH(stickyicon), Nonconvex, m->sel->tags & m->tagset[m->seltags]);
+ } else {
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, x, 0, w, bh, 1, 1);
diff --git a/dwm/patches/dwm-swallow-6.3.diff b/dwm/patches/dwm-swallow-6.3.diff
new file mode 100644
index 0000000..d2d3835
--- /dev/null
+++ b/dwm/patches/dwm-swallow-6.3.diff
@@ -0,0 +1,410 @@
+# From 0cf9a007511f7dfd7dd94171b172562ebac9b6d5 Mon Sep 17 00:00:00 2001
+# From: Tom Schwindl <schwindl@posteo.de>
+# Date: Sat, 10 Sep 2022 12:51:09 +0200
+# Subject: [PATCH] 6.3 swallow patch
+#
+# ---
+# config.def.h | 9 +-
+# config.mk | 3 +-
+# dwm.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++--
+# 3 files changed, 237 insertions(+), 10 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 061ad662f82a..0b2b8ffd30d5 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,6 +3,7 @@
+ /* appearance */
+ static const unsigned int borderpx = 1; /* border pixel of windows */
+ static const unsigned int snap = 32; /* snap pixel */
++static const int swallowfloating = 0; /* 1 means swallow floating windows by default */
+ static const int showbar = 1; /* 0 means no bar */
+ static const int topbar = 1; /* 0 means bottom bar */
+ static const char *fonts[] = { "monospace:size=10" };
+@@ -26,9 +27,11 @@ static const Rule rules[] = {
+ * WM_CLASS(STRING) = instance, class
+ * WM_NAME(STRING) = title
+ */
+- /* class instance title tags mask isfloating monitor */
+- { "Gimp", NULL, NULL, 0, 1, -1 },
+- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
++ /* class instance title tags mask isfloating isterminal noswallow monitor */
++ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 },
++ { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1, -1 },
++ { "St", NULL, NULL, 0, 0, 1, 0, -1 },
++ { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
+ };
+
+ /* layout(s) */
+diff --git a/config.mk b/config.mk
+index 81c493ef4aff..52d1ebf30bec 100644
+--- a/config.mk
++++ b/config.mk
+@@ -20,10 +20,11 @@ FREETYPEINC = /usr/include/freetype2
+ # OpenBSD (uncomment)
+ #FREETYPEINC = ${X11INC}/freetype2
+ #MANPREFIX = ${PREFIX}/man
++#KVMLIB = -lkvm
+
+ # includes and libs
+ INCS = -I${X11INC} -I${FREETYPEINC}
+-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
++LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB}
+
+ # flags
+ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff --git a/dwm.c b/dwm.c
+index e5efb6a22806..e68294b6b679 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -40,6 +40,12 @@
+ #include <X11/extensions/Xinerama.h>
+ #endif /* XINERAMA */
+ #include <X11/Xft/Xft.h>
++#include <X11/Xlib-xcb.h>
++#include <xcb/res.h>
++#ifdef __OpenBSD__
++#include <sys/sysctl.h>
++#include <kvm.h>
++#endif /* __OpenBSD */
+
+ #include "drw.h"
+ #include "util.h"
+@@ -92,9 +98,11 @@ struct Client {
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
+ int bw, oldbw;
+ unsigned int tags;
+- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow;
++ pid_t pid;
+ Client *next;
+ Client *snext;
++ Client *swallowing;
+ Monitor *mon;
+ Window win;
+ };
+@@ -138,6 +146,8 @@ typedef struct {
+ const char *title;
+ unsigned int tags;
+ int isfloating;
++ int isterminal;
++ int noswallow;
+ int monitor;
+ } Rule;
+
+@@ -235,6 +245,12 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+ static void zoom(const Arg *arg);
+
++static pid_t getparentprocess(pid_t p);
++static int isdescprocess(pid_t p, pid_t c);
++static Client *swallowingclient(Window w);
++static Client *termforwin(const Client *c);
++static pid_t winpid(Window w);
++
+ /* variables */
+ static const char broken[] = "broken";
+ static char stext[256];
+@@ -269,6 +285,8 @@ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
+
++static xcb_connection_t *xcon;
++
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+
+@@ -298,6 +316,8 @@ applyrules(Client *c)
+ && (!r->class || strstr(class, r->class))
+ && (!r->instance || strstr(instance, r->instance)))
+ {
++ c->isterminal = r->isterminal;
++ c->noswallow = r->noswallow;
+ c->isfloating = r->isfloating;
+ c->tags |= r->tags;
+ for (m = mons; m && m->num != r->monitor; m = m->next);
+@@ -416,6 +436,53 @@ attachstack(Client *c)
+ c->mon->stack = c;
+ }
+
++void
++swallow(Client *p, Client *c)
++{
++
++ if (c->noswallow || c->isterminal)
++ return;
++ if (c->noswallow && !swallowfloating && c->isfloating)
++ return;
++
++ detach(c);
++ detachstack(c);
++
++ setclientstate(c, WithdrawnState);
++ XUnmapWindow(dpy, p->win);
++
++ p->swallowing = c;
++ c->mon = p->mon;
++
++ Window w = p->win;
++ p->win = c->win;
++ c->win = w;
++ updatetitle(p);
++ XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h);
++ arrange(p->mon);
++ configure(p);
++ updateclientlist();
++}
++
++void
++unswallow(Client *c)
++{
++ c->win = c->swallowing->win;
++
++ free(c->swallowing);
++ c->swallowing = NULL;
++
++ /* unfullscreen the client */
++ setfullscreen(c, 0);
++ updatetitle(c);
++ arrange(c->mon);
++ XMapWindow(dpy, c->win);
++ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
++ setclientstate(c, NormalState);
++ focus(NULL);
++ arrange(c->mon);
++}
++
+ void
+ buttonpress(XEvent *e)
+ {
+@@ -656,6 +723,9 @@ destroynotify(XEvent *e)
+
+ if ((c = wintoclient(ev->window)))
+ unmanage(c, 1);
++
++ else if ((c = swallowingclient(ev->window)))
++ unmanage(c->swallowing, 1);
+ }
+
+ void
+@@ -1022,12 +1092,13 @@ killclient(const Arg *arg)
+ void
+ manage(Window w, XWindowAttributes *wa)
+ {
+- Client *c, *t = NULL;
++ Client *c, *t = NULL, *term = NULL;
+ Window trans = None;
+ XWindowChanges wc;
+
+ c = ecalloc(1, sizeof(Client));
+ c->win = w;
++ c->pid = winpid(w);
+ /* geometry */
+ c->x = c->oldx = wa->x;
+ c->y = c->oldy = wa->y;
+@@ -1042,6 +1113,7 @@ manage(Window w, XWindowAttributes *wa)
+ } else {
+ c->mon = selmon;
+ applyrules(c);
++ term = termforwin(c);
+ }
+
+ if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
+@@ -1076,6 +1148,8 @@ manage(Window w, XWindowAttributes *wa)
+ c->mon->sel = c;
+ arrange(c->mon);
+ XMapWindow(dpy, c->win);
++ if (term)
++ swallow(term, c);
+ focus(NULL);
+ }
+
+@@ -1763,6 +1837,20 @@ unmanage(Client *c, int destroyed)
+ Monitor *m = c->mon;
+ XWindowChanges wc;
+
++ if (c->swallowing) {
++ unswallow(c);
++ return;
++ }
++
++ Client *s = swallowingclient(c->win);
++ if (s) {
++ free(s->swallowing);
++ s->swallowing = NULL;
++ arrange(m);
++ focus(NULL);
++ return;
++ }
++
+ detach(c);
+ detachstack(c);
+ if (!destroyed) {
+@@ -1778,9 +1866,12 @@ unmanage(Client *c, int destroyed)
+ XUngrabServer(dpy);
+ }
+ free(c);
+- focus(NULL);
+- updateclientlist();
+- arrange(m);
++
++ if (!s) {
++ arrange(m);
++ focus(NULL);
++ updateclientlist();
++ }
+ }
+
+ void
+@@ -2044,6 +2135,136 @@ view(const Arg *arg)
+ arrange(selmon);
+ }
+
++pid_t
++winpid(Window w)
++{
++
++ pid_t result = 0;
++
++#ifdef __linux__
++ xcb_res_client_id_spec_t spec = {0};
++ spec.client = w;
++ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
++
++ xcb_generic_error_t *e = NULL;
++ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec);
++ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
++
++ if (!r)
++ return (pid_t)0;
++
++ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
++ for (; i.rem; xcb_res_client_id_value_next(&i)) {
++ spec = i.data->spec;
++ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
++ uint32_t *t = xcb_res_client_id_value_value(i.data);
++ result = *t;
++ break;
++ }
++ }
++
++ free(r);
++
++ if (result == (pid_t)-1)
++ result = 0;
++
++#endif /* __linux__ */
++
++#ifdef __OpenBSD__
++ Atom type;
++ int format;
++ unsigned long len, bytes;
++ unsigned char *prop;
++ pid_t ret;
++
++ if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 0), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop)
++ return 0;
++
++ ret = *(pid_t*)prop;
++ XFree(prop);
++ result = ret;
++#endif /* __OpenBSD__ */
++ return result;
++}
++
++pid_t
++getparentprocess(pid_t p)
++{
++ unsigned int v = 0;
++
++#ifdef __linux__
++ FILE *f;
++ char buf[256];
++ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p);
++
++ if (!(f = fopen(buf, "r")))
++ return 0;
++
++ fscanf(f, "%*u %*s %*c %u", &v);
++ fclose(f);
++#endif /* __linux__*/
++
++#ifdef __OpenBSD__
++ int n;
++ kvm_t *kd;
++ struct kinfo_proc *kp;
++
++ kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL);
++ if (!kd)
++ return 0;
++
++ kp = kvm_getprocs(kd, KERN_PROC_PID, p, sizeof(*kp), &n);
++ v = kp->p_ppid;
++#endif /* __OpenBSD__ */
++
++ return (pid_t)v;
++}
++
++int
++isdescprocess(pid_t p, pid_t c)
++{
++ while (p != c && c != 0)
++ c = getparentprocess(c);
++
++ return (int)c;
++}
++
++Client *
++termforwin(const Client *w)
++{
++ Client *c;
++ Monitor *m;
++
++ if (!w->pid || w->isterminal)
++ return NULL;
++
++ for (m = mons; m; m = m->next) {
++ for (c = m->clients; c; c = c->next) {
++ if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid))
++ return c;
++ }
++ }
++
++ return NULL;
++}
++
++Client *
++swallowingclient(Window w)
++{
++ Client *c;
++ Monitor *m;
++
++ for (m = mons; m; m = m->next) {
++ for (c = m->clients; c; c = c->next) {
++ if (c->swallowing && c->swallowing->win == w)
++ return c;
++ }
++ }
++
++ return NULL;
++}
++
+ Client *
+ wintoclient(Window w)
+ {
+@@ -2133,10 +2354,12 @@ main(int argc, char *argv[])
+ fputs("warning: no locale support\n", stderr);
+ if (!(dpy = XOpenDisplay(NULL)))
+ die("dwm: cannot open display");
++ if (!(xcon = XGetXCBConnection(dpy)))
++ die("dwm: cannot get xcb connection\n");
+ checkotherwm();
+ setup();
+ #ifdef __OpenBSD__
+- if (pledge("stdio rpath proc exec", NULL) == -1)
++ if (pledge("stdio rpath proc exec ps", NULL) == -1)
+ die("pledge");
+ #endif /* __OpenBSD__ */
+ scan();
+--
+2.37.2
diff --git a/dwm/patches/dwm-switchallmonitortags-6.3.diff b/dwm/patches/dwm-switchallmonitortags-6.3.diff
new file mode 100644
index 0000000..44b751f
--- /dev/null
+++ b/dwm/patches/dwm-switchallmonitortags-6.3.diff
@@ -0,0 +1,62 @@
+# From 31b89fe119b4a0298da98891aa37b134facb6311 Mon Sep 17 00:00:00 2001
+# From: yasumori <ysmr@protonmail.com>
+# Date: Fri, 27 May 2022 00:21:27 -0400
+# Subject: [PATCH] This patch allows the user to switch the selected tag of all
+# monitors.
+#
+# For example, if monitor A is currently on tag 1, and monitor B is on tag 2,
+# and the user presses MODKEY+SUPERKEY+3, both monitor A and B will switch to
+# tag 3 (without changing the currently selected monitor).
+# ---
+# config.def.h | 2 ++
+# dwm.c | 13 +++++++++++++
+# 2 files changed, 15 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index a2ac963..3f504ab 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -46,8 +46,10 @@ static const Layout layouts[] = {
+
+ /* key definitions */
+ #define MODKEY Mod1Mask
++#define SUPERKEY Mod4Mask
+ #define TAGKEYS(KEY,TAG) \
+ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
++ { MODKEY|SUPERKEY, KEY, viewall, {.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} },
+diff --git a/dwm.c b/dwm.c
+index 5646a5c..28736ee 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -228,6 +228,7 @@ static void updatetitle(Client *c);
+ static void updatewindowtype(Client *c);
+ static void updatewmhints(Client *c);
+ static void view(const Arg *arg);
++static void viewall(const Arg *arg);
+ static Client *wintoclient(Window w);
+ static Monitor *wintomon(Window w);
+ static int xerror(Display *dpy, XErrorEvent *ee);
+@@ -2054,6 +2055,18 @@ view(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++viewall(const Arg *arg)
++{
++ Monitor *m;
++
++ for (m = mons; m; m = m->next) {
++ m->tagset[m->seltags] = arg->ui;
++ arrange(m);
++ }
++ focus(NULL);
++}
++
+ Client *
+ wintoclient(Window w)
+ {
+--
+2.36.1
diff --git a/dwm/patches/dwm-taglabels-hide_vacant_tags_funcionality-6.2.diff b/dwm/patches/dwm-taglabels-hide_vacant_tags_funcionality-6.2.diff
new file mode 100644
index 0000000..d27b0d8
--- /dev/null
+++ b/dwm/patches/dwm-taglabels-hide_vacant_tags_funcionality-6.2.diff
@@ -0,0 +1,91 @@
+diff -pu dwm.hide_vacant_tags/config.def.h dwm.programtags+hidewithvacanttags/config.def.h
+--- dwm.hide_vacant_tags/config.def.h 2021-03-15 16:37:24.586622415 -0500
++++ dwm.programtags+hidewithvacanttags/config.def.h 2021-03-15 16:32:37.586956549 -0500
+@@ -21,6 +21,10 @@ static const char *colors[][3] = {
+ /* tagging */
+ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+
++static const char ptagf[] = "[%s %s]"; /* format of a tag label */
++static const char etagf[] = "[%s]"; /* format of an empty tag */
++static const int lcaselbl = 0; /* 1 means make tag label lowercase */
++
+ static const Rule rules[] = {
+ /* xprop(1):
+ * WM_CLASS(STRING) = instance, class
+diff -pu dwm.hide_vacant_tags/dwm.c dwm.programtags+hidewithvacanttags/dwm.c
+--- dwm.hide_vacant_tags/dwm.c 2021-03-15 16:37:38.189939908 -0500
++++ dwm.programtags+hidewithvacanttags/dwm.c 2021-03-15 16:32:23.693639390 -0500
+@@ -20,6 +20,7 @@
+ *
+ * To understand everything else, start reading main().
+ */
++#include <ctype.h> /* for making tab label lowercase, very tiny standard library */
+ #include <errno.h>
+ #include <locale.h>
+ #include <signal.h>
+@@ -272,6 +273,8 @@ static Window root, wmcheckwin;
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+
++unsigned int tagw[LENGTH(tags)];
++
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+
+@@ -438,7 +441,7 @@ buttonpress(XEvent *e)
+ /* do not reserve space for vacant tags */
+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
+ continue;
+- x += TEXTW(tags[i]);
++ x += tagw[i];
+ } while (ev->x >= x && ++i < LENGTH(tags));
+ if (i < LENGTH(tags)) {
+ click = ClkTagBar;
+@@ -706,6 +709,8 @@ drawbar(Monitor *m)
+ int boxw = drw->fonts->h / 6 + 2;
+ unsigned int i, occ = 0, urg = 0;
+ Client *c;
++ char tagdisp[64];
++ char *masterclientontag[LENGTH(tags)];
+
+ /* draw status first so it can be overdrawn by tags later */
+ if (m == selmon) { /* status is only drawn on selected monitor */
+@@ -714,10 +719,21 @@ drawbar(Monitor *m)
+ drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+ }
+
++ for (i = 0; i < LENGTH(tags); i++)
++ masterclientontag[i] = NULL;
++
+ 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 < LENGTH(tags); i++)
++ if (!masterclientontag[i] && c->tags & (1<<i)) {
++ XClassHint ch = { NULL, NULL };
++ XGetClassHint(dpy, c->win, &ch);
++ masterclientontag[i] = ch.res_class;
++ if (lcaselbl)
++ masterclientontag[i][0] = tolower(masterclientontag[i][0]);
++ }
+ }
+ x = 0;
+ for (i = 0; i < LENGTH(tags); i++) {
+@@ -725,9 +741,14 @@ drawbar(Monitor *m)
+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
+ continue;
+
+- w = TEXTW(tags[i]);
++ if (masterclientontag[i])
++ snprintf(tagdisp, 64, ptagf, tags[i], masterclientontag[i]);
++ else
++ snprintf(tagdisp, 64, etagf, tags[i]);
++ masterclientontag[i] = tagdisp;
++ tagw[i] = w = TEXTW(masterclientontag[i]);
+ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
++ drw_text(drw, x, 0, w, bh, lrpad / 2, masterclientontag[i], urg & 1 << i);
+ x += w;
+ }
+ w = blw = TEXTW(m->ltsymbol);
diff --git a/dwm/patches/dwm-tiledmove-20231210-b731.diff b/dwm/patches/dwm-tiledmove-20231210-b731.diff
new file mode 100644
index 0000000..8ede0c6
--- /dev/null
+++ b/dwm/patches/dwm-tiledmove-20231210-b731.diff
@@ -0,0 +1,82 @@
+# From 427c5fef13676179621949f0a8a4036e49d4b74e Mon Sep 17 00:00:00 2001
+# From: Niki <>
+# Date: Sun, 10 Dec 2023 00:29:59 +0000
+# Subject: [PATCH] The function `movemouse` now doesn't force clients to be
+# floating.
+#
+# Tiling clients when moved will swap with any existing clients that
+# overlap with the cursor, and snap to other monitors.
+# ---
+# dwm.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
+# 1 file changed, 53 insertions(+), 3 deletions(-)
+
+diff --git a/dwm.c b/dwm.c
+index d12be2d..b1023e0 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -1189,11 +1189,60 @@ movemouse(const Arg *arg)
+ 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))
+- togglefloating(NULL);
+ if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
+ resize(c, nx, ny, c->w, c->h, 1);
++ else if (selmon->lt[selmon->sellt]->arrange || !c->isfloating) {
++ if ((m = recttomon(ev.xmotion.x_root, ev.xmotion.y_root, 1, 1)) != selmon) {
++ sendmon(c, m);
++ selmon = m;
++ focus(NULL);
++ }
++
++ Client *cc = c->mon->clients;
++ while (1) {
++ if (cc == 0) break;
++ if(
++ cc != c && !cc->isfloating && ISVISIBLE(cc) &&
++ ev.xmotion.x_root > cc->x &&
++ ev.xmotion.x_root < cc->x + cc->w &&
++ ev.xmotion.y_root > cc->y &&
++ ev.xmotion.y_root < cc->y + cc->h ) {
++ break;
++ }
++
++ cc = cc->next;
++ }
++
++ if (cc) {
++ Client *cl1, *cl2, ocl1;
++
++ if (!selmon->lt[selmon->sellt]->arrange) return;
++
++ cl1 = c;
++ cl2 = cc;
++ ocl1 = *cl1;
++ strcpy(cl1->name, cl2->name);
++ cl1->win = cl2->win;
++ cl1->x = cl2->x;
++ cl1->y = cl2->y;
++ cl1->w = cl2->w;
++ cl1->h = cl2->h;
++
++ cl2->win = ocl1.win;
++ strcpy(cl2->name, ocl1.name);
++ cl2->x = ocl1.x;
++ cl2->y = ocl1.y;
++ cl2->w = ocl1.w;
++ cl2->h = ocl1.h;
++
++ selmon->sel = cl2;
++
++ c = cc;
++ focus(c);
++
++ arrange(cl1->mon);
++ }
++ }
+ break;
+ }
+ } while (ev.type != ButtonRelease);
+--
+2.43.0
diff --git a/dwm/patches/dwm-toggleallmonspertag-6.4.diff b/dwm/patches/dwm-toggleallmonspertag-6.4.diff
new file mode 100644
index 0000000..32527f6
--- /dev/null
+++ b/dwm/patches/dwm-toggleallmonspertag-6.4.diff
@@ -0,0 +1,74 @@
+diff --git a/config.def.h b/config.def.h
+index 061ad66..67afc6d 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -71,6 +71,7 @@ static const Key keys[] = {
+ { MODKEY, XK_h, setmfact, {.f = -0.05} },
+ { MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY, XK_Return, zoom, {0} },
++ { MODKEY|ShiftMask, XK_Tab, toggleall, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY|ShiftMask, XK_c, killclient, {0} },
+ { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
+diff --git a/dwm.c b/dwm.c
+index e5efb6a..62f711b 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -210,6 +210,7 @@ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *m);
++static void toggleall(const Arg *arg);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+ static void toggletag(const Arg *arg);
+@@ -1694,6 +1695,49 @@ tile(Monitor *m)
+ }
+ }
+
++
++void
++toggleall(const Arg *arg)
++{
++ int i;
++ unsigned int tmptag;
++
++ Monitor* m;
++ for(m = mons; m; m = m->next){
++
++ if ((arg->ui & TAGMASK) == m->tagset[m->seltags])
++ return;
++ m->seltags ^= 1; /* toggle sel tagset */
++ if (arg->ui & TAGMASK) {
++ m->tagset[m->seltags] = arg->ui & TAGMASK;
++ m->pertag->prevtag = m->pertag->curtag;
++
++ if (arg->ui == ~0)
++ m->pertag->curtag = 0;
++ else {
++ for (i = 0; !(arg->ui & 1 << i); i++) ;
++ m->pertag->curtag = i + 1;
++ }
++ } else {
++ tmptag = m->pertag->prevtag;
++ m->pertag->prevtag = m->pertag->curtag;
++ m->pertag->curtag = tmptag;
++ }
++
++ m->nmaster = m->pertag->nmasters[m->pertag->curtag];
++ m->mfact = m->pertag->mfacts[m->pertag->curtag];
++ m->sellt = m->pertag->sellts[m->pertag->curtag];
++ m->lt[m->sellt] = m->pertag->ltidxs[m->pertag->curtag][m->sellt];
++ m->lt[m->sellt^1] = m->pertag->ltidxs[m->pertag->curtag][m->sellt^1];
++
++ if (m->showbar != m->pertag->showbars[m->pertag->curtag])
++ togglebar(NULL);
++
++ focus(NULL);
++ arrange(m);
++ }
++}
++
+ void
+ togglebar(const Arg *arg)
+ {
diff --git a/dwm/patches/dwm-toggleborder-6.3.diff b/dwm/patches/dwm-toggleborder-6.3.diff
new file mode 100644
index 0000000..adc6bd0
--- /dev/null
+++ b/dwm/patches/dwm-toggleborder-6.3.diff
@@ -0,0 +1,52 @@
+# From ef85b0473590615fda4ba4b20a717e42c99e3f99 Mon Sep 17 00:00:00 2001
+# From: Stanisław Bitner <sbitner420@tutanota.com>
+# Date: Tue, 9 Aug 2022 23:17:47 +0200
+# Subject: [PATCH] toggleborder
+#
+# This patch allows you to toggle client border. It works by setting the
+# border of the client to 0 or to borderpx defined in configuration file.
+# ---
+# config.def.h | 1 +
+# dwm.c | 8 ++++++++
+# 2 files changed, 9 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index a2ac963..60b811f 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -65,6 +65,7 @@ static Key keys[] = {
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+ { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
+ { MODKEY, XK_b, togglebar, {0} },
++ { MODKEY|ShiftMask, XK_b, toggleborder, {0} },
+ { MODKEY, XK_j, focusstack, {.i = +1 } },
+ { MODKEY, XK_k, focusstack, {.i = -1 } },
+ { MODKEY, XK_i, incnmaster, {.i = +1 } },
+diff --git a/dwm.c b/dwm.c
+index 967c9e8..91d00f6 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -211,6 +211,7 @@ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *m);
+ static void togglebar(const Arg *arg);
++static void toggleborder(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+@@ -1707,6 +1708,13 @@ togglebar(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++toggleborder(const Arg *arg)
++{
++ selmon->sel->bw = (selmon->sel->bw == borderpx ? 0 : borderpx);
++ arrange(selmon);
++}
++
+ void
+ togglefloating(const Arg *arg)
+ {
+--
+2.37.1
diff --git a/dwm/patches/dwm-togglefloatingcenter-20210806-138b405f.diff b/dwm/patches/dwm-togglefloatingcenter-20210806-138b405f.diff
new file mode 100644
index 0000000..6e3c3d0
--- /dev/null
+++ b/dwm/patches/dwm-togglefloatingcenter-20210806-138b405f.diff
@@ -0,0 +1,30 @@
+# From efa326b2c71f0df1d097fd52a17684f5ccc5df6c Mon Sep 17 00:00:00 2001
+# From: Rizqi Nur Assyaufi <bandithijo@gmail.com>
+# Date: Sat, 7 Aug 2021 00:24:01 +0800
+# Subject: [PATCH] [dwm][patch][togglefloatingcenter] centered togglefloating
+# window
+#
+# Default behaviour when togglefloating() is floating from top-left corner.
+# This patch will allows you to toggle floating window client will be centered
+# position.
+# ---
+# dwm.c | 4 ++++
+# 1 file changed, 4 insertions(+)
+
+diff --git a/dwm.c b/dwm.c
+index 5e4d494..cbedb09 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -1719,6 +1719,10 @@ togglefloating(const Arg *arg)
+ if (selmon->sel->isfloating)
+ resize(selmon->sel, selmon->sel->x, selmon->sel->y,
+ selmon->sel->w, selmon->sel->h, 0);
++
++ selmon->sel->x = selmon->sel->mon->mx + (selmon->sel->mon->mw - WIDTH(selmon->sel)) / 2;
++ selmon->sel->y = selmon->sel->mon->my + (selmon->sel->mon->mh - HEIGHT(selmon->sel)) / 2;
++
+ arrange(selmon);
+ }
+
+--
+2.31.1
diff --git a/dwm/patches/dwm-toggletopbar-barpadding-6.4.diff b/dwm/patches/dwm-toggletopbar-barpadding-6.4.diff
new file mode 100644
index 0000000..982fa3d
--- /dev/null
+++ b/dwm/patches/dwm-toggletopbar-barpadding-6.4.diff
@@ -0,0 +1,43 @@
+diff -up a/config.def.h b/config.def.h
+--- a/config.def.h 2022-10-28 22:20:44.531059708 +0200
++++ b/config.def.h 2022-10-28 22:21:12.621059000 +0200
+@@ -67,6 +67,7 @@ static const Key keys[] = {
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+ { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
+ { MODKEY, XK_b, togglebar, {0} },
++ { MODKEY, XK_t, toggletopbar, {0} },
+ { MODKEY, XK_j, focusstack, {.i = +1 } },
+ { MODKEY, XK_k, focusstack, {.i = -1 } },
+ { MODKEY, XK_i, incnmaster, {.i = +1 } },
+diff -up a/b.c b/b.c
+--- a/b.c 2022-10-28 22:20:44.532059708 +0200
++++ b/b.c 2022-10-28 22:23:27.019055613 +0200
+@@ -211,6 +211,7 @@ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *m);
+ static void togglebar(const Arg *arg);
++static void toggletopbar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+@@ -1710,6 +1711,20 @@ togglebar(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++toggletopbar(const Arg *arg)
++{
++ selmon->topbar = !selmon->topbar;
++ updatebarpos(selmon);
++
++ if (selmon->topbar)
++ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, bh);
++ else
++ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by - vp, selmon->ww - 2 * sp, bh);
++
++ arrange(selmon);
++}
++
+ void
+ togglefloating(const Arg *arg)
+ {
diff --git a/dwm/patches/dwm-unicode_ellipsis-20222909-d3f93c7.diff b/dwm/patches/dwm-unicode_ellipsis-20222909-d3f93c7.diff
new file mode 100644
index 0000000..a03f88f
--- /dev/null
+++ b/dwm/patches/dwm-unicode_ellipsis-20222909-d3f93c7.diff
@@ -0,0 +1,22 @@
+diff --git a/drw.c b/drw.c
+index ced7d37..95da860 100644
+--- a/drw.c
++++ b/drw.c
+@@ -285,7 +285,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
+
+ usedfont = drw->fonts;
+ if (!ellipsis_width && render)
+- ellipsis_width = drw_fontset_getwidth(drw, "...");
++ ellipsis_width = drw_fontset_getwidth(drw, "…");
+ while (1) {
+ ew = ellipsis_len = utf8strlen = 0;
+ utf8str = text;
+@@ -339,7 +339,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
+ w -= ew;
+ }
+ if (render && overflow)
+- drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
++ drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "…", invert);
+
+ if (!*text || overflow) {
+ break;
diff --git a/dwm/patches/dwm-xresources-20210827-138b405.diff b/dwm/patches/dwm-xresources-20210827-138b405.diff
new file mode 100644
index 0000000..2a3a594
--- /dev/null
+++ b/dwm/patches/dwm-xresources-20210827-138b405.diff
@@ -0,0 +1,239 @@
+# From f30583c6e2ab5e7de6ef4ebf156076ac0f6e69fc Mon Sep 17 00:00:00 2001
+# From: Jack Bird <jack.bird@durham.ac.uk>
+# Date: Fri, 27 Aug 2021 00:53:14 +0100
+# Subject: [PATCH] xresources updated for 138b405
+#
+# ---
+# config.def.h | 61 ++++++++++++++++++++++++++++++--------------
+# drw.c | 2 +-
+# drw.h | 2 +-
+# dwm.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+# 4 files changed, 116 insertions(+), 21 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index a2ac963..87ac198 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -1,21 +1,23 @@
+ /* See LICENSE file for copyright and license details. */
+
+ /* 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 char *fonts[] = { "monospace:size=10" };
+-static const char dmenufont[] = "monospace:size=10";
+-static const char col_gray1[] = "#222222";
+-static const char col_gray2[] = "#444444";
+-static const char col_gray3[] = "#bbbbbb";
+-static const char col_gray4[] = "#eeeeee";
+-static const char col_cyan[] = "#005577";
+-static const char *colors[][3] = {
+- /* fg bg border */
+- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
++static unsigned int borderpx = 1; /* border pixel of windows */
++static unsigned int snap = 32; /* snap pixel */
++static int showbar = 1; /* 0 means no bar */
++static int topbar = 1; /* 0 means bottom bar */
++static char font[] = "monospace:size=10";
++static char dmenufont[] = "monospace:size=10";
++static const char *fonts[] = { font };
++static char normbgcolor[] = "#222222";
++static char normbordercolor[] = "#444444";
++static char normfgcolor[] = "#bbbbbb";
++static char selfgcolor[] = "#eeeeee";
++static char selbordercolor[] = "#005577";
++static char selbgcolor[] = "#005577";
++static char *colors[][3] = {
++ /* fg bg border */
++ [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor },
++ [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor },
+ };
+
+ /* tagging */
+@@ -32,9 +34,9 @@ static const Rule rules[] = {
+ };
+
+ /* 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 = 1; /* 1 means respect size hints in tiled resizals */
++static float mfact = 0.55; /* factor of master area size [0.05..0.95] */
++static int nmaster = 1; /* number of clients in master area */
++static int resizehints = 1; /* 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[] = {
+@@ -57,9 +59,30 @@ static const Layout layouts[] = {
+
+ /* commands */
+ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
+-static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
++static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL };
+ static const char *termcmd[] = { "st", NULL };
+
++/*
++ * Xresources preferences to load at startup
++ */
++ResourcePref resources[] = {
++ { "font", STRING, &font },
++ { "dmenufont", STRING, &dmenufont },
++ { "normbgcolor", STRING, &normbgcolor },
++ { "normbordercolor", STRING, &normbordercolor },
++ { "normfgcolor", STRING, &normfgcolor },
++ { "selbgcolor", STRING, &selbgcolor },
++ { "selbordercolor", STRING, &selbordercolor },
++ { "selfgcolor", STRING, &selfgcolor },
++ { "borderpx", INTEGER, &borderpx },
++ { "snap", INTEGER, &snap },
++ { "showbar", INTEGER, &showbar },
++ { "topbar", INTEGER, &topbar },
++ { "nmaster", INTEGER, &nmaster },
++ { "resizehints", INTEGER, &resizehints },
++ { "mfact", FLOAT, &mfact },
++};
++
+ static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+diff --git a/drw.c b/drw.c
+index 4cdbcbe..8f1059e 100644
+--- a/drw.c
++++ b/drw.c
+@@ -208,7 +208,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
+ /* 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, const char *clrnames[], size_t clrcount)
++drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
+ {
+ size_t i;
+ Clr *ret;
+diff --git a/drw.h b/drw.h
+index 4bcd5ad..42b04ce 100644
+--- a/drw.h
++++ b/drw.h
+@@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
+
+ /* Colorscheme abstraction */
+ void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
+-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
++Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
+
+ /* Cursor abstraction */
+ Cur *drw_cur_create(Drw *drw, int shape);
+diff --git a/dwm.c b/dwm.c
+index 5e4d494..2214b19 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -36,6 +36,7 @@
+ #include <X11/Xlib.h>
+ #include <X11/Xproto.h>
+ #include <X11/Xutil.h>
++#include <X11/Xresource.h>
+ #ifdef XINERAMA
+ #include <X11/extensions/Xinerama.h>
+ #endif /* XINERAMA */
+@@ -141,6 +142,19 @@ typedef struct {
+ int monitor;
+ } Rule;
+
++/* Xresources preferences */
++enum resource_type {
++ STRING = 0,
++ INTEGER = 1,
++ FLOAT = 2
++};
++
++typedef struct {
++ char *name;
++ enum resource_type type;
++ void *dst;
++} ResourcePref;
++
+ /* function declarations */
+ static void applyrules(Client *c);
+ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
+@@ -234,6 +248,8 @@ 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);
++static void load_xresources(void);
++static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
+
+ /* variables */
+ static const char broken[] = "broken";
+@@ -2127,6 +2143,60 @@ zoom(const Arg *arg)
+ pop(c);
+ }
+
++void
++resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
++{
++ char *sdst = NULL;
++ int *idst = NULL;
++ float *fdst = NULL;
++
++ sdst = dst;
++ idst = dst;
++ fdst = dst;
++
++ char fullname[256];
++ char *type;
++ XrmValue ret;
++
++ snprintf(fullname, sizeof(fullname), "%s.%s", "dwm", name);
++ fullname[sizeof(fullname) - 1] = '\0';
++
++ XrmGetResource(db, fullname, "*", &type, &ret);
++ if (!(ret.addr == NULL || strncmp("String", type, 64)))
++ {
++ switch (rtype) {
++ case STRING:
++ strcpy(sdst, ret.addr);
++ break;
++ case INTEGER:
++ *idst = strtoul(ret.addr, NULL, 10);
++ break;
++ case FLOAT:
++ *fdst = strtof(ret.addr, NULL);
++ break;
++ }
++ }
++}
++
++void
++load_xresources(void)
++{
++ Display *display;
++ char *resm;
++ XrmDatabase db;
++ ResourcePref *p;
++
++ display = XOpenDisplay(NULL);
++ resm = XResourceManagerString(display);
++ if (!resm)
++ return;
++
++ db = XrmGetStringDatabase(resm);
++ for (p = resources; p < resources + LENGTH(resources); p++)
++ resource_load(db, p->name, p->type, p->dst);
++ XCloseDisplay(display);
++}
++
+ int
+ main(int argc, char *argv[])
+ {
+@@ -2139,6 +2209,8 @@ main(int argc, char *argv[])
+ if (!(dpy = XOpenDisplay(NULL)))
+ die("dwm: cannot open display");
+ checkotherwm();
++ XrmInitialize();
++ load_xresources();
+ setup();
+ #ifdef __OpenBSD__
+ if (pledge("stdio rpath proc exec", NULL) == -1)
+--
+2.33.0
diff --git a/dwm/patches/dwmblocks-statuscmd-20210402-96cbb45.diff b/dwm/patches/dwmblocks-statuscmd-20210402-96cbb45.diff
new file mode 100644
index 0000000..982f93a
--- /dev/null
+++ b/dwm/patches/dwmblocks-statuscmd-20210402-96cbb45.diff
@@ -0,0 +1,126 @@
+# From 1669878c08607f481e3f879d6914fc4d3c9d7206 Mon Sep 17 00:00:00 2001
+# From: Daniel Bylinka <daniel.bylinka@gmail.com>
+# Date: Fri, 2 Apr 2021 19:20:17 +0200
+# Subject: [PATCH] [statuscmd] Format status text and handle button signals
+#
+# ---
+# dwmblocks.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
+# 1 file changed, 41 insertions(+), 7 deletions(-)
+
+diff --git a/dwmblocks.c b/dwmblocks.c
+index ded717c..78fdeb5 100644
+--- a/dwmblocks.c
++++ b/dwmblocks.c
+@@ -3,6 +3,7 @@
+ #include<string.h>
+ #include<unistd.h>
+ #include<signal.h>
++#include<sys/wait.h>
+ #ifndef NO_X
+ #include<X11/Xlib.h>
+ #endif
+@@ -27,14 +28,14 @@ typedef struct {
+ #ifndef __OpenBSD__
+ void dummysighandler(int num);
+ #endif
+-void sighandler(int num);
+ void getcmds(int time);
+ void getsigcmds(unsigned int signal);
+ void setupsignals();
+-void sighandler(int signum);
++void sighandler(int signum, siginfo_t *si, void *ucontext);
+ int getstatus(char *str, char *last);
+ void statusloop();
+ void termhandler();
++void chldhandler();
+ void pstdout();
+ #ifndef NO_X
+ void setroot();
+@@ -58,6 +59,8 @@ static int returnStatus = 0;
+ //opens process *cmd and stores output in *output
+ void getcmd(const Block *block, char *output)
+ {
++ if (block->signal)
++ *output++ = block->signal;
+ strcpy(output, block->icon);
+ FILE *cmdf = popen(block->command, "r");
+ if (!cmdf)
+@@ -102,15 +105,18 @@ void getsigcmds(unsigned int signal)
+
+ void setupsignals()
+ {
++ struct sigaction sa = { .sa_sigaction = sighandler, .sa_flags = SA_SIGINFO };
+ #ifndef __OpenBSD__
+ /* initialize all real time signals with dummy handler */
+- for (int i = SIGRTMIN; i <= SIGRTMAX; i++)
++ for (int i = SIGRTMIN; i <= SIGRTMAX; i++) {
+ signal(i, dummysighandler);
++ sigaddset(&sa.sa_mask, i);
++ }
+ #endif
+
+ for (unsigned int i = 0; i < LENGTH(blocks); i++) {
+ if (blocks[i].signal > 0)
+- signal(SIGMINUS+blocks[i].signal, sighandler);
++ sigaction(SIGMINUS+blocks[i].signal, &sa, NULL);
+ }
+
+ }
+@@ -178,10 +184,32 @@ void dummysighandler(int signum)
+ }
+ #endif
+
+-void sighandler(int signum)
++void sighandler(int signum, siginfo_t *si, void *ucontext)
+ {
+- getsigcmds(signum-SIGPLUS);
+- writestatus();
++ if (si->si_value.sival_int) {
++ pid_t parent = getpid();
++ if (fork() == 0) {
++#ifndef NO_X
++ if (dpy)
++ close(ConnectionNumber(dpy));
++#endif
++ int i;
++ for (i = 0; i < LENGTH(blocks) && blocks[i].signal != signum-SIGRTMIN; i++);
++
++ char shcmd[1024];
++ sprintf(shcmd, "%s; kill -%d %d", blocks[i].command, SIGRTMIN+blocks[i].signal, parent);
++ char *cmd[] = { "/bin/sh", "-c", shcmd, NULL };
++ char button[2] = { '0' + si->si_value.sival_int, '\0' };
++ setenv("BUTTON", button, 1);
++ setsid();
++ execvp(cmd[0], cmd);
++ perror(cmd[0]);
++ exit(EXIT_SUCCESS);
++ }
++ } else {
++ getsigcmds(signum-SIGPLUS);
++ writestatus();
++ }
+ }
+
+ void termhandler()
+@@ -189,6 +217,11 @@ void termhandler()
+ statusContinue = 0;
+ }
+
++void chldhandler()
++{
++ while (0 < waitpid(-1, NULL, WNOHANG));
++}
++
+ int main(int argc, char** argv)
+ {
+ for (int i = 0; i < argc; i++) {//Handle command line arguments
+@@ -205,6 +238,7 @@ int main(int argc, char** argv)
+ delim[delimLen++] = '\0';
+ signal(SIGTERM, termhandler);
+ signal(SIGINT, termhandler);
++ signal(SIGCHLD, chldhandler);
+ statusloop();
+ #ifndef NO_X
+ XCloseDisplay(dpy);
+--
+2.31.0