feat: rewrite window classes
feat: cache window class rewrite resolution Co-authored-by: Gabriel Fox <Inbox@GabrielFox.Dev>pull/2529/head
parent
3e2761e81f
commit
b9d5912a4f
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <gtkmm/button.h>
|
#include <gtkmm/button.h>
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
|
#include <json/value.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -17,7 +18,6 @@
|
||||||
#include "util/enum.hpp"
|
#include "util/enum.hpp"
|
||||||
|
|
||||||
using WindowAddress = std::string;
|
using WindowAddress = std::string;
|
||||||
using mywindowtype = std::string;
|
|
||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
class Workspaces;
|
class Workspaces;
|
||||||
|
@ -47,9 +47,7 @@ class Workspace {
|
||||||
void set_windows(uint value) { windows_ = value; };
|
void set_windows(uint value) { windows_ = value; };
|
||||||
void set_name(std::string value) { name_ = value; };
|
void set_name(std::string value) { name_ = value; };
|
||||||
bool contains_window(WindowAddress addr) { return window_map_.contains(addr); }
|
bool contains_window(WindowAddress addr) { return window_map_.contains(addr); }
|
||||||
void insert_window(WindowAddress addr, mywindowtype window_repr) {
|
void insert_window(WindowAddress addr, std::string window_repr);
|
||||||
window_map_.emplace(addr, window_repr);
|
|
||||||
};
|
|
||||||
void remove_window(WindowAddress addr) { window_map_.erase(addr); }
|
void remove_window(WindowAddress addr) { window_map_.erase(addr); }
|
||||||
void initialize_window_map(const Json::Value& clients_data);
|
void initialize_window_map(const Json::Value& clients_data);
|
||||||
|
|
||||||
|
@ -77,7 +75,7 @@ class Workspace {
|
||||||
bool is_urgent_ = false;
|
bool is_urgent_ = false;
|
||||||
bool is_visible_ = false;
|
bool is_visible_ = false;
|
||||||
|
|
||||||
std::map<WindowAddress, mywindowtype> window_map_;
|
std::map<WindowAddress, std::string> window_map_;
|
||||||
|
|
||||||
Gtk::Button button_;
|
Gtk::Button button_;
|
||||||
Gtk::Box content_;
|
Gtk::Box content_;
|
||||||
|
@ -97,6 +95,9 @@ class Workspaces : public AModule, public EventHandler {
|
||||||
|
|
||||||
auto get_bar_output() const -> std::string { return bar_.output->name; }
|
auto get_bar_output() const -> std::string { return bar_.output->name; }
|
||||||
|
|
||||||
|
std::string get_rewrite(std::string window_class);
|
||||||
|
std::string& get_window_separator() { return format_window_separator_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onEvent(const std::string&) override;
|
void onEvent(const std::string&) override;
|
||||||
void update_window_count();
|
void update_window_count();
|
||||||
|
@ -132,7 +133,8 @@ class Workspaces : public AModule, public EventHandler {
|
||||||
|
|
||||||
std::string format_;
|
std::string format_;
|
||||||
std::map<std::string, std::string> icons_map_;
|
std::map<std::string, std::string> icons_map_;
|
||||||
std::map<std::string, std::string> window_rewrite_rules_;
|
Json::Value window_rewrite_rules_;
|
||||||
|
std::map<std::string, std::string> regex_cache_;
|
||||||
std::string format_window_separator_;
|
std::string format_window_separator_;
|
||||||
bool with_icon_;
|
bool with_icon_;
|
||||||
uint64_t monitor_id_;
|
uint64_t monitor_id_;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "util/rewrite_string.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value &config)
|
Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value &config)
|
||||||
|
@ -74,13 +76,7 @@ auto Workspaces::parse_config(const Json::Value &config) -> void {
|
||||||
format_window_separator_ =
|
format_window_separator_ =
|
||||||
format_window_separator.isString() ? format_window_separator.asString() : " ";
|
format_window_separator.isString() ? format_window_separator.asString() : " ";
|
||||||
|
|
||||||
Json::Value window_rewrite_map = config["window-rewrite-map"];
|
window_rewrite_rules_ = config["window-rewrite"];
|
||||||
|
|
||||||
if (window_rewrite_map.isObject()) {
|
|
||||||
for (std::string &name : window_rewrite_map.getMemberNames()) {
|
|
||||||
window_rewrite_rules_.emplace(name, window_rewrite_map[name].asString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Workspaces::register_ipc() -> void {
|
auto Workspaces::register_ipc() -> void {
|
||||||
|
@ -234,26 +230,19 @@ void Workspaces::on_window_opened(std::string payload) {
|
||||||
|
|
||||||
std::string window_title = payload.substr(next_comma_idx + 1, payload.length() - next_comma_idx);
|
std::string window_title = payload.substr(next_comma_idx + 1, payload.length() - next_comma_idx);
|
||||||
|
|
||||||
fmt::println("> Inserting window [{}] [{}] [{}] [{}]", window_address, workspace_name,
|
|
||||||
window_class, window_title);
|
|
||||||
|
|
||||||
for (auto &workspace : workspaces_) {
|
for (auto &workspace : workspaces_) {
|
||||||
if (workspace->on_window_opened(window_address, workspace_name, window_class, window_title)) {
|
if (workspace->on_window_opened(window_address, workspace_name, window_class, window_title)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::println("<");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspaces::on_window_closed(std::string addr) {
|
void Workspaces::on_window_closed(std::string addr) {
|
||||||
fmt::println("> Removing window [{}]", addr);
|
|
||||||
for (auto &workspace : workspaces_) {
|
for (auto &workspace : workspaces_) {
|
||||||
if (workspace->on_window_closed(addr)) {
|
if (workspace->on_window_closed(addr)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt::println("<");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspaces::on_window_moved(std::string payload) {
|
void Workspaces::on_window_moved(std::string payload) {
|
||||||
|
@ -268,8 +257,6 @@ void Workspaces::on_window_moved(std::string payload) {
|
||||||
|
|
||||||
const Json::Value clients_json = gIPC->getSocket1JsonReply("clients");
|
const Json::Value clients_json = gIPC->getSocket1JsonReply("clients");
|
||||||
|
|
||||||
fmt::println(">> Moving window [{}] [{}]", window_address, workspace_name);
|
|
||||||
|
|
||||||
for (auto &workspace : workspaces_) {
|
for (auto &workspace : workspaces_) {
|
||||||
if (workspace->on_window_moved(window_address, workspace_name, clients_json)) {
|
if (workspace->on_window_moved(window_address, workspace_name, clients_json)) {
|
||||||
changes++;
|
changes++;
|
||||||
|
@ -278,8 +265,6 @@ void Workspaces::on_window_moved(std::string payload) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::println("<<");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspaces::update_window_count() {
|
void Workspaces::update_window_count() {
|
||||||
|
@ -317,10 +302,13 @@ void Workspace::initialize_window_map(const Json::Value &clients_data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Workspace::insert_window(WindowAddress addr, std::string window_class) {
|
||||||
|
window_map_.emplace(addr, workspace_manager_.get_rewrite(window_class));
|
||||||
|
};
|
||||||
|
|
||||||
bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_name,
|
bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_name,
|
||||||
const Json::Value &clients_data) {
|
const Json::Value &clients_data) {
|
||||||
if (workspace_name == name()) {
|
if (workspace_name == name()) {
|
||||||
fmt::println("\tInserting on workspace {}", id());
|
|
||||||
for (auto client : clients_data) {
|
for (auto client : clients_data) {
|
||||||
auto client_address = client["address"].asString().substr(2, addr.length());
|
auto client_address = client["address"].asString().substr(2, addr.length());
|
||||||
if (client_address == addr) {
|
if (client_address == addr) {
|
||||||
|
@ -329,7 +317,6 @@ bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_nam
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt::println("\tERROR on workspace {}", id());
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -339,7 +326,6 @@ bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_nam
|
||||||
bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_name,
|
bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_name,
|
||||||
std::string &window_class, std::string &window_title) {
|
std::string &window_class, std::string &window_title) {
|
||||||
if (workspace_name == name()) {
|
if (workspace_name == name()) {
|
||||||
fmt::println("\tInserting on workspace {}", id());
|
|
||||||
insert_window(addr, window_class);
|
insert_window(addr, window_class);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -349,7 +335,6 @@ bool Workspace::on_window_opened(WindowAddress &addr, std::string &workspace_nam
|
||||||
|
|
||||||
bool Workspace::on_window_closed(WindowAddress &addr) {
|
bool Workspace::on_window_closed(WindowAddress &addr) {
|
||||||
if (window_map_.contains(addr)) {
|
if (window_map_.contains(addr)) {
|
||||||
fmt::println("\tRemoving on workspace {}", id());
|
|
||||||
remove_window(addr);
|
remove_window(addr);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -581,15 +566,22 @@ void Workspace::update(const std::string &format, const std::string &icon) {
|
||||||
add_or_remove_class(style_context, is_urgent(), "urgent");
|
add_or_remove_class(style_context, is_urgent(), "urgent");
|
||||||
add_or_remove_class(style_context, is_visible(), "visible");
|
add_or_remove_class(style_context, is_visible(), "visible");
|
||||||
|
|
||||||
std::string first_letters;
|
std::string windows;
|
||||||
|
auto window_separator = workspace_manager_.get_window_separator();
|
||||||
|
|
||||||
|
bool is_not_first = false;
|
||||||
|
|
||||||
for (auto &[_pid, window_repr] : window_map_) {
|
for (auto &[_pid, window_repr] : window_map_) {
|
||||||
first_letters.append(window_repr.substr(0, 1));
|
if (is_not_first) {
|
||||||
|
windows.append(window_separator);
|
||||||
|
}
|
||||||
|
is_not_first = true;
|
||||||
|
windows.append(window_repr);
|
||||||
}
|
}
|
||||||
|
|
||||||
label_.set_markup(fmt::format(fmt::runtime(format), fmt::arg("id", id()),
|
label_.set_markup(fmt::format(fmt::runtime(format), fmt::arg("id", id()),
|
||||||
fmt::arg("name", name()), fmt::arg("icon", icon),
|
fmt::arg("name", name()), fmt::arg("icon", icon),
|
||||||
fmt::arg("windows", first_letters)));
|
fmt::arg("windows", windows)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspaces::sort_workspaces() {
|
void Workspaces::sort_workspaces() {
|
||||||
|
@ -748,4 +740,17 @@ 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 window_class_rewrite =
|
||||||
|
waybar::util::rewriteString(window_class, window_rewrite_rules_);
|
||||||
|
|
||||||
|
regex_cache_.emplace(window_class, window_class_rewrite);
|
||||||
|
|
||||||
|
return window_class_rewrite;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "util/rewrite_string.hpp"
|
#include "util/rewrite_string.hpp"
|
||||||
|
|
||||||
|
#include <fmt/core.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
@ -17,7 +18,7 @@ std::string rewriteString(const std::string& value, const Json::Value& rules) {
|
||||||
try {
|
try {
|
||||||
// malformated regexes will cause an exception.
|
// malformated regexes will cause an exception.
|
||||||
// in this case, log error and try the next rule.
|
// in this case, log error and try the next rule.
|
||||||
const std::regex rule{it.key().asString()};
|
const std::regex rule{it.key().asString(), std::regex_constants::icase};
|
||||||
if (std::regex_match(value, rule)) {
|
if (std::regex_match(value, rule)) {
|
||||||
res = std::regex_replace(res, rule, it->asString());
|
res = std::regex_replace(res, rule, it->asString());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue