Merge pull request #4537 from thomascrha/niri-workspace-ignore-workspaces

feat(niri/worspaces): add ignore-workspaces configuration option
This commit is contained in:
Alexis Rouillard
2026-07-04 00:52:19 +02:00
committed by GitHub
3 changed files with 46 additions and 0 deletions
+4
View File
@@ -3,6 +3,7 @@
#include <gtkmm/button.h>
#include <json/value.h>
#include <regex>
#include <vector>
#include "AModule.hpp"
@@ -23,12 +24,15 @@ class Workspaces : public AModule, public EventHandler {
void sortWorkspaces(std::vector<Json::Value>& workspaces) const;
Gtk::Button& addButton(const Json::Value& ws);
std::string getIcon(const std::string& value, const Json::Value& ws);
bool isWorkspaceIgnored(const std::string& name);
bool handleScroll(GdkEventScroll* /*unused*/) override;
const Bar& bar_;
Gtk::Box box_;
// Map from niri workspace id to button.
std::unordered_map<uint64_t, Gtk::Button> buttons_;
// Vec of regex rules to ignore workspaces.
std::vector<std::regex> ignoreWorkspaces_;
bool sort_by_id_ = false;
bool sort_by_name_ = false;
+5
View File
@@ -82,6 +82,11 @@ If none of the sorting options are enabled, workspaces keep their output/index o
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,
+37
View File
@@ -39,6 +39,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<IPC>();
gIPC->registerForIPC("WorkspacesChanged", this);
@@ -67,6 +85,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;
});
@@ -231,6 +259,15 @@ 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;
}
bool Workspaces::handleScroll(GdkEventScroll* e) {
if (gdk_event_get_pointer_emulated((GdkEvent*)e) != 0) {
/**