sites

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

dwm-statuscmd-20210402-67d76bd.diff (6197B)


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