commit 1070524ac033d6dc18519715a0ddf4fcfef5318c
Author: Daniel Bylinka <[email protected]>
Date:   Sun Apr 19 18:56:07 2020 +0200

    [dwm][patch] statuscmd: add dwmblocks integration and simplify export

diff --git a/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-6.2.diff 
b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-6.2.diff
index cbafb763..c8257496 100644
--- a/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-6.2.diff
+++ b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-6.2.diff
@@ -1,16 +1,16 @@
-From b4e7de63bb4d6c711fa8d34fd83c86bfada7236e Mon Sep 17 00:00:00 2001
+From 2761ad72b4b8a80e434e7eba1a24676119ab666d Mon Sep 17 00:00:00 2001
 From: Daniel Bylinka <[email protected]>
-Date: Sat, 4 Apr 2020 22:54:03 +0200
+Date: Sat, 18 Apr 2020 01:41:03 +0200
 Subject: [PATCH] statuscmd: run shell commands based on mouse button and
  position when clicking statusbar
 
 ---
  config.def.h |  8 +++++++-
- dwm.c        | 56 +++++++++++++++++++++++++++++++++++++++++++++++++---
- 2 files changed, 60 insertions(+), 4 deletions(-)
+ dwm.c        | 47 ++++++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 51 insertions(+), 4 deletions(-)
 
 diff --git a/config.def.h b/config.def.h
-index 1c0b587..b85d7a4 100644
+index 1c0b587..5cd7efa 100644
 --- a/config.def.h
 +++ b/config.def.h
 @@ -59,6 +59,10 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, 
manipulated in spawn()
@@ -18,7 +18,7 @@ index 1c0b587..b85d7a4 100644
  static const char *termcmd[]  = { "st", NULL };
  
 +/* commands spawned when clicking statusbar, the mouse button pressed is 
exported as BUTTON */
-+static const char *statuscmds[] = { "notify-send Mouse$BUTTON" };
++static char *statuscmds[] = { "notify-send Mouse$BUTTON" };
 +static char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL };
 +
  static Key keys[] = {
@@ -36,7 +36,7 @@ index 1c0b587..b85d7a4 100644
        { ClkClientWin,         MODKEY,         Button2,        togglefloating, 
{0} },
        { ClkClientWin,         MODKEY,         Button3,        resizemouse,    
{0} },
 diff --git a/dwm.c b/dwm.c
-index 4465af1..29f9f8d 100644
+index 4465af1..d35d173 100644
 --- a/dwm.c
 +++ b/dwm.c
 @@ -156,6 +156,7 @@ static void clientmessage(XEvent *e);
@@ -47,26 +47,25 @@ index 4465af1..29f9f8d 100644
  static Monitor *createmon(void);
  static void destroynotify(XEvent *e);
  static void detach(Client *c);
-@@ -237,6 +238,10 @@ static void zoom(const Arg *arg);
+@@ -237,6 +238,9 @@ static void zoom(const Arg *arg);
  /* variables */
  static const char broken[] = "broken";
  static char stext[256];
 +static char rawstext[256];
-+static const char statusexport[] = "export BUTTON=-;";
 +static int statuscmdn;
-+static int lastbutton;
++static char lastbutton[] = "-";
  static int screen;
  static int sw, sh;           /* X display screen geometry width, height */
  static int bh, blw = 0;      /* bar geometry */
-@@ -421,6 +426,7 @@ buttonpress(XEvent *e)
+@@ -421,6 +425,7 @@ buttonpress(XEvent *e)
        Client *c;
        Monitor *m;
        XButtonPressedEvent *ev = &e->xbutton;
-+      lastbutton = ev->button;
++      *lastbutton = '0' + ev->button;
  
        click = ClkRootWin;
        /* focus monitor if necessary */
-@@ -439,9 +445,26 @@ buttonpress(XEvent *e)
+@@ -439,9 +444,26 @@ buttonpress(XEvent *e)
                        arg.ui = 1 << i;
                } else if (ev->x < x + blw)
                        click = ClkLtSymbol;
