commit aa1472ed71a388a0061db7b9cf9695799ccc7534
Author: explosion-mental <[email protected]>
Date:   Thu May 26 23:02:53 2022 -0500

    [patch][dwm] update integrated-status-text patch

diff --git 
a/dwm.suckless.org/patches/integrated-status-text/dwm-integrated-status-text-6.3.diff
 
b/dwm.suckless.org/patches/integrated-status-text/dwm-integrated-status-text-6.3.diff
index f2a9278b..02c8fd96 100644
--- 
a/dwm.suckless.org/patches/integrated-status-text/dwm-integrated-status-text-6.3.diff
+++ 
b/dwm.suckless.org/patches/integrated-status-text/dwm-integrated-status-text-6.3.diff
@@ -1,100 +1,94 @@
-From f3a9dd0222319d72303be37ae5268831582fe487 Mon Sep 17 00:00:00 2001
+From 02f1f07ee4460787c971bd28e934cb5fc319253d Mon Sep 17 00:00:00 2001
 From: explosion-mental <[email protected]>
-Date: Sun, 27 Feb 2022 17:08:53 -0500
-Subject: [PATCH] [PATCH] Allows dwm to handle the text by itself This is a
- dwmblocks integration into dwm itself. You can update the blocks only with
- signals of with mouseclicks. The 'interval' value does nothing and is meant
- to be there to 're-use' on future patches. You can checkout my build with
- more features like 'async' updates https://github.com/explosion-mental/Dwm,
- which is were I'm extracting this patch.
+Date: Thu, 26 May 2022 22:34:14 -0500
+Subject: [PATCH] [PATCH] Allows dwm to handle the text by itself. You can
+ think of it like a dwmblocks integration into dwm itself. This is extracted
+ from my dwm build[0] in which you can find even more information.
 
-What you need to know:
-- dwm sets a enviromental variable with the PID of itself to be more
-  'friendly'. With this you can do `kill -35 $STATUSBAR`, which updates
-  block with signal 1 (34 + signal of the block)
-- other way to update a block is inside dwm itself, with the
-  `updateblock` function. It accepts an unsigned int (non negative)
-  number which value indicates the signal of the block you want to
-  update.
-- mouse clicks are handled with `sendstatusbar` (a mouse function only!)
-  which accepts the value that you want to pass to the block command
-  as a 'variable' called `BLOCK_BUTTON`, which should be handled in the
-  script (block command)
-- since this uses real time signals to handle the updates, shouldn't
-  work in openbsd, but I could be wrong.
+Example:
+```
+/* fg         command             interval  signal */
+{ "#000000",  "echo 'dwm block!",   10,       3},
+```
+
+- fg: the foreground color of the individual block, for the background it
+uses the bg of SchemeStatus.
+
+- command: it uses the output of the commands for the status text
+interval: in seconds, how much does it have to pass before updating the
+block.
+
+- interval: in seconds, how many seconds until the block it's updated
+
+- signal: have to be less than 30. This lets you update the block with
+`kill` by adding 35 to this value.
+For the block above it would be 34 + 3 = 37 -> `kill -37 $(pidof dwm)`.
+These signals are linux dependant.
+
+You can change `$(pidof dwm)` with `$STATUSBAR` to 'fix' signaling
+multiple instances of dwm, since this patch also wraps the PID of dwm
+into the `$STATUSBAR` enviromental variable.
+
+Last thing, mouse actions. For this you need to handle the env variable
+`$BLOCK_BUTTON` in a script, this is so you can easily reuse the scripts
+used in dwmblocks. And remember that mouse actions update the block.
+
+[0] https://github.com/explosion-mental/Dwm or
+https://codeberg.org/explosion-mental/Dwm
 ---
- config.def.h |  53 +++++++++++++++
- dwm.c        | 186 +++++++++++++++++++++++++++++++++++++++++++++++----
- 2 files changed, 227 insertions(+), 12 deletions(-)
+ config.def.h |  39 ++++++-
+ dwm.c        | 298 +++++++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 318 insertions(+), 19 deletions(-)
 
 diff --git a/config.def.h b/config.def.h
-index a2ac963..99d6b3d 100644
+index a2ac963..cad178c 100644
 --- a/config.def.h
 +++ b/config.def.h
