[PATCH] Add DWM control FIFO

From: sin <sin_AT_2f30.org>
Date: Wed, 29 Jan 2014 11:58:56 +0000

I've added the corresponding commands for all assigned
keybinds.

To use simply create the fifo in your .xinitrc, the
default path is at /tmp/dwm.fifo.

A simple command sequence would be:

   echo -n term > /tmp/dwm.fifo
   echo -n focusmon+ > /tmp/dwm.fifo
   echo -n term > /tmp/dwm.fifo
---
 config.def.h |   62 ++++++++++++++++++++
 dwm.c        |  179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 238 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 875885b..9264465 100644
--- a/config.def.h
+++ b/config.def.h
_AT_@ -108,3 +108,65 @@ static Button buttons[] = {
 	{ ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
 };
 
+static const char *dwmfifo = "/tmp/dwm.fifo";
+static Command commands[] = {
+	{ "dmenu",           dodmenu,          {.v = dmenucmd} },
+	{ "term",            doterm,           {.v = termcmd} },
+	{ "togglebar",       dotogglebar,      {0} },
+	{ "focusstack+",     dofocusstack,     {.i = +1} },
+	{ "focusstack-",     dofocusstack,     {.i = -1} },
+	{ "incnmaster+",     doincnmaster,     {.i = +1} },
+	{ "incnmaster-",     doincnmaster,     {.i = -1} },
+	{ "setmfact+",       dosetmfact,       {.f = +0.05} },
+	{ "setmfact-",       dosetmfact,       {.f = -0.05} },
+	{ "zoom",            dozoom,           {0} },
+	{ "view",            doview,           {0} },
+	{ "killclient",      dokillclient,     {0} },
+	{ "setlayout-tiled", dosetlayout,      {.v = &layouts[0]} },
+	{ "setlayout-float", dosetlayout,      {.v = &layouts[1]} },
+	{ "setlayout-mono",  dosetlayout,      {.v = &layouts[2]} },
+	{ "togglelayout",    dosetlayout,      {0} },
+	{ "togglefloating",  dotogglefloating, {0} },
+	{ "viewall",         doview,           {.ui = ~0} },
+	{ "tag",             dotag,            {.ui = ~0} },
+	{ "focusmon+",       dofocusmon,       {.i = +1} },
+	{ "focusmon-",       dofocusmon,       {.i = -1} },
+	{ "tagmon+",         dotagmon,         {.i = +1} },
+	{ "tagmon-",         dotagmon,         {.i = -1} },
+	{ "view1",           doview,           {.ui = 1 << 0} },
+	{ "view2",           doview,           {.ui = 1 << 1} },
+	{ "view3",           doview,           {.ui = 1 << 2} },
+	{ "view4",           doview,           {.ui = 1 << 3} },
+	{ "view5",           doview,           {.ui = 1 << 4} },
+	{ "view6",           doview,           {.ui = 1 << 5} },
+	{ "view7",           doview,           {.ui = 1 << 6} },
+	{ "view8",           doview,           {.ui = 1 << 7} },
+	{ "view9",           doview,           {.ui = 1 << 8} },
+	{ "toggleview1",     dotoggleview,     {.ui = 1 << 0} },
+	{ "toggleview2",     dotoggleview,     {.ui = 1 << 1} },
+	{ "toggleview3",     dotoggleview,     {.ui = 1 << 2} },
+	{ "toggleview4",     dotoggleview,     {.ui = 1 << 3} },
+	{ "toggleview5",     dotoggleview,     {.ui = 1 << 4} },
+	{ "toggleview6",     dotoggleview,     {.ui = 1 << 5} },
+	{ "toggleview7",     dotoggleview,     {.ui = 1 << 6} },
+	{ "toggleview8",     dotoggleview,     {.ui = 1 << 7} },
+	{ "toggleview9",     dotoggleview,     {.ui = 1 << 8} },
+	{ "tag1",            dotag,            {.ui = 1 << 0} },
+	{ "tag2",            dotag,            {.ui = 1 << 1} },
+	{ "tag3",            dotag,            {.ui = 1 << 2} },
+	{ "tag4",            dotag,            {.ui = 1 << 3} },
+	{ "tag5",            dotag,            {.ui = 1 << 4} },
+	{ "tag6",            dotag,            {.ui = 1 << 5} },
+	{ "tag7",            dotag,            {.ui = 1 << 6} },
+	{ "tag8",            dotag,            {.ui = 1 << 7} },
+	{ "tag9",            dotag,            {.ui = 1 << 8} },
+	{ "toggletag1",      dotoggletag,      {.ui = 1 << 0} },
+	{ "toggletag2",      dotoggletag,      {.ui = 1 << 1} },
+	{ "toggletag3",      dotoggletag,      {.ui = 1 << 2} },
+	{ "toggletag4",      dotoggletag,      {.ui = 1 << 3} },
+	{ "toggletag5",      dotoggletag,      {.ui = 1 << 4} },
+	{ "toggletag6",      dotoggletag,      {.ui = 1 << 5} },
+	{ "toggletag7",      dotoggletag,      {.ui = 1 << 6} },
+	{ "toggletag8",      dotoggletag,      {.ui = 1 << 7} },
+	{ "toggletag9",      dotoggletag,      {.ui = 1 << 8} },
+};
diff --git a/dwm.c b/dwm.c
index 1bbb4b3..7b1b8af 100644
--- a/dwm.c
+++ b/dwm.c
_AT_@ -21,6 +21,7 @@
  * To understand everything else, start reading main().
  */
 #include <errno.h>
+#include <fcntl.h>
 #include <locale.h>
 #include <stdarg.h>
 #include <signal.h>
_AT_@ -28,6 +29,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/select.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <X11/cursorfont.h>
_AT_@ -140,6 +143,12 @@ typedef struct {
 	int monitor;
 } Rule;
 
+typedef struct {
+	const char *name;
+	void (*func)(const Arg *arg);
+	const Arg arg;
+} Command;
+
 /* function declarations */
 static void applyrules(Client *c);
 static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact);
