sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dwm-statuscmd-20260124-a9aa0d8.diff (6917B)


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