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
> @@ -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 (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;
> @@ -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.26.2
> 
> 

This patch should probably be on the wiki?

-- 
Kind regards,
Hiltjo

Reply via email to