sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

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