Somewhat disconvenient after true multitab terminals, that new term tabs don't inherit workdir from previous active. Here is some attempt to make such a bond.
Not sure, what's better way here to get gettextprop() variant for unlimited string - without dublicating it in same as done for sprintf and strcpy.
>From a775618bb892f7cd111bc35339a304149195a411 Mon Sep 17 00:00:00 2001 From: Nikita Zlobin <nick877...@gmail.com> Date: Thu, 4 Jun 2020 00:58:35 +0500 Subject: [tabbed][PATCH] Use PWD xprop to set workdir for spawned clients To: hackers@suckless.org workdir could be got from active client via xprop, then set for spawned client. Terminals can pass it with xprop -id ${WINDOWID} command from hook, created for PWD change. Setting up hook depends on what shell is used. For bash it's doable either via cd() function or PROMPT_COMMAND. Example bash command: > xprop -id "${WINDOWID}" -f PWD 8s -set "PWD" "${PWD}" Rename gettextprop to gettextpropn, add proper gettextprop, for unpredictable data length. Reading workdir may need unpredictable string length. Just like with strcpy/strcpyn, variant expecting limited buffer could end with 'n'. Well, it could be agettextprop, like asprintf, but then what should match to sprintf... --- tabbed.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/tabbed.c b/tabbed.c index eafe28a..af207c8 100644 --- a/tabbed.c +++ b/tabbed.c @@ -49,7 +49,7 @@ enum { ColFG, ColBG, ColLast }; /* color */ enum { WMProtocols, WMDelete, WMName, WMState, WMFullscreen, - XEmbed, WMSelectTab, WMLast }; /* default atoms */ + XEmbed, WMSelectTab, PWD, WMLast }; /* default atoms */ typedef union { int i; @@ -109,7 +109,8 @@ static char *getatom(int a); static int getclient(Window w); static XftColor getcolor(const char *colstr); static int getfirsttab(void); -static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); +static char * gettextprop(Window w, Atom atom); +static Bool gettextpropn(Window w, Atom atom, char *text, unsigned int size); static void initfont(const char *fontstr); static Bool isprotodel(int c); static void keypress(const XEvent *e); @@ -599,8 +600,34 @@ getfirsttab(void) ret; } +char * +gettextprop(Window w, Atom atom) +{ + char *text; + char **list = NULL; + int n; + XTextProperty name; + + XGetTextProperty(dpy, w, &name, atom); + if (!name.nitems) + return NULL; + + if (name.encoding == XA_STRING) { + text = ecalloc(1, strlen((char *)name.value) + 1); + strcpy(text, (char *)name.value); + } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success + && n > 0 && *list) { + text = ecalloc(1, strlen(*list) + 1); + strcpy(text, *list); + XFreeStringList(list); + } + XFree(name.value); + + return text; +} + Bool -gettextprop(Window w, Atom atom, char *text, unsigned int size) +gettextpropn(Window w, Atom atom, char *text, unsigned int size) { char **list = NULL; int n; @@ -995,6 +1022,7 @@ setup(void) wmatom[WMSelectTab] = XInternAtom(dpy, "_TABBED_SELECT_TAB", False); wmatom[WMState] = XInternAtom(dpy, "_NET_WM_STATE", False); wmatom[XEmbed] = XInternAtom(dpy, "_XEMBED", False); + wmatom[PWD] = XInternAtom(dpy, "PWD", False); /* init appearance */ wx = 0; @@ -1090,7 +1118,17 @@ sigchld(int unused) void spawn(const Arg *arg) { + char * pwd = NULL; + + if (sel != -1) + pwd = gettextprop(clients[sel]->win, wmatom[PWD]); + if (fork() == 0) { + if (pwd) { + chdir(pwd); + free(pwd); + } + if(dpy) close(ConnectionNumber(dpy)); @@ -1107,6 +1145,7 @@ spawn(const Arg *arg) perror(" failed"); exit(0); } + free(pwd); } int @@ -1213,9 +1252,9 @@ updatenumlockmask(void) void updatetitle(int c) { - if (!gettextprop(clients[c]->win, wmatom[WMName], clients[c]->name, + if (!gettextpropn(clients[c]->win, wmatom[WMName], clients[c]->name, sizeof(clients[c]->name))) - gettextprop(clients[c]->win, XA_WM_NAME, clients[c]->name, + gettextpropn(clients[c]->win, XA_WM_NAME, clients[c]->name, sizeof(clients[c]->name)); if (sel == c) xsettitle(win, clients[c]->name); -- 2.24.1