diff --git a/docs/modules/Workspaces.md b/docs/modules/Workspaces.md index bc66c7c..9dfe7df 100644 --- a/docs/modules/Workspaces.md +++ b/docs/modules/Workspaces.md @@ -98,15 +98,16 @@ end: ## Styling -| Selector | Description | -|--------------------------------|--------------------------------------| -| `.workspaces` | Workspaces widget box | -| `.workspaces .item` | Workspace button | -| `.workspaces .item.focused` | Workspace button (workspace focused) | +| Selector | Description | +| ------------------------------ | ------------------------------------------------------- | +| `.workspaces` | Workspaces widget box | +| `.workspaces .item` | Workspace button | +| `.workspaces .item.focused` | Workspace button (workspace focused) | | `.workspaces .item.visible` | Workspace button (workspace visible, including focused) | -| `.workspaces .item.inactive` | Workspace button (favourite, not currently open) -| `.workspaces .item .icon` | Workspace button icon (any type) | -| `.workspaces .item .text-icon` | Workspace button icon (textual only) | -| `.workspaces .item .image` | Workspace button icon (image only) | +| `.workspaces .item.urgent` | Workspace button (workspace contains urgent window) | +| `.workspaces .item.inactive` | Workspace button (favourite, not currently open) | +| `.workspaces .item .icon` | Workspace button icon (any type) | +| `.workspaces .item .text-icon` | Workspace button icon (textual only) | +| `.workspaces .item .image` | Workspace button icon (image only) | For more information on styling, please see the [styling guide](styling-guide). diff --git a/examples/style.css b/examples/style.css index f32fbcc..89a3468 100644 --- a/examples/style.css +++ b/examples/style.css @@ -201,6 +201,10 @@ scale trough { background-color: @color_bg_dark; } +.workspaces .item.urgent { + background-color: @color_urgent; +} + .workspaces .item:hover { box-shadow: inset 0 -3px; } diff --git a/src/clients/compositor/hyprland.rs b/src/clients/compositor/hyprland.rs index ee526ea..f7bb09f 100644 --- a/src/clients/compositor/hyprland.rs +++ b/src/clients/compositor/hyprland.rs @@ -166,6 +166,9 @@ impl Client { } { + let tx = tx.clone(); + let lock = lock.clone(); + event_listener.add_workspace_destroy_handler(move |data| { let _lock = lock!(lock); debug!("Received workspace destroy: {data:?}"); @@ -173,6 +176,35 @@ impl Client { }); } + { + event_listener.add_urgent_state_handler(move |address| { + let _lock = lock!(lock); + debug!("Received urgent state: {address:?}"); + + let clients = match hyprland::data::Clients::get() { + Ok(clients) => clients, + Err(err) => { + error!("Failed to get clients: {err}"); + return; + } + }; + clients.iter().find(|c| c.address == address).map_or_else( + || { + error!("Unable to locate client"); + }, + |c| { + send!( + tx, + WorkspaceUpdate::Urgent { + id: c.workspace.id as i64, + urgent: true, + } + ); + }, + ); + }); + } + event_listener .start_listener() .expect("Failed to start listener"); @@ -194,6 +226,14 @@ impl Client { } ); + send!( + tx, + WorkspaceUpdate::Urgent { + id: workspace.id, + urgent: false, + } + ); + prev_workspace.replace(workspace); } diff --git a/src/clients/compositor/mod.rs b/src/clients/compositor/mod.rs index e03dbe4..5243fcc 100644 --- a/src/clients/compositor/mod.rs +++ b/src/clients/compositor/mod.rs @@ -135,6 +135,12 @@ pub enum WorkspaceUpdate { name: String, }, + /// The urgent state of a node changed. + Urgent { + id: i64, + urgent: bool, + }, + /// An update was triggered by the compositor but this was not mapped by Ironbar. /// /// This is purely used for ergonomics within the compositor clients diff --git a/src/clients/compositor/sway.rs b/src/clients/compositor/sway.rs index 397c225..7cc61b7 100644 --- a/src/clients/compositor/sway.rs +++ b/src/clients/compositor/sway.rs @@ -109,6 +109,16 @@ impl From for WorkspaceUpdate { WorkspaceChange::Move => { Self::Move(event.current.expect("Missing current workspace").into()) } + WorkspaceChange::Urgent => { + if let Some(node) = event.current { + Self::Urgent { + id: node.id, + urgent: node.urgent, + } + } else { + Self::Unknown + } + } _ => Self::Unknown, } } diff --git a/src/modules/workspaces.rs b/src/modules/workspaces.rs index 1bb8bd3..c9fbc77 100644 --- a/src/modules/workspaces.rs +++ b/src/modules/workspaces.rs @@ -416,6 +416,16 @@ impl Module for WorkspacesModule { } } } + WorkspaceUpdate::Urgent { id, urgent } => { + let button = button_map.get(&id); + if let Some(item) = button { + if urgent { + item.add_class("urgent"); + } else { + item.style_context().remove_class("urgent"); + } + } + } WorkspaceUpdate::Unknown => warn!("Received unknown type workspace event") }; });