sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | 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