From 0d8f51e0a3be6876e74ab82c581018dd5191aff1 Mon Sep 17 00:00:00 2001
From: "Devin J. Pohly" <djpohly@gmail.com>
Date: Thu, 23 Apr 2020 20:40:02 -0500
Subject: implement focusmon and tagmon

---
 config.def.h |  4 ++++
 dwl.c        | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/config.def.h b/config.def.h
index 42be079..d3c1b0d 100644
--- a/config.def.h
+++ b/config.def.h
@@ -55,6 +55,10 @@ static const Key keys[] = {
 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space,      togglefloating, {0} },
 	{ MODKEY,                    XKB_KEY_0,          view,           {.ui = ~0} },
 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag,            {.ui = ~0} },
+	{ MODKEY,                    XKB_KEY_comma,      focusmon,       {.i = -1} },
+	{ MODKEY,                    XKB_KEY_period,     focusmon,       {.i = +1} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less,       tagmon,         {.i = -1} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater,    tagmon,         {.i = +1} },
 	TAGKEYS(          XKB_KEY_1, XKB_KEY_exclam,                     0),
 	TAGKEYS(          XKB_KEY_2, XKB_KEY_at,                         1),
 	TAGKEYS(          XKB_KEY_3, XKB_KEY_numbersign,                 2),
diff --git a/dwl.c b/dwl.c
index 633e80f..a8633e8 100644
--- a/dwl.c
+++ b/dwl.c
@@ -130,7 +130,9 @@ static void createnotify(struct wl_listener *listener, void *data);
 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 Monitor *dirtomon(int dir);
 static void focus(Client *c, struct wlr_surface *surface);
+static void focusmon(const Arg *arg);
 static void focusstack(const Arg *arg);
 static void incnmaster(const Arg *arg);
 static void inputdevice(struct wl_listener *listener, void *data);
@@ -149,12 +151,14 @@ static void resize(Client *c, int x, int y, int w, int h);
 static void resizemouse(const Arg *arg);
 static void run(char *startup_cmd);
 static Client *selclient(void);
+static void sendmon(Client *c, Monitor *m);
 static void setcursor(struct wl_listener *listener, void *data);
 static void setlayout(const Arg *arg);
 static void setmfact(const Arg *arg);
 static void setup(void);
 static void spawn(const Arg *arg);
 static void tag(const Arg *arg);
+static void tagmon(const Arg *arg);
 static void tile(Monitor *m);
 static void togglefloating(const Arg *arg);
 static void toggletag(const Arg *arg);
@@ -387,6 +391,22 @@ destroynotify(struct wl_listener *listener, void *data)
 	free(c);
 }
 
+Monitor *
+dirtomon(int dir)
+{
+	Monitor *m;
+
+	if (dir > 0) {
+		if (selmon->link.next == &mons)
+			return wl_container_of(mons.next, m, link);
+		return wl_container_of(selmon->link.next, m, link);
+	} else {
+		if (selmon->link.prev == &mons)
+			return wl_container_of(mons.prev, m, link);
+		return wl_container_of(selmon->link.prev, m, link);
+	}
+}
+
 void
 focus(Client *c, struct wlr_surface *surface)
 {
@@ -446,6 +466,17 @@ focus(Client *c, struct wlr_surface *surface)
 	}
 }
 
+void
+focusmon(const Arg *arg)
+{
+	Monitor *m = dirtomon(arg->i);
+
+	if (m == selmon)
+		return;
+	selmon = m;
+	focus(NULL, NULL);
+}
+
 void
 focusstack(const Arg *arg)
 {
@@ -933,6 +964,18 @@ selclient(void)
 	return c;
 }
 
+void
+sendmon(Client *c, Monitor *m)
+{
+	if (c->mon == m)
+		return;
+	c->mon = m;
+	c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
+
+	if (c == selclient())
+		focus(NULL, NULL);
+}
+
 void
 setcursor(struct wl_listener *listener, void *data)
 {
@@ -1099,6 +1142,15 @@ tag(const Arg *arg)
 	}
 }
 
+void
+tagmon(const Arg *arg)
+{
+	Client *sel = selclient();
+	if (!sel)
+		return;
+	sendmon(sel, dirtomon(arg->i));
+}
+
 void
 tile(Monitor *m)
 {
-- 
cgit v1.2.3