Initializing git repository

This commit is contained in:
Ashish Kumar Yadav 2020-07-04 02:34:11 +05:30
commit f73a8d5b2c
8 changed files with 859 additions and 0 deletions

29
Makefile Normal file
View file

@ -0,0 +1,29 @@
#PREFIX = /usr/local
PREFIX = ${HOME}/.local
CC = gcc
CFLAGS = -Wall -Wextra -Os
CFLAGSEXTRA = -Wno-unused-parameter -Wno-missing-field-initializers
build: dwmblocks sigdwmblocks
dwmblocks: dwmblocks.c blocks.h
${CC} ${CFLAGS} ${CFLAGSEXTRA} -lX11 dwmblocks.c -o dwmblocks
sigdwmblocks: sigdwmblocks.c
${CC} ${CFLAGS} sigdwmblocks.c -o sigdwmblocks
xgetrootname: xgetrootname.c
${CC} ${CFLAGS} xgetrootname.c -o xgetrootname
clean:
rm -f dwmblocks sigdwmblocks
install: build
mkdir -p ${DESTDIR}${PREFIX}/bin
install -m 0755 dwmblocks ${DESTDIR}${PREFIX}/bin/dwmblocks
install -m 0755 sigdwmblocks ${DESTDIR}${PREFIX}/bin/sigdwmblocks
uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/dwmblocks ${DESTDIR}${PREFIX}/bin/sigdwmblocks
.PHONY: build clean install uninstall

57
README.md Normal file
View file

