From 623867a367ba8c3ee9ac1582015dcf1d6991a78f Mon Sep 17 00:00:00 2001
From: "Devin J. Pohly" <djpohly@gmail.com>
Date: Thu, 23 Apr 2020 00:47:15 -0500
Subject: turn focusnext into dwm's focusstack

---
 config.def.h | 12 +++++++-----
 dwl.c        | 27 ++++++++++++++++++---------
 2 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/config.def.h b/config.def.h
index ede6f72..6eb617b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -32,11 +32,13 @@ static const struct xkb_rule_names xkb_rules = {
 static const char *termcmd[]  = { "kitty", "-o", "linux_display_server=wayland", NULL };
 
 static const Key keys[] = {
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn,     {.v = termcmd } },
-	{ MODKEY,                    XKB_KEY_j,      focusnext, {0} },
-	{ MODKEY,                    XKB_KEY_t,      setlayout, {.v = &layouts[0]} },
-	{ MODKEY,                    XKB_KEY_f,      setlayout, {.v = &layouts[1]} },
-	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q,      quit,      {0} },
+	/* modifier                  key                 function        argument */
+	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return,     spawn,          {.v = termcmd } },
+	{ MODKEY,                    XKB_KEY_j,          focusstack,     {.i = +1} },
+	{ MODKEY,                    XKB_KEY_k,          focusstack,     {.i = -1} },
+	{ MODKEY,                    XKB_KEY_t,          setlayout,      {.v = &layouts[0]} },
+	{ MODKEY,                    XKB_KEY_f,          setlayout,      {.v = &layouts[1]} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q,          quit,           {0} },
 };
 
 static const Button buttons[] = {
diff --git a/dwl.c b/dwl.c
index 8add044..6f117c1 100644
--- a/dwl.c
+++ b/dwl.c
@@ -125,7 +125,7 @@ static void createpointer(struct wlr_input_device *device);
 static void cursorframe(struct wl_listener *listener, void *data);
 static void destroynotify(struct wl_listener *listener, void *data);
 static void focus(Client *c, struct wlr_surface *surface);
-static void focusnext(const Arg *arg);
+static void focusstack(const Arg *arg);
 static void inputdevice(struct wl_listener *listener, void *data);
 static bool keybinding(uint32_t mods, xkb_keysym_t sym);
 static void keypress(struct wl_listener *listener, void *data);
@@ -409,20 +409,29 @@ focus(Client *c, struct wlr_surface *surface)
 }
 
 void
-focusnext(const Arg *arg)
+focusstack(const Arg *arg)
 {
-	/* Focus the client on the selected monitor which comes first in tiling
-	 * order after the currently selected client */
+	/* Focus the next or previous client (in tiling order) on selmon */
 	Client *sel = selclient();
 	if (!sel)
 		return;
 	Client *c;
-	wl_list_for_each(c, &sel->link, link) {
-		if (&c->link == &clients)
-			continue;  /* wrap past the sentinel node */
-		if (VISIBLEON(c, selmon))
-			break;  /* found it */
+	if (arg->i > 0) {
+		wl_list_for_each(c, &sel->link, link) {
+			if (&c->link == &clients)
+				continue;  /* wrap past the sentinel node */
+			if (VISIBLEON(c, selmon))
+				break;  /* found it */
+		}
+	} else {
+		wl_list_for_each_reverse(c, &sel->link, link) {
+			if (&c->link == &clients)
+				continue;  /* wrap past the sentinel node */
+			if (VISIBLEON(c, selmon))
+				break;  /* found it */
+		}
 	}
+	/* If only one client is visible on selmon, then c == sel */
 	focus(c, c->xdg_surface->surface);
 }
 
-- 
cgit v1.2.3