_AT_@ -161,9 +170,27 @@ 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 dodmenu(const Arg *arg);
+static void dofocusmon(const Arg *arg);
+static void dofocusstack(const Arg *arg);
+static void doincnmaster(const Arg *arg);
+static void dokillclient(const Arg *arg);
+static void dosetlayout(const Arg *arg);
+static void dosetmfact(const Arg *arg);
+static void dotag(const Arg *arg);
+static void dotagmon(const Arg *arg);
+static void doterm(const Arg *arg);
+static void dotogglebar(const Arg *arg);
+static void dotogglefloating(const Arg *arg);
+static void dotoggletag(const Arg *arg);
+static void dotoggleview(const Arg *arg);
+static void doview(const Arg *arg);
+static void dozoom(const Arg *arg);
 static void drawbar(Monitor *m);
 static void drawbars(void);
 static void enternotify(XEvent *e);
+static Bool evpredicate();
 static void expose(XEvent *e);
 static void focus(Client *c);
 static void focusin(XEvent *e);
_AT_@ -266,6 +293,7 @@ static Drw *drw;
 static Fnt *fnt;
 static Monitor *mons, *selmon;
 static Window root;
+static int fifofd;
 
 /* configuration, allows nested code to access above variables */
 #include "config.h"
_AT_@ -485,6 +513,8 @@ cleanup(void) {
 	XSync(dpy, False);
 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
 	XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
+	if (fifofd != -1)
+		close(fifofd);
 }
 
 void
_AT_@ -691,6 +721,121 @@ dirtomon(int dir) {
 }
 
 void
