commit 16019480fe6123e0d57d9a4b3ec7d6dd293beaf9
Author: explosion-mental <[email protected]>
Date:   Sun Feb 27 17:32:54 2022 -0500

    [dwm][patch] integrated status text

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
new file mode 100644
index 00000000..f2a9278b
--- /dev/null
+++ 
b/dwm.suckless.org/patches/integrated-status-text/dwm-integrated-status-text-6.3.diff
@@ -0,0 +1,420 @@
+From f3a9dd0222319d72303be37ae5268831582fe487 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.
+
+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.
+---
+ config.def.h |  53 +++++++++++++++
+ dwm.c        | 186 +++++++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 227 insertions(+), 12 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index a2ac963..99d6b3d 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -18,6 +18,49 @@ static const char *colors[][3]      = {
+       [SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
+ };
+
++/* 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},
++};
++
++/* inverse the order of the blocks, comment to disable */
++#define INVERSED
++/* delimeter between blocks commands. NULL character ('++static char 
delimiter[] = " ";
++/* max number of character that one block command can output */
++#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 */
++      { ClkStatusText,        0,              Button1,        sendstatusbar,  
 {.i = 1 } },
++      { ClkStatusText,        0,              Button2,        sendstatusbar,  
 {.i = 2 } },
++      { ClkStatusText,        0,              Button3,        sendstatusbar,  
 {.i = 3 } },
++      { ClkStatusText,        0,              Button4,        sendstatusbar,  
 {.i = 4 } },
++      { 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} },
+diff --git a/dwm.c b/dwm.c
+index a96f33c..6e79e5f 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -141,6 +141,12 @@ typedef struct {
+       int monitor;
+ } Rule;
+
++typedef struct {
++      const char *command;
++      const unsigned int interval;
++      const unsigned int signal;
++} Block;
++
+ /* 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);
+ 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 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);
+ static void scan(void);
+ static int sendevent(Client *c, Atom proto);
+ static void sendmon(Client *c, Monitor *m);
++static void sendstatusbar(const Arg *arg);
+ 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);
+
+ /* 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;
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+
++static char blockoutput[LENGTH(blocks)][CMDLENGTH] = {0};
++
+ /* 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)
+                       arg.ui = 1 << i;
+               } else if (ev->x < x + blw)
+                       click = ClkLtSymbol;
+-              else if (ev->x > selmon->ww - (int)TEXTW(stext))
++              else if (ev->x > (x = selmon->ww - stsw)) {
+                       click = ClkStatusText;
+-              else
++                      int len, i;
++              #ifdef INVERSED
++                      for (i = LENGTH(blocks) - 1; i >= 0; i--)
++              #else
++                      for (i = 0; i < LENGTH(blocks); i++)
++              #endif /* INVERSED */
++                      {
++                              if (*blockoutput[i] == '++                      
                continue;
++                              len = TEXTW(blockoutput[i]) - lrpad + 
TEXTW(delimiter) - lrpad;
++                              x += len;
++                              if (ev->x <= x && ev->x >= x - len) { /* if the 
mouse is between the block area */
++                                      blocknum = i; /* store what block the 
mouse is clicking */
++                                      break;
++                              }
++                      }
++              } else
+                       click = ClkWinTitle;
+       } else if ((c = wintoclient(ev->window))) {
+               focus(c);
+@@ -706,11 +735,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]);
+-              tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+-              drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+-      }
++      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)
+       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)
++{
++      FILE *cmdf = popen(blocks[i].command, "r");
++      if (!cmdf)
++              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);
++
++      pclose(cmdf);
++
++      strcpy(output, tmpstr);
++      remove_all(output, '
');     /* chop off newline */
++}
++
++void
++getsigcmds(unsigned int signal)
++{
++      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]);
++      }
++}
++
++int
++getstatus(int width)
++{
++      int i, len, all = width, delimlen = TEXTW(delimiter) - lrpad;
++
++      drw_setscheme(drw, scheme[SchemeNorm]); /* 're-set' the scheme */
++#ifdef INVERSED
++      for (i = 0; i < LENGTH(blocks); i++)
++#else
++      for (i = LENGTH(blocks) - 1; i >= 0; i--)
++#endif /* INVERSED */
++      {
++              if (*blockoutput[i] == '++                      continue;
++              len = TEXTW(blockoutput[i]) - lrpad;
++              all -= len;
++              drw_text(drw, all, 0, len, bh, 0, blockoutput[i], 0);
++              /* draw delimiter */
++              if (delimiter == '++                    continue;
++              all -= delimlen;
++              drw_text(drw, all, 0, delimlen, bh, 0, delimiter, 0);
++      }
++
++      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)
++{
++      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);
++      }
++}
++
+ void
+ setclientstate(Client *c, long state)
+ {
+@@ -1530,6 +1644,27 @@ setmfact(const Arg *arg)
+       arrange(selmon);
+ }
+
++void
++sighandler(int signum)
++{
++      XEvent event;
++
++      getsigcmds(signum-SIGRTMIN);
++
++      /* 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);
++}
++
++void
++dummysighandler(int unused)
++{
++      return;
++}
++
+ void
+ setup(void)
+ {
+@@ -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);
++
++      /* init blocks */
++#ifdef INVERSED
++      for (i = LENGTH(blocks) - 1; i >= 0; i--)
++#else
++      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]);
++      }
++
++      /* 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;
+ }
+
++void
++updateblock(const Arg *arg)
++{
++      getsigcmds(arg->ui);
++      updatestatus();
++}
++
+ void
+ updateclientlist()
+ {
+@@ -1993,8 +2157,6 @@ updatesizehints(Client *c)
+ void
+ updatestatus(void)
+ {
+-      if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
+-              strcpy(stext, "dwm-"VERSION);
+       drawbar(selmon);
+ }
+
+--
+2.35.1
+
diff --git a/dwm.suckless.org/patches/integrated-status-text/index.md 
b/dwm.suckless.org/patches/integrated-status-text/index.md
new file mode 100644
index 00000000..bb07ee43
--- /dev/null
+++ b/dwm.suckless.org/patches/integrated-status-text/index.md
@@ -0,0 +1,35 @@
+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://github.com/explosion-mental/Dwm, which is were I'm extracting
+this patch.
+
+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.
+
+Download
+--------
+* [dwm-integrated-status-text-6.3.diff](dwm-integrated-status-text-6.3.diff)
+* [github 
mirror](https://github.com/explosion-mental/Dwm/blob/main/Patches/dwm-integrated-status-text-6.3.diff)
+
+Authors
+-------
+* explosion-mental - <[email protected]>


Reply via email to