From a09e766a4342f580582082a92b2de65f33208eb4 Mon Sep 17 00:00:00 2001
From: Christopher Drelich <cd@cdrakka.com>
Date: Thu, 24 May 2018 00:56:56 -0400
Subject: [PATCH] Function to cycle through available layouts.

MOD-CTRL-, and MOD-CTRL-.
cycle backwards and forwards through available layouts.
Probably only useful if you have a lot of additional layouts.
The NULL, NULL layout should always be the last layout in your list,
in order to guarantee consistent behavior.
---
 config.def.h |  3 +++
 dwm.1        |  6 ++++++
 dwm.c        | 18 ++++++++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/config.def.h b/config.def.h
index a9ac303..153b880 100644
--- a/config.def.h
+++ b/config.def.h
@@ -41,6 +41,7 @@ static const Layout layouts[] = {
 	{ "[]=",      tile },    /* first entry is default */
 	{ "><>",      NULL },    /* no layout function means floating behavior */
 	{ "[M]",      monocle },
+	{ NULL,       NULL },
 };
 
 /* key definitions */
@@ -76,6 +77,8 @@ static Key keys[] = {
 	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
 	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
 	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
+	{ MODKEY|ControlMask,		XK_comma,  cyclelayout,    {.i = -1 } },
+	{ MODKEY|ControlMask,           XK_period, cyclelayout,    {.i = +1 } },
 	{ MODKEY,                       XK_space,  setlayout,      {0} },
 	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
 	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
diff --git a/dwm.1 b/dwm.1
index 13b3729..165891b 100644
--- a/dwm.1
+++ b/dwm.1
@@ -92,6 +92,12 @@ Sets monocle layout.
 .B Mod1\-space
 Toggles between current and previous layout.
 .TP
+.B Mod1\-Control\-,
+Cycles backwards in layout list.
+.TP
+.B Mod1\-Control\-.
+Cycles forwards in layout list.
+.TP
 .B Mod1\-j
 Focus next window.
 .TP
diff --git a/dwm.c b/dwm.c
index bb95e26..db73000 100644
--- a/dwm.c
+++ b/dwm.c
@@ -157,6 +157,7 @@ static void configure(Client *c);
 static void configurenotify(XEvent *e);
 static void configurerequest(XEvent *e);
 static Monitor *createmon(void);
+static void cyclelayout(const Arg *arg);
 static void destroynotify(XEvent *e);
 static void detach(Client *c);
 static void detachstack(Client *c);
@@ -645,6 +646,23 @@ createmon(void)
 }
 
 void
+cyclelayout(const Arg *arg) {
+	Layout *l;
+	for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++);
+	if(arg->i > 0) {
+		if(l->symbol && (l + 1)->symbol)
+			setlayout(&((Arg) { .v = (l + 1) }));
+		else
+			setlayout(&((Arg) { .v = layouts }));
+	} else {
+		if(l != layouts && (l - 1)->symbol)
+			setlayout(&((Arg) { .v = (l - 1) }));
+		else
+			setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] }));
+	}
+}
+
+void
 destroynotify(XEvent *e)
 {
 	Client *c;
-- 
2.7.4

