Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

window urgency #1319

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft

window urgency #1319

wants to merge 4 commits into from

Conversation

Duncaen
Copy link
Contributor

@Duncaen Duncaen commented Mar 21, 2025

quick draft of urgency support through serial-less xdg-activation. This PR adds an urgency boolean to windows and adds methods to set and get the urgency through the LayoutElement trait.
The next commit adds IPC events that indicate workspace urgency based on whether a window on the workspace has urgency, not sure if the IPC should also emit window events for that.

yambar patch:

From 90871daaac49fd87c29445b072ab7fc85d924eec Mon Sep 17 00:00:00 2001
From: Duncan Overbruck <[email protected]>
Date: Fri, 21 Mar 2025 18:12:18 +0100
Subject: [PATCH] add urgency tag to niri-workspaces

---
 modules/niri-common.c     | 23 +++++++++++++++++++++++
 modules/niri-common.h     |  2 ++
 modules/niri-workspaces.c |  5 +++--
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/modules/niri-common.c b/modules/niri-common.c
index ac53921..f380d85 100644
--- a/modules/niri-common.c
+++ b/modules/niri-common.c
@@ -12,6 +12,7 @@
 #include <unistd.h>
 
 #include "../log.h"
+#include "json_object.h"
 #include "niri-common.h"
 
 #define LOG_MODULE "niri:common"
@@ -82,6 +83,7 @@ parser(char *response)
                 ws->active = json_object_get_boolean(json_object_object_get(ws_obj, "is_active"));
                 ws->focused = json_object_get_boolean(json_object_object_get(ws_obj, "is_focused"));
                 ws->empty = json_object_get_int(json_object_object_get(ws_obj, "active_window_id")) == 0;
+                ws->urgent = json_object_get_boolean(json_object_object_get(ws_obj, "is_urgent"));
 
                 char const *name = json_object_get_string(json_object_object_get(ws_obj, "name"));
                 if (name)
@@ -185,6 +187,27 @@ parser(char *response)
             events |= keyboard_layouts_switched;
         }
 
+        // "WorkspaceUrgencyChanged": {
+        //   "id": 1,
+        //   "urgent": true
+        // }
+        else if (strcmp(key, "WorkspaceUrgencyChanged") == 0) {
+            json_object *obj = json_object_iter_peek_value(&it);
+            int id = json_object_get_int(json_object_object_get(obj, "id"));
+            bool urgent = json_object_get_boolean(json_object_object_get(obj, "urgent"));
+
+            tll_foreach(instance.workspaces, it)
+            {
+                if (it->item->id == id) {
+                    it->item->urgent = urgent;
+                    break;
+                }
+            }
+            mtx_unlock(&instance.mtx);
+
+            events |= workspace_urgency_changed;
+        }
+
         json_object_iter_next(&it);
     }
 
diff --git a/modules/niri-common.h b/modules/niri-common.h
index 18afe38..8aa2f39 100644
--- a/modules/niri-common.h
+++ b/modules/niri-common.h
@@ -10,6 +10,7 @@ enum niri_event {
     workspace_active_window_changed = (1 << 2),
     keyboard_layouts_changed = (1 << 3),
     keyboard_layouts_switched = (1 << 4),
+    workspace_urgency_changed = (1 << 5),
 };
 
 struct niri_subscriber {
@@ -24,6 +25,7 @@ struct niri_workspace {
     bool active;
     bool focused;
     bool empty;
+    bool urgent;
 };
 
 struct niri_socket {
diff --git a/modules/niri-workspaces.c b/modules/niri-workspaces.c
index bca0150..99a8c83 100644
--- a/modules/niri-workspaces.c
+++ b/modules/niri-workspaces.c
@@ -56,8 +56,9 @@ content(struct module *module)
                 tag_new_bool(module, "active", it->item->active),
                 tag_new_bool(module, "focused", it->item->focused),
                 tag_new_bool(module, "empty", it->item->empty),
+                tag_new_bool(module, "urgent", it->item->urgent),
             },
-            .count = 5,
+            .count = 6,
         };
 
         exposable[i++] = private->label->instantiate(private->label, &tags);
@@ -86,7 +87,7 @@ run(struct module *module)
     if (private->niri == NULL)
         return 1;
 
-    int fd = niri_socket_subscribe(workspaces_changed | workspace_activated | workspace_active_window_changed);
+    int fd = niri_socket_subscribe(workspaces_changed | workspace_activated | workspace_active_window_changed | workspace_urgency_changed);
     if (fd == -1) {
         niri_socket_close();
         return 1;
-- 
2.49.0

And a yambar configuration example:

  left:
    - niri-workspaces:
        content:
            map:
              default: {string: {text: "{id}", margin: 5}}
              conditions:
                urgent: {string: {text: "{id}", deco: {background: {color: af3029ff } }, margin: 5}}
                active: {string: {text: "{id}", deco: {background: {color: 383838ff } }, margin: 5}}

@Duncaen Duncaen marked this pull request as draft March 21, 2025 17:36
@Duncaen Duncaen force-pushed the urgent branch 2 times, most recently from 972eefc to a9b5bf6 Compare March 22, 2025 18:26
@FreeFull
Copy link
Contributor

I think it would also be nice to have a niri action to set a specific window as urgent, similar to niri msg action focus-window --id <ID>

@Duncaen Duncaen force-pushed the urgent branch 2 times, most recently from 524415d to 5f0e514 Compare March 27, 2025 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants