Compare commits
No commits in common. "7dd9a3bddcdfbf92dd43696bfb4356d591b1a482" and "d58dfbb32237d688955ab7cddfe83ed391e48dc2" have entirely different histories.
7dd9a3bddc
...
d58dfbb322
@ -1,2 +0,0 @@
|
|||||||
BasedOnStyle: Google
|
|
||||||
IndentWidth: 4
|
|
24
Makefile
24
Makefile
@ -1,21 +1,19 @@
|
|||||||
.POSIX:
|
.POSIX:
|
||||||
|
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
CFLAGS = -Ofast
|
CC = gcc
|
||||||
LDLIBS = -lX11
|
|
||||||
|
|
||||||
BIN = dwmblocks
|
|
||||||
|
|
||||||
$(BIN): main.o
|
|
||||||
$(CC) $^ -o $@ $(LDLIBS)
|
|
||||||
|
|
||||||
|
dwmblocks: main.o
|
||||||
|
$(CC) main.o -lX11 -Ofast -o dwmblocks
|
||||||
|
main.o: main.c config.h
|
||||||
|
$(CC) -Ofast -c main.c
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o $(BIN)
|
rm -f *.o *.gch dwmblocks
|
||||||
|
install: dwmblocks
|
||||||
install: $(BIN)
|
mkdir -p $(DESTDIR)$(PREFIX)/bin
|
||||||
install -D -m 755 $(BIN) $(DESTDIR)$(PREFIX)/bin/$(BIN)
|
cp -f dwmblocks $(DESTDIR)$(PREFIX)/bin
|
||||||
|
chmod 755 $(DESTDIR)$(PREFIX)/bin/dwmblocks
|
||||||
uninstall:
|
uninstall:
|
||||||
$(RM) $(DESTDIR)$(PREFIX)/bin/$(BIN)
|
rm -f $(DESTDIR)$(PREFIX)/bin/dwmblocks
|
||||||
|
|
||||||
.PHONY: clean install uninstall
|
.PHONY: clean install uninstall
|
||||||
|
@ -125,6 +125,8 @@ To use this feature, define the `CLICKABLE_BLOCKS` feature macro in your `config
|
|||||||
|
|
||||||
Apart from that, you need `dwm` to be patched with [statuscmd](https://dwm.suckless.org/patches/statuscmd/).
|
Apart from that, you need `dwm` to be patched with [statuscmd](https://dwm.suckless.org/patches/statuscmd/).
|
||||||
|
|
||||||
|
> Earlier, `dwmblocks-async` used to require a patch to be applied to `dwm`. However, the code has been redone so there's no need to apply that patch anymore.
|
||||||
|
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
This work would not have been possible without [Luke's build of dwmblocks](https://github.com/LukeSmithxyz/dwmblocks) and [Daniel Bylinka's statuscmd patch](https://dwm.suckless.org/patches/statuscmd/).
|
This work would not have been possible without [Luke's build of dwmblocks](https://github.com/LukeSmithxyz/dwmblocks) and [Daniel Bylinka's statuscmd patch](https://dwm.suckless.org/patches/statuscmd/).
|
||||||
|
71
main.c
71
main.c
@ -48,10 +48,7 @@ static int execLock = 0;
|
|||||||
|
|
||||||
// Longest UTF-8 character is 4 bytes long
|
// Longest UTF-8 character is 4 bytes long
|
||||||
static char outputs[LEN(blocks)][CMDLENGTH * 4 + 1 + CLICKABLE_BLOCKS];
|
static char outputs[LEN(blocks)][CMDLENGTH * 4 + 1 + CLICKABLE_BLOCKS];
|
||||||
static char
|
static char statusBar[2][LEN(blocks) * (LEN(outputs[0]) - 1) + (LEN(blocks) - 1 + LEADING_DELIMITER) * (LEN(DELIMITER) - 1) + 1];
|
||||||
statusBar[2]
|
|
||||||
[LEN(blocks) * (LEN(outputs[0]) - 1) +
|
|
||||||
(LEN(blocks) - 1 + LEADING_DELIMITER) * (LEN(DELIMITER) - 1) + 1];
|
|
||||||
|
|
||||||
void (*writeStatus)();
|
void (*writeStatus)();
|
||||||
|
|
||||||
@ -72,7 +69,8 @@ void closePipe(int *pipe) {
|
|||||||
|
|
||||||
void execBlock(int i, const char* button) {
|
void execBlock(int i, const char* button) {
|
||||||
// Ensure only one child process exists per block at an instance
|
// Ensure only one child process exists per block at an instance
|
||||||
if (execLock & 1 << i) return;
|
if (execLock & 1 << i)
|
||||||
|
return;
|
||||||
// Lock execution of block until current instance finishes execution
|
// Lock execution of block until current instance finishes execution
|
||||||
execLock |= 1 << i;
|
execLock |= 1 << i;
|
||||||
|
|
||||||
@ -81,16 +79,16 @@ void execBlock(int i, const char *button) {
|
|||||||
dup2(pipes[i][1], STDOUT_FILENO);
|
dup2(pipes[i][1], STDOUT_FILENO);
|
||||||
close(pipes[i][1]);
|
close(pipes[i][1]);
|
||||||
|
|
||||||
if (button) setenv("BLOCK_BUTTON", button, 1);
|
if (button)
|
||||||
|
setenv("BLOCK_BUTTON", button, 1);
|
||||||
execl("/bin/sh", "sh", "-c", blocks[i].command, (char*)NULL);
|
execl("/bin/sh", "sh", "-c", blocks[i].command, (char*)NULL);
|
||||||
exit(EXIT_FAILURE);
|
_exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void execBlocks(unsigned int time) {
|
void execBlocks(unsigned int time) {
|
||||||
for (int i = 0; i < LEN(blocks); i++)
|
for (int i = 0; i < LEN(blocks); i++)
|
||||||
if (time == 0 ||
|
if (time == 0 || (blocks[i].interval != 0 && time % blocks[i].interval == 0))
|
||||||
(blocks[i].interval != 0 && time % blocks[i].interval == 0))
|
|
||||||
execBlock(i, NULL);
|
execBlock(i, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,10 +118,11 @@ void updateBlock(int i) {
|
|||||||
while (buffer[j] != '\n' && count < CMDLENGTH) {
|
while (buffer[j] != '\n' && count < CMDLENGTH) {
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
// Skip continuation bytes, if any
|
// Skip continuation bytes, if any.
|
||||||
char ch = buffer[j];
|
char ch = buffer[j];
|
||||||
int skip = 1;
|
int skip = 1;
|
||||||
while ((ch & 0xc0) > 0x80) ch <<= 1, skip++;
|
while ((ch & 0xc0) > 0x80)
|
||||||
|
ch <<= 1, skip++;
|
||||||
j += skip;
|
j += skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +131,8 @@ void updateBlock(int i) {
|
|||||||
buffer[j] = ' ';
|
buffer[j] = ' ';
|
||||||
|
|
||||||
// Trim trailing spaces
|
// Trim trailing spaces
|
||||||
while (j >= 0 && buffer[j] == ' ') j--;
|
while (j >= 0 && buffer[j] == ' ')
|
||||||
|
j--;
|
||||||
buffer[j + 1] = 0;
|
buffer[j + 1] = 0;
|
||||||
|
|
||||||
// Clear the pipe
|
// Clear the pipe
|
||||||
@ -156,27 +156,25 @@ void updateBlock(int i) {
|
|||||||
|
|
||||||
void debug() {
|
void debug() {
|
||||||
// Only write out if text has changed
|
// Only write out if text has changed
|
||||||
if (!getStatus(statusBar[0], statusBar[1])) return;
|
if (!getStatus(statusBar[0], statusBar[1]))
|
||||||
|
return;
|
||||||
|
|
||||||
write(STDOUT_FILENO, statusBar[0], strlen(statusBar[0]));
|
write(STDOUT_FILENO, statusBar[0], strlen(statusBar[0]));
|
||||||
write(STDOUT_FILENO, "\n", 1);
|
write(STDOUT_FILENO, "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int setupX() {
|
|
||||||
dpy = XOpenDisplay(NULL);
|
|
||||||
if (!dpy) return 1;
|
|
||||||
|
|
||||||
screen = DefaultScreen(dpy);
|
|
||||||
root = RootWindow(dpy, screen);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRoot() {
|
void setRoot() {
|
||||||
// Only set root if text has changed
|
// Only set root if text has changed
|
||||||
if (!getStatus(statusBar[0], statusBar[1])) return;
|
if (!getStatus(statusBar[0], statusBar[1]))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Display* d = XOpenDisplay(NULL);
|
||||||
|
if (d)
|
||||||
|
dpy = d;
|
||||||
|
screen = DefaultScreen(dpy);
|
||||||
|
root = RootWindow(dpy, screen);
|
||||||
XStoreName(dpy, root, statusBar[0]);
|
XStoreName(dpy, root, statusBar[0]);
|
||||||
XFlush(dpy);
|
XCloseDisplay(dpy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void signalHandler() {
|
void signalHandler() {
|
||||||
@ -201,15 +199,16 @@ void signalHandler() {
|
|||||||
|
|
||||||
for (int j = 0; j < LEN(blocks); j++) {
|
for (int j = 0; j < LEN(blocks); j++) {
|
||||||
if (blocks[j].signal == signal - SIGRTMIN) {
|
if (blocks[j].signal == signal - SIGRTMIN) {
|
||||||
char button[4]; // value can't be more than 255;
|
char button[] = {'0' + info.ssi_int & 0xff, 0};
|
||||||
sprintf(button, "%d", info.ssi_int & 0xff);
|
|
||||||
execBlock(j, button);
|
execBlock(j, button);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void termHandler() { statusContinue = 0; }
|
void termHandler() {
|
||||||
|
statusContinue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void setupSignals() {
|
void setupSignals() {
|
||||||
sigset_t handledSignals;
|
sigset_t handledSignals;
|
||||||
@ -228,7 +227,8 @@ void setupSignals() {
|
|||||||
epoll_ctl(epollFD, EPOLL_CTL_ADD, signalFD, &event);
|
epoll_ctl(epollFD, EPOLL_CTL_ADD, signalFD, &event);
|
||||||
|
|
||||||
// Block all realtime and handled signals
|
// Block all realtime and handled signals
|
||||||
for (int i = SIGRTMIN; i <= SIGRTMAX; i++) sigaddset(&handledSignals, i);
|
for (int i = SIGRTMIN; i <= SIGRTMAX; i++)
|
||||||
|
sigaddset(&handledSignals, i);
|
||||||
sigprocmask(SIG_BLOCK, &handledSignals, NULL);
|
sigprocmask(SIG_BLOCK, &handledSignals, NULL);
|
||||||
|
|
||||||
// Handle termination signals
|
// Handle termination signals
|
||||||
@ -258,7 +258,8 @@ void statusLoop() {
|
|||||||
signalHandler();
|
signalHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventCount != -1) writeStatus();
|
if (eventCount != -1)
|
||||||
|
writeStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,22 +284,18 @@ void init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(const int argc, const char* argv[]) {
|
int main(const int argc, const char* argv[]) {
|
||||||
if (setupX()) {
|
|
||||||
fprintf(stderr, "dwmblocks: Failed to open display\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
writeStatus = setRoot;
|
writeStatus = setRoot;
|
||||||
for (int i = 0; i < argc; i++)
|
for (int i = 0; i < argc; i++)
|
||||||
if (!strcmp("-d", argv[i])) writeStatus = debug;
|
if (!strcmp("-d", argv[i]))
|
||||||
|
writeStatus = debug;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
statusLoop();
|
statusLoop();
|
||||||
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
close(epollFD);
|
close(epollFD);
|
||||||
close(signalFD);
|
close(signalFD);
|
||||||
for (int i = 0; i < LEN(pipes); i++) closePipe(pipes[i]);
|
for (int i = 0; i < LEN(pipes); i++)
|
||||||
|
closePipe(pipes[i]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user