diff --git a/include/modules/niri/workspaces.hpp b/include/modules/niri/workspaces.hpp index a6850ed1..1dc6837c 100644 --- a/include/modules/niri/workspaces.hpp +++ b/include/modules/niri/workspaces.hpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include "AModule.hpp" #include "bar.hpp" @@ -20,11 +22,14 @@ class Workspaces : public AModule, public EventHandler { void doUpdate(); Gtk::Button &addButton(const Json::Value &ws); std::string getIcon(const std::string &value, const Json::Value &ws); + bool isWorkspaceIgnored(const std::string &name); const Bar &bar_; Gtk::Box box_; // Map from niri workspace id to button. std::unordered_map buttons_; + // Vec of regex rules to ignore workspaces. + std::vector ignoreWorkspaces_; }; } // namespace waybar::modules::niri diff --git a/man/waybar-niri-workspaces.5.scd b/man/waybar-niri-workspaces.5.scd index 4be85eb3..f1fc6775 100644 --- a/man/waybar-niri-workspaces.5.scd +++ b/man/waybar-niri-workspaces.5.scd @@ -50,6 +50,11 @@ Addressed by *niri/workspaces* default: false ++ Enables this module to consume all left over space dynamically. +*ignore-workspaces*: ++ + typeof: array ++ + default: [] ++ + Regexes to match against workspaces names and index's. If there's a match, the workspace will not be shown. + # FORMAT REPLACEMENTS *{value}*: Name of the workspace, or index for unnamed workspaces, diff --git a/src/modules/niri/workspaces.cpp b/src/modules/niri/workspaces.cpp index 7dfc0b35..6c17beb3 100644 --- a/src/modules/niri/workspaces.cpp +++ b/src/modules/niri/workspaces.cpp @@ -15,6 +15,24 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value box_.get_style_context()->add_class(MODULE_CLASS); event_box_.add(box_); + // Parse ignore-workspaces rules. + auto ignoreWorkspaces = config["ignore-workspaces"]; + if (ignoreWorkspaces.isArray()) { + for (const auto &workspaceRegex : ignoreWorkspaces) { + if (workspaceRegex.isString()) { + std::string ruleString = workspaceRegex.asString(); + try { + const std::regex rule{ruleString, std::regex_constants::icase}; + ignoreWorkspaces_.emplace_back(rule); + } catch (const std::regex_error &e) { + spdlog::error("Invalid ignore-workspaces rule {}: {}", ruleString, e.what()); + } + } else { + spdlog::error("Not a string in ignore-workspaces: '{}'", workspaceRegex); + } + } + } + if (!gIPC) gIPC = std::make_unique(); gIPC->registerForIPC("WorkspacesChanged", this); @@ -37,6 +55,16 @@ void Workspaces::doUpdate() { const auto &workspaces = gIPC->workspaces(); std::copy_if(workspaces.cbegin(), workspaces.cend(), std::back_inserter(my_workspaces), [&](const auto &ws) { + std::string name; + if (ws["name"]) { + name = ws["name"].asString(); + } else { + name = std::to_string(ws["idx"].asUInt()); + } + if (isWorkspaceIgnored(name)) { + return false; + } + if (alloutputs) return true; return ws["output"].asString() == bar_.output->name; }); @@ -193,4 +221,13 @@ std::string Workspaces::getIcon(const std::string &value, const Json::Value &ws) return value; } +bool Workspaces::isWorkspaceIgnored(const std::string &name) { + for (auto &rule : ignoreWorkspaces_) { + if (std::regex_match(name, rule)) { + return true; + } + } + return false; +} + } // namespace waybar::modules::niri