Merge pull request #2563 from Syndelis/feat/hyprland-window-rename-by-title

This commit is contained in:
Alexis Rouillard
2023-10-15 21:21:32 +02:00
committed by GitHub
8 changed files with 221 additions and 72 deletions

View File

@ -49,9 +49,9 @@ auto waybar::modules::Disk::update() -> void {
float specific_free, specific_used, specific_total, divisor;
divisor = calc_specific_divisor(unit_);
specific_free = (stats.f_bavail * stats.f_frsize)/divisor;
specific_used = ((stats.f_blocks - stats.f_bfree) * stats.f_frsize)/divisor;
specific_total = (stats.f_blocks * stats.f_frsize)/divisor;
specific_free = (stats.f_bavail * stats.f_frsize) / divisor;
specific_used = ((stats.f_blocks - stats.f_bfree) * stats.f_frsize) / divisor;
specific_total = (stats.f_blocks * stats.f_frsize) / divisor;
auto free = pow_format(stats.f_bavail * stats.f_frsize, "B", true);
auto used = pow_format((stats.f_blocks - stats.f_bfree) * stats.f_frsize, "B", true);
@ -72,7 +72,7 @@ auto waybar::modules::Disk::update() -> void {
fmt::runtime(format), stats.f_bavail * 100 / stats.f_blocks, fmt::arg("free", free),
fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks), fmt::arg("used", used),
fmt::arg("percentage_used", percentage_used), fmt::arg("total", total),
fmt::arg("path", path_), fmt::arg("specific_free", specific_free),
fmt::arg("path", path_), fmt::arg("specific_free", specific_free),
fmt::arg("specific_used", specific_used), fmt::arg("specific_total", specific_total)));
}
@ -85,7 +85,7 @@ auto waybar::modules::Disk::update() -> void {
fmt::runtime(tooltip_format), stats.f_bavail * 100 / stats.f_blocks, fmt::arg("free", free),
fmt::arg("percentage_free", stats.f_bavail * 100 / stats.f_blocks), fmt::arg("used", used),
fmt::arg("percentage_used", percentage_used), fmt::arg("total", total),
fmt::arg("path", path_), fmt::arg("specific_free", specific_free),
fmt::arg("path", path_), fmt::arg("specific_free", specific_free),
fmt::arg("specific_used", specific_used), fmt::arg("specific_total", specific_total)));
}
// Call parent update
@ -109,7 +109,7 @@ float waybar::modules::Disk::calc_specific_divisor(std::string divisor) {
return 1000.0 * 1000.0 * 1000.0 * 1000.0;
} else if (divisor == "TiB") {
return 1024.0 * 1024.0 * 1024.0 * 1024.0;
} else { //default to Bytes if it is anything that we don't recongnise
} else { // default to Bytes if it is anything that we don't recongnise
return 1.0;
}
}

View File

