cleanup onEvent, dont use try/catch for flow control
parent
acc911737d
commit
dab1493644
|
@ -88,7 +88,7 @@ class Workspace {
|
|||
void initialize_window_map(const Json::Value& clients_data);
|
||||
|
||||
bool on_window_opened(WindowCreationPayload const& create_window_paylod);
|
||||
std::optional<std::string> on_window_closed(WindowAddress const& addr);
|
||||
std::optional<std::string> close_window(WindowAddress const& addr);
|
||||
|
||||
void update(const std::string& format, const std::string& icon);
|
||||
|
||||
|
@ -127,7 +127,7 @@ class Workspaces : public AModule, public EventHandler {
|
|||
|
||||
std::string get_rewrite(std::string window_class, std::string window_title);
|
||||
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_; }
|
||||
|
||||
|
@ -142,10 +142,23 @@ class Workspaces : public AModule, public EventHandler {
|
|||
void parse_config(const Json::Value& config);
|
||||
void register_ipc();
|
||||
|
||||
// workspace events
|
||||
void on_workspace_activated(std::string const& 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);
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -225,7 +225,7 @@ auto Workspaces::update() -> void {
|
|||
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
|
||||
// `special:special:<some_name>`. This function checks for that and is used
|
||||
// to avoid creating (and then removing) such workspaces.
|
||||
|
@ -233,7 +233,7 @@ bool isDoubleSpecial(std::string &workspace_name) {
|
|||
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_) {
|
||||
if (std::regex_match(name, rule)) {
|
||||
return true;
|
||||
|
@ -250,44 +250,15 @@ void Workspaces::onEvent(const std::string &ev) {
|
|||
std::string payload = ev.substr(eventName.size() + 2);
|
||||
|
||||
if (eventName == "workspace") {
|
||||
active_workspace_name_ = payload;
|
||||
|
||||
on_workspace_activated(payload);
|
||||
} else if (eventName == "destroyworkspace") {
|
||||
if (!isDoubleSpecial(payload)) {
|
||||
workspaces_to_remove_.push_back(payload);
|
||||
}
|
||||
on_workspace_destroyed(payload);
|
||||
} else if (eventName == "createworkspace") {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
on_workspace_created(payload);
|
||||
} else if (eventName == "focusedmon") {
|
||||
active_workspace_name_ = payload.substr(payload.find(',') + 1);
|
||||
|
||||
on_monitor_focused(payload);
|
||||
} else if (eventName == "moveworkspace" && !all_outputs()) {
|
||||
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);
|
||||
}
|
||||
on_workspace_moved(payload);
|
||||
} else if (eventName == "openwindow") {
|
||||
on_window_opened(payload);
|
||||
} else if (eventName == "closewindow") {
|
||||
|
@ -297,41 +268,76 @@ void Workspaces::onEvent(const std::string &ev) {
|
|||
} else if (eventName == "urgent") {
|
||||
set_urgent_workspace(payload);
|
||||
} else if (eventName == "renameworkspace") {
|
||||
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;
|
||||
}
|
||||
}
|
||||
on_workspace_renamed(payload);
|
||||
} 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({*client});
|
||||
}
|
||||
}
|
||||
on_window_title_event(payload);
|
||||
}
|
||||
|
||||
dp.emit();
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -356,7 +362,7 @@ void Workspaces::on_window_opened(std::string const &payload) {
|
|||
void Workspaces::on_window_closed(std::string const &addr) {
|
||||
update_window_count();
|
||||
for (auto &workspace : workspaces_) {
|
||||
if (workspace->on_window_closed(addr)) {
|
||||
if (workspace->close_window(addr)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -384,12 +390,9 @@ void Workspaces::on_window_moved(std::string const &payload) {
|
|||
|
||||
// Take the window's representation from the old workspace...
|
||||
for (auto &workspace : workspaces_) {
|
||||
try {
|
||||
window_repr = workspace->on_window_closed(window_address).value();
|
||||
if (auto window_addr = workspace->close_window(window_address); window_addr != std::nullopt) {
|
||||
window_repr = window_addr.value();
|
||||
break;
|
||||
} catch (const std::bad_optional_access &e) {
|
||||
// window was not found in this workspace
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,6 +402,26 @@ void Workspaces::on_window_moved(std::string const &payload) {
|
|||
}
|
||||
}
|
||||
|
||||
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});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Workspaces::update_window_count() {
|
||||
const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces");
|
||||
for (auto &workspace : workspaces_) {
|
||||
|
@ -446,11 +469,11 @@ bool Workspace::on_window_opened(WindowCreationPayload const &create_window_payl
|
|||
return false;
|
||||
}
|
||||
|
||||
std::optional<std::string> Workspace::on_window_closed(WindowAddress const &addr) {
|
||||
std::optional<std::string> Workspace::close_window(WindowAddress const &addr) {
|
||||
if (window_map_.contains(addr)) {
|
||||
return remove_window(addr);
|
||||
}
|
||||
return {};
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void Workspaces::create_workspace(Json::Value const &workspace_data,
|
||||
|
|
Loading…
Reference in New Issue