On Thu, Jun 11, 2020 at 01:56:21PM +0500, Nikita Zlobin wrote:
> 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 d426c0d..90498d0 100644
> --- a/tabbed.c
> +++ b/tabbed.c
> _AT_@ -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;
> _AT_@ -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);
> _AT_@ -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 (Xutf8TextPropertyToTextList(dpy, &name, &list, &n) >= Success
> + && n > 0 && *list) {
> + text = ecalloc(1, strlen(*list) + 1);
> + strcpy(text, *list);
You could use strdup() here.
> + 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;
> _AT_@ -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;
> _AT_@ -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));
>
> _AT_@ -1107,6 +1145,7 @@ spawn(const Arg *arg)
> perror(" failed");
> exit(0);
> }
> + free(pwd);
> }
>
> int
> _AT_@ -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.26.2
>
>
This patch should probably be on the wiki?
--
Kind regards,
Hiltjo
Received on Thu Jun 11 2020 - 22:14:31 CEST