From 0f819209af51462bb59ff2afb219c80b39f02921 Mon Sep 17 00:00:00 2001 From: Zedhugh Chen Date: Tue, 26 Mar 2024 23:08:53 +0800 Subject: [PATCH] add dwm patch --- .../dwm/dwm-autostart-20210120-cb3f58a.diff | 179 ++++++++++ .../x11-wm/dwm/dwm-focusonnetactive-6.2.diff | 57 ++++ .../x11-wm/dwm/dwm-keymodes-20220422.diff | 307 ++++++++++++++++++ .../x11-wm/dwm/dwm-preserveonrestart-6.3.diff | 118 +++++++ .../dwm/dwm-restartsig-20180523-6.2.diff | 139 ++++++++ .../x11-wm/dwm/dwm-statusallmons-6.2.diff | 25 ++ 6 files changed, 825 insertions(+) create mode 100644 gentoo_portage/patches/x11-wm/dwm/dwm-autostart-20210120-cb3f58a.diff create mode 100644 gentoo_portage/patches/x11-wm/dwm/dwm-focusonnetactive-6.2.diff create mode 100644 gentoo_portage/patches/x11-wm/dwm/dwm-keymodes-20220422.diff create mode 100644 gentoo_portage/patches/x11-wm/dwm/dwm-preserveonrestart-6.3.diff create mode 100644 gentoo_portage/patches/x11-wm/dwm/dwm-restartsig-20180523-6.2.diff create mode 100644 gentoo_portage/patches/x11-wm/dwm/dwm-statusallmons-6.2.diff diff --git a/gentoo_portage/patches/x11-wm/dwm/dwm-autostart-20210120-cb3f58a.diff b/gentoo_portage/patches/x11-wm/dwm/dwm-autostart-20210120-cb3f58a.diff new file mode 100644 index 0000000..efee676 --- /dev/null +++ b/gentoo_portage/patches/x11-wm/dwm/dwm-autostart-20210120-cb3f58a.diff @@ -0,0 +1,179 @@ +From 37e970479dc5d40e57fc0cbfeaa5e39941483237 Mon Sep 17 00:00:00 2001 +From: Gan Ainm +Date: Wed, 10 Jun 2020 10:59:02 +0000 +Subject: [PATCH] dwm-xdgautostart-6.2.diff + +=================================================================== +--- + dwm.1 | 23 +++++++++++++++++ + dwm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 105 insertions(+) + +diff --git a/dwm.1 b/dwm.1 +index 13b3729..9533aa6 100644 +--- a/dwm.1 ++++ b/dwm.1 +@@ -30,6 +30,14 @@ top left corner. The tags which are applied to one or more windows are + indicated with an empty square in the top left corner. + .P + dwm draws a small border around windows to indicate the focus state. ++.P ++On start, dwm can start additional programs that may be specified in two special ++shell scripts (see the FILES section below), autostart_blocking.sh and ++autostart.sh. The former is executed first and dwm will wait for its ++termination before starting. The latter is executed in the background before ++dwm enters its handler loop. ++.P ++Either of these files may be omitted. + .SH OPTIONS + .TP + .B \-v +@@ -152,6 +160,21 @@ Toggles focused window between floating and tiled state. + .TP + .B Mod1\-Button3 + Resize focused window while dragging. Tiled windows will be toggled to the floating state. ++.SH FILES ++The files containing programs to be started along with dwm are searched for in ++the following directories: ++.IP "1. $XDG_DATA_HOME/dwm" ++.IP "2. $HOME/.local/share/dwm" ++.IP "3. $HOME/.dwm" ++.P ++The first existing directory is scanned for any of the autostart files below. ++.TP 15 ++autostart.sh ++This file is started as a shell background process before dwm enters its handler ++loop. ++.TP 15 ++autostart_blocking.sh ++This file is started before any autostart.sh; dwm waits for its termination. + .SH CUSTOMIZATION + dwm is customized by creating a custom config.h and (re)compiling the source + code. This keeps it fast, secure and simple. +diff --git a/dwm.c b/dwm.c +index 4465af1..2156b49 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -193,6 +194,7 @@ static void resizeclient(Client *c, int x, int y, int w, int h); + static void resizemouse(const Arg *arg); + static void restack(Monitor *m); + static void run(void); ++static void runautostart(void); + static void scan(void); + static int sendevent(Client *c, Atom proto); + static void sendmon(Client *c, Monitor *m); +@@ -235,7 +237,11 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee); + static void zoom(const Arg *arg); + + /* variables */ ++static const char autostartblocksh[] = "autostart_blocking.sh"; ++static const char autostartsh[] = "autostart.sh"; + static const char broken[] = "broken"; ++static const char dwmdir[] = "dwm"; ++static const char localshare[] = ".local/share"; + static char stext[256]; + static int screen; + static int sw, sh; /* X display screen geometry width, height */ +@@ -1380,6 +1386,83 @@ run(void) + handler[ev.type](&ev); /* call handler */ + } + ++void ++runautostart(void) ++{ ++ char *pathpfx; ++ char *path; ++ char *xdgdatahome; ++ char *home; ++ struct stat sb; ++ ++ if ((home = getenv("HOME")) == NULL) ++ /* this is almost impossible */ ++ return; ++ ++ /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm, ++ * otherwise use ~/.local/share/dwm as autostart script directory ++ */ ++ xdgdatahome = getenv("XDG_DATA_HOME"); ++ if (xdgdatahome != NULL && *xdgdatahome != '\0') { ++ /* space for path segments, separators and nul */ ++ pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2); ++ ++ if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) { ++ free(pathpfx); ++ return; ++ } ++ } else { ++ /* space for path segments, separators and nul */ ++ pathpfx = ecalloc(1, strlen(home) + strlen(localshare) ++ + strlen(dwmdir) + 3); ++ ++ if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) { ++ free(pathpfx); ++ return; ++ } ++ } ++ ++ /* check if the autostart script directory exists */ ++ if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) { ++ /* the XDG conformant path does not exist or is no directory ++ * so we try ~/.dwm instead ++ */ ++ char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3); ++ if(pathpfx_new == NULL) { ++ free(pathpfx); ++ return; ++ } ++ pathpfx = pathpfx_new; ++ ++ if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) { ++ free(pathpfx); ++ return; ++ } ++ } ++ ++ /* try the blocking script first */ ++ path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2); ++ if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) { ++ free(path); ++ free(pathpfx); ++ } ++ ++ if (access(path, X_OK) == 0) ++ system(path); ++ ++ /* now the non-blocking script */ ++ if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) { ++ free(path); ++ free(pathpfx); ++ } ++ ++ if (access(path, X_OK) == 0) ++ system(strcat(path, " &")); ++ ++ free(pathpfx); ++ free(path); ++} ++ + void + scan(void) + { +@@ -2142,6 +2223,7 @@ main(int argc, char *argv[]) + die("pledge"); + #endif /* __OpenBSD__ */ + scan(); ++ runautostart(); + run(); + cleanup(); + XCloseDisplay(dpy); +-- +2.27.0 + diff --git a/gentoo_portage/patches/x11-wm/dwm/dwm-focusonnetactive-6.2.diff b/gentoo_portage/patches/x11-wm/dwm/dwm-focusonnetactive-6.2.diff new file mode 100644 index 0000000..5d358d2 --- /dev/null +++ b/gentoo_portage/patches/x11-wm/dwm/dwm-focusonnetactive-6.2.diff @@ -0,0 +1,57 @@ +From 286ca3bb1af08b452bf8140abcc23d4ef61baaa2 Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Tue, 7 Apr 2020 12:33:04 +0200 +Subject: [PATCH] Activate a window in response to _NET_ACTIVE_WINDOW + +By default, dwm response to client requests to _NET_ACTIVE_WINDOW client +messages by setting the urgency bit on the named window. + +This patch activates the window instead. + +Both behaviours are legitimate according to +https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472702304 + +One should decide which of these one should perform based on the message +senders' untestable claims that it represents the end-user. Setting the +urgency bit is the conservative decision. This patch implements the more +trusting alternative. + +It also allows dwm to work with `wmctrl -a` and other external window +management utilities + +--- + dwm.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/dwm.c b/dwm.c +index 4465af1..3919d47 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -514,6 +514,7 @@ clientmessage(XEvent *e) + { + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); ++ unsigned int i; + + if (!c) + return; +@@ -523,8 +524,14 @@ clientmessage(XEvent *e) + 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); ++ for (i = 0; i < LENGTH(tags) && !((1 << i) & c->tags); i++); ++ if (i < LENGTH(tags)) { ++ const Arg a = {.ui = 1 << i}; ++ selmon = c->mon; ++ view(&a); ++ focus(c); ++ restack(selmon); ++ } + } + } + +-- +2.17.1 + diff --git a/gentoo_portage/patches/x11-wm/dwm/dwm-keymodes-20220422.diff b/gentoo_portage/patches/x11-wm/dwm/dwm-keymodes-20220422.diff new file mode 100644 index 0000000..fbde705 --- /dev/null +++ b/gentoo_portage/patches/x11-wm/dwm/dwm-keymodes-20220422.diff @@ -0,0 +1,307 @@ +diff --git a/config.def.h b/config.def.h +index a2ac963..3bde49d 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -47,10 +47,10 @@ 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} }, ++ { {0,0,0,0}, {KEY,0,0,0}, view, {.ui = 1 << TAG} }, \ ++ { {ControlMask,0,0,0}, {KEY,0,0,0}, toggleview, {.ui = 1 << TAG} }, \ ++ { {ShiftMask,0,0,0}, {KEY,0,0,0}, tag, {.ui = 1 << TAG} }, \ ++ { {ControlMask|ShiftMask,0,0,0}, {KEY,0,0,0}, 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 } } +@@ -62,39 +62,50 @@ static const char *termcmd[] = { "st", NULL }; + + static 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} }, ++ { MODKEY, XK_Escape, setkeymode, {.ui = ModeCommand} }, ++}; ++ ++static Key cmdkeys[] = { ++ /* modifier keys function argument */ ++ { 0, XK_Escape, clearcmd, {0} }, ++ { ControlMask, XK_g, clearcmd, {0} }, ++ { 0, XK_i, setkeymode, {.ui = ModeInsert} }, ++}; ++static Command commands[] = { ++ /* modifier (4 keys) keysyms (4 keys) function argument */ ++ { {0, 0, 0, 0}, { XK_p, 0, 0, 0}, spawn, {.v = dmenucmd } }, ++ { {ShiftMask, 0, 0, 0}, { XK_Return, 0, 0, 0}, spawn, {.v = termcmd } }, ++ { {0, 0, 0, 0}, { XK_b, 0, 0, 0}, togglebar, {0} }, ++ { {0, 0, 0, 0}, { XK_j, 0, 0, 0}, focusstack, {.i = +1 } }, ++ { {0, 0, 0, 0}, { XK_k, 0, 0, 0}, focusstack, {.i = -1 } }, ++ { {0, 0, 0, 0}, { XK_i, 0, 0, 0}, incnmaster, {.i = +1 } }, ++ { {0, 0, 0, 0}, { XK_d, 0, 0, 0}, incnmaster, {.i = -1 } }, ++ { {0, 0, 0, 0}, { XK_h, 0, 0, 0}, setmfact, {.f = -0.05} }, ++ { {0, 0, 0, 0}, { XK_l, 0, 0, 0}, setmfact, {.f = +0.05} }, ++ { {0, 0, 0, 0}, { XK_Return, 0, 0, 0}, zoom, {0} }, ++ { {ControlMask, 0, 0, 0}, { XK_i, 0, 0, 0}, view, {0} }, ++ { {ShiftMask, 0, 0, 0}, { XK_k, 0, 0, 0}, killclient, {0} }, ++ { {0, 0, 0, 0}, { XK_t, 0, 0, 0}, setlayout, {.v = &layouts[0]} }, ++ { {0, 0, 0, 0}, { XK_f, 0, 0, 0}, setlayout, {.v = &layouts[1]} }, ++ { {0, 0, 0, 0}, { XK_m, 0, 0, 0}, setlayout, {.v = &layouts[2]} }, ++ { {0, 0, 0, 0}, { XK_space, 0, 0, 0}, setlayout, {0} }, ++ { {ShiftMask, 0, 0, 0}, { XK_space, 0, 0, 0}, togglefloating, {0} }, ++ { {0, 0, 0, 0}, { XK_0, 0, 0, 0}, view, {.ui = ~0 } }, ++ { {ShiftMask, 0, 0, 0}, { XK_0, 0, 0, 0}, tag, {.ui = ~0 } }, ++ { {0, 0, 0, 0}, { XK_comma, 0, 0, 0}, focusmon, {.i = -1 } }, ++ { {0, 0, 0, 0}, { XK_period, 0, 0, 0}, focusmon, {.i = +1 } }, ++ { {ShiftMask, 0, 0, 0}, { XK_comma, 0, 0, 0}, tagmon, {.i = -1 } }, ++ { {ShiftMask, 0, 0, 0}, { XK_period, 0, 0, 0}, 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) ++ { {ShiftMask, 0, 0, 0}, { XK_q, 0, 0, 0}, quit, {0} }, + }; + + /* button definitions */ +@@ -113,4 +124,3 @@ static Button buttons[] = { + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + }; +- +diff --git a/dwm.c b/dwm.c +index 0fc328a..487484e 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -60,6 +60,7 @@ + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ + enum { SchemeNorm, SchemeSel }; /* color schemes */ ++enum { ModeCommand, ModeInsert }; + enum { NetSupported, NetWMName, NetWMState, NetWMCheck, + NetWMFullscreen, NetActiveWindow, NetWMWindowType, + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ +@@ -99,6 +100,13 @@ struct Client { + Window win; + }; + ++typedef struct { ++ unsigned int mod[4]; ++ KeySym keysym[4]; ++ void (*func)(const Arg *); ++ const Arg arg; ++} Command; ++ + typedef struct { + unsigned int mod; + KeySym keysym; +@@ -152,6 +160,7 @@ static void buttonpress(XEvent *e); + static void checkotherwm(void); + static void cleanup(void); + static void cleanupmon(Monitor *mon); ++static void clearcmd(const Arg *arg); + static void clientmessage(XEvent *e); + static void configure(Client *c); + static void configurenotify(XEvent *e); +@@ -177,6 +186,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 keypresscmd(XEvent *e); + static void killclient(const Arg *arg); + static void manage(Window w, XWindowAttributes *wa); + static void mappingnotify(XEvent *e); +@@ -200,6 +210,8 @@ 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 setinsertmode(void); ++static void setkeymode(const Arg *arg); + static void setlayout(const Arg *arg); + static void setmfact(const Arg *arg); + static void setup(void); +@@ -243,6 +255,8 @@ 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 (*xerrorxlib)(Display *, XErrorEvent *); ++static unsigned int cmdmod[4]; ++static unsigned int keymode = ModeCommand; + static unsigned int numlockmask = 0; + static void (*handler[LASTEvent]) (XEvent *) = { + [ButtonPress] = buttonpress, +@@ -266,6 +280,7 @@ static Cur *cursor[CurLast]; + static Clr **scheme; + static Display *dpy; + static Drw *drw; ++static KeySym cmdkeysym[4]; + static Monitor *mons, *selmon; + static Window root, wmcheckwin; + +@@ -513,6 +528,17 @@ cleanupmon(Monitor *mon) + free(mon); + } + ++void ++clearcmd(const Arg *arg) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < LENGTH(cmdkeysym); i++) { ++ cmdkeysym[i] = 0; ++ cmdmod[i] = 0; ++ } ++} ++ + void + clientmessage(XEvent *e) + { +@@ -955,6 +981,13 @@ grabbuttons(Client *c, int focused) + void + grabkeys(void) + { ++ if (keymode == ModeCommand) { ++ XUngrabKey(dpy, AnyKey, AnyModifier, root); ++ XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime); ++ return; ++ } ++ ++ XUngrabKeyboard(dpy, CurrentTime); + updatenumlockmask(); + { + unsigned int i, j; +@@ -996,6 +1029,11 @@ keypress(XEvent *e) + KeySym keysym; + XKeyEvent *ev; + ++ if (keymode == ModeCommand) { ++ keypresscmd(e); ++ return; ++ } ++ + ev = &e->xkey; + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + for (i = 0; i < LENGTH(keys); i++) +@@ -1005,6 +1043,53 @@ keypress(XEvent *e) + keys[i].func(&(keys[i].arg)); + } + ++void ++keypresscmd(XEvent *e) { ++ unsigned int i, j; ++ int matches = 0; ++ KeySym keysym; ++ XKeyEvent *ev; ++ ++ ev = &e->xkey; ++ keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); ++ if (XK_Shift_L <= keysym && keysym <= XK_Hyper_R) { ++ return; ++ } ++ ++ for (i = 0; i < LENGTH(cmdkeys); i++) { ++ if (keysym == cmdkeys[i].keysym ++ && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state) ++ && cmdkeys[i].func) { ++ cmdkeys[i].func(&(cmdkeys[i].arg)); ++ return; ++ } ++ } ++ ++ for (j = 0; j < LENGTH(cmdkeysym); j++) { ++ if (cmdkeysym[j] == 0) { ++ cmdkeysym[j] = keysym; ++ cmdmod[j] = ev->state; ++ break; ++ } ++ } ++ ++ for (i = 0; i < LENGTH(commands); i++) { ++ matches = 0; ++ for (j = 0; j < LENGTH(cmdkeysym); j++) { ++ if (cmdkeysym[j] == commands[i].keysym[j] ++ && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j])) ++ matches++; ++ } ++ if (matches == LENGTH(cmdkeysym)) { ++ if (commands[i].func) ++ commands[i].func(&(commands[i].arg)); ++ clearcmd(NULL); ++ return; ++ } ++ } ++} ++ ++ + void + killclient(const Arg *arg) + { +@@ -1438,6 +1523,24 @@ setclientstate(Client *c, long state) + PropModeReplace, (unsigned char *)data, 2); + } + ++void ++setinsertmode() ++{ ++ keymode = ModeInsert; ++ clearcmd(NULL); ++ grabkeys(); ++} ++ ++void ++setkeymode(const Arg *arg) ++{ ++ if(!arg) ++ return; ++ keymode = arg->ui; ++ clearcmd(NULL); ++ grabkeys(); ++} ++ + int + sendevent(Client *c, Atom proto) + { +@@ -1645,6 +1748,7 @@ sigchld(int unused) + void + spawn(const Arg *arg) + { ++ setinsertmode(); + if (arg->v == dmenucmd) + dmenumon[0] = '0' + selmon->num; + if (fork() == 0) { diff --git a/gentoo_portage/patches/x11-wm/dwm/dwm-preserveonrestart-6.3.diff b/gentoo_portage/patches/x11-wm/dwm/dwm-preserveonrestart-6.3.diff new file mode 100644 index 0000000..079cf05 --- /dev/null +++ b/gentoo_portage/patches/x11-wm/dwm/dwm-preserveonrestart-6.3.diff @@ -0,0 +1,118 @@ +From 713fa8650f5a20006451ebcccf57a4512e83bae8 Mon Sep 17 00:00:00 2001 +From: Arda Atci +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/gentoo_portage/patches/x11-wm/dwm/dwm-restartsig-20180523-6.2.diff b/gentoo_portage/patches/x11-wm/dwm/dwm-restartsig-20180523-6.2.diff new file mode 100644 index 0000000..f1f8680 --- /dev/null +++ b/gentoo_portage/patches/x11-wm/dwm/dwm-restartsig-20180523-6.2.diff @@ -0,0 +1,139 @@ +From 2991f37f0aaf44b9f9b11e7893ff0af8eb88f649 Mon Sep 17 00:00:00 2001 +From: Christopher Drelich +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/gentoo_portage/patches/x11-wm/dwm/dwm-statusallmons-6.2.diff b/gentoo_portage/patches/x11-wm/dwm/dwm-statusallmons-6.2.diff new file mode 100644 index 0000000..9d9633d --- /dev/null +++ b/gentoo_portage/patches/x11-wm/dwm/dwm-statusallmons-6.2.diff @@ -0,0 +1,25 @@ +diff -up a/dwm.c b/dwm.c +--- a/dwm.c 2020-07-09 16:49:10.023585649 +0200 ++++ b/dwm.c 2020-07-09 16:49:43.497542191 +0200 +@@ -702,7 +702,7 @@ drawbar(Monitor *m) + Client *c; + + /* draw status first so it can be overdrawn by tags later */ +- if (m == selmon) { /* status is only drawn on selected monitor */ ++ if (m == selmon || 1) { /* status is only drawn on selected monitor */ + drw_setscheme(drw, scheme[SchemeNorm]); + sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ + drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); +@@ -1987,9 +1987,11 @@ updatesizehints(Client *c) + void + updatestatus(void) + { ++ Monitor* m; + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-"VERSION); +- drawbar(selmon); ++ for(m = mons; m; m = m->next) ++ drawbar(m); + } + + void