aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--niri-ipc/src/lib.rs9
-rw-r--r--niri-ipc/src/state.rs7
-rw-r--r--src/ipc/client.rs3
-rw-r--r--src/ipc/server.rs7
-rw-r--r--src/layout/workspace.rs4
5 files changed, 30 insertions, 0 deletions
diff --git a/niri-ipc/src/lib.rs b/niri-ipc/src/lib.rs
index 75d9a543..fcb2d1ff 100644
--- a/niri-ipc/src/lib.rs
+++ b/niri-ipc/src/lib.rs
@@ -1150,6 +1150,8 @@ pub struct Workspace {
///
/// Can be `None` if no outputs are currently connected.
pub output: Option<String>,
+ /// Whether the workspace currently has an urgent window in its output.
+ pub is_urgent: bool,
/// Whether the workspace is currently active on its output.
///
/// Every output has one active workspace, the one that is currently visible on that output.
@@ -1224,6 +1226,13 @@ pub enum Event {
/// workspaces are missing from here, then they were deleted.
workspaces: Vec<Workspace>,
},
+ /// The workspace urgency changed.
+ WorkspaceUrgencyChanged {
+ /// Id of the workspace.
+ id: u64,
+ /// Whether this workspace has an urgent window.
+ urgent: bool,
+ },
/// A workspace was activated on an output.
///
/// This doesn't always mean the workspace became focused, just that it's now the active
diff --git a/niri-ipc/src/state.rs b/niri-ipc/src/state.rs
index 0689104d..9edeeabf 100644
--- a/niri-ipc/src/state.rs
+++ b/niri-ipc/src/state.rs
@@ -103,6 +103,13 @@ impl EventStreamStatePart for WorkspacesState {
Event::WorkspacesChanged { workspaces } => {
self.workspaces = workspaces.into_iter().map(|ws| (ws.id, ws)).collect();
}
+ Event::WorkspaceUrgencyChanged { id, urgent } => {
+ for ws in self.workspaces.values_mut() {
+ if ws.id == id {
+ ws.is_urgent = urgent;
+ }
+ }
+ }
Event::WorkspaceActivated { id, focused } => {
let ws = self.workspaces.get(&id);
let ws = ws.expect("activated workspace was missing from the map");
diff --git a/src/ipc/client.rs b/src/ipc/client.rs
index 6f969703..654890ab 100644
--- a/src/ipc/client.rs
+++ b/src/ipc/client.rs
@@ -405,6 +405,9 @@ pub fn handle_msg(msg: Msg, json: bool) -> anyhow::Result<()> {
Event::WorkspacesChanged { workspaces } => {
println!("Workspaces changed: {workspaces:?}");
}
+ Event::WorkspaceUrgencyChanged { id, urgent } => {
+ println!("Workspace {id}: urgency changed to {urgent}");
+ }
Event::WorkspaceActivated { id, focused } => {
let word = if focused { "focused" } else { "activated" };
println!("Workspace {word}: {id}");
diff --git a/src/ipc/server.rs b/src/ipc/server.rs
index 06ff0fd1..b3901998 100644
--- a/src/ipc/server.rs
+++ b/src/ipc/server.rs
@@ -579,6 +579,12 @@ impl State {
});
}
+ // Check if this workspace urgent state changed.
+ let urgent = ws.is_urgent();
+ if urgent != ipc_ws.is_urgent {
+ events.push(Event::WorkspaceUrgencyChanged { id, urgent });
+ }
+
// Check if this workspace became focused.
let is_focused = Some(id) == focused_ws_id;
if is_focused && !ipc_ws.is_focused {
@@ -610,6 +616,7 @@ impl State {
idx: u8::try_from(ws_idx + 1).unwrap_or(u8::MAX),
name: ws.name().cloned(),
output: mon.map(|mon| mon.output_name().clone()),
+ is_urgent: ws.is_urgent(),
is_active: mon.is_some_and(|mon| mon.active_workspace_idx() == ws_idx),
is_focused: Some(id) == focused_ws_id,
active_window_id: ws.active_window().map(|win| win.id().get()),
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs
index 6ae045f7..c6662214 100644
--- a/src/layout/workspace.rs
+++ b/src/layout/workspace.rs
@@ -1608,6 +1608,10 @@ impl<W: LayoutElement> Workspace<W> {
self.scrolling.scroll_amount_to_activate(window)
}
+ pub fn is_urgent(&self) -> bool {
+ self.windows().any(|win| win.is_urgent())
+ }
+
pub fn activate_window(&mut self, window: &W::Id) -> bool {
if self.floating.activate_window(window) {
self.floating_is_active = FloatingActive::Yes;