From 6ccecbb335b6e090d8f21de7fc617ba69f7f3823 Mon Sep 17 00:00:00 2001 From: evageq 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 @@ -21,6 +21,7 @@ * To understand everything else, start reading main(). */ #include +#include #include #include #include @@ -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 */ @@ -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); @@ -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); @@ -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, '\n'); + if (p != NULL) + { + *p = '\0'; + } + 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; @@ -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