statuscmd patch for clickable modules

This commit is contained in:
Luke Smith 2020-04-13 00:14:56 -04:00
commit 730022acdf
No known key found for this signature in database
GPG key ID: 4C50B54A911F6252
4 changed files with 185 additions and 35 deletions

View file

@ -10,3 +10,9 @@ I do this to avoid redundancy in LARBS, both i3 and dwm use the same statusbar s
# signalling changes
For example, the audio module has the update signal 10 by default.
Thus, running `pkill -RTMIN+10 dwmblocks` will update it.
# clickable modules
Like i3blocks, this build allows you to build in additional actions into your scripts in response to click events.
See the above linked scripts for examples of this using the `$BLOCK_BUTTON` variable.
For this feature to work, you need the appropriate patch in dwm as well. See [here](https://gist.github.com/danbyl/54f7c1d57fc6507242a95b71c3d8fdea).
Credit for those patches goes to Daniel Bylinka (daniel.bylinka@gmail.com).

View file

@ -7,13 +7,16 @@ static const Block blocks[] = {
/* {"", "crypto", 0, 13}, */
{"", "torrent", 20, 7},
{"", "news", 0, 6},
/* {"", "memory", 10, 14}, */
/* {"", "cpu", 10, 13}, */
/* {"", "moonphase", 18000, 5}, */
{"", "weather", 18000, 5},
{"", "mailbox", 180, 12},
{"", "volume", 1, 0},
{"", "battery | tr \'\n\' \' \'", 5, 0},
{"", "clock", 60, 0},
{"", "volume", 1, 10},
{"", "battery | tr \'\n\' \' \'", 5, 3},
{"", "clock", 60, 1},
{"", "internet", 5, 4},
{"", "help", 0, 15},
};
//sets delimeter between status commands. NULL character ('\0') means no delimeter.

View file

@ -5,6 +5,7 @@
#include<signal.h>
#include<X11/Xlib.h>
#define LENGTH(X) (sizeof(X) / sizeof (X[0]))
#define CMDLENGTH 50
typedef struct {
char* icon;
@ -13,15 +14,17 @@ typedef struct {
unsigned int signal;
} Block;
void sighandler(int num);
void buttonhandler(int sig, siginfo_t *si, void *ucontext);
void replace(char *str, char old, char new);
void getcmds(int time);
#ifndef __OpenBSD__
void getsigcmds(int signal);
void setupsignals();
void getstatus(char *str);
void sighandler(int signum);
#endif
int getstatus(char *str, char *last);
void setroot();
void statusloop();
void statusinit();
void sighandler(int signum);
void termhandler(int signum);
@ -30,10 +33,13 @@ void termhandler(int signum);
static Display *dpy;
static int screen;
static Window root;
static char statusbar[LENGTH(blocks)][50] = {0};
static char statusstr[256];
static char *statuscat;
static int statusContinue=1;
static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
static char statusstr[2][256];
static char exportstring[CMDLENGTH + 22] = "export BLOCK_BUTTON=-;";
static int button = 0;
static int statusContinue = 1;
static void (*writestatus) () = setroot;
void replace(char *str, char old, char new)
{
int N = strlen(str);
@ -45,17 +51,34 @@ void replace(char *str, char old, char new)
//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");
char* cmd;
FILE *cmdf;
if (button)
{
cmd = strcat(exportstring, block->command);
cmd[20] = '0' + button;
button = 0;
cmdf = popen(cmd,"r");
cmd[22] = '\0';
}
else
{
cmd = block->command;
cmdf = popen(cmd,"r");
}
if (!cmdf)
return;
//int N = strlen(output);
char c;
int i = strlen(block->icon);
while((c = fgetc(cmdf)) != EOF)
output[i++] = c;
if (delim != '\0' && --i)
fgets(output+i, CMDLENGTH-i, cmdf);
i = strlen(output);
if (delim != '\0' && i)
output[i++] = delim;
output[i++] = '\0';
pclose(cmdf);
@ -72,6 +95,7 @@ void getcmds(int time)
}
}
#ifndef __OpenBSD__
void getsigcmds(int signal)
{
const Block *current;
@ -85,65 +109,87 @@ 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);
}
}
sa.sa_sigaction = buttonhandler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1, &sa, NULL);
}
#endif
void getstatus(char *str)
int getstatus(char *str, char *last)
{
int j = 0;
for(int i = 0; i < LENGTH(blocks); j+=strlen(statusbar[i++]))
{
strcpy(str + j, statusbar[i]);
}
str[--j] = '\0';
strcpy(last, str);
str[0] = '\0';
for(int i = 0; i < LENGTH(blocks); i++)
strcat(str, statusbar[i]);
str[strlen(str)-1] = '\0';
return strcmp(str, last);//0 if they are the same
}
void setroot()
{
if (!getstatus(statusstr[0], statusstr[1]))//Only set root if text has changed.
return;
Display *d = XOpenDisplay(NULL);
if (d) {
dpy = d;
}
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
getstatus(statusstr);
XStoreName(dpy, root, statusstr);
XStoreName(dpy, root, statusstr[0]);
XCloseDisplay(dpy);
}
void pstdout()
{
if (!getstatus(statusstr[0], statusstr[1]))//Only write out if text has changed.
return;
printf("%s\n",statusstr[0]);
fflush(stdout);
}
void statusloop()
{
#ifndef __OpenBSD__
setupsignals();
#endif
int i = 0;
getcmds(-1);
while(statusContinue)
{
getcmds(i);
setroot();
writestatus();
sleep(1.0);
i++;
}
}
void statusinit()
{
statusloop();
}
#ifndef __OpenBSD__
void sighandler(int signum)
{
getsigcmds(signum-SIGRTMIN);
setroot();
writestatus();
}
void buttonhandler(int sig, siginfo_t *si, void *ucontext)
{
button = si->si_value.sival_int & 0xff;
getsigcmds(si->si_value.sival_int >> 8);
writestatus();
}
#endif
void termhandler(int signum)
{
statusContinue = 0;
@ -156,8 +202,10 @@ int main(int argc, char** argv)
{
if (!strcmp("-d",argv[i]))
delim = argv[++i][0];
else if(!strcmp("-p",argv[i]))
writestatus = pstdout;
}
signal(SIGTERM, termhandler);
signal(SIGINT, termhandler);
statusinit();
statusloop();
}

