Merge pull request #2592 from zjeffer/hyprland/workspaces

General cleanup in hyprland/workspaces
This commit is contained in:
Alexis Rouillard 2023-10-23 08:45:52 +02:00 committed by GitHub
commit f2085fcd92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 202 additions and 164 deletions

View File

@ -14,7 +14,7 @@ namespace waybar::modules::hyprland {
class Window : public waybar::AAppIconLabel, public EventHandler { class Window : public waybar::AAppIconLabel, public EventHandler {
public: public:
Window(const std::string&, const waybar::Bar&, const Json::Value&); Window(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Window(); ~Window() override;
auto update() -> void override; auto update() -> void override;

View File

@ -26,12 +26,13 @@ namespace waybar::modules::hyprland {
class Workspaces; class Workspaces;
class CreateWindow { class WindowCreationPayload {
public: public:
CreateWindow(std::string workspace_name, WindowAddress window_address, std::string window_repr); WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
CreateWindow(std::string workspace_name, WindowAddress window_address, std::string window_class, std::string window_repr);
std::string window_title); WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
CreateWindow(Json::Value& client_data); std::string window_class, std::string window_title);
WindowCreationPayload(Json::Value const& client_data);
int increment_time_spent_uncreated(); int increment_time_spent_uncreated();
bool is_empty(Workspaces& workspace_manager); bool is_empty(Workspaces& workspace_manager);
@ -49,18 +50,18 @@ class CreateWindow {
using Repr = std::string; using Repr = std::string;
using ClassAndTitle = std::pair<std::string, std::string>; using ClassAndTitle = std::pair<std::string, std::string>;
std::variant<Repr, ClassAndTitle> window_; std::variant<Repr, ClassAndTitle> window_;
WindowAddress window_address_; WindowAddress window_address_;
std::string workspace_name_; std::string workspace_name_;
int time_spent_uncreated_ = 0; int time_spent_uncreated_ = 0;
}; };
class Workspace { class Workspace {
public: public:
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager, explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
const Json::Value& clients_json = Json::Value::nullRef); const Json::Value& clients_data = Json::Value::nullRef);
std::string& select_icon(std::map<std::string, std::string>& icons_map); std::string& select_icon(std::map<std::string, std::string>& icons_map);
Gtk::Button& button() { return button_; }; Gtk::Button& button() { return button_; };
@ -74,21 +75,20 @@ class Workspace {
bool is_empty() const { return windows_ == 0; }; bool is_empty() const { return windows_ == 0; };
bool is_urgent() const { return is_urgent_; }; bool is_urgent() const { return is_urgent_; };
auto handle_clicked(GdkEventButton* bt) -> bool; bool handle_clicked(GdkEventButton* bt) const;
void set_active(bool value = true) { active_ = value; }; void set_active(bool value = true) { active_ = value; };
void set_persistent(bool value = true) { is_persistent_ = value; }; void set_persistent(bool value = true) { is_persistent_ = value; };
void set_urgent(bool value = true) { is_urgent_ = value; }; void set_urgent(bool value = true) { is_urgent_ = value; };
void set_visible(bool value = true) { is_visible_ = value; }; void set_visible(bool value = true) { is_visible_ = value; };
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 const& value) { name_ = value; };
bool contains_window(WindowAddress addr) const { return window_map_.contains(addr); } bool contains_window(WindowAddress const& addr) const { return window_map_.contains(addr); }
void insert_window(CreateWindow create_window_paylod); void insert_window(WindowCreationPayload create_window_paylod);
std::string remove_window(WindowAddress addr); std::string remove_window(WindowAddress const& addr);
void initialize_window_map(const Json::Value& clients_data); void initialize_window_map(const Json::Value& clients_data);
bool on_window_opened(CreateWindow create_window_paylod); bool on_window_opened(WindowCreationPayload const& create_window_paylod);
std::optional<std::string> close_window(WindowAddress const& addr);
std::optional<std::string> on_window_closed(WindowAddress& addr);
void update(const std::string& format, const std::string& icon); void update(const std::string& format, const std::string& icon);
@ -127,26 +127,39 @@ class Workspaces : public AModule, public EventHandler {
std::string get_rewrite(std::string window_class, std::string window_title); std::string get_rewrite(std::string window_class, std::string window_title);
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); bool is_workspace_ignored(std::string const& workspace_name);
bool window_rewrite_config_uses_title() const { return any_window_rewrite_rule_uses_title_; } bool window_rewrite_config_uses_title() const { return any_window_rewrite_rule_uses_title_; }
private: private:
void onEvent(const std::string&) override; void onEvent(const std::string& e) override;
void update_window_count(); void update_window_count();
void sort_workspaces(); void sort_workspaces();
void create_workspace(Json::Value& workspace_data, void create_workspace(Json::Value const& workspace_data,
const Json::Value& clients_data = Json::Value::nullRef); Json::Value const& clients_data = Json::Value::nullRef);
void remove_workspace(std::string name); void remove_workspace(std::string const& name);
void set_urgent_workspace(std::string windowaddress); void set_urgent_workspace(std::string const& windowaddress);
void parse_config(const Json::Value& config); void parse_config(const Json::Value& config);
void register_ipc(); void register_ipc();
void on_window_opened(std::string payload); // workspace events
void on_window_closed(std::string payload); void on_workspace_activated(std::string const& payload);
void on_window_moved(std::string payload); void on_workspace_destroyed(std::string const& payload);
void on_workspace_created(std::string const& payload);
void on_workspace_moved(std::string const& payload);
void on_workspace_renamed(std::string const& payload);
int window_rewrite_priority_function(std::string& window_rule); // monitor events
void on_monitor_focused(std::string const& payload);
// window events
void on_window_opened(std::string const& payload);
void on_window_closed(std::string const& payload);
void on_window_moved(std::string const& payload);
void on_window_title_event(std::string const& payload);
int window_rewrite_priority_function(std::string const& window_rule);
bool all_outputs_ = false; bool all_outputs_ = false;
bool show_special_ = false; bool show_special_ = false;
@ -178,7 +191,7 @@ 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<CreateWindow> windows_to_create_; std::vector<WindowCreationPayload> windows_to_create_;
std::vector<std::regex> ignore_workspaces_; std::vector<std::regex> ignore_workspaces_;

View File

@ -14,23 +14,24 @@
namespace waybar::modules::hyprland { namespace waybar::modules::hyprland {
int Workspaces::window_rewrite_priority_function(std::string &window_rule) { int Workspaces::window_rewrite_priority_function(std::string const &window_rule) {
// Rules that match against title are prioritized // Rules that match against title are prioritized
// Rules that don't specify if they're matching against either title or class are deprioritized // 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 const has_title = window_rule.find("title") != std::string::npos;
bool has_class = window_rule.find("class") != std::string::npos; bool const has_class = window_rule.find("class") != std::string::npos;
if (has_title && has_class) { if (has_title && has_class) {
any_window_rewrite_rule_uses_title_ = true; any_window_rewrite_rule_uses_title_ = true;
return 3; return 3;
} else if (has_title) { }
if (has_title) {
any_window_rewrite_rule_uses_title_ = true; any_window_rewrite_rule_uses_title_ = true;
return 2; return 2;
} else if (has_class) {
return 1;
} else {
return 0;
} }
if (has_class) {
return 1;
}
return 0;
} }
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)
@ -51,7 +52,7 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value
} }
auto Workspaces::parse_config(const Json::Value &config) -> void { auto Workspaces::parse_config(const Json::Value &config) -> void {
Json::Value config_format = config["format"]; const Json::Value &config_format = config["format"];
format_ = config_format.isString() ? config_format.asString() : "{name}"; format_ = config_format.isString() ? config_format.asString() : "{name}";
with_icon_ = format_.find("{icon}") != std::string::npos; with_icon_ = format_.find("{icon}") != std::string::npos;
@ -109,13 +110,13 @@ auto Workspaces::parse_config(const Json::Value &config) -> void {
} }
} }
Json::Value format_window_separator = config["format-window-separator"]; const 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() : " ";
Json::Value window_rewrite = config["window-rewrite"]; const Json::Value &window_rewrite = config["window-rewrite"];
Json::Value window_rewrite_default_config = config["window-rewrite-default"]; const Json::Value &window_rewrite_default_config = config["window-rewrite-default"];
std::string window_rewrite_default = std::string window_rewrite_default =
window_rewrite_default_config.isString() ? window_rewrite_default_config.asString() : "?"; window_rewrite_default_config.isString() ? window_rewrite_default_config.asString() : "?";
@ -152,13 +153,13 @@ auto Workspaces::register_ipc() -> void {
} }
auto Workspaces::update() -> void { auto Workspaces::update() -> void {
for (std::string workspace_to_remove : workspaces_to_remove_) { for (const std::string &workspace_to_remove : workspaces_to_remove_) {
remove_workspace(workspace_to_remove); remove_workspace(workspace_to_remove);
} }
workspaces_to_remove_.clear(); workspaces_to_remove_.clear();
for (Json::Value &workspace_to_create : workspaces_to_create_) { for (Json::Value const &workspace_to_create : workspaces_to_create_) {
create_workspace(workspace_to_create); create_workspace(workspace_to_create);
} }
@ -195,7 +196,7 @@ auto Workspaces::update() -> void {
} }
bool any_window_created = false; bool any_window_created = false;
std::vector<CreateWindow> not_created; std::vector<WindowCreationPayload> not_created;
for (auto &window_payload : windows_to_create_) { for (auto &window_payload : windows_to_create_) {
bool created = false; bool created = false;
@ -207,7 +208,7 @@ auto Workspaces::update() -> void {
} }
} }
if (!created) { if (!created) {
static const int WINDOW_CREATION_TIMEOUT = 2; static auto const WINDOW_CREATION_TIMEOUT = 2;
if (window_payload.increment_time_spent_uncreated() < WINDOW_CREATION_TIMEOUT) { if (window_payload.increment_time_spent_uncreated() < WINDOW_CREATION_TIMEOUT) {
not_created.push_back(window_payload); not_created.push_back(window_payload);
} }
@ -224,7 +225,7 @@ auto Workspaces::update() -> void {
AModule::update(); AModule::update();
} }
bool isDoubleSpecial(std::string &workspace_name) { bool isDoubleSpecial(std::string const &workspace_name) {
// Hyprland's IPC sometimes reports the creation of workspaces strangely named // Hyprland's IPC sometimes reports the creation of workspaces strangely named
// `special:special:<some_name>`. This function checks for that and is used // `special:special:<some_name>`. This function checks for that and is used
// to avoid creating (and then removing) such workspaces. // to avoid creating (and then removing) such workspaces.
@ -232,7 +233,7 @@ 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) { bool Workspaces::is_workspace_ignored(std::string const &name) {
for (auto &rule : ignore_workspaces_) { for (auto &rule : ignore_workspaces_) {
if (std::regex_match(name, rule)) { if (std::regex_match(name, rule)) {
return true; return true;
@ -249,92 +250,96 @@ void Workspaces::onEvent(const std::string &ev) {
std::string payload = ev.substr(eventName.size() + 2); std::string payload = ev.substr(eventName.size() + 2);
if (eventName == "workspace") { if (eventName == "workspace") {
active_workspace_name_ = payload; on_workspace_activated(payload);
} else if (eventName == "destroyworkspace") { } else if (eventName == "destroyworkspace") {
if (!isDoubleSpecial(payload)) { on_workspace_destroyed(payload);
workspaces_to_remove_.push_back(payload);
}
} else if (eventName == "createworkspace") { } else if (eventName == "createworkspace") {
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces"); on_workspace_created(payload);
if (!is_workspace_ignored(payload)) {
for (Json::Value workspace_json : workspaces_json) {
std::string name = workspace_json["name"].asString();
if (name == payload &&
(all_outputs() || bar_.output->name == workspace_json["monitor"].asString()) &&
(show_special() || !name.starts_with("special")) && !isDoubleSpecial(payload)) {
workspaces_to_create_.push_back(workspace_json);
break;
}
}
}
} else if (eventName == "focusedmon") { } else if (eventName == "focusedmon") {
active_workspace_name_ = payload.substr(payload.find(',') + 1); on_monitor_focused(payload);
} else if (eventName == "moveworkspace" && !all_outputs()) { } else if (eventName == "moveworkspace" && !all_outputs()) {
std::string workspace = payload.substr(0, payload.find(',')); on_workspace_moved(payload);
std::string new_output = payload.substr(payload.find(',') + 1);
if (bar_.output->name == new_output) { // TODO: implement this better
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
for (Json::Value workspace_json : workspaces_json) {
std::string name = workspace_json["name"].asString();
if (name == workspace && bar_.output->name == workspace_json["monitor"].asString()) {
workspaces_to_create_.push_back(workspace_json);
break;
}
}
} else {
workspaces_to_remove_.push_back(workspace);
}
} else if (eventName == "openwindow") { } else if (eventName == "openwindow") {
update_window_count();
on_window_opened(payload); on_window_opened(payload);
} else if (eventName == "closewindow") { } else if (eventName == "closewindow") {
update_window_count();
on_window_closed(payload); on_window_closed(payload);
} else if (eventName == "movewindow") { } else if (eventName == "movewindow") {
update_window_count();
on_window_moved(payload); on_window_moved(payload);
} else if (eventName == "urgent") { } else if (eventName == "urgent") {
set_urgent_workspace(payload); set_urgent_workspace(payload);
} else if (eventName == "renameworkspace") { } else if (eventName == "renameworkspace") {
std::string workspace_id_str = payload.substr(0, payload.find(',')); on_workspace_renamed(payload);
int workspace_id = workspace_id_str == "special" ? -99 : std::stoi(workspace_id_str);
std::string new_name = payload.substr(payload.find(',') + 1);
for (auto &workspace : workspaces_) {
if (workspace->id() == workspace_id) {
if (workspace->name() == active_workspace_name_) {
active_workspace_name_ = new_name;
}
workspace->set_name(new_name);
break;
}
}
} else if (eventName == "windowtitle") { } else if (eventName == "windowtitle") {
auto window_workspace = on_window_title_event(payload);
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({*client});
}
}
} }
dp.emit(); dp.emit();
} }
void Workspaces::on_window_opened(std::string payload) { void Workspaces::on_workspace_activated(std::string const &payload) {
active_workspace_name_ = payload;
}
void Workspaces::on_workspace_destroyed(std::string const &payload) {
if (!isDoubleSpecial(payload)) {
workspaces_to_remove_.push_back(payload);
}
}
void Workspaces::on_workspace_created(std::string const &payload) {
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
if (!is_workspace_ignored(payload)) {
for (Json::Value workspace_json : workspaces_json) {
std::string name = workspace_json["name"].asString();
if (name == payload &&
(all_outputs() || bar_.output->name == workspace_json["monitor"].asString()) &&
(show_special() || !name.starts_with("special")) && !isDoubleSpecial(payload)) {
workspaces_to_create_.push_back(workspace_json);
break;
}
}
}
}
void Workspaces::on_workspace_moved(std::string const &payload) {
std::string workspace = payload.substr(0, payload.find(','));
std::string new_output = payload.substr(payload.find(',') + 1);
if (bar_.output->name == new_output) { // TODO: implement this better
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
for (Json::Value workspace_json : workspaces_json) {
std::string name = workspace_json["name"].asString();
if (name == workspace && bar_.output->name == workspace_json["monitor"].asString()) {
workspaces_to_create_.push_back(workspace_json);
break;
}
}
} else {
workspaces_to_remove_.push_back(workspace);
}
}
void Workspaces::on_workspace_renamed(std::string const &payload) {
std::string workspace_id_str = payload.substr(0, payload.find(','));
int workspace_id = workspace_id_str == "special" ? -99 : std::stoi(workspace_id_str);
std::string new_name = payload.substr(payload.find(',') + 1);
for (auto &workspace : workspaces_) {
if (workspace->id() == workspace_id) {
if (workspace->name() == active_workspace_name_) {
active_workspace_name_ = new_name;
}
workspace->set_name(new_name);
break;
}
}
}
void Workspaces::on_monitor_focused(std::string const &payload) {
active_workspace_name_ = payload.substr(payload.find(',') + 1);
}
void Workspaces::on_window_opened(std::string const &payload) {
update_window_count();
size_t last_comma_idx = 0; size_t last_comma_idx = 0;
size_t next_comma_idx = payload.find(','); size_t next_comma_idx = payload.find(',');
std::string window_address = payload.substr(last_comma_idx, next_comma_idx - last_comma_idx); std::string window_address = payload.substr(last_comma_idx, next_comma_idx - last_comma_idx);
@ -351,19 +356,20 @@ 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);
windows_to_create_.emplace_back( windows_to_create_.emplace_back(workspace_name, window_address, window_class, window_title);
CreateWindow(workspace_name, window_address, window_class, window_title));
} }
void Workspaces::on_window_closed(std::string addr) { void Workspaces::on_window_closed(std::string const &addr) {
update_window_count();
for (auto &workspace : workspaces_) { for (auto &workspace : workspaces_) {
if (workspace->on_window_closed(addr)) { if (workspace->close_window(addr)) {
break; break;
} }
} }
} }
void Workspaces::on_window_moved(std::string payload) { void Workspaces::on_window_moved(std::string const &payload) {
update_window_count();
size_t last_comma_idx = 0; size_t last_comma_idx = 0;
size_t next_comma_idx = payload.find(','); size_t next_comma_idx = payload.find(',');
std::string window_address = payload.substr(last_comma_idx, next_comma_idx - last_comma_idx); std::string window_address = payload.substr(last_comma_idx, next_comma_idx - last_comma_idx);
@ -384,18 +390,35 @@ void Workspaces::on_window_moved(std::string payload) {
// Take the window's representation from the old workspace... // Take the window's representation from the old workspace...
for (auto &workspace : workspaces_) { for (auto &workspace : workspaces_) {
try { if (auto window_addr = workspace->close_window(window_address); window_addr != std::nullopt) {
window_repr = workspace->on_window_closed(window_address).value(); window_repr = window_addr.value();
break; break;
} catch (const std::bad_optional_access &e) {
// window was not found in this workspace
continue;
} }
} }
// ...and add it to the new workspace // ...and add it to the new workspace
if (!window_repr.empty()) { if (!window_repr.empty()) {
windows_to_create_.emplace_back(CreateWindow(workspace_name, window_address, window_repr)); windows_to_create_.emplace_back(workspace_name, window_address, window_repr);
}
}
void Workspaces::on_window_title_event(std::string const &payload) {
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({*client});
}
} }
} }
@ -426,37 +449,35 @@ void Workspace::initialize_window_map(const Json::Value &clients_data) {
} }
} }
void Workspace::insert_window(CreateWindow create_window_paylod) { void Workspace::insert_window(WindowCreationPayload create_window_paylod) {
if (!create_window_paylod.is_empty(workspace_manager_)) { if (!create_window_paylod.is_empty(workspace_manager_)) {
window_map_[create_window_paylod.addr()] = create_window_paylod.repr(workspace_manager_); window_map_[create_window_paylod.addr()] = create_window_paylod.repr(workspace_manager_);
} }
}; };
std::string Workspace::remove_window(WindowAddress addr) { std::string Workspace::remove_window(WindowAddress const &addr) {
std::string window_repr = window_map_[addr]; std::string window_repr = window_map_[addr];
window_map_.erase(addr); window_map_.erase(addr);
return window_repr; return window_repr;
} }
bool Workspace::on_window_opened(CreateWindow create_window_paylod) { bool Workspace::on_window_opened(WindowCreationPayload const &create_window_paylod) {
if (create_window_paylod.workspace_name() == name()) { if (create_window_paylod.workspace_name() == name()) {
insert_window(create_window_paylod); insert_window(create_window_paylod);
return true; return true;
} else {
return false;
} }
return false;
} }
std::optional<std::string> Workspace::on_window_closed(WindowAddress &addr) { std::optional<std::string> Workspace::close_window(WindowAddress const &addr) {
if (window_map_.contains(addr)) { if (window_map_.contains(addr)) {
return remove_window(addr); return remove_window(addr);
} else {
return {};
} }
return std::nullopt;
} }
void Workspaces::create_workspace(Json::Value &workspace_data, const Json::Value &clients_data) { void Workspaces::create_workspace(Json::Value const &workspace_data,
Json::Value const &clients_data) {
// avoid recreating existing workspaces // avoid recreating existing workspaces
auto workspace_name = workspace_data["name"].asString(); auto workspace_name = workspace_data["name"].asString();
auto workspace = std::find_if( auto workspace = std::find_if(
@ -477,7 +498,7 @@ void Workspaces::create_workspace(Json::Value &workspace_data, const Json::Value
new_workspace_button.show_all(); new_workspace_button.show_all();
} }
void Workspaces::remove_workspace(std::string name) { void Workspaces::remove_workspace(std::string const &name) {
auto workspace = auto workspace =
std::find_if(workspaces_.begin(), workspaces_.end(), [&](std::unique_ptr<Workspace> &x) { std::find_if(workspaces_.begin(), workspaces_.end(), [&](std::unique_ptr<Workspace> &x) {
return (name.starts_with("special:") && name.substr(8) == x->name()) || name == x->name(); return (name.starts_with("special:") && name.substr(8) == x->name()) || name == x->name();
@ -816,7 +837,7 @@ std::string &Workspace::select_icon(std::map<std::string, std::string> &icons_ma
return name_; return name_;
} }
auto Workspace::handle_clicked(GdkEventButton *bt) -> bool { bool Workspace::handle_clicked(GdkEventButton *bt) const {
try { try {
if (id() > 0) { // normal or numbered persistent if (id() > 0) { // normal or numbered persistent
gIPC->getSocket1Reply("dispatch workspace " + std::to_string(id())); gIPC->getSocket1Reply("dispatch workspace " + std::to_string(id()));
@ -834,7 +855,7 @@ auto Workspace::handle_clicked(GdkEventButton *bt) -> bool {
return false; return false;
} }
void Workspaces::set_urgent_workspace(std::string windowaddress) { void Workspaces::set_urgent_workspace(std::string const &windowaddress) {
const Json::Value clients_json = gIPC->getSocket1JsonReply("clients"); const Json::Value clients_json = gIPC->getSocket1JsonReply("clients");
int workspace_id = -1; int workspace_id = -1;
@ -863,58 +884,63 @@ std::string Workspaces::get_rewrite(std::string window_class, std::string window
return window_rewrite_rules_.get(window_repr_key); return window_rewrite_rules_.get(window_repr_key);
} }
CreateWindow::CreateWindow(std::string workspace_name, WindowAddress window_address, WindowCreationPayload::WindowCreationPayload(std::string workspace_name,
std::string window_repr) WindowAddress window_address, std::string window_repr)
: window_(window_repr), window_address_(window_address), workspace_name_(workspace_name) { : window_(std::move(window_repr)),
window_address_(std::move(window_address)),
workspace_name_(std::move(workspace_name)) {
clear_addr(); clear_addr();
clear_workspace_name(); clear_workspace_name();
} }
CreateWindow::CreateWindow(std::string workspace_name, WindowAddress window_address, WindowCreationPayload::WindowCreationPayload(std::string workspace_name,
std::string window_class, std::string window_title) WindowAddress window_address, std::string window_class,
: window_(std::make_pair(window_class, window_title)), std::string window_title)
window_address_(window_address), : window_(std::make_pair(std::move(window_class), std::move(window_title))),
workspace_name_(workspace_name) { window_address_(std::move(window_address)),
workspace_name_(std::move(workspace_name)) {
clear_addr(); clear_addr();
clear_workspace_name(); clear_workspace_name();
} }
CreateWindow::CreateWindow(Json::Value &client_data) { WindowCreationPayload::WindowCreationPayload(Json::Value const &client_data)
window_address_ = client_data["address"].asString(); : window_(std::make_pair(client_data["class"].asString(), client_data["title"].asString())),
workspace_name_ = client_data["workspace"]["name"].asString(); window_address_(client_data["address"].asString()),
window_ = std::make_pair(client_data["class"].asString(), client_data["title"].asString()); workspace_name_(client_data["workspace"]["name"].asString()) {
clear_addr(); clear_addr();
clear_workspace_name(); clear_workspace_name();
} }
std::string CreateWindow::repr(Workspaces &workspace_manager) { std::string WindowCreationPayload::repr(Workspaces &workspace_manager) {
if (std::holds_alternative<Repr>(window_)) { if (std::holds_alternative<Repr>(window_)) {
return std::get<Repr>(window_); return std::get<Repr>(window_);
} else if (std::holds_alternative<ClassAndTitle>(window_)) { }
if (std::holds_alternative<ClassAndTitle>(window_)) {
auto [window_class, window_title] = std::get<ClassAndTitle>(window_); auto [window_class, window_title] = std::get<ClassAndTitle>(window_);
return workspace_manager.get_rewrite(window_class, window_title); return workspace_manager.get_rewrite(window_class, window_title);
} else {
// Unreachable
return "";
} }
// Unreachable
spdlog::error("WorkspaceWindow::repr: Unreachable");
throw std::runtime_error("WorkspaceWindow::repr: Unreachable");
} }
bool CreateWindow::is_empty(Workspaces &workspace_manager) { bool WindowCreationPayload::is_empty(Workspaces &workspace_manager) {
if (std::holds_alternative<Repr>(window_)) { if (std::holds_alternative<Repr>(window_)) {
return std::get<Repr>(window_).empty(); return std::get<Repr>(window_).empty();
} else if (std::holds_alternative<ClassAndTitle>(window_)) { }
if (std::holds_alternative<ClassAndTitle>(window_)) {
auto [window_class, window_title] = std::get<ClassAndTitle>(window_); auto [window_class, window_title] = std::get<ClassAndTitle>(window_);
return (window_class.empty() && return (window_class.empty() &&
(!workspace_manager.window_rewrite_config_uses_title() || window_title.empty())); (!workspace_manager.window_rewrite_config_uses_title() || window_title.empty()));
} else {
// Unreachable
return true;
} }
// Unreachable
spdlog::error("WorkspaceWindow::is_empty: Unreachable");
throw std::runtime_error("WorkspaceWindow::is_empty: Unreachable");
} }
int CreateWindow::increment_time_spent_uncreated() { return time_spent_uncreated_++; } int WindowCreationPayload::increment_time_spent_uncreated() { return time_spent_uncreated_++; }
void CreateWindow::clear_addr() { void WindowCreationPayload::clear_addr() {
// substr(2, ...) is necessary because Hyprland's JSON follows this format: // substr(2, ...) is necessary because Hyprland's JSON follows this format:
// 0x{ADDR} // 0x{ADDR}
// While Hyprland's IPC follows this format: // While Hyprland's IPC follows this format:
@ -928,7 +954,7 @@ void CreateWindow::clear_addr() {
} }
} }
void CreateWindow::clear_workspace_name() { void WindowCreationPayload::clear_workspace_name() {
// The workspace name may optionally feature "special:" at the beginning. // The workspace name may optionally feature "special:" at the beginning.
// If so, we need to remove it because the workspace is saved WITHOUT the // If so, we need to remove it because the workspace is saved WITHOUT the
// special qualifier. The reasoning is that not all of Hyprland's IPC events // special qualifier. The reasoning is that not all of Hyprland's IPC events
@ -943,7 +969,7 @@ void CreateWindow::clear_workspace_name() {
} }
} }
void CreateWindow::move_to_worksace(std::string &new_workspace_name) { void WindowCreationPayload::move_to_worksace(std::string &new_workspace_name) {
workspace_name_ = new_workspace_name; workspace_name_ = new_workspace_name;
} }

View File

@ -655,8 +655,7 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
higher priority. Disable router -> RTA_GATEWAY -> up new router -> set higher priority added higher priority. Disable router -> RTA_GATEWAY -> up new router -> set higher priority added
checking route id checking route id
**/ **/
if (!is_del_event && if (!is_del_event && ((net->ifid_ == -1) || (priority < net->route_priority))) {
((net->ifid_ == -1) || (priority < net->route_priority))) {
// Clear if's state for the case were there is a higher priority // Clear if's state for the case were there is a higher priority
// route on a different interface. // route on a different interface.
net->clearIface(); net->clearIface();