@@ -95,7 +94,7 @@ index 4465af1..29f9f8d 100644
                        click = ClkWinTitle;
        } else if ((c = wintoclient(ev->window))) {
                focus(c);
-@@ -627,6 +650,19 @@ configurerequest(XEvent *e)
+@@ -627,6 +649,19 @@ configurerequest(XEvent *e)
        XSync(dpy, False);
  }
  
@@ -115,38 +114,18 @@ index 4465af1..29f9f8d 100644
  Monitor *
  createmon(void)
  {
-@@ -1636,11 +1672,22 @@ sigchld(int unused)
-       while (0 < waitpid(-1, NULL, WNOHANG));
- }
- 
-+
- void
- spawn(const Arg *arg)
+@@ -1641,6 +1676,10 @@ spawn(const Arg *arg)
  {
-+      char *cmd = NULL;
        if (arg->v == dmenucmd)
                dmenumon[0] = '0' + selmon->num;
 +      else if (arg->v == statuscmd) {
-+              int len = strlen(statuscmds[statuscmdn]) + 1;
-+              if (!(cmd = malloc(sizeof(char)*len + sizeof(statusexport))))
-+                      die("malloc:");
-+              strcpy(cmd, statusexport);
-+              strcat(cmd, statuscmds[statuscmdn]);
-+              cmd[LENGTH(statusexport)-3] = '0' + lastbutton;
-+              statuscmd[2] = cmd;
++              statuscmd[2] = statuscmds[statuscmdn];
++              setenv("BUTTON", lastbutton, 1);
 +      }
        if (fork() == 0) {
                if (dpy)
                        close(ConnectionNumber(dpy));
-@@ -1650,6 +1697,7 @@ spawn(const Arg *arg)
-               perror(" failed");
-               exit(EXIT_SUCCESS);
-       }
-+      free(cmd);
- }
- 
- void
-@@ -1987,8 +2035,10 @@ updatesizehints(Client *c)
+@@ -1987,8 +2026,10 @@ updatesizehints(Client *c)
  void
  updatestatus(void)
  {
@@ -159,5 +138,5 @@ index 4465af1..29f9f8d 100644
  }
  
 -- 
-2.26.0
+2.26.1
 
