dwm-statuscmd-20241009-8933ebc.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dwm-statuscmd-20241009-8933ebc.diff (6623B)
       ---
            1 From ca2a2e6386a746ebfc3480787e5d99da11e7abee Mon Sep 17 00:00:00 2001
            2 From: Justinas Grigas <dev@jstnas.com>
            3 Date: Wed, 9 Oct 2024 01:00:20 +0100
            4 Subject: [PATCH] [dwm][statuscmd] better click regions
            5 
            6 The main improvement of this patch over the previous version 20210405 is that
            7 the click region now ends on a matching signal raw byte.
            8 
            9 The matching byte is optional, and without it dwm will behave as before.
           10 
           11 To take advantage of this feature, scripts need to be modified to print the raw
           12 byte at the end as well.
           13 
           14 In addition, this patch cleanly applies onto master branch.
           15 ---
           16  config.def.h |   6 ++-
           17  dwm.c        | 104 ++++++++++++++++++++++++++++++++++++++++++++++++---
           18  2 files changed, 104 insertions(+), 6 deletions(-)
           19 
           20 diff --git a/config.def.h b/config.def.h
           21 index 9efa774..d008275 100644
           22 --- a/config.def.h
           23 +++ b/config.def.h
           24 @@ -55,6 +55,8 @@ static const Layout layouts[] = {
           25  /* helper for spawning shell commands in the pre dwm-5.0 fashion */
           26  #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
           27  
           28 +#define STATUSBAR "dwmblocks"
           29 +
           30  /* commands */
           31  static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
           32  static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
           33 @@ -104,7 +106,9 @@ static const Button buttons[] = {
           34          { ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
           35          { ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &layouts[2]} },
           36          { ClkWinTitle,          0,              Button2,        zoom,           {0} },
           37 -        { ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
           38 +        { ClkStatusText,        0,              Button1,        sigstatusbar,   {.i = 1} },
           39 +        { ClkStatusText,        0,              Button2,        sigstatusbar,   {.i = 2} },
           40 +        { ClkStatusText,        0,              Button3,        sigstatusbar,   {.i = 3} },
           41          { ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
           42          { ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} },
           43          { ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} },
           44 diff --git a/dwm.c b/dwm.c
           45 index 1443802..94ee0c7 100644
           46 --- a/dwm.c
           47 +++ b/dwm.c
           48 @@ -171,6 +171,7 @@ static void focusstack(const Arg *arg);
           49  static Atom getatomprop(Client *c, Atom prop);
           50  static int getrootptr(int *x, int *y);
           51  static long getstate(Window w);
           52 +static pid_t getstatusbarpid();
           53  static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
           54  static void grabbuttons(Client *c, int focused);
           55  static void grabkeys(void);
           56 @@ -204,6 +205,7 @@ static void setmfact(const Arg *arg);
           57  static void setup(void);
           58  static void seturgent(Client *c, int urg);
           59  static void showhide(Client *c);
           60 +static void sigstatusbar(const Arg *arg);
           61  static void spawn(const Arg *arg);
           62  static void tag(const Arg *arg);
           63  static void tagmon(const Arg *arg);
           64 @@ -236,6 +238,9 @@ static void zoom(const Arg *arg);
           65  /* variables */
           66  static const char broken[] = "broken";
           67  static char stext[256];
           68 +static int statusw;
           69 +static int statussig;
           70 +static pid_t statuspid = -1;
           71  static int screen;
           72  static int sw, sh;           /* X display screen geometry width, height */
           73  static int bh;               /* bar height */
           74 @@ -422,6 +427,7 @@ buttonpress(XEvent *e)
           75          Client *c;
           76          Monitor *m;
           77          XButtonPressedEvent *ev = &e->xbutton;
           78 +        char *text, *s, ch;
           79  
           80          click = ClkRootWin;
           81          /* focus monitor if necessary */
           82 @@ -440,9 +446,27 @@ buttonpress(XEvent *e)
           83                          arg.ui = 1 << i;
           84                  } else if (ev->x < x + TEXTW(selmon->ltsymbol))
           85                          click = ClkLtSymbol;
           86 -                else if (ev->x > selmon->ww - (int)TEXTW(stext))
           87 +                else if (ev->x > selmon->ww - statusw) {
           88 +                        x = selmon->ww - statusw;
           89                          click = ClkStatusText;
           90 -                else
           91 +                        statussig = 0;
           92 +                        for (text = s = stext; *s && x <= ev->x; s++) {
           93 +                                if ((unsigned char)(*s) < ' ') {
           94 +                                        ch = *s;
           95 +                                        *s = '\0';
           96 +                                        x += TEXTW(text) - lrpad;
           97 +                                        *s = ch;
           98 +                                        text = s + 1;
           99 +                                        if (x >= ev->x)
          100 +                                                break;
          101 +                                        /* reset on matching signal raw byte */
          102 +                                        if (ch == statussig)
          103 +                                                statussig = 0;
          104 +                                        else
          105 +                                                statussig = ch;
          106 +                                }
          107 +                        }
          108 +                } else
          109                          click = ClkWinTitle;
          110          } else if ((c = wintoclient(ev->window))) {
          111                  focus(c);
          112 @@ -708,9 +732,24 @@ drawbar(Monitor *m)
          113  
          114          /* draw status first so it can be overdrawn by tags later */
          115          if (m == selmon) { /* status is only drawn on selected monitor */
          116 +                char *text, *s, ch;
          117                  drw_setscheme(drw, scheme[SchemeNorm]);
          118 -                tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
          119 -                drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
          120 +
          121 +                x = 0;
          122 +                for (text = s = stext; *s; s++) {
          123 +                        if ((unsigned char)(*s) < ' ') {
          124 +                                ch = *s;
          125 +                                *s = '\0';
          126 +                                tw = TEXTW(text) - lrpad;
          127 +                                drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0);
          128 +                                x += tw;
          129 +                                *s = ch;
          130 +                                text = s + 1;
          131 +                        }
          132 +                }
          133 +                tw = TEXTW(text) - lrpad + 2;
          134 +                drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0);
          135 +                tw = statusw;
          136          }
          137  
          138          for (c = m->clients; c; c = c->next) {
          139 @@ -876,6 +915,30 @@ getatomprop(Client *c, Atom prop)
          140          return atom;
          141  }
          142  
          143 +pid_t
          144 +getstatusbarpid()
          145 +{
          146 +        char buf[32], *str = buf, *c;
          147 +        FILE *fp;
          148 +
          149 +        if (statuspid > 0) {
          150 +                snprintf(buf, sizeof(buf), "/proc/%u/cmdline", statuspid);
          151 +                if ((fp = fopen(buf, "r"))) {
          152 +                        fgets(buf, sizeof(buf), fp);
          153 +                        while ((c = strchr(str, '/')))
          154 +                                str = c + 1;
          155 +                        fclose(fp);
          156 +                        if (!strcmp(str, STATUSBAR))
          157 +                                return statuspid;
          158 +                }
          159 +        }
          160 +        if (!(fp = popen("pidof -s "STATUSBAR, "r")))
          161 +                return -1;
          162 +        fgets(buf, sizeof(buf), fp);
          163 +        pclose(fp);
          164 +        return strtol(buf, NULL, 10);
          165 +}
          166 +
          167  int
          168  getrootptr(int *x, int *y)
          169  {
          170 @@ -1643,6 +1706,20 @@ showhide(Client *c)
          171          }
          172  }
          173  
          174 +void
          175 +sigstatusbar(const Arg *arg)
          176 +{
          177 +        union sigval sv;
          178 +
          179 +        if (!statussig)
          180 +                return;
          181 +        sv.sival_int = arg->i;
          182 +        if ((statuspid = getstatusbarpid()) <= 0)
          183 +                return;
          184 +
          185 +        sigqueue(statuspid, SIGRTMIN+statussig, sv);
          186 +}
          187 +
          188  void
          189  spawn(const Arg *arg)
          190  {
          191 @@ -2004,8 +2081,25 @@ updatesizehints(Client *c)
          192  void
          193  updatestatus(void)
          194  {
          195 -        if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
          196 +        if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) {
          197                  strcpy(stext, "dwm-"VERSION);
          198 +                statusw = TEXTW(stext) - lrpad + 2;
          199 +        } else {
          200 +                char *text, *s, ch;
          201 +
          202 +                statusw  = 0;
          203 +                for (text = s = stext; *s; s++) {
          204 +                        if ((unsigned char)(*s) < ' ') {
          205 +                                ch = *s;
          206 +                                *s = '\0';
          207 +                                statusw += TEXTW(text) - lrpad;
          208 +                                *s = ch;
          209 +                                text = s + 1;
          210 +                        }
          211 +                }
          212 +                statusw += TEXTW(text) - lrpad + 2;
          213 +
          214 +        }
          215          drawbar(selmon);
          216  }
          217  
          218 -- 
          219 2.46.2
          220