@ -1,19 +1,36 @@
#include "modules/hyprland/workspaces.hpp"
#include <fmt/ostream.h>
#include <json/value.h>
#include <spdlog/spdlog.h>
#include <algorithm>
#include <charconv>
#include <memory>
#include <optional>
#include <string>
#include "util/rewrite_string.hpp"
#include "util/regex_collection.hpp"
namespace waybar::modules::hyprland {
int Workspaces::window_rewrite_priority_function(std::string &window_rule) {
// Rules that match against title are prioritized
// Rules that don't specify if they're matching against either title or class are deprioritized
bool has_title = window_rule.find("title") != std::string::npos;
bool has_class = window_rule.find("class") != std::string::npos;
if (has_title && has_class) {
any_window_rewrite_rule_uses_title_ = true;
return 3;
} else if (has_title) {
any_window_rewrite_rule_uses_title_ = true;
return 2;
} else if (has_class) {
return 1;
} else {
return 0;
}
}
Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value &config)
: AModule(config, "workspaces", id, false, false),
bar_(bar),
@ -94,11 +111,16 @@ auto Workspaces::parse_config(const Json::Value &config) -> void {
format_window_separator_ =
format_window_separator.isString() ? format_window_separator.asString() : " ";
window_rewrite_rules_ = config["window-rewrite"];
Json::Value window_rewrite = config["window-rewrite"];
Json::Value window_rewrite_default = config["window-rewrite-default"];
window_rewrite_default_ =
window_rewrite_default.isString() ? window_rewrite_default.asString() : "?";
Json::Value window_rewrite_default_config = config["window-rewrite-default"];
std::string window_rewrite_default =
window_rewrite_default_config.isString() ? window_rewrite_default_config.asString() : "?";
window_rewrite_rules_ = util::RegexCollection(
window_rewrite, window_rewrite_default, [this](std::string &window_rule) {
return this->window_rewrite_priority_function(window_rule);
});
}
auto Workspaces::register_ipc() -> void {
@ -118,6 +140,13 @@ auto Workspaces::register_ipc() -> void {
gIPC->registerForIPC("closewindow", this);
gIPC->registerForIPC("movewindow", this);
gIPC->registerForIPC("urgent", this);
if (window_rewrite_config_uses_title()) {
spdlog::info(
"Registering for Hyprland's 'windowtitle' events because a user-defined window "
"rewrite rule uses the 'title' field.");
gIPC->registerForIPC("windowtitle", this);
}
}
auto Workspaces::update() -> void {
@ -252,6 +281,25 @@ void Workspaces::onEvent(const std::string &ev) {
break;
}
}
} else if (eventName == "windowtitle") {
auto window_workspace =
std::find_if(workspaces_.begin(), workspaces_.end(),
[payload](auto &workspace) { return workspace->contains_window(payload); });
if (window_workspace != workspaces_.end()) {
Json::Value clients_data = gIPC->getSocket1JsonReply("clients");
std::string json_window_address = fmt::format("0x{}", payload);
auto client = std::find_if(clients_data.begin(), clients_data.end(),
[json_window_address](auto &client) {
return client["address"].asString() == json_window_address;
});
if (!client->empty()) {
(*window_workspace)
->insert_window(payload, (*client)["class"].asString(), (*client)["title"].asString());
}
}
}
dp.emit();
@ -353,15 +401,22 @@ void Workspace::initialize_window_map(const Json::Value &clients_data) {
// {ADDR}
WindowAddress client_address = client["address"].asString();
client_address = client_address.substr(2, client_address.length() - 2);
insert_window(client_address, client["class"].asString());
insert_window(client_address, client["class"].asString(), client["title"].asString());
}
}
}
void Workspace::insert_window(WindowAddress addr, std::string window_class) {
auto window_repr = workspace_manager_.get_rewrite(window_class);
void Workspace::insert_window(WindowAddress addr, std::string window_class,
std::string window_title) {
if (window_class.empty() &&
(!workspace_manager_.window_rewrite_config_uses_title() || window_title.empty())) {
return;
}
auto window_repr = workspace_manager_.get_rewrite(window_class, window_title);
if (!window_repr.empty()) {
window_map_.emplace(addr, window_repr);
window_map_[addr] = window_repr;
}
};
@ -375,7 +430,7 @@ std::string Workspace::remove_window(WindowAddress addr) {
bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_name,
std::string window_repr) {
if (workspace_name == name()) {
window_map_.emplace(addr, window_repr);
window_map_[addr] = window_repr;
return true;
} else {
return false;
@ -385,7 +440,7 @@ bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_nam
bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_name,
std::string &window_class, std::string &window_title) {
if (workspace_name == name()) {
insert_window(addr, window_class);
insert_window(addr, window_class, window_title);
return true;
} else {
return false;
@ -798,23 +853,14 @@ void Workspaces::set_urgent_workspace(std::string windowaddress) {
}
}
std::string Workspaces::get_rewrite(std::string window_class) {
if (regex_cache_.contains(window_class)) {
return regex_cache_[window_class];
std::string Workspaces::get_rewrite(std::string window_class, std::string window_title) {
std::string window_repr_key;
if (window_rewrite_config_uses_title()) {
window_repr_key = fmt::format("class<{}> title<{}>", window_class, window_title);
} else {
window_repr_key = fmt::format("class<{}>", window_class);
}
bool matched_any;
std::string window_class_rewrite =
waybar::util::rewriteStringOnce(window_class, window_rewrite_rules_, matched_any);
if (!matched_any) {
window_class_rewrite = window_rewrite_default_;
}
regex_cache_.emplace(window_class, window_class_rewrite);
return window_class_rewrite;
return window_rewrite_rules_.get(window_repr_key);
}
} // namespace waybar::modules::hyprland