sites

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

commit 307963264c4f839883562c07b6fbfc8e3ebac7fa
parent 5dc49ea1bb3cdf8e3088eac5e818febc6e578446
Author: Santtu Lakkala <inz@inz.fi>
Date:   Fri, 14 Jul 2023 13:39:32 +0300

[dwm][patch][dwmfifo] Fix busyloop

Diffstat:
Ddwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230713-e81f17d.diff | 342-------------------------------------------------------------------------------
Adwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230714-e81f17d.diff | 342+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdwm.suckless.org/patches/dwmfifo/index.md | 2+-
3 files changed, 343 insertions(+), 343 deletions(-)

diff --git a/dwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230713-e81f17d.diff b/dwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230713-e81f17d.diff @@ -1,342 +0,0 @@ -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/dwm-dwmfifo-20230714-e81f17d.diff b/dwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230714-e81f17d.diff @@ -0,0 +1,342 @@ +From 898a3f86703be6fb6f3690916797b80bf1d4dbc8 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..13537fc 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_RDWR | 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 @@ -28,7 +28,7 @@ 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) +* [dwm-dwmfifo-20230713-e81f17d.diff](dwm-dwmfifo-20230714-e81f17d.diff) (8.1k) (2023-07-14) Author ------