diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index 53bc55fcb6..c40b845a81 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -173,10 +173,7 @@ class Workspaces : public AModule, public EventHandler { {"NUMBER", SORT_METHOD::NUMBER}, {"DEFAULT", SORT_METHOD::DEFAULT}}; - void fill_persistent_workspaces(); void create_persistent_workspaces(); - std::vector persistent_workspaces_to_create_; - bool persistent_created_ = false; std::string format_; diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 91b6242ebd..af30382855 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -365,10 +365,10 @@ void Workspaces::on_window_opened(std::string const &payload) { windows_to_create_.emplace_back(workspace_name, window_address, window_class, window_title); } -void Workspaces::on_window_closed(std::string const &addr) { +void Workspaces::on_window_closed(std::string const &payload) { update_window_count(); for (auto &workspace : workspaces_) { - if (workspace->close_window(addr)) { + if (workspace->close_window(payload)) { break; } } @@ -518,75 +518,28 @@ void Workspaces::remove_workspace(std::string const &name) { return; } - if ((*workspace)->is_persistent()) { - // don't remove persistent workspaces, create_workspace will take care of replacement - return; - } - box_.remove(workspace->get()->button()); workspaces_.erase(workspace); } -void Workspaces::fill_persistent_workspaces() { - if (config_["persistent_workspaces"].isObject()) { - spdlog::warn( - "persistent_workspaces is deprecated. Please change config to use persistent-workspaces."); - } - - if (config_["persistent-workspaces"].isObject() || config_["persistent_workspaces"].isObject()) { - const Json::Value persistent_workspaces = config_["persistent-workspaces"].isObject() - ? config_["persistent-workspaces"] - : config_["persistent_workspaces"]; - const std::vector keys = persistent_workspaces.getMemberNames(); - - for (const std::string &key : keys) { - // only add if either: - // 1. key is "*" and this monitor is not already defined in the config - // 2. key is the current monitor name - bool can_create = - (key == "*" && std::find(keys.begin(), keys.end(), bar_.output->name) == keys.end()) || - key == bar_.output->name; - const Json::Value &value = persistent_workspaces[key]; - - if (value.isInt()) { - // value is a number => create that many workspaces for this monitor - if (can_create) { - int amount = value.asInt(); - spdlog::debug("Creating {} persistent workspaces for monitor {}", amount, - bar_.output->name); - for (int i = 0; i < amount; i++) { - persistent_workspaces_to_create_.emplace_back( - std::to_string(monitor_id_ * amount + i + 1)); - } - } - } else if (value.isArray() && !value.empty()) { - // value is an array => create defined workspaces for this monitor - if (can_create) { - for (const Json::Value &workspace : value) { - if (workspace.isInt()) { - spdlog::debug("Creating workspace {} on monitor {}", workspace, bar_.output->name); - persistent_workspaces_to_create_.emplace_back(std::to_string(workspace.asInt())); - } - } - } else { - // key is the workspace and value is array of monitors to create on - for (const Json::Value &monitor : value) { - if (monitor.isString() && monitor.asString() == bar_.output->name) { - persistent_workspaces_to_create_.emplace_back(key); - break; - } - } - } - } else { - // this workspace should be displayed on all monitors - persistent_workspaces_to_create_.emplace_back(key); - } +void Workspaces::create_persistent_workspaces() { + // get workspaces that need to be persistent for this monitor + // THIS IS STILL VERY MUCH WIP + std::vector persistent_workspaces; + auto const &workspaceRules = gIPC->getSocket1JsonReply("workspacerules"); + for (auto const &rule : workspaceRules) { + auto const &workspaceString = rule["workspaceString"]; + if (workspaceString.isInt()) { + persistent_workspaces.emplace_back( + workspaceString.asInt() == -99 ? "special" : workspaceString.asString()); + } else if (workspaceString.isString() && workspaceString.asString().starts_with("name:")) { + persistent_workspaces.emplace_back(workspaceString.asString().substr(5)); } } -} -void Workspaces::create_persistent_workspaces() { - for (const std::string &workspace_name : persistent_workspaces_to_create_) { + + // create the workspaces + for (const std::string &workspace_name : persistent_workspaces) { Json::Value new_workspace; try { // numbered persistent workspaces get the name as ID @@ -607,18 +560,6 @@ void Workspaces::create_persistent_workspaces() { void Workspaces::init() { active_workspace_name_ = (gIPC->getSocket1JsonReply("activeworkspace"))["name"].asString(); - // get monitor ID from name (used by persistent workspaces) - monitor_id_ = 0; - auto monitors = gIPC->getSocket1JsonReply("monitors"); - auto current_monitor = std::find_if( - monitors.begin(), monitors.end(), - [this](const Json::Value &m) { return m["name"].asString() == bar_.output->name; }); - if (current_monitor == monitors.end()) { - spdlog::error("Monitor '{}' does not have an ID? Using 0", bar_.output->name); - } else { - monitor_id_ = (*current_monitor)["id"].asInt(); - } - const Json::Value workspaces_json = gIPC->getSocket1JsonReply("workspaces"); const Json::Value clients_json = gIPC->getSocket1JsonReply("clients"); @@ -631,8 +572,13 @@ void Workspaces::init() { } } - fill_persistent_workspaces(); - create_persistent_workspaces(); + // TODO: create workspaces that are bound to monitors but not yet created + // 1. get list of workspace rules + // 2. if a workspace is bound and persistent, create it + auto const workspaceRules = gIPC->getSocket1JsonReply("workspacerules"); + for (Json::Value const &rule : workspaceRules) { + auto const &workspace = rule["workspaceString"]; + } update_window_count(); @@ -662,8 +608,26 @@ Workspace::Workspace(const Json::Value &workspace_data, Workspaces &workspace_ma is_special_ = true; } - if (workspace_data.isMember("persistent")) { - is_persistent_ = workspace_data["persistent"].asBool(); + auto const workspaceRules = gIPC->getSocket1JsonReply("workspacerules"); + for (Json::Value const &rule : workspaceRules) { + // check if this rule is for this workspaceString + auto const &workspaceString = rule["workspaceString"]; + if (workspaceString.isInt() && workspaceString.asInt() == id_) { + is_persistent_ = rule["persistent"].asBool(); + spdlog::info("Persistent value for workspaceString {} is {}", workspaceString.asInt(), + is_persistent_); + break; + } + if (workspaceString.isString() && workspaceString.asString().starts_with("name:") && + workspaceString.asString().substr(5) == name_) { + if (rule["persistent"].isBool()) { + is_persistent_ = rule["persistent"].asBool(); + spdlog::info("Persistent value for workspaceString {} is {}", workspaceString.asString(), + is_persistent_); + break; + } + spdlog::warn("Invalid persistent value for workspaceString {}", workspaceString.asString()); + } } button_.add_events(Gdk::BUTTON_PRESS_MASK); @@ -771,8 +735,7 @@ void Workspaces::sort_workspaces() { if (a->id() == -99 || b->id() == -99) { return b->id() == -99; } - // both are 0 (not yet named persistents) / both are named specials (-98 <= ID - // <=-1) + // both are named specials (-98 <= ID <=-1) return is_name_less; } @@ -848,9 +811,9 @@ std::string &Workspace::select_icon(std::map &icons_ma bool Workspace::handle_clicked(GdkEventButton *bt) const { try { - if (id() > 0) { // normal or numbered persistent + if (id() > 0) { // normal gIPC->getSocket1Reply("dispatch workspace " + std::to_string(id())); - } else if (!is_special()) { // named + } else if (!is_special()) { // named (this includes persistent) gIPC->getSocket1Reply("dispatch workspace name:" + name()); } else if (id() != -99) { // named special gIPC->getSocket1Reply("dispatch togglespecialworkspace " + name()); diff --git a/src/util/regex_collection.cpp b/src/util/regex_collection.cpp index df0879c181..704d65455d 100644 --- a/src/util/regex_collection.cpp +++ b/src/util/regex_collection.cpp @@ -66,4 +66,4 @@ std::string& RegexCollection::get(std::string& value) { return get(value, matched_any); } -} // namespace waybar::util \ No newline at end of file +} // namespace waybar::util