dwm-6.6-spawn_window_cwd.diff (3879B)
1 From 6ccecbb335b6e090d8f21de7fc617ba69f7f3823 Mon Sep 17 00:00:00 2001 2 From: evageq <gostevevg0@gmail.com> 3 Date: Sun, 11 Jan 2026 16:07:19 +0300 4 Subject: [PATCH] dwm.c: Spawn term in win cwd enhanced 5 6 --- 7 dwm.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 8 1 file changed, 81 insertions(+), 1 deletion(-) 9 10 diff --git a/dwm.c b/dwm.c 11 index ade3c86..60f6275 100644 12 --- a/dwm.c 13 +++ b/dwm.c 14 @@ -21,6 +21,7 @@ 15 * To understand everything else, start reading main(). 16 */ 17 #include <errno.h> 18 +#include <libgen.h> 19 #include <locale.h> 20 #include <signal.h> 21 #include <stdarg.h> 22 @@ -61,7 +62,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ 23 enum { SchemeNorm, SchemeSel }; /* color schemes */ 24 enum { NetSupported, NetWMName, NetWMState, NetWMCheck, 25 NetWMFullscreen, NetActiveWindow, NetWMWindowType, 26 - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ 27 + NetWMWindowTypeDialog, NetClientList, NetWMPid, NetLast }; /* EWMH atoms */ 28 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ 29 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, 30 ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ 31 @@ -172,6 +173,7 @@ static Atom getatomprop(Client *c, Atom prop); 32 static int getrootptr(int *x, int *y); 33 static long getstate(Window w); 34 static int gettextprop(Window w, Atom atom, char *text, unsigned int size); 35 +static int getwincwd(size_t n, char buf[n]); 36 static void grabbuttons(Client *c, int focused); 37 static void grabkeys(void); 38 static void incnmaster(const Arg *arg); 39 @@ -1580,6 +1582,7 @@ setup(void) 40 netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); 41 netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); 42 netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); 43 + netatom[NetWMPid] = XInternAtom(dpy, "_NET_WM_PID", False); 44 /* init cursors */ 45 cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); 46 cursor[CurResize] = drw_cur_create(drw, XC_sizing); 47 @@ -1645,10 +1648,86 @@ showhide(Client *c) 48 } 49 } 50 51 +int 52 +getwincwd(size_t n, char buf[n]) 53 +{ 54 + enum { 55 + CMDBUFLEN = 128, 56 + TMPBUFLEN = 128, 57 + }; 58 + 59 + Client *c; 60 + unsigned char *pid_data = NULL; 61 + unsigned long nitems, bytes_after; 62 + int format; 63 + Atom type; 64 + char command[CMDBUFLEN]; 65 + long int command_res; 66 + char tmpbuf[TMPBUFLEN]; 67 + FILE *fp; 68 + 69 + if (selmon->sel == NULL) 70 + { 71 + return -1; 72 + } 73 + 74 + c = wintoclient(selmon->sel->win); 75 + if (XGetWindowProperty(dpy, c->win, netatom[NetWMPid], 0, 1, False, AnyPropertyType, 76 + &type, &format, &nitems, &bytes_after, &pid_data) != Success) 77 + { 78 + return -1; 79 + } 80 + 81 + snprintf(command, sizeof(command), "pgrep --newest --parent %d 2>/dev/null", *(pid_t*)pid_data); 82 + 83 + fp = popen(command, "r"); 84 + if (fp == NULL) 85 + { 86 + return -1; 87 + } 88 + fgets(tmpbuf, sizeof(tmpbuf), fp); 89 + pclose(fp); 90 + 91 + errno = 0; 92 + command_res = strtol(tmpbuf, NULL, 10); 93 + if (command_res <= 0 || errno != 0) 94 + { 95 + return -1; 96 + } 97 + 98 + snprintf(command, sizeof(command), "readlink /proc/%ld/cwd 2>/dev/null", command_res); 99 + fp = popen(command, "r"); 100 + if (fp == NULL) 101 + { 102 + return -1; 103 + } 104 + fgets(tmpbuf, sizeof(tmpbuf), fp); 105 + pclose(fp); 106 + 107 + char *p = strchr(tmpbuf, '\n'); 108 + if (p != NULL) 109 + { 110 + *p = '\0'; 111 + } 112 + strncpy(buf, tmpbuf, n); 113 + 114 + return 0; 115 +} 116 + 117 void 118 spawn(const Arg *arg) 119 { 120 struct sigaction sa; 121 + const char *home = getenv("HOME"); 122 + char cwd[PATH_MAX]; 123 + 124 + if (getwincwd(LENGTH(cwd), cwd) != 0) 125 + { 126 + if (home != NULL) 127 + { 128 + strncpy(cwd, home, LENGTH(cwd)); 129 + } 130 + } 131 132 if (arg->v == dmenucmd) 133 dmenumon[0] = '0' + selmon->num; 134 @@ -1662,6 +1741,7 @@ spawn(const Arg *arg) 135 sa.sa_handler = SIG_DFL; 136 sigaction(SIGCHLD, &sa, NULL); 137 138 + chdir(cwd); 139 execvp(((char **)arg->v)[0], (char **)arg->v); 140 die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); 141 } 142 -- 143 2.52.0 144