niri: add support for urgency indicators to workspaces

This commit is contained in:
Duncan Overbruck
2025-05-13 21:34:24 +02:00
parent 0332d2ebf8
commit 47e0f42523
3 changed files with 21 additions and 0 deletions

View File

@ -70,6 +70,7 @@ Additional to workspace name matching, the following *format-icons* can be set.
- *default*: Will be shown, when no string matches are found. - *default*: Will be shown, when no string matches are found.
- *focused*: Will be shown, when workspace is focused. - *focused*: Will be shown, when workspace is focused.
- *active*: Will be shown, when workspace is active on its output. - *active*: Will be shown, when workspace is active on its output.
- *urgent*: Will be shown, when workspace has urgent windows.
# EXAMPLES # EXAMPLES
@ -95,6 +96,7 @@ Additional to workspace name matching, the following *format-icons* can be set.
- *#workspaces button* - *#workspaces button*
- *#workspaces button.focused*: The single focused workspace. - *#workspaces button.focused*: The single focused workspace.
- *#workspaces button.active*: The workspace is active (visible) on its output. - *#workspaces button.active*: The workspace is active (visible) on its output.
- *#workspaces button.urgent*: The workspace has one or more urgent windows.
- *#workspaces button.empty*: The workspace is empty. - *#workspaces button.empty*: The workspace is empty.
- *#workspaces button.current_output*: The workspace is from the same output as - *#workspaces button.current_output*: The workspace is from the same output as
the bar that it is displayed on. the bar that it is displayed on.

View File

@ -147,6 +147,17 @@ void IPC::parseIPC(const std::string &line) {
} else { } else {
spdlog::error("Active window changed on unknown workspace"); spdlog::error("Active window changed on unknown workspace");
} }
} else if (const auto &payload = ev["WorkspaceUrgencyChanged"]) {
const auto id = payload["id"].asUInt64();
const auto urgent = payload["urgent"].asBool();
auto it = std::find_if(workspaces_.begin(), workspaces_.end(),
[id](const auto &ws) { return ws["id"].asUInt64() == id; });
if (it != workspaces_.end()) {
auto &ws = *it;
ws["is_urgent"] = urgent;
} else {
spdlog::error("Urgency changed for unknown workspace");
}
} else if (const auto &payload = ev["KeyboardLayoutsChanged"]) { } else if (const auto &payload = ev["KeyboardLayoutsChanged"]) {
const auto &layouts = payload["keyboard_layouts"]; const auto &layouts = payload["keyboard_layouts"];
const auto &names = layouts["names"]; const auto &names = layouts["names"];

View File

@ -20,6 +20,7 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value
gIPC->registerForIPC("WorkspacesChanged", this); gIPC->registerForIPC("WorkspacesChanged", this);
gIPC->registerForIPC("WorkspaceActivated", this); gIPC->registerForIPC("WorkspaceActivated", this);
gIPC->registerForIPC("WorkspaceActiveWindowChanged", this); gIPC->registerForIPC("WorkspaceActiveWindowChanged", this);
gIPC->registerForIPC("WorkspaceUrgencyChanged", this);
dp.emit(); dp.emit();
} }
@ -67,6 +68,11 @@ void Workspaces::doUpdate() {
else else
style_context->remove_class("active"); style_context->remove_class("active");
if (ws["is_urgent"].asBool())
style_context->add_class("urgent");
else
style_context->remove_class("urgent");
if (ws["output"]) { if (ws["output"]) {
if (ws["output"].asString() == bar_.output->name) if (ws["output"].asString() == bar_.output->name)
style_context->add_class("current_output"); style_context->add_class("current_output");
@ -166,6 +172,8 @@ std::string Workspaces::getIcon(const std::string &value, const Json::Value &ws)
const auto &icons = config_["format-icons"]; const auto &icons = config_["format-icons"];
if (!icons) return value; if (!icons) return value;
if (ws["is_urgent"].asBool() && icons["urgent"]) return icons["urgent"].asString();
if (ws["is_focused"].asBool() && icons["focused"]) return icons["focused"].asString(); if (ws["is_focused"].asBool() && icons["focused"]) return icons["focused"].asString();
if (ws["is_active"].asBool() && icons["active"]) return icons["active"].asString(); if (ws["is_active"].asBool() && icons["active"]) return icons["active"].asString();