+dispatchcmd(void)
+{
+	int i;
+	char buf[BUFSIZ];
+	ssize_t n;
+
+	n = read(fifofd, buf, sizeof(buf) - 1);
+	if (n == -1)
+		die("Failed to read from DWM fifo\n");
+	buf[n] = '\0';
+	for (i = 0; i < LENGTH(commands); i++) {
+		if (strcmp(commands[i].name, buf) == 0) {
+			commands[i].func(&commands[i].arg);
+			break;
+		}
+	}
+}
+
+void
+dodmenu(const Arg *arg)
+{
+	spawn(arg);
+}
+
+static void
+dofocusmon(const Arg *arg)
+{
+	focusmon(arg);
+}
+
+void
+dofocusstack(const Arg *arg)
+{
+	focusstack(arg);
+}
+
+void
+doincnmaster(const Arg *arg)
+{
+	incnmaster(arg);
+}
+
+void
+dokillclient(const Arg *arg)
+{
+	killclient(arg);
+}
+
+void
+dosetlayout(const Arg *arg)
+{
+	setlayout(arg);
+}
+
+void
+dosetmfact(const Arg *arg)
+{
+	setmfact(arg);
+}
+
+static void
+dotag(const Arg *arg)
+{
+	tag(arg);
+}
+
+static void
+dotagmon(const Arg *arg)
+{
+	tagmon(arg);
+}
+
+void
+doterm(const Arg *arg)
+{
+	spawn(arg);
+}
+
+void
+dotogglebar(const Arg *arg)
+{
+	togglebar(arg);
+}
+
+static void
+dotogglefloating(const Arg *arg)
+{
+	togglefloating(arg);
+}
+
+static void
+dotoggletag(const Arg *arg)
+{
+	toggletag(arg);
+}
+
+static void
+dotoggleview(const Arg *arg)
+{
+	toggleview(arg);
+}
+
+void
+doview(const Arg *arg)
+{
+	view(arg);
+}
+
+void
+dozoom(const Arg *arg)
+{
+	zoom(arg);
+}
+
+void
 drawbar(Monitor *m) {
 	int x, xx, w;
 	unsigned int i, occ = 0, urg = 0;
_AT_@ -768,6 +913,12 @@ enternotify(XEvent *e) {
 	focus(c);
 }
 
+Bool
+evpredicate()
+{
+	return True;
+}
+
 void
 expose(XEvent *e) {
 	Monitor *m;
_AT_@ -1341,11 +1492,30 @@ restack(Monitor *m) {
 void
 run(void) {
 	XEvent ev;
+	fd_set rfds;
+	int n;
+	int x11fd, maxfd;
 	/* main event loop */
 	XSync(dpy, False);
-	while(running && !XNextEvent(dpy, &ev))
-		if(handler[ev.type])
-			handler[ev.type](&ev); /* call handler */
+	x11fd = ConnectionNumber(dpy);
+	maxfd = fifofd;
+	if (x11fd > maxfd)
+		maxfd = x11fd;
+	maxfd++;
+	while (running) {
+		FD_ZERO(&rfds);
+		FD_SET(fifofd, &rfds);
+		FD_SET(x11fd, &rfds);
+		n = select(maxfd, &rfds, NULL, NULL, NULL);
+		if (n > 0) {
+			if (FD_ISSET(fifofd, &rfds))
+				dispatchcmd();
+			if (FD_ISSET(x11fd, &rfds))
+				if (XCheckIfEvent(dpy, &ev, evpredicate, NULL))
+					if (handler[ev.type])
+						handler[ev.type](&ev); /* call handler */
+		}
+	}
 }
 
 void
_AT_@ -1543,6 +1713,9 @@ setup(void) {
 	XSelectInput(dpy, root, wa.event_mask);
 	grabkeys();
 	focus(NULL);
+	fifofd = open(dwmfifo, O_RDWR | O_NONBLOCK);
+	if (fifofd < 0)
+		die("Failed to open DWM fifo\n");
 }
 
 void
-- 
1.7.10.4
--bp/iNruPH9dso1Pn--
Received on Mon Sep 17 2001 - 00:00:00 CEST

This archive was generated by hypermail 2.3.0 : Wed Jan 29 2014 - 14:00:04 CET