-
-
Save danbyl/54f7c1d57fc6507242a95b71c3d8fdea to your computer and use it in GitHub Desktop.
dwm and dwmblocks patch for clickable bar - https://dwm.suckless.org/patches/statuscmd/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/config.def.h b/config.def.h | |
index 1c0b587..b67825e 100644 | |
--- a/config.def.h | |
+++ b/config.def.h | |
@@ -103,7 +103,9 @@ static Button buttons[] = { | |
{ ClkLtSymbol, 0, Button1, setlayout, {0} }, | |
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, | |
{ ClkWinTitle, 0, Button2, zoom, {0} }, | |
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, | |
+ { ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1} }, | |
+ { ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2} }, | |
+ { ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3} }, | |
{ ClkClientWin, MODKEY, Button1, movemouse, {0} }, | |
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} }, | |
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} }, | |
diff --git a/dwm.c b/dwm.c | |
index 4465af1..c600131 100644 | |
--- a/dwm.c | |
+++ b/dwm.c | |
@@ -156,6 +156,7 @@ static void clientmessage(XEvent *e); | |
static void configure(Client *c); | |
static void configurenotify(XEvent *e); | |
static void configurerequest(XEvent *e); | |
+static void copyvalidchars(char *text, char *rawtext); | |
static Monitor *createmon(void); | |
static void destroynotify(XEvent *e); | |
static void detach(Client *c); | |
@@ -169,6 +170,7 @@ static void focus(Client *c); | |
static void focusin(XEvent *e); | |
static void focusmon(const Arg *arg); | |
static void focusstack(const Arg *arg); | |
+static int getdwmblockspid(); | |
static int getrootptr(int *x, int *y); | |
static long getstate(Window w); | |
static int gettextprop(Window w, Atom atom, char *text, unsigned int size); | |
@@ -205,6 +207,7 @@ static void setup(void); | |
static void seturgent(Client *c, int urg); | |
static void showhide(Client *c); | |
static void sigchld(int unused); | |
+static void sigdwmblocks(const Arg *arg); | |
static void spawn(const Arg *arg); | |
static void tag(const Arg *arg); | |
static void tagmon(const Arg *arg); | |
@@ -237,6 +240,9 @@ static void zoom(const Arg *arg); | |
/* variables */ | |
static const char broken[] = "broken"; | |
static char stext[256]; | |
+static char rawstext[256]; | |
+static int dwmblockssig; | |
+pid_t dwmblockspid = 0; | |
static int screen; | |
static int sw, sh; /* X display screen geometry width, height */ | |
static int bh, blw = 0; /* bar geometry */ | |
@@ -439,9 +445,26 @@ buttonpress(XEvent *e) | |
arg.ui = 1 << i; | |
} else if (ev->x < x + blw) | |
click = ClkLtSymbol; | |
- else if (ev->x > selmon->ww - TEXTW(stext)) | |
+ else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) { | |
click = ClkStatusText; | |
- else | |
+ | |
+ char *text = rawstext; | |
+ int i = -1; | |
+ char ch; | |
+ dwmblockssig = 0; | |
+ while (text[++i]) { | |
+ if ((unsigned char)text[i] < ' ') { | |
+ ch = text[i]; | |
+ text[i] = '\0'; | |
+ x += TEXTW(text) - lrpad; | |
+ text[i] = ch; | |
+ text += i+1; | |
+ i = -1; | |
+ if (x >= ev->x) break; | |
+ dwmblockssig = ch; | |
+ } | |
+ } | |
+ } else | |
click = ClkWinTitle; | |
} else if ((c = wintoclient(ev->window))) { | |
focus(c); | |
@@ -627,6 +650,19 @@ configurerequest(XEvent *e) | |
XSync(dpy, False); | |
} | |
+void | |
+copyvalidchars(char *text, char *rawtext) | |
+{ | |
+ int i = -1, j = 0; | |
+ | |
+ while(rawtext[++i]) { | |
+ if ((unsigned char)rawtext[i] >= ' ') { | |
+ text[j++] = rawtext[i]; | |
+ } | |
+ } | |
+ text[j] = '\0'; | |
+} | |
+ | |
Monitor * | |
createmon(void) | |
{ | |
@@ -871,6 +907,18 @@ getatomprop(Client *c, Atom prop) | |
return atom; | |
} | |
+int | |
+getdwmblockspid() | |
+{ | |
+ char buf[16]; | |
+ FILE *fp = popen("pidof -s dwmblocks", "r"); | |
+ fgets(buf, sizeof(buf), fp); | |
+ pid_t pid = strtoul(buf, NULL, 10); | |
+ pclose(fp); | |
+ dwmblockspid = pid; | |
+ return pid != 0 ? 0 : -1; | |
+} | |
+ | |
int | |
getrootptr(int *x, int *y) | |
{ | |
@@ -1636,6 +1684,23 @@ sigchld(int unused) | |
while (0 < waitpid(-1, NULL, WNOHANG)); | |
} | |
+void | |
+sigdwmblocks(const Arg *arg) | |
+{ | |
+ union sigval sv; | |
+ sv.sival_int = (dwmblockssig << 8) | arg->i; | |
+ if (!dwmblockspid) | |
+ if (getdwmblockspid() == -1) | |
+ return; | |
+ | |
+ if (sigqueue(dwmblockspid, SIGUSR1, sv) == -1) { | |
+ if (errno == ESRCH) { | |
+ if (!getdwmblockspid()) | |
+ sigqueue(dwmblockspid, SIGUSR1, sv); | |
+ } | |
+ } | |
+} | |
+ | |
void | |
spawn(const Arg *arg) | |
{ | |
@@ -1987,8 +2052,10 @@ updatesizehints(Client *c) | |
void | |
updatestatus(void) | |
{ | |
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) | |
+ if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext))) | |
strcpy(stext, "dwm-"VERSION); | |
+ else | |
+ copyvalidchars(stext, rawstext); | |
drawbar(selmon); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/dwmblocks.c b/dwmblocks.c | |
index 2f3b774..ba7dbb5 100644 | |
--- a/dwmblocks.c | |
+++ b/dwmblocks.c | |
@@ -14,6 +14,7 @@ typedef struct { | |
unsigned int signal; | |
} Block; | |
void sighandler(int num); | |
+void buttonhandler(int sig, siginfo_t *si, void *ucontext); | |
void getcmds(int time); | |
#ifndef __OpenBSD__ | |
void getsigcmds(int signal); | |
@@ -33,15 +34,32 @@ static int screen; | |
static Window root; | |
static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0}; | |
static char statusstr[2][256]; | |
+static char button[] = "\0"; | |
static int statusContinue = 1; | |
static void (*writestatus) () = setroot; | |
//opens process *cmd and stores output in *output | |
void getcmd(const Block *block, char *output) | |
{ | |
+ if (block->signal) | |
+ { | |
+ output[0] = block->signal; | |
+ output++; | |
+ } | |
strcpy(output, block->icon); | |
char *cmd = block->command; | |
- FILE *cmdf = popen(cmd,"r"); | |
+ FILE *cmdf; | |
+ if (*button) | |
+ { | |
+ setenv("BUTTON", button, 1); | |
+ cmdf = popen(cmd,"r"); | |
+ *button = '\0'; | |
+ unsetenv("BUTTON"); | |
+ } | |
+ else | |
+ { | |
+ cmdf = popen(cmd,"r"); | |
+ } | |
if (!cmdf) | |
return; | |
char c; | |
@@ -79,12 +97,18 @@ void getsigcmds(int signal) | |
void setupsignals() | |
{ | |
+ struct sigaction sa; | |
for(int i = 0; i < LENGTH(blocks); i++) | |
{ | |
if (blocks[i].signal > 0) | |
+ { | |
signal(SIGRTMIN+blocks[i].signal, sighandler); | |
+ sigaddset(&sa.sa_mask, SIGRTMIN+blocks[i].signal); // ignore signal when handling SIGUSR1 | |
+ } | |
} | |
- | |
+ sa.sa_sigaction = buttonhandler; | |
+ sa.sa_flags = SA_SIGINFO; | |
+ sigaction(SIGUSR1, &sa, NULL); | |
} | |
#endif | |
@@ -143,6 +167,13 @@ void sighandler(int signum) | |
getsigcmds(signum-SIGRTMIN); | |
writestatus(); | |
} | |
+ | |
+void buttonhandler(int sig, siginfo_t *si, void *ucontext) | |
+{ | |
+ *button = '0' + si->si_value.sival_int & 0xff; | |
+ getsigcmds(si->si_value.sival_int >> 8); | |
+ writestatus(); | |
+} | |
#endif | |
void termhandler(int signum) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment