sites

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

commit 77a71712f0d34efdd594addd4f4dd1058b8a3f30
parent 8053764526d97c27e38f49885572ac9be6e84e22
Author: Santtu Lakkala <inz@inz.fi>
Date:   Thu, 13 Jul 2023 16:02:41 +0300

[dwm][patch][dwmfifo] Add new version of dwmfifo patch

Diffstat:
Adwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230713-e81f17d.diff | 342+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdwm.suckless.org/patches/dwmfifo/index.md | 5++++-
2 files changed, 346 insertions(+), 1 deletion(-)

diff --git a/dwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230713-e81f17d.diff b/dwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230713-e81f17d.diff @@ -0,0 +1,342 @@ +From a37879a10bbca1591a2677ddecd641a4bcb8ffbd Mon Sep 17 00:00:00 2001 +From: Santtu Lakkala <inz@inz.fi> +Date: Thu, 13 Jul 2023 15:48:14 +0300 +Subject: [PATCH] Command FIFO for dwm + +Builds on the previous version of dwmfifo, but: + - proper buffering and line detection + - basic argument parsing + - new commands to show a window by xid or name pattern +--- + config.def.h | 26 +++++++ + dwm.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 223 insertions(+), 3 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9efa774..fc4db01 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -114,3 +114,29 @@ static const Button buttons[] = { + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + }; + ++static const char *dwmfifo = "/tmp/dwm.fifo"; ++static Command commands[] = { ++ { "dmenu", spawn, {.v = dmenucmd} }, ++ { "term", spawn, {.v = termcmd} }, ++ { "quit", quit, {0} }, ++ { "togglebar", togglebar, {0} }, ++ { "focusstack", focusstack, .parse = parseplusminus }, ++ { "incnmaster", incnmaster, .parse = parseplusminus }, ++ { "setmfact", setmfact, .parse = parseplusminus }, ++ { "zoom", zoom, {0} }, ++ { "killclient", killclient, {0} }, ++ { "setlayout-tiled", setlayout, {.v = &layouts[0]} }, ++ { "setlayout-float", setlayout, {.v = &layouts[1]} }, ++ { "setlayout-mono", setlayout, {.v = &layouts[2]} }, ++ { "togglelayout", setlayout, {0} }, ++ { "togglefloating", togglefloating, {0} }, ++ { "viewwin", viewwin, .parse = parsexid }, ++ { "viewname", viewname, .parse = parsestr }, ++ { "viewall", view, {.ui = ~0} }, ++ { "focusmon", focusmon, .parse = parseplusminus }, ++ { "tagmon", tagmon, .parse = parseplusminus }, ++ { "view", view, .parse = parsetag }, ++ { "toggleview", toggleview, .parse = parsetag }, ++ { "tag", tag, .parse = parsetag }, ++ { "toggletag", toggletag, .parse = parsetag }, ++}; +diff --git a/dwm.c b/dwm.c +index f1d86b2..202ed6a 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -21,6 +21,7 @@ + * To understand everything else, start reading main(). + */ + #include <errno.h> ++#include <fcntl.h> + #include <locale.h> + #include <signal.h> + #include <stdarg.h> +@@ -28,6 +29,8 @@ + #include <stdlib.h> + #include <string.h> + #include <unistd.h> ++#include <poll.h> ++#include <fnmatch.h> + #include <sys/types.h> + #include <sys/wait.h> + #include <X11/cursorfont.h> +@@ -141,6 +144,13 @@ typedef struct { + int monitor; + } Rule; + ++typedef struct { ++ const char *name; ++ void (*func)(const Arg *arg); ++ const Arg arg; ++ int (*parse)(Arg *arg, const char *s, size_t len); ++} Command; ++ + /* function declarations */ + static void applyrules(Client *c); + static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); +@@ -161,6 +171,7 @@ static void destroynotify(XEvent *e); + static void detach(Client *c); + static void detachstack(Client *c); + static Monitor *dirtomon(int dir); ++static void dispatchcmd(void); + static void drawbar(Monitor *m); + static void drawbars(void); + static void enternotify(XEvent *e); +@@ -227,6 +238,8 @@ static void updatetitle(Client *c); + static void updatewindowtype(Client *c); + static void updatewmhints(Client *c); + static void view(const Arg *arg); ++static void viewwin(const Arg *arg); ++static void viewname(const Arg *arg); + static Client *wintoclient(Window w); + static Monitor *wintomon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); +@@ -267,10 +280,63 @@ static Display *dpy; + static Drw *drw; + static Monitor *mons, *selmon; + static Window root, wmcheckwin; ++static int fifofd; ++ ++static int parsetag(Arg *a, const char *s, size_t len); ++static int parseplusminus(Arg *a, const char *s, size_t len); ++static int parsexid(Arg *a, const char *s, size_t len); ++static int parsestr(Arg *a, const char *s, size_t len); + + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++static int parsetag(Arg *a, const char *s, size_t len) ++{ ++ char *end; ++ unsigned int rv = strtoul(s, &end, 10); ++ if (end == s) ++ a->ui = 0; ++ else if (rv > LENGTH(tags)) ++ return 0; ++ else if (rv == 0) ++ a->ui = ~0U; ++ else ++ a->ui = 1U << (rv - 1); ++ ++ return 1; ++} ++ ++static int parseplusminus(Arg *a, const char *s, size_t len) ++{ ++ if (*s == '+') ++ a->i = +1; ++ else if (*s == '-') ++ a->i = -1; ++ else ++ return 0; ++ return 1; ++} ++ ++static int parsexid(Arg *a, const char *s, size_t len) ++{ ++ char *end; ++ unsigned long long sv = strtoull(s, &end, 0); ++ ++ if (end == s) ++ return 0; ++ ++ a->v = (void *)(intptr_t)sv; ++ return 1; ++} ++ ++static int parsestr(Arg *a, const char *s, size_t len) ++{ ++ while (*s == ' ' || *s == '\t') ++ s++; ++ a->v = s; ++ return 1; ++} ++ + /* compile-time check if all tags fit into an unsigned int bit array. */ + struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +@@ -494,6 +560,7 @@ cleanup(void) + XSync(dpy, False); + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); ++ close(fifofd); + } + + void +@@ -695,6 +762,71 @@ dirtomon(int dir) + return m; + } + ++static const char * ++strnprefix(const char *haystack, size_t hlen, const char *needle) ++{ ++ while (*needle && hlen--) { ++ if (*haystack++ != *needle++) ++ return 0; ++ } ++ ++ if (*needle) ++ return NULL; ++ return haystack; ++} ++ ++void ++dispatchcmd(void) ++{ ++ static char buf[BUFSIZ]; ++ static char * const bend = 1[&buf]; ++ static char *bw = buf; ++ static int longline = 0; ++ ssize_t n; ++ char *nl; ++ char *pl = buf; ++ char *dend; ++ Command *i; ++ ++ n = read(fifofd, bw, bend - bw); ++ if (n == -1) ++ die("Failed to read() from DWM fifo %s:", dwmfifo); ++ dend = bw + n; ++ ++ if (longline) { ++ if (!(nl = memchr(bw, '\n', dend - bw))) ++ return; ++ bw = pl = nl + 1; ++ longline = 0; ++ } ++ ++ while ((nl = memchr(bw, '\n', dend - bw))) { ++ for (i = commands; i < 1[&commands]; i++) { ++ const char *arg; ++ ++ if (!(arg = strnprefix(pl, nl - pl, i->name))) ++ continue; ++ *nl = '\0'; ++ if (i->parse) { ++ Arg a; ++ if (i->parse(&a, arg, nl - arg)) ++ i->func(&a); ++ } else { ++ i->func(&i->arg); ++ } ++ ++ break; ++ } ++ bw = pl = nl + 1; ++ } ++ ++ memmove(buf, pl, dend - pl); ++ bw = dend - pl + buf; ++ ++ if (bw == bend) ++ bw = buf; ++} ++ + void + drawbar(Monitor *m) + { +@@ -1379,15 +1511,31 @@ restack(Monitor *m) + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); + } + ++static Bool evpredicate() ++{ ++ return True; ++} ++ + void + run(void) + { + XEvent ev; ++ struct pollfd fds[2] = { ++ { .events = POLLIN }, ++ { .fd = fifofd, .events = POLLIN } ++ }; + /* main event loop */ + XSync(dpy, False); +- while (running && !XNextEvent(dpy, &ev)) +- if (handler[ev.type]) +- handler[ev.type](&ev); /* call handler */ ++ fds[0].fd = ConnectionNumber(dpy); ++ while (running) { ++ (void)poll(fds, 1[&fds] - fds, -1); ++ if (fds[1].revents & POLLIN) ++ dispatchcmd(); ++ if (fds[0].revents & POLLIN) ++ while (XCheckIfEvent(dpy, &ev, evpredicate, NULL)) ++ if (handler[ev.type]) ++ handler[ev.type](&ev); /* call handler */ ++ } + } + + void +@@ -1611,6 +1759,9 @@ setup(void) + XSelectInput(dpy, root, wa.event_mask); + grabkeys(); + focus(NULL); ++ fifofd = open(dwmfifo, O_RDONLY | O_CLOEXEC | O_NONBLOCK); ++ if (fifofd < 0) ++ die("Failed to open() DWM fifo %s:", dwmfifo); + } + + void +@@ -2062,6 +2213,49 @@ view(const Arg *arg) + arrange(selmon); + } + ++void ++viewclient(Client *c) ++{ ++ if (!(c->tags & c->mon->tagset[c->mon->seltags])) ++ view(&(Arg){ .ui = c->tags }); ++ focus(c); ++} ++ ++void ++viewwin(const Arg *arg) ++{ ++ Client *c = wintoclient((Window)(intptr_t)arg->v); ++ ++ if (!c) ++ return; ++ ++ viewclient(c); ++} ++ ++Client * ++pattoclient(const char *pattern) ++{ ++ Client *c; ++ Monitor *m; ++ ++ for (m = mons; m; m = m->next) ++ for (c = m->clients; c; c = c->next) ++ if (!fnmatch(pattern, c->name, 0)) ++ return c; ++ return NULL; ++} ++ ++void ++viewname(const Arg *arg) ++{ ++ Client *c = pattoclient(arg->v); ++ ++ if (!c) ++ return; ++ ++ viewclient(c); ++} ++ + Client * + wintoclient(Window w) + { +-- +2.25.1 + diff --git a/dwm.suckless.org/patches/dwmfifo/index.md b/dwm.suckless.org/patches/dwmfifo/index.md @@ -19,7 +19,8 @@ terminals on each of the 2 monitors. echo term > /tmp/dwm.fifo The sleep in between is currently needed to avoid buffering up more than a -single command. You may experiment with the actual sleep value. +single command. You may experiment with the actual sleep value. Sleeps are no +longer needed with the 20230713 version. Similarly you can modify your config.h and add more commands that you may want to execute (like tabbed-surf or similar). @@ -27,7 +28,9 @@ to execute (like tabbed-surf or similar). Download -------- * [dwm-dwmfifo-6.1.diff](dwm-dwmfifo-6.1.diff) (6.9k) (2014-01-29) +* [dwm-dwmfifo-20230713-e81f17d.diff](dwm-dwmfifo-20230713-e81f17d.diff) (8.1k) (2023-07-13) Author ------ * sin - <sin@2f30.org> +* inz - <inz@inz.fi>