View file

@ -0,0 +1,93 @@
diff --git a/dwmblocks.c b/dwmblocks.c
index 88bdfb0..7bd14df 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 replace(char *str, char old, char new);
void getcmds(int time);
#ifndef __OpenBSD__
@@ -34,6 +35,8 @@ static int screen;
static Window root;
static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
static char statusstr[2][256];
+static char exportstring[CMDLENGTH + 16] = "export BUTTON=-;";
+static int button = 0;
static int statusContinue = 1;
static void (*writestatus) () = setroot;
@@ -48,16 +51,34 @@ void replace(char *str, char old, char new)
//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");
+ char* cmd;
+ FILE *cmdf;
+ if (button)
+ {
+ cmd = strcat(exportstring, block->command);
+ cmd[14] = '0' + button;
+ button = 0;
+ cmdf = popen(cmd,"r");
+ cmd[16] = '\0';
+ }
+ else
+ {
+ cmd = block->command;
+ cmdf = popen(cmd,"r");
+ }
if (!cmdf)
return;
char c;
int i = strlen(block->icon);
fgets(output+i, CMDLENGTH-i, cmdf);
i = strlen(output);
- if (delim != '\0' && --i)
+ if (delim != '\0' && i)
output[i++] = delim;
output[i++] = '\0';
pclose(cmdf);
@@ -88,11 +106,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);
+ }
}
+ sa.sa_sigaction = buttonhandler;
+ sa.sa_flags = SA_SIGINFO;
+ sigaction(SIGUSR1, &sa, NULL);
}
#endif
@@ -152,6 +177,14 @@ void sighandler(int signum)
getsigcmds(signum-SIGRTMIN);
writestatus();
}
+
+void buttonhandler(int sig, siginfo_t *si, void *ucontext)
+{
+ button = si->si_value.sival_int & 0xff;
+ getsigcmds(si->si_value.sival_int >> 8);
+ writestatus();
+}
+
#endif
void termhandler(int signum)