[wiki] [sites] [dwm][patches][spawn_window_cwd] Add patch that enhance spawn_cwd one || evageq

From: <git_AT_suckless.org>
Date: Sun, 11 Jan 2026 19:01:19 +0100

commit 11b6a14636d6fd3deca3e55eae9c0af0e3dda61b
Author: evageq <gostevevg0_AT_gmail.com>
Date: Sun Jan 11 20:52:51 2026 +0300

    [dwm][patches][spawn_window_cwd] Add patch that enhance spawn_cwd one

diff --git a/dwm.suckless.org/patches/spawn_window_cwd/dwm-6.6-spawn_window_cwd.diff b/dwm.suckless.org/patches/spawn_window_cwd/dwm-6.6-spawn_window_cwd.diff
new file mode 100644
index 00000000..cc5291d5
--- /dev/null
+++ b/dwm.suckless.org/patches/spawn_window_cwd/dwm-6.6-spawn_window_cwd.diff
_AT_@ -0,0 +1,144 @@
+From 6ccecbb335b6e090d8f21de7fc617ba69f7f3823 Mon Sep 17 00:00:00 2001
+From: evageq <gostevevg0_AT_gmail.com>
+Date: Sun, 11 Jan 2026 16:07:19 +0300
+Subject: [PATCH] dwm.c: Spawn term in win cwd enhanced
+
+---
+ dwm.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 81 insertions(+), 1 deletion(-)
+
+diff --git a/dwm.c b/dwm.c
+index ade3c86..60f6275 100644
+--- a/dwm.c
++++ b/dwm.c
+_AT_@ -21,6 +21,7 @@
+ * To understand everything else, start reading main().
+ */
+ #include <errno.h>
++#include <libgen.h>
+ #include <locale.h>
+ #include <signal.h>
+ #include <stdarg.h>
+_AT_@ -61,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, NetWMPid, NetLast }; /* EWMH atoms */
+ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
+ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
+ ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+_AT_@ -172,6 +173,7 @@ static Atom getatomprop(Client *c, Atom prop);
+ static int getrootptr(int *x, int *y);
+ static long getstate(Window w);
+ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
++static int getwincwd(size_t n, char buf[n]);
+ static void grabbuttons(Client *c, int focused);
+ static void grabkeys(void);
+ static void incnmaster(const Arg *arg);
+_AT_@ -1580,6 +1582,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[NetWMPid] = XInternAtom(dpy, "_NET_WM_PID", False);
+ /* init cursors */
+ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
+ cursor[CurResize] = drw_cur_create(drw, XC_sizing);
+_AT_@ -1645,10 +1648,86 @@ showhide(Client *c)
+ }
+ }
+
++int
++getwincwd(size_t n, char buf[n])
++{
++ enum {
++ CMDBUFLEN = 128,
++ TMPBUFLEN = 128,
++ };
++
++ Client *c;
++ unsigned char *pid_data = NULL;
++ unsigned long nitems, bytes_after;
++ int format;
++ Atom type;
++ char command[CMDBUFLEN];
++ long int command_res;
++ char tmpbuf[TMPBUFLEN];
++ FILE *fp;
++
++ if (selmon->sel == NULL)
++ {
++ return -1;
++ }
++
++ c = wintoclient(selmon->sel->win);
++ if (XGetWindowProperty(dpy, c->win, netatom[NetWMPid], 0, 1, False, AnyPropertyType,
++ &type, &format, &nitems, &bytes_after, &pid_data) != Success)
++ {
++ return -1;
++ }
++
++ snprintf(command, sizeof(command), "pgrep --newest --parent %d 2>/dev/null", *(pid_t*)pid_data);
++
++ fp = popen(command, "r");
++ if (fp == NULL)
++ {
++ return -1;
++ }
++ fgets(tmpbuf, sizeof(tmpbuf), fp);
++ pclose(fp);
++
++ errno = 0;
++ command_res = strtol(tmpbuf, NULL, 10);
++ if (command_res <= 0 || errno != 0)
++ {
++ return -1;
++ }
++
++ snprintf(command, sizeof(command), "readlink /proc/%ld/cwd 2>/dev/null", command_res);
++ fp = popen(command, "r");
++ if (fp == NULL)
++ {
++ return -1;
++ }
++ fgets(tmpbuf, sizeof(tmpbuf), fp);
++ pclose(fp);
++
++ char *p = strchr(tmpbuf, '
');
++ if (p != NULL)
++ {
++ *p = '++ }
++ strncpy(buf, tmpbuf, n);
++
++ return 0;
++}
++
+ void
+ spawn(const Arg *arg)
+ {
+ struct sigaction sa;
++ const char *home = getenv("HOME");
++ char cwd[PATH_MAX];
++
++ if (getwincwd(LENGTH(cwd), cwd) != 0)
++ {
++ if (home != NULL)
++ {
++ strncpy(cwd, home, LENGTH(cwd));
++ }
++ }
+
+ if (arg->v == dmenucmd)
+ dmenumon[0] = '0' + selmon->num;
+_AT_@ -1662,6 +1741,7 @@ spawn(const Arg *arg)
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &sa, NULL);
+
++ chdir(cwd);
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]);
+ }
+--
+2.52.0
+
diff --git a/dwm.suckless.org/patches/spawn_window_cwd/index.md b/dwm.suckless.org/patches/spawn_window_cwd/index.md
new file mode 100644
index 00000000..1603fb6d
--- /dev/null
+++ b/dwm.suckless.org/patches/spawn_window_cwd/index.md
_AT_@ -0,0 +1,19 @@
+spawn\_window\_cwd
+==================
+
+Description
+-----------
+This patch spawns programs from the currently focused client's window.
+Similar to the spawn\_cwd patch, it incorporates enhanced logic and resolves limitations from the original implementation.
+Instead of parsing the client's window name (which may not provide the cwd),
+it searches for the newest ppid and uses its cwd,
+which is typically the shell, or $HOME in case of failure.
+
+Download
+--------
+* [dwm-6.6-spawn\_window\_cwd.diff](dwm-6.6-spawn_window_cwd.diff)
+
+Author
+------
+* Gostev Evgenii - <gostevevg0_AT_gmail.com>
+
Received on Sun Jan 11 2026 - 19:01:19 CET

This archive was generated by hypermail 2.3.0 : Sun Jan 11 2026 - 19:12:43 CET