@ -0,0 +1,57 @@
# dwmblocks
Modular status monitor for dwm written in C.
# Usage
`dwmblocks [-d delimiter]`
# Modifying blocks
Blocks are added and removed by editing the blocks.h file. Read it for more
info.
# Colored output and clickability
The patches folder contains a patch for dwm which is required for dwmblocks to
function properly. It adds support for colored text, clickability and cursor
hinting when hovering on text output of clickable blocks (inspired by polybar).
Clickability is inspired by the statuscmd patch for dwm. On clicking on text
corresponding to a clickable block, the program specified to handle clicks for
that block is executed with the first argument specifying which button was
clicked (1 for left, 2 for middle and 3 for right by default).
Colored output is inspired by the statuscolors patch for dwm. To add colors,
have your programs for the blocks output raw characters from '\x11' to '\x31'.
'\x11' in status text switches the active colorscheme to the first one in the
scheme array in dwm and so on. See
[statuscolors patch](https://dwm.suckless.org/patches/statuscolors/)
for more info. Keep in mind that you have to start from '\x11' instead of '\x01'
as instructed on the page.
# Signaling changes
To signal a specific block to update, run `sigdwmblocks signal [sigval]`.
`sigval` is optional and must be an integer. When not provided it defaults to 0.
`sigval` is passed as the first argument to the program specified for updating
the block.
# xgetrootname
It is a small program to get the current root name. May prove helpful in
debugging.
# Installation
Clone the repository and run `make clean install` after getting in the project
directory. By default the program is installed in `$HOME/.local/bin`. If
xgetrootname is required run `make xgetrootname`.
# Acknowledgements
Some ideas and code was taken from other projects. Credits for those go to -
* torrinfail ([original dwmblocks implementation](https://github.com/torrinfail/dwmblocks))
* Daniel Bylinka ([statuscmd patch for dwm](https://dwm.suckless.org/patches/statuscmd/))
* Jeremy Jay ([statuscolors patch for dwm](https://dwm.suckless.org/patches/statuscolors/))

33
blocks.h Normal file
View file

@ -0,0 +1,33 @@
/* time interval in seconds to sleep before looking for updates in the main loop */
#define SLEEPINTERVAL 30
#define PATH(name) "/home/ashish/.scripts/statusbar/"name
/* If multiple realtime signals are pending, then the lowest numbered signal is delivered first.
* If interval of a block is set to 0, the block will only be updated once at startup.
* If interval is set to a negative value, the block will never be updated in the main loop.
* Set signal to 0 if signalling is not required for the block.
* Keep signal for clickable blocks less than 10. */
/* pathu - path of the program whose output is to be used for status text
* patch - path of the program to be executed on clicks */
static Block blocks[] = {
/* pathu pathc interval signal */
{ PATH("hotspot.sh"), PATH("hotspot_button.sh"), -1, 1},
{ PATH("time.sh"), NULL, 30, 0},
{ PATH("calendar.sh"), PATH("calendar_button.sh"), 60, 2},
// { PATH("mail.sh"), PATH("mail_button.sh"), 30, 3},
{ PATH("volume.sh"), PATH("volume_button.sh"), 0, 4},
{ PATH("cpu_temp.sh"), PATH("cpu_temp_button.sh"), 30, 5},
{ PATH("battery.sh"), PATH("battery_button.sh"), 0, 6},
{ NULL } /* just to mark the end of the array */
};
static const char *delim = " | ";

301
dwmblocks.c Normal file
View file

@ -0,0 +1,301 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <X11/Xlib.h>
#define CMDLENGTH 25 /* must be positive */
#define STTLENGTH 256 /* must be big enough */
#define LOCKFILE "/tmp/dwmblocks.pid"
#define EMPTYCMDOUT(block) (block->cmdoutcur[0] == '\n' || block->cmdoutcur[0] == '\0')
#define NOTATCMDOUTEND(block, i) (i < CMDLENGTH && block->cmdoutcur[i] != '\n' && block->cmdoutcur[i] != '\0')
typedef struct {
char *pathu;
char *pathc;
const int interval;
const int signal;
char cmdoutcur[CMDLENGTH];
char cmdoutprv[CMDLENGTH];
} Block;
static void buttonhandler(int signal, siginfo_t *si, void *ucontext);
static void getcmd(Block *block, int *sigval);
static void setroot();
static void setupsignals();
static void sighandler(int signum, siginfo_t *si, void *ucontext);
static void statusloop();
static void termhandler(int signum);
static int updatestatus();
static void writepid();
#include "blocks.h"
static int statusContinue = 1;
static char statusstr[STTLENGTH];
static size_t delimlength;
static Display *dpy;
static Window root;
void
buttonhandler(int signal, siginfo_t *si, void *ucontext)
{
signal = si->si_value.sival_int >> 8;
switch (fork()) {
case -1:
perror("buttonhandler - fork");
exit(1);
case 0:
for (Block *current = blocks; current->pathu; current++) {
if (current->signal == signal) {
char button[] = { '0' + (si->si_value.sival_int & 0xff), '\0' };
char *arg[] = { current->pathc, button, NULL };
setsid();
execv(arg[0], arg);
perror("buttonhandler - execv");
_exit(127);
}
}
exit(0);
}
}
void
getcmd(Block *block, int *sigval)
{
int fd[2];
if (pipe(fd) == -1) {
perror("getcmd - pipe");
exit(1);
}
switch (fork()) {
case -1:
perror("getcmd - fork");
exit(1);
case 0:
close(fd[0]);
if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
perror("getcmd - dup2");
exit(1);
}
close(fd[1]);
if (sigval) {
char buf[12];
char *arg[] = { block->pathu, buf, NULL };
snprintf(buf, sizeof buf, "%d", *sigval);
execv(arg[0], arg);
} else {
char *arg[] = { block->pathu, NULL };
execv(arg[0], arg);
}
perror("getcmd - execv");
_exit(127);
default:
close(fd[1]);
if (read(fd[0], block->cmdoutcur, CMDLENGTH) == -1) {
perror("getcmd - read");
exit(1);
}
close(fd[0]);
}
}
void
setroot()
{
if (updatestatus()) /* only set root if block outputs have changed */
return;
XStoreName(dpy, root, statusstr);
XFlush(dpy);
}
void
setupsignals()
{
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
/* to handle INT, HUP and TERM */
sa.sa_handler = termhandler;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
/* to ignore unused realtime signals */
sa.sa_handler = SIG_IGN;
for (int i = SIGRTMIN; i <= SIGRTMAX; i++)
sigaction(i, &sa, NULL);
/* to handle signals generated by dwm on click events */
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sa.sa_sigaction = buttonhandler;
sigaction(SIGRTMIN, &sa, NULL);
/* to handle update signals for individual blocks */
sa.sa_sigaction = sighandler;
for (Block *current = blocks; current->pathu; current++)
if (current->signal > 0)
sigaction(SIGRTMIN + current->signal, &sa, NULL);
/* to prevent forked children from becoming zombies */
sa.sa_flags = SA_NOCLDWAIT | SA_RESTART;
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
}
void
sighandler(int signum, siginfo_t *si, void *ucontext)
{
signum -= SIGRTMIN;
for (Block *current = blocks; current->pathu; current++) {
if (current->signal == signum)
getcmd(current, &(si->si_value.sival_int));
}
setroot();
}
void
statusloop()
{
int i;
setupsignals();
for (Block *current = blocks; current->pathu; current++)
if (current->interval >= 0)
getcmd(current, NULL);
setroot();
sleep(SLEEPINTERVAL);
i = SLEEPINTERVAL;
while (statusContinue) {
for (Block *current = blocks; current->pathu; current++)
if (current->interval > 0 && i % current->interval == 0)
getcmd(current, NULL);
setroot();
sleep(SLEEPINTERVAL);
i += SLEEPINTERVAL;
}
}
void
termhandler(int signum)
{
statusContinue = 0;
}
/* returns whether block outputs have changed and updates statusstr if they have */
int
updatestatus()
{
int i;
char *str = statusstr;
Block *current;
for (current = blocks; current->pathu; current++) {
if (EMPTYCMDOUT(current)) {
if (current->cmdoutprv[0] != current->cmdoutcur[0])
goto updatestrstrt;
continue;
}
i = 0;
do {
if (current->cmdoutcur[i] == current->cmdoutprv[i]) {
i++;
continue;
} else {
str += i;
goto updatestrmddl;
}
} while (NOTATCMDOUTEND(current, i));
str += i;
if (current->pathc && current->signal)
str++;
str += delimlength;
}
return 1;
updatestrstrt:
current->cmdoutprv[0] = current->cmdoutcur[0];
for (current++; current->pathu; current++) {
if (EMPTYCMDOUT(current)) {
current->cmdoutprv[0] = current->cmdoutcur[0];
continue;
}
i = 0;
updatestrmddl:
do {
*(str++) = current->cmdoutcur[i];
current->cmdoutprv[i] = current->cmdoutcur[i];
i++;
} while (NOTATCMDOUTEND(current, i));
if (current->pathc && current->signal)
*(str++) = current->signal;
for (i = 0; delim[i]; i++)
*(str++) = delim[i];
*(str++) = '\n';
}
if (str != statusstr)
*(str - delimlength) = '\0';
return 0;
}
void
writepid()
{
int fd;
char buf[20];
struct flock fl;
ssize_t len;
fd = open(LOCKFILE, O_RDWR|O_CREAT, 0644);
if (fd == -1) {
perror("writepid - fd");
exit(1);
}
fl.l_type = F_WRLCK;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
if (fcntl(fd, F_SETLK, &fl) == -1) {
if (errno == EACCES || errno == EAGAIN) {
fputs("Error: another instance of dwmblocks is already running.\n", stderr);
exit(2);
}
perror("lockfile - fcntl");
exit(1);
}
if (ftruncate(fd, 0) == -1) {
perror("writepid - ftruncate");
exit(1);
}
snprintf(buf, sizeof buf, "%ld", (long)getpid());
len = strlen(buf);
if (write(fd, buf, len) != len) {
perror("writepid - write");
exit(1);
}
}
int
main(int argc, char *argv[])
{
writepid();
if (argc > 2) {
if (strcmp("-d", argv[1]) == 0)
delim = argv[2];
}
delimlength = strlen(delim) + 1;
if (!(dpy = XOpenDisplay(NULL))) {
fputs("Error: could not open display.\n", stderr);
return 1;
}
root = RootWindow(dpy, DefaultScreen(dpy));
statusloop();
unlink(LOCKFILE);
XStoreName(dpy, root, "");
XCloseDisplay(dpy);
return 0;
}

View file

@ -0,0 +1,341 @@
diff -ruN dwm-6.2-ori/config.def.h dwm-6.2/config.def.h
--- dwm-6.2-ori/config.def.h 2019-02-02 18:25:28.000000000 +0530
+++ dwm-6.2/config.def.h 2020-07-02 22:13:34.676860032 +0530
@@ -12,10 +12,34 @@
static const char col_gray3[] = "#bbbbbb";
static const char col_gray4[] = "#eeeeee";
static const char col_cyan[] = "#005577";
+static const char col1[] = "#ffffff";
+static const char col2[] = "#ffffff";
+static const char col3[] = "#ffffff";
+static const char col4[] = "#ffffff";
+static const char col5[] = "#ffffff";
+static const char col6[] = "#ffffff";
+static const char col7[] = "#ffffff";
+static const char col8[] = "#ffffff";
+static const char col9[] = "#ffffff";
+static const char col10[] = "#ffffff";
+static const char col11[] = "#ffffff";
+static const char col12[] = "#ffffff";
static const char *colors[][3] = {
/* fg bg border */
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+ [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ [SchemeCol1] = { col1, col_gray1, col_gray2 },
+ [SchemeCol2] = { col2, col_gray1, col_gray2 },
+ [SchemeCol3] = { col3, col_gray1, col_gray2 },
+ [SchemeCol4] = { col4, col_gray1, col_gray2 },
+ [SchemeCol5] = { col5, col_gray1, col_gray2 },
+ [SchemeCol6] = { col6, col_gray1, col_gray2 },
+ [SchemeCol7] = { col7, col_gray1, col_gray2 },
+ [SchemeCol8] = { col8, col_gray1, col_gray2 },
+ [SchemeCol9] = { col8, col_gray1, col_gray2 },
+ [SchemeCol10] = { col10, col_gray1, col_gray2 },
+ [SchemeCol11] = { col11, col_gray1, col_gray2 },
+ [SchemeCol12] = { col12, col_gray1, col_gray2 },
};
/* tagging */
@@ -103,7 +127,9 @@
{ 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 -ruN dwm-6.2-ori/dwm.c dwm-6.2/dwm.c
--- dwm-6.2-ori/dwm.c 2019-02-02 18:25:28.000000000 +0530
+++ dwm-6.2/dwm.c 2020-07-02 22:29:22.207225539 +0530
@@ -40,6 +40,8 @@
#include <X11/extensions/Xinerama.h>
#endif /* XINERAMA */
#include <X11/Xft/Xft.h>
+#include <fcntl.h>
+#include <sys/prctl.h>
#include "drw.h"
#include "util.h"
@@ -56,10 +58,15 @@
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+#define TTEXTW(X) drw_fontset_getwidth(drw, (X))
+
+#define DWMBLOCKSLOCKFILE "/tmp/dwmblocks.pid"
/* enums */
-enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel }; /* color schemes */
+enum { CurNormal, CurHand, CurResize, CurMove, CurLast }; /* cursor */
+enum { SchemeNorm, SchemeSel, SchemeCol1, SchemeCol2, SchemeCol3,
+ SchemeCol4, SchemeCol5, SchemeCol6, SchemeCol7, SchemeCol8,
+ SchemeCol9, SchemeCol10, SchemeCol11, SchemeCol12 }; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
@@ -205,6 +212,7 @@
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);
@@ -216,9 +224,11 @@
static void unfocus(Client *c, int setfocus);
static void unmanage(Client *c, int destroyed);
static void unmapnotify(XEvent *e);
+static void updatebarcursor(int cursorpos);
static void updatebarpos(Monitor *m);
static void updatebars(void);
static void updateclientlist(void);
+static void updatedwmblockssig(int x, int e);
static int updategeom(void);
static void updatenumlockmask(void);
static void updatesizehints(Client *c);
@@ -236,7 +246,10 @@
/* variables */
static const char broken[] = "broken";
-static char stext[256];
+static char stextc[256];
+static char stexts[256];
+static int wstext;
+static int dwmblockssig;
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
@@ -439,10 +452,14 @@
arg.ui = 1 << i;
} else if (ev->x < x + blw)
click = ClkLtSymbol;
- else if (ev->x > selmon->ww - TEXTW(stext))
- click = ClkStatusText;
- else
- click = ClkWinTitle;
+ else if (ev->x < selmon->ww - wstext)
+ click = ClkWinTitle;
+// else if (ev->x < selmon->ww - lrpad / 2 && ev->x >= (x = selmon->ww - wstext + lrpad / 2)) {
+ else if (ev->x < selmon->ww - lrpad / 2 && ev->x >= selmon->ww - wstext + lrpad / 2) {
+ click = ClkStatusText;
+// updatedwmblockssig(x, ev->x);
+ } else
+ return;
} else if ((c = wintoclient(ev->window))) {
focus(c);
restack(selmon);
@@ -695,7 +712,7 @@
void
drawbar(Monitor *m)
{
- int x, w, sw = 0;
+ int x, w;
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
@@ -703,9 +720,30 @@
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
- drw_setscheme(drw, scheme[SchemeNorm]);
- sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
+ char *ts = stextc;
+ char *tp = stextc;
+ char ctmp;
+
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ x = drw_text(drw, m->ww - wstext, 0, lrpad / 2, bh, 0, "", 0); /* to keep left padding clean */
+loopbegin:
+ /* + 10 and stextc, stexts to avoid conflict b/w statusclr and statussig */
+ if ((unsigned char)*ts > LENGTH(colors) + 10 ) {
+ ts++;
+ goto loopbegin;
+ }
+ ctmp = *ts;
+ *ts = '\0';
+ x = drw_text(drw, x, 0, TTEXTW(tp), bh, 0, tp, 0);
+ if (ctmp == '\0')
+ goto loopend;
+ /* - 11 due to + 10 above */
+ drw_setscheme(drw, scheme[(unsigned char)ctmp - 11]);
+ *ts = ctmp;
+ tp = ++ts;
+ goto loopbegin;
+loopend:
+ drw_text(drw, x, 0, m->ww - x, bh, 0, "", 0); /* to keep right padding clean */
}
for (c = m->clients; c; c = c->next) {
@@ -728,7 +766,7 @@
drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
- if ((w = m->ww - sw - x) > bh) {
+ if ((w = m->ww - wstext - x) > bh) {
if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
@@ -1122,8 +1160,11 @@
Monitor *m;
XMotionEvent *ev = &e->xmotion;
- if (ev->window != root)
+ if (ev->window != root) {
+ if (ev->window == selmon->barwin)
+ updatebarcursor(ev->x);
return;
+ }
if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
unfocus(selmon->sel, 1);
selmon = m;
@@ -1564,6 +1605,7 @@
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
+ cursor[CurHand] = drw_cur_create(drw, XC_hand2);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
cursor[CurMove] = drw_cur_create(drw, XC_fleur);
/* init appearance */
@@ -1637,6 +1679,28 @@
}
void
+sigdwmblocks(const Arg *arg)
+{
+ int fd;
+ struct flock fl;
+ union sigval sv;
+
+ if (dwmblockssig <= 0 || dwmblockssig >= 10)
+ return;
+ sv.sival_int = (dwmblockssig << 8) | arg->i;
+ fd = open(DWMBLOCKSLOCKFILE, O_RDONLY);
+ if (fd == -1)
+ return;
+ fl.l_type = F_WRLCK;
+ fl.l_start = 0;
+ fl.l_whence = SEEK_SET;
+ fl.l_len = 0;
+ if (fcntl(fd, F_GETLK, &fl) == -1 || fl.l_type == F_UNLCK)
+ return;
+ sigqueue(fl.l_pid, SIGRTMIN, sv);
+}
+
+void
spawn(const Arg *arg)
{
if (arg->v == dmenucmd)
@@ -1805,7 +1869,7 @@
XSetWindowAttributes wa = {
.override_redirect = True,
.background_pixmap = ParentRelative,
- .event_mask = ButtonPressMask|ExposureMask
+ .event_mask = ButtonPressMask|ExposureMask|PointerMotionMask
};
XClassHint ch = {"dwm", "dwm"};
for (m = mons; m; m = m->next) {
@@ -1821,6 +1885,33 @@
}
void
+updatebarcursor(int cursorpos)
+{
+ static int currentcursor = 0;
+ int x;
+
+ if (BETWEEN(cursorpos, (x = selmon->ww - wstext + lrpad / 2), x + wstext - lrpad)) {
+ updatedwmblockssig(x, cursorpos);
+ if (currentcursor) {
+ if (dwmblockssig <= 0 || dwmblockssig >= 10) {
+ currentcursor = 0;
+ XDefineCursor(dpy, selmon->barwin, cursor[CurNormal]->cursor);
+ }
+ } else {
+ if (dwmblockssig > 0 && dwmblockssig < 10) {
+ currentcursor = 1;
+ XDefineCursor(dpy, selmon->barwin, cursor[CurHand]->cursor);
+ }
+ }
+ } else {
+ if (currentcursor) {
+ currentcursor = 0;
+ XDefineCursor(dpy, selmon->barwin, cursor[CurNormal]->cursor);
+ }
+ }
+}
+
+void
updatebarpos(Monitor *m)
{
m->wy = m->my;
@@ -1847,6 +1938,31 @@
(unsigned char *) &(c->win), 1);
}
+void
+updatedwmblockssig(int x, int e)
+{
+ char *ts = stexts;
+ char *tp = stexts;
+ char ctmp;
+
+ while (*ts) {
+ if ((unsigned char)*ts > 10) {
+ ts++;
+ continue;
+ }
+ ctmp = *ts;
+ *ts = '\0';
+ x += TTEXTW(tp);
+ *ts = ctmp;
+ if (x >= e) {
+ dwmblockssig = (unsigned char)ctmp;
+ return;
+ }
+ tp = ++ts;
+ }
+ dwmblockssig = 0;
+}
+
int
updategeom(void)
{
@@ -1987,9 +2103,28 @@
void
updatestatus(void)
{
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
- strcpy(stext, "dwm-"VERSION);
- drawbar(selmon);
+ char rawstext[256];
+
+ if (gettextprop(root, XA_WM_NAME, rawstext, sizeof rawstext)) {
+ int i = -1, j = 0, k = 0, l = 0;
+ char stextf[256];
+
+ while (rawstext[++i]) {
+ if ((unsigned char)rawstext[i] >= ' ')
+ stextf[j++] = stextc[k++] = stexts[l++] = rawstext[i];
+ else if ((unsigned char)rawstext[i] > 10)
+ stextc[k++] = rawstext[i];
+ else
+ stexts[l++] = rawstext[i];
+ }
+ stextf[j] = stextc[k] = stexts[l] = '\0';
+ wstext = TEXTW(stextf);
+ } else {
+ strcpy(stextc, "dwm-"VERSION);
+ strcpy(stexts, stextc);
+ wstext = TEXTW(stextc);
+ }
+ drawbar(selmon);
}
void

75
sigdwmblocks.c Normal file
View file

@ -0,0 +1,75 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#define LOCKFILE "/tmp/dwmblocks.pid"
void
sendsignal(int signum, union sigval sv)
{
int fd;
struct flock fl;
fd = open(LOCKFILE, O_RDONLY);
if (fd == -1) {
if (errno == ENOENT) {
fputs("Error: no running instance of dwmblocks.", stderr);
exit(2);
}
perror("sendsignal - fd");
exit(1);
}
fl.l_type = F_WRLCK;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
if (fcntl(fd, F_GETLK, &fl) == -1) {
perror("sendsignal - fcntl");
exit(1);
}
if (fl.l_type == F_UNLCK) {
fputs("Error: no running instance of dwmblocks.", stderr);
exit(2);
}
if (sigqueue(fl.l_pid, signum, sv) == -1) {
if (errno == EINVAL) {
fputs("Error: invalid signal provided in argument.", stderr);
exit(3);
} else if (errno == ESRCH) {
fputs("Error: no running instance of dwmblocks.", stderr);
exit(2);
} else {
perror("sendsignal - sigqueue");
exit(1);
}
}
}
int
main(int argc, char *argv[])
{
if (argc > 1) {
int signal;
union sigval sv;
if (sscanf(argv[1], "%d", &signal) == 1 &&
signal > 0 && (signal += SIGRTMIN) <= SIGRTMAX) {
if (argc == 2) {
sv.sival_int = 0;
sendsignal(signal, sv);
return 0;
} else if (argc == 3 &&
sscanf(argv[2], "%d", &(sv.sival_int)) == 1) {
sendsignal(signal, sv);
return 0;
}
}
}
fprintf(stderr, "Usage: %s signal [sigval]\n", argv[0]);
return 3;
}

BIN
xgetrootname Executable file

Binary file not shown.

23
xgetrootname.c Normal file
View file

@ -0,0 +1,23 @@
#include <stdio.h>
#include <X11/Xlib.h>
int
main()
{
Display *dpy;
Window root;
char *name;
if (!(dpy = XOpenDisplay(NULL))) {
fputs("Error: could not open display.\n", stderr);
return 1;
}
root = RootWindow(dpy, DefaultScreen(dpy));
if (XFetchName(dpy, root, &name) && name[0])
printf("%s\n", name);
else
puts("No name has been set for the root window.");
XFree(name);
XCloseDisplay(dpy);
return 0;
}