Merge pull request #2568 from Syndelis/feat/hyprland-ignore-workspaces

This commit is contained in:
Alexis Rouillard 2023-10-12 07:32:56 +02:00 committed by GitHub
commit a3774dc586
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 9 deletions

View File

@ -9,6 +9,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <regex>
#include <string> #include <string>
#include <vector> #include <vector>
@ -94,6 +95,7 @@ class Workspaces : public AModule, public EventHandler {
std::string get_rewrite(std::string window_class); std::string get_rewrite(std::string window_class);
std::string& get_window_separator() { return format_window_separator_; } std::string& get_window_separator() { return format_window_separator_; }
bool is_workspace_ignored(std::string& workspace_name);
private: private:
void onEvent(const std::string&) override; void onEvent(const std::string&) override;
@ -140,6 +142,9 @@ class Workspaces : public AModule, public EventHandler {
std::vector<std::unique_ptr<Workspace>> workspaces_; std::vector<std::unique_ptr<Workspace>> workspaces_;
std::vector<Json::Value> workspaces_to_create_; std::vector<Json::Value> workspaces_to_create_;
std::vector<std::string> workspaces_to_remove_; std::vector<std::string> workspaces_to_remove_;
std::vector<std::regex> ignore_workspaces_;
std::mutex mutex_; std::mutex mutex_;
const Bar& bar_; const Bar& bar_;
Gtk::Box box_; Gtk::Box box_;

View File

@ -51,6 +51,11 @@ Addressed by *hyprland/workspaces*
default: false ++ default: false ++
If set to true, only the active workspace will be shown. If set to true, only the active workspace will be shown.
*ignore-workspaces*: ++
typeof: array ++
default: [] ++
Regexes to match against workspaces names. If there's a match, the workspace will not be shown. This takes precedence over *show-special*, *all-outputs* and *active-only*.
*sort-by*: ++ *sort-by*: ++
typeof: string ++ typeof: string ++
default: "default" ++ default: "default" ++
@ -131,6 +136,14 @@ Additional to workspace name matching, the following *format-icons* can be set.
} }
``` ```
"hyprland/workspaces": {
// Formatting omitted for brevity
"ignore-workspaces": [
"(special:)?chrome-sharing-indicator"
]
}
```
# Style # Style
- *#workspaces* - *#workspaces*

View File

@ -73,6 +73,23 @@ auto Workspaces::parse_config(const Json::Value &config) -> void {
} }
} }
Json::Value ignore_workspaces = config["ignore-workspaces"];
if (ignore_workspaces.isArray()) {
for (Json::Value &workspace_regex : ignore_workspaces) {
if (workspace_regex.isString()) {
std::string rule_string = workspace_regex.asString();
try {
const std::regex rule{rule_string, std::regex_constants::icase};
ignore_workspaces_.emplace_back(rule);
} catch (const std::regex_error &e) {
spdlog::error("Invalid rule {}: {}", rule_string, e.what());
}
} else {
spdlog::error("Not a string: '{}'", workspace_regex);
}
}
}
Json::Value format_window_separator = config["format-window-separator"]; Json::Value format_window_separator = config["format-window-separator"];
format_window_separator_ = format_window_separator_ =
format_window_separator.isString() ? format_window_separator.asString() : " "; format_window_separator.isString() ? format_window_separator.asString() : " ";
@ -156,6 +173,17 @@ bool isDoubleSpecial(std::string &workspace_name) {
return workspace_name.find("special:special:") != std::string::npos; return workspace_name.find("special:special:") != std::string::npos;
} }
bool Workspaces::is_workspace_ignored(std::string &name) {
for (auto &rule : ignore_workspaces_) {
if (std::regex_match(name, rule)) {
return true;
break;
}
}
return false;
}
void Workspaces::onEvent(const std::string &ev) { void Workspaces::onEvent(const std::string &ev) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
std::string eventName(begin(ev), begin(ev) + ev.find_first_of('>')); std::string eventName(begin(ev), begin(ev) + ev.find_first_of('>'));
@ -170,6 +198,8 @@ void Workspaces::onEvent(const std::string &ev) {
} }
} else if (eventName == "createworkspace") { } else if (eventName == "createworkspace") {
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces"); const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
if (!is_workspace_ignored(payload)) {
for (Json::Value workspace_json : workspaces_json) { for (Json::Value workspace_json : workspaces_json) {
std::string name = workspace_json["name"].asString(); std::string name = workspace_json["name"].asString();
if (name == payload && if (name == payload &&
@ -179,7 +209,7 @@ void Workspaces::onEvent(const std::string &ev) {
break; break;
} }
} }
}
} else if (eventName == "focusedmon") { } else if (eventName == "focusedmon") {
active_workspace_name_ = payload.substr(payload.find(',') + 1); active_workspace_name_ = payload.substr(payload.find(',') + 1);
@ -511,8 +541,10 @@ void Workspaces::init() {
const Json::Value clients_json = gIPC->getSocket1JsonReply("clients"); const Json::Value clients_json = gIPC->getSocket1JsonReply("clients");
for (Json::Value workspace_json : workspaces_json) { for (Json::Value workspace_json : workspaces_json) {
std::string workspace_name = workspace_json["name"].asString();
if ((all_outputs() || bar_.output->name == workspace_json["monitor"].asString()) && if ((all_outputs() || bar_.output->name == workspace_json["monitor"].asString()) &&
(!workspace_json["name"].asString().starts_with("special") || show_special())) { (!workspace_name.starts_with("special") || show_special()) &&
!is_workspace_ignored(workspace_name)) {
create_workspace(workspace_json, clients_json); create_workspace(workspace_json, clients_json);
} }
} }