-@@ -18,6 +18,49 @@ static const char *colors[][3]      = {
+@@ -16,8 +16,38 @@ static const char *colors[][3]      = {
+       /*               fg         bg         border   */
+       [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
        [SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
++      [SchemeStatus]={ col_cyan, col_gray1,  NULL  },
  };
-
+ 
++
 +/* status bar */
 +static const Block blocks[] = {
-+      /* command                              interval        signal */
-+      { "sb-clock",                           30,             1},
-+      { "sb-disk",                            9000,           2},
-+      { "sb-battery",                         10,             3},
-+      { "sb-internet",                        10,             4},
-+      { "sb-mailbox",                         0,              5},
-+      { "sb-moonphase",                       18000,          6},
-+      { "sb-forecast",                        18000,          7},
-+      { "sb-volume",                          0,              8},
-+//    { "sb-price btc Bitcoin 💰",             9000,           21},
-+//    { "sb-price eth Ethereum 🍸",            9000,           23},
-+//    { "sb-price xmr \"Monero\" 🔒",          9000,           24},
-+//    { "sb-price link \"Chainlink\" 🔗",      300,            25},
-+//    { "sb-price bat \"Basic Attention Token\" 🦁",9000,      20},
-+//    { "sb-price lbc \"LBRY Token\" 📚",      9000,           22},
-+//    { "sb-cpu",                             10,             18},
-+//    { "sb-kbselect",                        0,              30},
-+//    { "sb-memory",                          10,             14},
-+//    { "sb-torrent",                         20,             7},
-+//    { "sb-crypto",                          0,              13},
-+//    { "sb-help-icon",                       0,              15},
-+//    { "sb-nettraf",                         1,              16},
-+//    { "sb-news",                            0,              6},
-+//    { "sb-xbpsup",                          18000,          8},
-+      { "sb-pacpackages",                     0,              9},
-+      { "sb-sync",                            0,              10},
-+//    { "sb-mpc",                             0,              26},
-+      { "sb-music",                           0,              11},
-+//    { "sb-tasks",                           10,             12},
-+      { "sb-notes",                           0,              13},
-+      { "cat /tmp/recordingicon 2>/dev/null", 0,              14},
-+//    { "sb-count",                           0,              21},
++      /* fg     command                               interval        signal 
*/
++      { col_gray3, "sb-clock",                        20,             1},
++      { col_gray1, "sb-disk",                         9000,           2},
++      { col_gray2, "sb-battery",                      10,             3},
++      { col_gray3, "sb-internet",                     10,             4},
++      { col_cyan, "sb-mailbox",                       0,              5},
++      { "#000001", "sb-moonphase",                    0,              6},
++      { "#1F0077", "sb-forecast",                     0,              7},
++      { "#000077", "sb-volume",                       0,              8},
++      { "#F77000", "sb-pacpackages",                  0,              9},
++      { "#177000", "sb-sync",                         0,              10},
++//    { col_gray1, "sb-mpc",                          0,              26},
++      { col_gray2, "sb-music",                        0,              11},
++//    { col_gray3, "sb-tasks",                        10,             12},
++      { col_gray4, "sb-notes",                        0,              13},
++      { col_cyan, "echo '';cat /tmp/recordingicon",   0,              14},
 +};
 +
 +/* inverse the order of the blocks, comment to disable */
-+#define INVERSED
++#define INVERSED      1
 +/* delimeter between blocks commands. NULL character (' +static char 
delimiter[] = " ";
 +/* max number of character that one block command can output */
-+#define CMDLENGTH             50
++#define CMDLENGTH     50
++
 +
  /* tagging */
  static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-
-@@ -62,6 +105,9 @@ static const char *termcmd[]  = { "st", NULL };
-
- static Key keys[] = {
-       /* modifier                     key        function        argument */
-+      { MODKEY,       XK_minus,       spawn,  SHCMD("pamixer --allow-boost -d 
3; kill -42 $STATUSBAR")},
-+      { MODKEY,       XK_equal,       spawn,  SHCMD("pamixer --allow-boost -i 
3")},
-+      { MODKEY,       XK_equal,       updateblock,    { .ui = 8 } },
-       { MODKEY,                       XK_p,      spawn,          {.v = 
dmenucmd } },
-       { MODKEY|ShiftMask,             XK_Return, spawn,          {.v = 
termcmd } },
-       { MODKEY,                       XK_b,      togglebar,      {0} },
-@@ -101,6 +147,13 @@ static Key keys[] = {
- /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, 
ClkClientWin, or ClkRootWin */
- static Button buttons[] = {
-       /* click                event mask      button          function        
argument */
+ 
+@@ -104,7 +134,14 @@ 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,        sendstatusbar,  
 {.i = 1 } },
 +      { ClkStatusText,        0,              Button2,        sendstatusbar,  
 {.i = 2 } },
 +      { ClkStatusText,        0,              Button3,        sendstatusbar,  
 {.i = 3 } },
@@ -102,18 +96,36 @@ index a2ac963..99d6b3d 100644
 +      { ClkStatusText,        0,              Button5,        sendstatusbar,  
 {.i = 5 } },
 +      { ClkStatusText,        ShiftMask,      Button1,        sendstatusbar,  
 {.i = 6 } },
 +
-       { ClkLtSymbol,          0,              Button1,        setlayout,      
{0} },
-       { ClkLtSymbol,          0,              Button3,        setlayout,      
{.v = &layouts[2]} },
-       { ClkWinTitle,          0,              Button2,        zoom,           
{0} },
+       { ClkClientWin,         MODKEY,         Button1,        movemouse,      
{0} },
+       { ClkClientWin,         MODKEY,         Button2,        togglefloating, 
{0} },
+       { ClkClientWin,         MODKEY,         Button3,        resizemouse,    
{0} },
 diff --git a/dwm.c b/dwm.c
-index a96f33c..6e79e5f 100644
+index a96f33c..5789f72 100644
 --- a/dwm.c
 +++ b/dwm.c
-@@ -141,6 +141,12 @@ typedef struct {
+@@ -28,6 +28,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <poll.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <X11/cursorfont.h>
+@@ -59,7 +60,7 @@
+ 
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+-enum { SchemeNorm, SchemeSel }; /* color schemes */
++enum { SchemeNorm, SchemeSel, SchemeStatus }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+        NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+        NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+@@ -141,6 +142,13 @@ typedef struct {
        int monitor;
  } Rule;
-
+ 
 +typedef struct {
++      const char *color;
 +      const char *command;
 +      const unsigned int interval;
 +      const unsigned int signal;
@@ -122,17 +134,19 @@ index a96f33c..6e79e5f 100644
  /* function declarations */
  static void applyrules(Client *c);
  static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int 
interact);
-@@ -172,6 +178,9 @@ static void focusstack(const Arg *arg);
+@@ -172,6 +180,11 @@ static void focusstack(const Arg *arg);
  static Atom getatomprop(Client *c, Atom prop);
  static int getrootptr(int *x, int *y);
  static long getstate(Window w);
-+static void getcmd(int i, char *output);
-+static void getsigcmds(unsigned int signal);
++static void getcmd(int i, char *button);
++static void getcmds(int time);
++static void getsigcmds(int signal);
++static int gcd(int a, int b);
 +static int getstatus(int width);
  static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
  static void grabbuttons(Client *c, int focused);
  static void grabkeys(void);
-@@ -197,6 +206,7 @@ static void run(void);
+@@ -197,14 +210,17 @@ static void run(void);
  static void scan(void);
  static int sendevent(Client *c, Atom proto);
  static void sendmon(Client *c, Monitor *m);
@@ -140,42 +154,45 @@ index a96f33c..6e79e5f 100644
  static void setclientstate(Client *c, long state);
  static void setfocus(Client *c);
  static void setfullscreen(Client *c, int fullscreen);
-@@ -219,6 +229,7 @@ static void unmanage(Client *c, int destroyed);
- static void unmapnotify(XEvent *e);
- static void updatebarpos(Monitor *m);
- static void updatebars(void);
-+static void updateblock(const Arg *arg);
- static void updateclientlist(void);
- static int updategeom(void);
- static void updatenumlockmask(void);
-@@ -237,7 +248,7 @@ static void zoom(const Arg *arg);
-
+ static void setlayout(const Arg *arg);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
++static void setsignal(int sig, void (*handler)(int sig));
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
++static void sigalrm(int unused);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+@@ -237,13 +253,16 @@ static void zoom(const Arg *arg);
+ 
  /* variables */
  static const char broken[] = "broken";
 -static char stext[256];
-+static unsigned int stsw = 0, blocknum;
  static int screen;
  static int sw, sh;           /* X display screen geometry width, height */
  static int bh, blw = 0;      /* bar geometry */
-@@ -260,7 +271,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
-       [PropertyNotify] = propertynotify,
-       [UnmapNotify] = unmapnotify
- };
--static Atom wmatom[WMLast], netatom[NetLast];
-+static Atom wmatom[WMLast], netatom[NetLast], dwmstatus;
- static int running = 1;
- static Cur *cursor[CurLast];
- static Clr **scheme;
-@@ -272,6 +283,8 @@ static Window root, wmcheckwin;
+ static int lrpad;            /* sum of left and right padding for text */
+ static int (*xerrorxlib)(Display *, XErrorEvent *);
++static unsigned int blocknum; /* blocks idx in mouse click */
++static unsigned int stsw = 0; /* status width */
+ static unsigned int numlockmask = 0;
++static unsigned int sleepinterval = 0, maxinterval = 0, count = 0;
++static unsigned int execlock = 0; /* ensure only one child process exists per 
block at an instance */
+ static void (*handler[LASTEvent]) (XEvent *) = {
+       [ButtonPress] = buttonpress,
+       [ClientMessage] = clientmessage,
+@@ -272,6 +291,9 @@ static Window root, wmcheckwin;
  /* configuration, allows nested code to access above variables */
  #include "config.h"
-
-+static char blockoutput[LENGTH(blocks)][CMDLENGTH] = {0};
+ 
++static char blockoutput[LENGTH(blocks)][CMDLENGTH + 1] = {0};
++static int pipes[LENGTH(blocks)][2];
 +
  /* compile-time check if all tags fit into an unsigned int bit array. */
  struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
-
-@@ -440,9 +453,25 @@ buttonpress(XEvent *e)
+ 
+@@ -440,9 +462,26 @@ buttonpress(XEvent *e)
                        arg.ui = 1 << i;
                } else if (ev->x < x + blw)
                        click = ClkLtSymbol;
@@ -184,13 +201,14 @@ index a96f33c..6e79e5f 100644
                        click = ClkStatusText;
 -              else
 +                      int len, i;
-+              #ifdef INVERSED
++
++                      #if INVERSED
 +                      for (i = LENGTH(blocks) - 1; i >= 0; i--)
-+              #else
++                      #else
 +                      for (i = 0; i < LENGTH(blocks); i++)
-+              #endif /* INVERSED */
++                      #endif /* INVERSED */
 +                      {
-+                              if (*blockoutput[i] == '++                      
        if (*blockoutput[i] == ' +                                      
continue;
 +                              len = TEXTW(blockoutput[i]) - lrpad + 
TEXTW(delimiter) - lrpad;
 +                              x += len;
@@ -203,9 +221,9 @@ index a96f33c..6e79e5f 100644
                        click = ClkWinTitle;
        } else if ((c = wintoclient(ev->window))) {
                focus(c);
-@@ -706,11 +735,8 @@ drawbar(Monitor *m)
+@@ -706,11 +745,8 @@ drawbar(Monitor *m)
                return;
-
+ 
        /* draw status first so it can be overdrawn by tags later */
 -      if (m == selmon) { /* status is only drawn on selected monitor */
 -              drw_setscheme(drw, scheme[SchemeNorm]);
@@ -214,81 +232,91 @@ index a96f33c..6e79e5f 100644
 -      }
 +      if (m == selmon) /* status is only drawn on selected monitor */
 +              tw = getstatus(m->ww);
-
+ 
        for (c = m->clients; c; c = c->next) {
                occ |= c->tags;
-@@ -903,6 +929,81 @@ getstate(Window w)
+@@ -903,6 +939,106 @@ getstate(Window w)
        return result;
  }
-
-+static void
-+remove_all(char *str, char to_remove)
-+{
-+      char *read = str, *write = str;
-+      do {
-+              while (*read == to_remove) read++;
-+              *write++ = *read;
-+              read++;
-+      } while (*(read-1));
-+}
-+
+ 
 +void
-+getcmd(int i, char *output)
++getcmd(int i, char *button)
 +{
-+      FILE *cmdf = popen(blocks[i].command, "r");
-+      if (!cmdf)
++      if (!selmon->showbar)
 +              return;
 +
-+      /* keep trying while (even if) the interrupt error */
-+      char tmpstr[CMDLENGTH] = "", *s;
-+      int e;
-+      do {
-+              errno = 0;
-+              s = fgets(tmpstr, CMDLENGTH - (strlen(delimiter) + 1), cmdf);
-+              e = errno;
-+      } while (!s && e == EINTR);
++      if (execlock & 1 << i) { /* block is already running */
++              //fprintf(stderr, "dwm: ignoring block %d, command %s
", i, blocks[i].command);
++              return;
++      }
 +
-+      pclose(cmdf);
++      /* lock execution of block until current instance finishes execution */
++      execlock |= 1 << i;
 +
-+      strcpy(output, tmpstr);
-+      remove_all(output, '
');     /* chop off newline */
++      if (fork() == 0) {
++              if (dpy)
++                      close(ConnectionNumber(dpy));
++              dup2(pipes[i][1], STDOUT_FILENO);
++              close(pipes[i][0]);
++              close(pipes[i][1]);
++
++              if (button)
++                      setenv("BLOCK_BUTTON", button, 1);
++              execlp("/bin/sh", "sh", "-c", blocks[i].command, (char *) NULL);
++              fprintf(stderr, "dwm: block %d, execlp %s", i, 
blocks[i].command);
++              perror(" failed");
++              exit(EXIT_SUCCESS);
++      }
 +}
 +
 +void
-+getsigcmds(unsigned int signal)
++getcmds(int time)
 +{
 +      int i;
-+#ifdef INVERSED
-+      for (i = LENGTH(blocks) - 1; i >= 0; i--)
-+#else
 +      for (i = 0; i < LENGTH(blocks); i++)
-+#endif /* INVERSED */
-+      {
-+              if (blocks[i].signal == signal)
-+                      getcmd(i, blockoutput[i]);
-+      }
++              if ((blocks[i].interval != 0 && time % blocks[i].interval == 0) 
|| time == -1)
++                      getcmd(i, NULL);
++}
++
++void
++getsigcmds(int signal)
++{
++      int i;
++      unsigned int sig = signal - SIGRTMIN;
++      for (i = 0; i < LENGTH(blocks); i++)
++              if (blocks[i].signal == sig)
++                      getcmd(i, NULL);
 +}
 +
 +int
 +getstatus(int width)
 +{
 +      int i, len, all = width, delimlen = TEXTW(delimiter) - lrpad;
++      char fgcol[8];
++                              /* fg           bg */
++      const char *cols[8] =   { fgcol, colors[SchemeStatus][ColBg] };
++      //uncomment to inverse the colors
++      //const char *cols[8] =         { colors[SchemeStatus][ColBg], fgcol };
 +
-+      drw_setscheme(drw, scheme[SchemeNorm]); /* 're-set' the scheme */
-+#ifdef INVERSED
++      #if INVERSED
 +      for (i = 0; i < LENGTH(blocks); i++)
-+#else
++      #else
 +      for (i = LENGTH(blocks) - 1; i >= 0; i--)
-+#endif /* INVERSED */
++      #endif /* INVERSED */
 +      {
 +              if (*blockoutput[i] == ' +                      continue;
++              strncpy(fgcol, blocks[i].color, 8);
++              /* re-load the scheme with the new colors */
++              scheme[SchemeStatus] = drw_scm_create(drw, cols, 3);
++              drw_setscheme(drw, scheme[SchemeStatus]); /* 're-set' the 
scheme */
 +              len = TEXTW(blockoutput[i]) - lrpad;
 +              all -= len;
 +              drw_text(drw, all, 0, len, bh, 0, blockoutput[i], 0);
 +              /* draw delimiter */
-+              if (delimiter == '++            if (*delimiter == ' +           
        continue;
++              drw_setscheme(drw, scheme[SchemeNorm]);
 +              all -= delimlen;
 +              drw_text(drw, all, 0, delimlen, bh, 0, delimiter, 0);
 +      }
@@ -296,117 +324,208 @@ index a96f33c..6e79e5f 100644
 +      return stsw = width - all;
 +}
 +
- int
- gettextprop(Window w, Atom atom, char *text, unsigned int size)
- {
-@@ -1219,7 +1320,7 @@ propertynotify(XEvent *e)
-       Window trans;
-       XPropertyEvent *ev = &e->xproperty;
-
--      if ((ev->window == root) && (ev->atom == XA_WM_NAME))
-+      if ((ev->window == root) && ((ev->atom == XA_WM_NAME) || (ev->atom == 
dwmstatus)))
-               updatestatus();
-       else if (ev->state == PropertyDelete)
-               return; /* ignore */
-@@ -1427,6 +1528,19 @@ sendmon(Client *c, Monitor *m)
-       arrange(NULL);
- }
-
-+void
-+sendstatusbar(const Arg *arg)
++int
++gcd(int a, int b)
 +{
-+      if (fork() == 0) {
-+              char button[2] = { '0' + arg->i & 0xff, '-+             char 
shcmd[CMDLENGTH + 20];
-+              snprintf(shcmd, LENGTH(shcmd), "%s && kill -%d %d", 
blocks[blocknum].command, blocks[blocknum].signal + 34, getppid());
-+              setenv("BLOCK_BUTTON", button, 1);
-+              execlp("/bin/sh", "sh", "-c", shcmd, (char*)NULL);
-+              exit(EXIT_SUCCESS);
++      int temp;
++
++      while (b > 0) {
++              temp = a % b;
++              a = b;
++              b = temp;
 +      }
++
++      return a;
 +}
 +
++
+ int
+ gettextprop(Window w, Atom atom, char *text, unsigned int size)
+ {
+@@ -1376,12 +1512,99 @@ restack(Monitor *m)
  void
- setclientstate(Client *c, long state)
+ run(void)
  {
-@@ -1530,6 +1644,27 @@ setmfact(const Arg *arg)
-       arrange(selmon);
- }
-
-+void
-+sighandler(int signum)
-+{
-+      XEvent event;
++      int i;
+       XEvent ev;
++      struct pollfd fds[LENGTH(blocks) + 1] = {0};
 +
-+      getsigcmds(signum-SIGRTMIN);
++      fds[0].fd = ConnectionNumber(dpy);
++      fds[0].events = POLLIN;
 +
-+      /* send a custom Atom in PropertyNotify event to the root window */
-+      event.type = PropertyNotify;
-+      event.xproperty.atom = dwmstatus;
-+      event.xproperty.window = root;
-+      XSendEvent(dpy, root, False, PropertyNotify, &event);
-+      XFlush(dpy);
-+}
++      #if INVERSED
++      for (i = LENGTH(blocks) - 1; i >= 0; i--)
++      #else
++      for (i = 0; i < LENGTH(blocks); i++)
++      #endif /* INVERSED */
++      {
++              pipe(pipes[i]);
++              fds[i + 1].fd = pipes[i][0];
++              fds[i + 1].events = POLLIN;
++              getcmd(i, NULL);
++              if (blocks[i].interval) {
++                      maxinterval = MAX(blocks[i].interval, maxinterval);
++                      sleepinterval = gcd(blocks[i].interval, sleepinterval);
++              }
++      }
++
++      alarm(sleepinterval);
+       /* main event loop */
+       XSync(dpy, False);
+-      while (running && !XNextEvent(dpy, &ev))
+-              if (handler[ev.type])
+-                      handler[ev.type](&ev); /* call handler */
++      while (running) {
++
++              /* bar hidden, then skip poll */
++              if (!selmon->showbar) {
++                      XNextEvent(dpy, &ev);
++                      if (handler[ev.type])
++                              handler[ev.type](&ev); /* call handler */
++                      continue;
++              }
++
++              if ((poll(fds, LENGTH(blocks) + 1, -1)) == -1) {
++                      /* FIXME other than SIGALRM and the real time signals,
++                       * there seems to be a signal being que if using
++                       * 'xsetroot -name' sutff */
++                      if (errno == EINTR) /* signal caught */
++                              continue;
++                      fprintf(stderr, "dwm: poll ");
++                      perror("failed");
++                      exit(EXIT_FAILURE);
++              }
++
++              /* handle display fd */
++              if (fds[0].revents & POLLIN) {
++                      while (running && XPending(dpy)) {
++                              XNextEvent(dpy, &ev);
++                              if (handler[ev.type])
++                                      handler[ev.type](&ev); /* call handler 
*/
++                      }
++              } else if (fds[0].revents & POLLHUP) {
++                      fprintf(stderr, "dwm: main event loop, hang up");
++                      perror(" failed");
++                      exit(EXIT_FAILURE);
++              }
++
++              /* handle blocks */
++              for (i = 0; i < LENGTH(blocks); i++) {
++                      if (fds[i + 1].revents & POLLIN) {
++                              /* empty buffer with CMDLENGTH + 1 byte for the 
null terminator */
++                              int bt = read(fds[i + 1].fd, blockoutput[i], 
CMDLENGTH);
++                              /* remove lock for the current block */
++                              execlock &= ~(1 << i);
++
++                              if (bt == -1) { /* if read failed */
++                                      fprintf(stderr, "dwm: read failed in 
block %s
", blocks[i].command);
++                                      perror(" failed");
++                                      continue;
++                              }
 +
++                              if (blockoutput[i][bt - 1] == '
') /* chop off ending new line, if one is present */
++                                      blockoutput[i][bt - 1] = '++            
                else /* NULL terminate the string */
++                                      blockoutput[i][bt++] = '++
++                              drawbar(selmon);
++                      } else if (fds[i + 1].revents & POLLHUP) {
++                              fprintf(stderr, "dwm: block %d hangup", i);
++                              perror(" failed");
++                              exit(EXIT_FAILURE);
++                      }
++              }
++      }
++
++      /* close the pipes after running */
++      for (i = 0; i < LENGTH(blocks); i++) {
++              close(pipes[i][0]);
++              close(pipes[i][1]);
++      }
+ }
+ 
+ void
+@@ -1427,6 +1650,13 @@ sendmon(Client *c, Monitor *m)
+       arrange(NULL);
+ }
+ 
 +void
-+dummysighandler(int unused)
++sendstatusbar(const Arg *arg)
 +{
-+      return;
++      char button[2] = { '0' + arg->i & 0xff, '++     getcmd(blocknum, 
button);
 +}
 +
  void
- setup(void)
+ setclientstate(Client *c, long state)
  {
-@@ -1540,6 +1675,27 @@ setup(void)
-       /* clean up any zombies immediately */
-       sigchld(0);
-
-+      /* ignore all real time signals */
-+      for (i = SIGRTMIN; i <= SIGRTMAX; i++)
-+              signal(i, dummysighandler);
+@@ -1537,8 +1767,20 @@ setup(void)
+       XSetWindowAttributes wa;
+       Atom utf8string;
+ 
+-      /* clean up any zombies immediately */
+-      sigchld(0);
++      setsignal(SIGCHLD, sigchld); /* zombies */
++      setsignal(SIGALRM, sigalrm); /* timer */
 +
-+      /* init blocks */
-+#ifdef INVERSED
-+      for (i = LENGTH(blocks) - 1; i >= 0; i--)
-+#else
++      #ifdef __linux__
++      /* handle defined real time signals (linux only) */
 +      for (i = 0; i < LENGTH(blocks); i++)
-+#endif /* INVERSED */
-+      {
-+              if (blocks[i].signal) /* init signals */
-+                      signal(SIGRTMIN+blocks[i].signal, sighandler);
-+              getcmd(i, blockoutput[i]);
-+      }
++              if (blocks[i].signal)
++                      setsignal(SIGRTMIN + blocks[i].signal, getsigcmds);
++      #endif /* __linux__ */
 +
 +      /* pid as an enviromental variable */
 +      char envpid[16];
 +      snprintf(envpid, LENGTH(envpid), "%d", getpid());
 +      setenv("STATUSBAR", envpid, 1);
-+
+ 
        /* init screen */
        screen = DefaultScreen(dpy);
-       sw = DisplayWidth(dpy, screen);
-@@ -1552,6 +1708,7 @@ setup(void)
-       bh = drw->fonts->h + 2;
-       updategeom();
-       /* init atoms */
-+      dwmstatus = XInternAtom(dpy, "UPDATE_DWM_STATUSBAR", False);
-       utf8string = XInternAtom(dpy, "UTF8_STRING", False);
-       wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
-       wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-@@ -1839,6 +1996,13 @@ updatebarpos(Monitor *m)
-               m->by = -bh;
+@@ -1600,6 +1842,21 @@ setup(void)
+       focus(NULL);
  }
-
+ 
++void
++setsignal(int sig, void (*handler)(int unused))
++{
++      struct sigaction sa;
++
++      sa.sa_handler = handler;
++      sigemptyset(&sa.sa_mask);
++      sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
++
++      if (sigaction(sig, &sa, 0) == -1) {
++              fprintf(stderr, "signal %d ", sig);
++              perror("failed to setup");
++              exit(EXIT_FAILURE);
++      }
++}
+ 
+ void
+ seturgent(Client *c, int urg)
+@@ -1632,11 +1889,18 @@ showhide(Client *c)
+       }
+ }
+ 
++
 +void
-+updateblock(const Arg *arg)
++sigalrm(int unused)
 +{
-+      getsigcmds(arg->ui);
-+      updatestatus();
++      getcmds(count);
++      alarm(sleepinterval);
++      count = (count + sleepinterval - 1) % maxinterval + 1;
 +}
 +
  void
- updateclientlist()
+ sigchld(int unused)
  {
-@@ -1993,8 +2157,6 @@ updatesizehints(Client *c)
+-      if (signal(SIGCHLD, sigchld) == SIG_ERR)
+-              die("can't install SIGCHLD handler:");
+       while (0 < waitpid(-1, NULL, WNOHANG));
+ }
+ 
+@@ -1993,8 +2257,6 @@ updatesizehints(Client *c)
  void
  updatestatus(void)
  {
@@ -414,7 +533,7 @@ index a96f33c..6e79e5f 100644
 -              strcpy(stext, "dwm-"VERSION);
        drawbar(selmon);
  }
-
---
-2.35.1
+ 
+-- 
+2.36.1
 
diff --git a/dwm.suckless.org/patches/integrated-status-text/index.md 
b/dwm.suckless.org/patches/integrated-status-text/index.md
index c2c71a8f..3d035567 100644
--- a/dwm.suckless.org/patches/integrated-status-text/index.md
+++ b/dwm.suckless.org/patches/integrated-status-text/index.md
@@ -3,26 +3,40 @@ integrated status text
 
 Description
 -----------
-Allows dwm to handle the text by itself This is a dwmblocks integration into
-dwm itself. You can update the blocks only with signals of with mouseclicks.
-The 'interval' value does nothing and is meant to be there to 're-use' on
-future patches. You can checkout my build with more features like 'async'
-updates
-[https://codeberg.org/explosion-mental/Dwm](https://codeberg.org/explosion-mental/Dwm),
-which is were I'm extracting this patch, if you want a much better experience.
-
-What you need to know:
-- This patch makes dwm sets a enviromental variable with the PID of itself to
-  be more 'friendly'. With this you can do `kill -35 $STATUSBAR`, which updates
-  block with signal 1 (34 + signal of the block)
-- Other way to update a block is inside dwm itself, with the `updateblock`
-  function. It accepts an unsigned int (non negative) number which value
-  indicates the signal of the block you want to update.
-- Mouse clicks are handled with `sendstatusbar` (a mouse function only!) which
-  accepts the value that you want to pass to the block command as a 'variable'
-  called `BLOCK_BUTTON`, which should be handled in the script (block command)
-- Since this uses real time signals to handle the updates, shouldn't work in
-  openbsd, but I could be wrong.
+Allows dwm to handle the text by itself. You can
+ think of it like a dwmblocks integration into dwm itself. This is extracted
+ from my dwm build[0] in which you can find even more information.
+
+Example:
+```
+/* fg         command             interval  signal */
+{ "#000000",  "echo 'dwm block!",   10,       3},
+```
+
+- fg: the foreground color of the individual block, for the background it uses
+  the bg of SchemeStatus. You can swap behaviour uncommenting a comment in
+  dwm.c (search for 'uncomment to inverse the colors')
+
+- command: it uses the output of the commands for the status text interval: in
+  seconds, how much does it have to pass before updating the block.
+
+- interval: in seconds, how many seconds until the block it's updated
+
+- signal: have to be less than 30. This lets you update the block with `kill`
+  by adding 35 to this value.
+  For the block above it would be 34 + 3 = 37 -> `kill -37 $(pidof dwm)`.
+  These signals are linux dependant.
+
+You can change `$(pidof dwm)` with `$STATUSBAR` to 'fix' signaling multiple
+instances of dwm, since this patch also wraps the PID of dwm into the
+`$STATUSBAR` enviromental variable.
+
+Last thing, mouse actions. For this you need to handle the env variable
+`$BLOCK_BUTTON` in a script, this is so you can easily reuse the scripts used
+in dwmblocks. And remember that mouse actions update the block.
+
+[0] https://github.com/explosion-mental/Dwm or
+https://codeberg.org/explosion-mental/Dwm
 
 Download
 --------


Reply via email to