From 3c06b905e5c8ada98e5c9ac7cb589bd74eca0cf3 Mon Sep 17 00:00:00 2001
From: tavo <dev@tavo.one>
Date: Fri, 13 Dec 2024 14:12:18 -0600
Subject: [PATCH] git

---
 ...80a334f200f68c2c8f3e384313ebbaf5-tavo.diff | 1171 +++++++++++++++++
 1 file changed, 1171 insertions(+)
 create mode 100644 dwm-cfb8627a80a334f200f68c2c8f3e384313ebbaf5-tavo.diff

diff --git a/dwm-cfb8627a80a334f200f68c2c8f3e384313ebbaf5-tavo.diff b/dwm-cfb8627a80a334f200f68c2c8f3e384313ebbaf5-tavo.diff
new file mode 100644
index 0000000..b6f7b99
--- /dev/null
+++ b/dwm-cfb8627a80a334f200f68c2c8f3e384313ebbaf5-tavo.diff
@@ -0,0 +1,1171 @@
+Applied patches (in listed order):
+dwm-warp-6.4.diff
+dwm-swallow-6.3.diff
+dwm-sticky-6.4.diff
+dwm-pertag-20200914-61bb8b2.diff
+dwm-notitle-20210715-138b405.diff
+dwm-movestack-20211115-a786211.diff
+dwm-fullgaps-6.4.diff
+dwm-attachbottom-6.3.diff
+dwm-alwayscenter-20200625-f04cac6.diff
+dwm-windowmap-20221026.diff
+dwm-noborderselflickerfix-2022042627-d93ff48803f0.diff
+---
+diff '--color=auto' -Nu a/config.def.h b/config.def.h
+--- a/config.def.h	2024-12-13 14:02:33.452592229 -0600
++++ b/config.def.h	2024-12-13 13:36:45.519666924 -0600
+@@ -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 @@
+ 	 *	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) */
+@@ -60,6 +63,7 @@
+ 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 "movestack.c"
+ static const Key keys[] = {
+ 	/* modifier                     key        function        argument */
+ 	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
+@@ -71,6 +75,8 @@
+ 	{ MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
+ 	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
+ 	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
++	{ MODKEY|ShiftMask,             XK_j,      movestack,      {.i = +1 } },
++	{ MODKEY|ShiftMask,             XK_k,      movestack,      {.i = -1 } },
+ 	{ MODKEY,                       XK_Return, zoom,           {0} },
+ 	{ MODKEY,                       XK_Tab,    view,           {0} },
+ 	{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
+@@ -95,6 +101,7 @@
+ 	TAGKEYS(                        XK_8,                      7)
+ 	TAGKEYS(                        XK_9,                      8)
+ 	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
++	{ MODKEY,                       XK_s,      togglesticky,   {0} },
+ };
+ 
+ /* button definitions */
+@@ -103,7 +110,6 @@
+ 	/* click                event mask      button          function        argument */
+ 	{ ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
+ 	{ ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &layouts[2]} },
+-	{ ClkWinTitle,          0,              Button2,        zoom,           {0} },
+ 	{ ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
+ 	{ ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
+ 	{ ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} },
+diff '--color=auto' -Nu a/config.h b/config.h
+--- a/config.h	1969-12-31 18:00:00.000000000 -0600
++++ b/config.h	2024-12-13 13:57:27.581997867 -0600
+@@ -0,0 +1,123 @@
++/* See LICENSE file for copyright and license details. */
++
++/* appearance */
++static const unsigned int borderpx  = 1;        /* border pixel of windows */
++static const unsigned int snap      = 1;       /* 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             = 0;        /* 0 means bottom bar */
++static const char *fonts[]          = { "JetBrainsMono:bold:size=10" };
++static const char dmenufont[]       = "JetBrainsMono: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";
++/*Custom colors*/
++static const char col_light[]       = "#7fbbb3";
++static const char col_dark[]        = "#1d2021";
++static const char col_black[]       = "#000000";
++static const char *colors[][3]      = {
++	/*               fg         bg         border   */
++	/*[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },*/
++	/*[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },*/
++	[SchemeNorm] = { col_dark, col_black, col_dark },
++	[SchemeSel]  = { col_dark, col_light, col_light },
++};
++
++/* 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  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) */
++static const float mfact     = 0.50; /* factor of master area size [0.05..0.95] */
++static const int nmaster     = 1;    /* number of clients in master area */
++static const int 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[] = {
++	/* symbol     arrange function */
++	{ "",      tile },    /* first entry is default */
++	{ "[M]",      monocle },
++};
++
++/* key definitions */
++#define MODKEY Mod4Mask
++#define TAGKEYS(KEY,TAG) \
++	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
++	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
++	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
++	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
++
++/* 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 };
++
++#include "movestack.c"
++static const Key keys[] = {
++	/* modifier                     key        function        argument */
++	{ MODKEY,                       XK_r,      spawn,          {.v = dmenucmd } },
++	{ MODKEY,                       XK_Return, spawn,          {.v = termcmd } },
++	{ MODKEY|ShiftMask,             XK_b,      togglebar,      {0} },
++	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
++	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
++	{ MODKEY|ShiftMask,             XK_i,      incnmaster,     {.i = +1 } },
++	{ MODKEY|ShiftMask,             XK_d,      incnmaster,     {.i = -1 } },
++	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
++	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
++	{ MODKEY|ShiftMask,             XK_j,      movestack,      {.i = +1 } },
++	{ MODKEY|ShiftMask,             XK_k,      movestack,      {.i = -1 } },
++	{ MODKEY|ShiftMask,             XK_Return, zoom,           {0} },
++	{ MODKEY,                       XK_c,      killclient,     {0} },
++	{ MODKEY|ShiftMask,             XK_t,      setlayout,      {.v = &layouts[0]} },
++	{ MODKEY|ShiftMask,             XK_m,      setlayout,      {.v = &layouts[1]} },
++	{ MODKEY,                       XK_t,      togglefloating, {0} },
++	{ MODKEY,                       XK_0,      view,           {.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} },
++	{ MODKEY,                       XK_s,      togglesticky,   {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]} },
++	{ 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 '--color=auto' -Nu a/config.mk b/config.mk
+--- a/config.mk	2024-12-13 14:02:33.452592229 -0600
++++ b/config.mk	2024-12-13 13:36:45.519666924 -0600
+@@ -20,10 +20,11 @@
+ # 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_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff '--color=auto' -Nu a/dwm.c b/dwm.c
+--- a/dwm.c	2024-12-13 14:02:33.452592229 -0600
++++ b/dwm.c	2024-12-13 13:40:36.901568536 -0600
+@@ -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"
+@@ -49,7 +55,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 MOUSEMASK               (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
+ #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
+@@ -60,11 +66,11 @@
+ 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,
+-       ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
++enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkClientWin,
++       ClkRootWin, ClkLast }; /* clicks */
+ 
+ typedef union {
+ 	int i;
+@@ -91,9 +97,11 @@
+ 	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, issticky;
++	pid_t pid;
+ 	Client *next;
+ 	Client *snext;
++	Client *swallowing;
+ 	Monitor *mon;
+ 	Window win;
+ };
+@@ -110,6 +118,7 @@
+ 	void (*arrange)(Monitor *);
+ } Layout;
+ 
++typedef struct Pertag Pertag;
+ struct Monitor {
+ 	char ltsymbol[16];
+ 	float mfact;
+@@ -129,6 +138,7 @@
+ 	Monitor *next;
+ 	Window barwin;
+ 	const Layout *lt[2];
++	Pertag *pertag;
+ };
+ 
+ typedef struct {
+@@ -137,6 +147,8 @@
+ 	const char *title;
+ 	unsigned int tags;
+ 	int isfloating;
++	int isterminal;
++	int noswallow;
+ 	int monitor;
+ } Rule;
+ 
+@@ -146,6 +158,7 @@
+ static void arrange(Monitor *m);
+ static void arrangemon(Monitor *m);
+ static void attach(Client *c);
++static void attachbottom(Client *c);
+ static void attachstack(Client *c);
+ static void buttonpress(XEvent *e);
+ static void checkotherwm(void);
+@@ -199,17 +212,20 @@
+ 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);
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
++static int solitary(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 togglesticky(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -226,6 +242,10 @@
+ static void updatewindowtype(Client *c);
+ static void updatewmhints(Client *c);
+ static void view(const Arg *arg);
++static void window_set_state(Display *dpy, Window win, long state);
++static void window_map(Display *dpy, Client *c, int deiconify);
++static void window_unmap(Display *dpy, Window win, Window root, int iconify);
++static void warp(const Client *c);
+ static Client *wintoclient(Window w);
+ static Monitor *wintomon(Window w);
+ static int xerror(Display *dpy, XErrorEvent *ee);
+@@ -233,6 +253,12 @@
+ 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];
+@@ -267,9 +293,20 @@
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
+ 
++static xcb_connection_t *xcon;
++
+ /* 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 */
++};
++
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+ 
+@@ -296,6 +333,8 @@
+ 		&& (!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);
+@@ -408,6 +447,15 @@
+ }
+ 
+ void
++attachbottom(Client *c)
++{
++	Client **tc;
++	c->next = NULL;
++	for (tc = &c->mon->clients; *tc; tc = &(*tc)->next);
++	*tc = c;
++}
++
++void
+ attachstack(Client *c)
+ {
+ 	c->snext = c->mon->stack;
+@@ -415,6 +463,53 @@
+ }
+ 
+ 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)
+ {
+ 	unsigned int i, x, click;
+@@ -440,10 +535,8 @@
+ 			arg.ui = 1 << i;
+ 		} else if (ev->x < x + TEXTW(selmon->ltsymbol))
+ 			click = ClkLtSymbol;
+-		else if (ev->x > selmon->ww - (int)TEXTW(stext))
+-			click = ClkStatusText;
+ 		else
+-			click = ClkWinTitle;
++			click = ClkStatusText;
+ 	} else if ((c = wintoclient(ev->window))) {
+ 		focus(c);
+ 		restack(selmon);
+@@ -524,6 +617,10 @@
+ 		|| 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);
+@@ -633,6 +730,7 @@
+ createmon(void)
+ {
+ 	Monitor *m;
++	unsigned int i;
+ 
+ 	m = ecalloc(1, sizeof(Monitor));
+ 	m->tagset[0] = m->tagset[1] = 1;
+@@ -643,6 +741,20 @@
+ 	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;
+ }
+ 
+@@ -654,6 +766,9 @@
+ 
+ 	if ((c = wintoclient(ev->window)))
+ 		unmanage(c, 1);
++
++	else if ((c = swallowingclient(ev->window)))
++		unmanage(c->swallowing, 1);
+ }
+ 
+ void
+@@ -698,7 +813,6 @@
+ 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;
+@@ -724,7 +838,7 @@
+ 		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,
++			drw_rect(drw, x + 2 * boxw, 4 * boxw - 2, w - (4 * boxw + 1), boxw / 2,
+ 				m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+ 				urg & 1 << i);
+ 		x += w;
+@@ -734,15 +848,8 @@
+ 	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_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);
+-		}
+ 	}
+ 	drw_map(drw, m->barwin, 0, 0, m->ww, bh);
+ }
+@@ -800,7 +907,11 @@
+ 		detachstack(c);
+ 		attachstack(c);
+ 		grabbuttons(c, 1);
+-		XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
++		/* Avoid flickering when another client appears and the border
++		 * is restored */
++		if (!solitary(c)) {
++			XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
++		}
+ 		setfocus(c);
+ 	} else {
+ 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+@@ -832,6 +943,7 @@
+ 	unfocus(selmon->sel, 0);
+ 	selmon = m;
+ 	focus(NULL);
++	warp(selmon->sel);
+ }
+ 
+ void
+@@ -979,7 +1091,7 @@
+ 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);
+ }
+ 
+@@ -1030,12 +1142,13 @@
+ 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;
+@@ -1050,6 +1163,7 @@
+ 	} else {
+ 		c->mon = selmon;
+ 		applyrules(c);
++		term = termforwin(c);
+ 	}
+ 
+ 	if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
+@@ -1067,13 +1181,15 @@
+ 	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)
+ 		c->isfloating = c->oldstate = trans != None || c->isfixed;
+ 	if (c->isfloating)
+ 		XRaiseWindow(dpy, c->win);
+-	attach(c);
++	attachbottom(c);
+ 	attachstack(c);
+ 	XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
+ 		(unsigned char *) &(c->win), 1);
+@@ -1084,6 +1200,8 @@
+ 	c->mon->sel = c;
+ 	arrange(c->mon);
+ 	XMapWindow(dpy, c->win);
++	if (term)
++		swallow(term, c);
+ 	focus(NULL);
+ }
+ 
+@@ -1244,11 +1362,8 @@
+ 			drawbars();
+ 			break;
+ 		}
+-		if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
++		if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName])
+ 			updatetitle(c);
+-			if (c == c->mon->sel)
+-				drawbar(c->mon);
+-		}
+ 		if (ev->atom == netatom[NetWMWindowType])
+ 			updatewindowtype(c);
+ 	}
+@@ -1291,6 +1406,11 @@
+ 	c->oldw = c->w; c->w = wc.width = w;
+ 	c->oldh = c->h; c->h = wc.height = h;
+ 	wc.border_width = c->bw;
++	if (solitary(c)) {
++		c->w = wc.width += c->bw * 2;
++		c->h = wc.height += c->bw * 2;
++		wc.border_width = 0;
++	}
+ 	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
+ 	configure(c);
+ 	XSync(dpy, False);
+@@ -1374,6 +1494,8 @@
+ 				wc.sibling = c->win;
+ 			}
+ 	}
++	if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && m->lt[m->sellt]->arrange != &monocle)
++		warp(m->sel);
+ 	XSync(dpy, False);
+ 	while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+ }
+@@ -1426,7 +1548,7 @@
+ 	detachstack(c);
+ 	c->mon = m;
+ 	c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
+-	attach(c);
++	attachbottom(c);
+ 	attachstack(c);
+ 	focus(NULL);
+ 	arrange(NULL);
+@@ -1507,12 +1629,29 @@
+ }
+ 
+ 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)
+ {
+ 	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);
+@@ -1531,7 +1670,7 @@
+ 	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);
+ }
+ 
+@@ -1575,6 +1714,7 @@
+ 	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);
+@@ -1632,17 +1772,24 @@
+ 		return;
+ 	if (ISVISIBLE(c)) {
+ 		/* show clients top down */
+-		XMoveWindow(dpy, c->win, c->x, c->y);
+-		if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
+-			resize(c, c->x, c->y, c->w, c->h, 0);
++		window_map(dpy, c, 1);
+ 		showhide(c->snext);
+ 	} else {
+ 		/* hide clients bottom up */
+ 		showhide(c->snext);
+-		XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
++		window_unmap(dpy, c->win, root, 1);
+ 	}
+ }
+ 
++int
++solitary(Client *c)
++{
++	return ((nexttiled(c->mon->clients) == c && !nexttiled(c->next))
++	    || &monocle == c->mon->lt[c->mon->sellt]->arrange)
++	    && !c->isfullscreen && !c->isfloating
++	    && NULL != c->mon->lt[c->mon->sellt]->arrange;
++}
++
+ void
+ spawn(const Arg *arg)
+ {
+@@ -1714,7 +1861,7 @@
+ 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);
+@@ -1735,6 +1882,15 @@
+ }
+ 
+ void
++togglesticky(const Arg *arg)
++{
++	if (!selmon->sel)
++		return;
++	setsticky(selmon->sel, !selmon->sel->issticky);
++	arrange(selmon);
++}
++
++void
+ toggletag(const Arg *arg)
+ {
+ 	unsigned int newtags;
+@@ -1753,9 +1909,33 @@
+ 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);
+ 	}
+@@ -1780,6 +1960,20 @@
+ 	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) {
+@@ -1795,9 +1989,12 @@
+ 		XUngrabServer(dpy);
+ 	}
+ 	free(c);
+-	focus(NULL);
+-	updateclientlist();
+-	arrange(m);
++
++	if (!s) {
++		arrange(m);
++		focus(NULL);
++		updateclientlist();
++	}
+ }
+ 
+ void
+@@ -1914,7 +2111,7 @@
+ 				m->clients = c->next;
+ 				detachstack(c);
+ 				c->mon = mons;
+-				attach(c);
++				attachbottom(c);
+ 				attachstack(c);
+ 			}
+ 			if (m == selmon)
+@@ -2026,6 +2223,9 @@
+ 
+ 	if (state == netatom[NetWMFullscreen])
+ 		setfullscreen(c, 1);
++	if (state == netatom[NetWMSticky]) {
++		setsticky(c, 1);
++	}
+ 	if (wtype == netatom[NetWMWindowTypeDialog])
+ 		c->isfloating = 1;
+ }
+@@ -2050,17 +2250,240 @@
+ }
+ 
+ void
++window_set_state(Display *dpy, Window win, long state)
++{
++	long data[] = { state, None };
++
++	XChangeProperty(dpy, win, wmatom[WMState], wmatom[WMState], 32,
++		PropModeReplace, (unsigned char*)data, 2);
++}
++
++void
++window_map(Display *dpy, Client *c, int deiconify)
++{
++	Window win = c->win;
++
++	if (deiconify)
++		window_set_state(dpy, win, NormalState);
++
++	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
++	XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
++	XMapWindow(dpy, win);
++}
++
++void
++window_unmap(Display *dpy, Window win, Window root, int iconify)
++{
++	static XWindowAttributes ca, ra;
++
++	XGrabServer(dpy);
++	XGetWindowAttributes(dpy, root, &ra);
++	XGetWindowAttributes(dpy, win, &ca);
++
++	/* Prevent UnmapNotify events */
++	XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
++	XSelectInput(dpy, win, ca.your_event_mask & ~StructureNotifyMask);
++
++	XUnmapWindow(dpy, win);
++
++	if (iconify)
++		window_set_state(dpy, win, IconicState);
++
++	XSelectInput(dpy, root, ra.your_event_mask);
++	XSelectInput(dpy, win, ca.your_event_mask);
++	XUngrabServer(dpy);
++}
++
++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;
++		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(NULL);
+ 	arrange(selmon);
+ }
+ 
++void
++warp(const Client *c)
++{
++	int x, y;
++
++	if (!c) {
++		XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww / 2, selmon->wy + selmon->wh / 2);
++		return;
++	}
++
++	if (!getrootptr(&x, &y) ||
++		(x > c->x - c->bw &&
++		 y > c->y - c->bw &&
++		 x < c->x + c->w + c->bw*2 &&
++		 y < c->y + c->h + c->bw*2) ||
++		(y > c->mon->by && y < c->mon->by + bh) ||
++		(c->mon->topbar && !y))
++		return;
++
++	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
++}
++
++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)
+ {
+@@ -2150,10 +2573,12 @@
+ 		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();
+@@ -2162,3 +2587,4 @@
+ 	XCloseDisplay(dpy);
+ 	return EXIT_SUCCESS;
+ }
++
+Common subdirectories: a/.git and b/.git
+diff '--color=auto' -Nu a/movestack.c b/movestack.c
+--- a/movestack.c	1969-12-31 18:00:00.000000000 -0600
++++ b/movestack.c	2024-12-13 13:36:45.519666924 -0600
+@@ -0,0 +1,48 @@
++void
++movestack(const Arg *arg) {
++	Client *c = NULL, *p = NULL, *pc = NULL, *i;
++
++	if(arg->i > 0) {
++		/* find the client after selmon->sel */
++		for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
++		if(!c)
++			for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
++
++	}
++	else {
++		/* find the client before selmon->sel */
++		for(i = selmon->clients; i != selmon->sel; i = i->next)
++			if(ISVISIBLE(i) && !i->isfloating)
++				c = i;
++		if(!c)
++			for(; i; i = i->next)
++				if(ISVISIBLE(i) && !i->isfloating)
++					c = i;
++	}
++	/* find the client before selmon->sel and c */
++	for(i = selmon->clients; i && (!p || !pc); i = i->next) {
++		if(i->next == selmon->sel)
++			p = i;
++		if(i->next == c)
++			pc = i;
++	}
++
++	/* swap c and selmon->sel selmon->clients in the selmon->clients list */
++	if(c && c != selmon->sel) {
++		Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next;
++		selmon->sel->next = c->next==selmon->sel?c:c->next;
++		c->next = temp;
++
++		if(p && p != c)
++			p->next = c;
++		if(pc && pc != selmon->sel)
++			pc->next = selmon->sel;
++
++		if(selmon->sel == selmon->clients)
++			selmon->clients = c;
++		else if(c == selmon->clients)
++			selmon->clients = selmon->sel;
++
++		arrange(selmon);
++	}
++}
+\ No newline at end of file