From d8cf65c74f3b7132302027cfbf940de8548d7d17 Mon Sep 17 00:00:00 2001
From: "Devin J. Pohly" <djpohly@gmail.com>
Date: Sat, 22 May 2021 21:18:48 -0500
Subject: implement urgency hint

---
 dwl.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 9 deletions(-)

(limited to 'dwl.c')

diff --git a/dwl.c b/dwl.c
index d7e798b..4d0bc84 100644
--- a/dwl.c
+++ b/dwl.c
@@ -37,6 +37,7 @@
 #include <wlr/types/wlr_viewporter.h>
 #include <wlr/types/wlr_virtual_keyboard_v1.h>
 #include <wlr/types/wlr_xcursor_manager.h>
+#include <wlr/types/wlr_xdg_activation_v1.h>
 #include <wlr/types/wlr_xdg_decoration_v1.h>
 #include <wlr/types/wlr_xdg_output_v1.h>
 #include <wlr/types/wlr_xdg_shell.h>
@@ -107,7 +108,7 @@ typedef struct {
 #endif
 	int bw;
 	unsigned int tags;
-	int isfloating;
+	int isfloating, isurgent;
 	uint32_t resize; /* configure serial of a pending resize */
 	int prevx;
 	int prevy;
@@ -290,6 +291,7 @@ static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
 static void unmapnotify(struct wl_listener *listener, void *data);
 static void updatemons(struct wl_listener *listener, void *data);
 static void updatetitle(struct wl_listener *listener, void *data);
+static void urgent(struct wl_listener *listener, void *data);
 static void view(const Arg *arg);
 static void virtualkeyboard(struct wl_listener *listener, void *data);
 static Client *xytoclient(double x, double y);
@@ -306,6 +308,7 @@ static struct wlr_renderer *drw;
 static struct wlr_compositor *compositor;
 
 static struct wlr_xdg_shell *xdg_shell;
+static struct wlr_xdg_activation_v1 *activation;
 static struct wl_list clients; /* tiling order */
 static struct wl_list fstack;  /* focus order */
 static struct wl_list stack;   /* stacking z-order */
@@ -347,6 +350,7 @@ static struct wl_listener new_xdg_surface = {.notify = createnotify};
 static struct wl_listener new_layer_shell_surface = {.notify = createlayersurface};
 static struct wl_listener output_mgr_apply = {.notify = outputmgrapply};
 static struct wl_listener output_mgr_test = {.notify = outputmgrtest};
+static struct wl_listener request_activate = {.notify = urgent};
 static struct wl_listener request_cursor = {.notify = setcursor};
 static struct wl_listener request_set_psel = {.notify = setpsel};
 static struct wl_listener request_set_sel = {.notify = setsel};
@@ -1078,6 +1082,7 @@ focusclient(Client *c, int lift)
 		wl_list_remove(&c->flink);
 		wl_list_insert(&fstack, &c->flink);
 		selmon = c->mon;
+		c->isurgent = 0;
 	}
 	printstatus();
 
@@ -1550,22 +1555,29 @@ void
 printstatus(void)
 {
 	Monitor *m = NULL;
-	Client *c = NULL;
-	unsigned int activetags;
+	Client *c;
+	unsigned int occ, urg, sel;
 
 	wl_list_for_each(m, &mons, link) {
-		activetags=0;
+		occ = urg = 0;
 		wl_list_for_each(c, &clients, link) {
-			if (c->mon == m)
-				activetags |= c->tags;
+			if (c->mon != m)
+				continue;
+			occ |= c->tags;
+			if (c->isurgent)
+				urg |= c->tags;
 		}
-		if (focustop(m))
+		if ((c = focustop(m))) {
 			printf("%s title %s\n", m->wlr_output->name, client_get_title(focustop(m)));
-		else
+			sel = c->tags;
+		} else {
 			printf("%s title \n", m->wlr_output->name);
+			sel = 0;
+		}
 
 		printf("%s selmon %u\n", m->wlr_output->name, m == selmon);
-		printf("%s tags %u %u\n", m->wlr_output->name, activetags, m->tagset[m->seltags]);
+		printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags],
+				sel, urg);
 		printf("%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol);
 	}
 	fflush(stdout);
@@ -1825,6 +1837,7 @@ run(char *startup_cmd)
 	}
 	/* If nobody is reading the status output, don't terminate */
 	signal(SIGPIPE, SIG_IGN);
+	printstatus();
 
 	/* Run the Wayland event loop. This does not return until you exit the
 	 * compositor. Starting the backend rigged up all of the necessary event
@@ -1997,6 +2010,10 @@ setup(void)
 	wlr_primary_selection_v1_device_manager_create(dpy);
 	wlr_viewporter_create(dpy);
 
+	/* Initializes the interface used to implement urgency hints */
+	activation = wlr_xdg_activation_v1_create(dpy);
+	wl_signal_add(&activation->events.request_activate, &request_activate);
+
 	/* Creates an output layout, which a wlroots utility for working with an
 	 * arrangement of screens in a physical layout. */
 	output_layout = wlr_output_layout_create();
@@ -2310,6 +2327,21 @@ updatetitle(struct wl_listener *listener, void *data)
 		printstatus();
 }
 
+void
+urgent(struct wl_listener *listener, void *data)
+{
+	struct wlr_xdg_activation_v1_request_activate_event *event = data;
+	Client *c;
+
+	if (!wlr_surface_is_xdg_surface(event->surface))
+		return;
+	c = wlr_xdg_surface_from_wlr_surface(event->surface)->data;
+	if (c != selclient()) {
+		c->isurgent = 1;
+		printstatus();
+	}
+}
+
 void
 view(const Arg *arg)
 {
-- 
cgit v1.2.1