commit 77a71712f0d34efdd594addd4f4dd1058b8a3f30
Author: Santtu Lakkala <[email protected]>
Date:   Thu Jul 13 16:02:41 2023 +0300

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

diff --git a/dwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230713-e81f17d.diff 
b/dwm.suckless.org/patches/dwmfifo/dwm-dwmfifo-20230713-e81f17d.diff
new file mode 100644
index 00000000..fd3e911d
--- /dev/null
+++ 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 <[email protected]>
+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 == '     ')
++              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, '
', dend - bw)))
++                      return;
++              bw = pl = nl + 1;
++              longline = 0;
++      }
++
++      while ((nl = memchr(bw, '
', dend - bw))) {
++              for (i = commands; i < 1[&commands]; i++) {
++                      const char *arg;
++
++                      if (!(arg = strnprefix(pl, nl - pl, i->name)))
++                              continue;
++                      *nl = '++                       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
index 55d1434c..844c3ae1 100644
--- 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 - <[email protected]>
+* inz - <[email protected]>


Reply via email to