diff --git a/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-signal-6.2.diff 
b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-signal-6.2.diff
new file mode 100644
index 00000000..97fda1bb
--- /dev/null
+++ b/dwm.suckless.org/patches/statuscmd/dwm-statuscmd-signal-6.2.diff
@@ -0,0 +1,157 @@
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..b67825e 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -103,7 +103,9 @@ static Button buttons[] = {
+       { ClkLtSymbol,          0,              Button1,        setlayout,      
{0} },
+       { ClkLtSymbol,          0,              Button3,        setlayout,      
{.v = &layouts[2]} },
+       { ClkWinTitle,          0,              Button2,        zoom,           
{0} },
+-      { ClkStatusText,        0,              Button2,        spawn,          
{.v = termcmd } },
++      { ClkStatusText,        0,              Button1,        sigdwmblocks,   
{.i = 1} },
++      { ClkStatusText,        0,              Button2,        sigdwmblocks,   
{.i = 2} },
++      { ClkStatusText,        0,              Button3,        sigdwmblocks,   
{.i = 3} },
+       { ClkClientWin,         MODKEY,         Button1,        movemouse,      
{0} },
+       { ClkClientWin,         MODKEY,         Button2,        togglefloating, 
{0} },
+       { ClkClientWin,         MODKEY,         Button3,        resizemouse,    
{0} },
+diff --git a/dwm.c b/dwm.c
+index 4465af1..c600131 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -156,6 +156,7 @@ static void clientmessage(XEvent *e);
+ static void configure(Client *c);
+ static void configurenotify(XEvent *e);
+ static void configurerequest(XEvent *e);
++static void copyvalidchars(char *text, char *rawtext);
+ static Monitor *createmon(void);
+ static void destroynotify(XEvent *e);
+ static void detach(Client *c);
+@@ -169,6 +170,7 @@ static void focus(Client *c);
+ static void focusin(XEvent *e);
+ static void focusmon(const Arg *arg);
+ static void focusstack(const Arg *arg);
++static int getdwmblockspid();
+ static int getrootptr(int *x, int *y);
+ static long getstate(Window w);
+ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
+@@ -205,6 +207,7 @@ static void setup(void);
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
++static void sigdwmblocks(const Arg *arg);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+@@ -237,6 +240,9 @@ static void zoom(const Arg *arg);
+ /* variables */
+ static const char broken[] = "broken";
+ static char stext[256];
++static char rawstext[256];
++static int dwmblockssig;
++pid_t dwmblockspid = 0;
+ static int screen;
+ static int sw, sh;           /* X display screen geometry width, height */
+ static int bh, blw = 0;      /* bar geometry */
+@@ -439,9 +445,26 @@ buttonpress(XEvent *e)
+                       arg.ui = 1 << i;
+               } else if (ev->x < x + blw)
+                       click = ClkLtSymbol;
+-              else if (ev->x > selmon->ww - TEXTW(stext))
++              else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) {
+                       click = ClkStatusText;
+-              else
++
++                      char *text = rawstext;
++                      int i = -1;
++                      char ch;
++                      dwmblockssig = 0;
++                      while (text[++i]) {
++                              if ((unsigned char)text[i] < ' ') {
++                                      ch = text[i];
++                                      text[i] = '++                           
        x += TEXTW(text) - lrpad;
++                                      text[i] = ch;
++                                      text += i+1;
++                                      i = -1;
++                                      if (x >= ev->x) break;
++                                      dwmblockssig = ch;
++                              }
++                      }
++              } else
+                       click = ClkWinTitle;
+       } else if ((c = wintoclient(ev->window))) {
+               focus(c);
+@@ -627,6 +650,19 @@ configurerequest(XEvent *e)
+       XSync(dpy, False);
+ }
+ 
++void
++copyvalidchars(char *text, char *rawtext)
++{
++      int i = -1, j = 0;
++
++      while(rawtext[++i]) {
++              if ((unsigned char)rawtext[i] >= ' ') {
++                      text[j++] = rawtext[i];
++              }
++      }
++      text[j] = '++}
++
+ Monitor *
+ createmon(void)
+ {
+@@ -871,6 +907,18 @@ getatomprop(Client *c, Atom prop)
+       return atom;
+ }
+ 
++int
++getdwmblockspid()
++{
++      char buf[16];
++      FILE *fp = popen("pidof -s dwmblocks", "r");
++      fgets(buf, sizeof(buf), fp);
++      pid_t pid = strtoul(buf, NULL, 10);
++      pclose(fp);
++      dwmblockspid = pid;
++      return pid != 0 ? 0 : -1;
++}
++
+ int
+ getrootptr(int *x, int *y)
+ {
+@@ -1636,6 +1684,23 @@ sigchld(int unused)
+       while (0 < waitpid(-1, NULL, WNOHANG));
+ }
+ 
++void
++sigdwmblocks(const Arg *arg)
++{
++      union sigval sv;
++      sv.sival_int = (dwmblockssig << 8) | arg->i;
++      if (!dwmblockspid)
++              if (getdwmblockspid() == -1)
++                      return;
++
++      if (sigqueue(dwmblockspid, SIGUSR1, sv) == -1) {
++              if (errno == ESRCH) {
++                      if (!getdwmblockspid())
++                              sigqueue(dwmblockspid, SIGUSR1, sv);
++              }
++      }
++}
++
+ void
+ spawn(const Arg *arg)
+ {
+@@ -1987,8 +2052,10 @@ updatesizehints(Client *c)
+ void
+ updatestatus(void)
+ {
+-      if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
++      if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext)))
+               strcpy(stext, "dwm-"VERSION);
++      else
++              copyvalidchars(stext, rawstext);
+       drawbar(selmon);
+ }
+ 
diff --git a/dwm.suckless.org/patches/statuscmd/dwmblocks-statuscmd.diff 
b/dwm.suckless.org/patches/statuscmd/dwmblocks-statuscmd.diff
new file mode 100644
index 00000000..961f22a4
--- /dev/null
+++ b/dwm.suckless.org/patches/statuscmd/dwmblocks-statuscmd.diff
@@ -0,0 +1,80 @@
+diff --git a/dwmblocks.c b/dwmblocks.c
+index 2f3b774..ba7dbb5 100644
+--- a/dwmblocks.c
++++ b/dwmblocks.c
+@@ -14,6 +14,7 @@ typedef struct {
+       unsigned int signal;
+ } Block;
+ void sighandler(int num);
++void buttonhandler(int sig, siginfo_t *si, void *ucontext);
+ void getcmds(int time);
+ #ifndef __OpenBSD__
+ void getsigcmds(int signal);
+@@ -33,15 +34,32 @@ static int screen;
+ static Window root;
+ static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
+ static char statusstr[2][256];
++static char button[] = "+ static int statusContinue = 1;
+ static void (*writestatus) () = setroot;
+ 
+ //opens process *cmd and stores output in *output
+ void getcmd(const Block *block, char *output)
+ {
++      if (block->signal)
++      {
++              output[0] = block->signal;
++              output++;
++      }
+       strcpy(output, block->icon);
+       char *cmd = block->command;
+-      FILE *cmdf = popen(cmd,"r");
++      FILE *cmdf;
++      if (*button)
++      {
++              setenv("BUTTON", button, 1);
++              cmdf = popen(cmd,"r");
++              *button = '++           unsetenv("BUTTON");
++      }
++      else
++      {
++              cmdf = popen(cmd,"r");
++      }
+       if (!cmdf)
+               return;
+       char c;
+@@ -79,12 +97,18 @@ void getsigcmds(int signal)
+ 
+ void setupsignals()
+ {
++      struct sigaction sa;
+       for(int i = 0; i < LENGTH(blocks); i++)
+       {         
+               if (blocks[i].signal > 0)
++              {
+                       signal(SIGRTMIN+blocks[i].signal, sighandler);
++                      sigaddset(&sa.sa_mask, SIGRTMIN+blocks[i].signal); // 
ignore signal when handling SIGUSR1
++              }
+       }
+-
++      sa.sa_sigaction = buttonhandler;
++      sa.sa_flags = SA_SIGINFO;
++      sigaction(SIGUSR1, &sa, NULL);
+ }
+ #endif
+ 
+@@ -143,6 +167,13 @@ void sighandler(int signum)
+       getsigcmds(signum-SIGRTMIN);
+       writestatus();
+ }
++
++void buttonhandler(int sig, siginfo_t *si, void *ucontext)
++{
++      *button = '0' + si->si_value.sival_int & 0xff;
++      getsigcmds(si->si_value.sival_int >> 8);
++      writestatus();
++}
+ #endif
+ 
+ void termhandler(int signum)
diff --git a/dwm.suckless.org/patches/statuscmd/index.md 
b/dwm.suckless.org/patches/statuscmd/index.md
index 995efc19..c320d3ce 100644
--- a/dwm.suckless.org/patches/statuscmd/index.md
+++ b/dwm.suckless.org/patches/statuscmd/index.md
@@ -44,9 +44,26 @@ where having certain unprintable characters such as '
' in the status
 string can make dwm laggy is "fixed", since they are not copied to the
 string that is actually drawn.
 
+dwmblocks integration
+---------------------
+A program that sets the status for dwm such as
+[dwmblocks](https://github.com/torrinfail/dwmblocks) can be patched to manage
+the commands while dwm only finds the location clicked in the status bar.
+This way, no changes are needed in dwm when adding or reordering modules.
+
+Instead of running a command from within dwm using the control character
+as an index, the dwm-statuscmd-signal patch sends a SIGUSR1 signal to
+dwmblocks with the button and control character encoded into the signal value.
+
+The dwmblocks-statuscmd patch makes dwmblocks put each block's signal in
+front of its output text and handles the SIGUSR1 signal by running the
+block's command with $BUTTON exported.
+
 Download
 --------
 * [dwm-statuscmd-6.2.diff](dwm-statuscmd-6.2.diff)
+* [dwm-statuscmd-signal-6.2.diff](dwm-statuscmd-signal-6.2.diff)
+* [dwmblocks-statuscmd.diff](dwmblocks-statuscmd.diff)
 
 Author
 ------


Reply via email to