diff --git a/include/modules/wlr/workspace_manager.hpp b/include/modules/wlr/workspace_manager.hpp index 963d610f..1fdb9929 100644 --- a/include/modules/wlr/workspace_manager.hpp +++ b/include/modules/wlr/workspace_manager.hpp @@ -22,7 +22,7 @@ class WorkspaceGroup; class Workspace { public: Workspace(const waybar::Bar &bar, const Json::Value &config, WorkspaceGroup &workspace_group, - zext_workspace_handle_v1 *workspace, uint32_t id); + zext_workspace_handle_v1 *workspace, uint32_t id, std::string name); ~Workspace(); auto update() -> void; @@ -30,11 +30,14 @@ class Workspace { auto is_active() const -> bool { return state_ & static_cast(State::ACTIVE); } auto is_urgent() const -> bool { return state_ & static_cast(State::URGENT); } auto is_hidden() const -> bool { return state_ & static_cast(State::HIDDEN); } + auto is_persistent() const -> bool { return persistent_; } // wlr stuff auto handle_name(const std::string &name) -> void; auto handle_coordinates(const std::vector &coordinates) -> void; auto handle_state(const std::vector &state) -> void; auto handle_remove() -> void; + auto make_persistent() -> void; + auto handle_duplicate() -> void; auto handle_done() -> void; auto handle_clicked(GdkEventButton *bt) -> bool; @@ -67,6 +70,7 @@ class Workspace { static std::map icons_map_; std::string format_; bool with_icon_ = false; + bool persistent_ = false; Gtk::Button button_; Gtk::Box content_; @@ -87,11 +91,14 @@ class WorkspaceGroup { auto active_only() const -> bool; auto creation_delayed() const -> bool; auto workspaces() -> std::vector> & { return workspaces_; } + auto persistent_workspaces() -> std::vector & { return persistent_workspaces_; } auto sort_workspaces() -> void; auto set_need_to_sort() -> void { need_to_sort = true; } auto add_button(Gtk::Button &button) -> void; auto remove_button(Gtk::Button &button) -> void; + auto fill_persistent_workspaces() -> void; + auto create_persistent_workspaces() -> void; // wlr stuff auto handle_workspace_create(zext_workspace_handle_v1 *workspace_handle) -> void; @@ -115,6 +122,8 @@ class WorkspaceGroup { uint32_t id_; std::vector> workspaces_; bool need_to_sort = false; + std::vector persistent_workspaces_; + bool persistent_created_ = false; }; class WorkspaceManager : public AModule { diff --git a/src/modules/wlr/workspace_manager.cpp b/src/modules/wlr/workspace_manager.cpp index c1b68c84..6a496e6f 100644 --- a/src/modules/wlr/workspace_manager.cpp +++ b/src/modules/wlr/workspace_manager.cpp @@ -208,6 +208,38 @@ WorkspaceGroup::WorkspaceGroup(const Bar &bar, Gtk::Box &box, const Json::Value add_workspace_group_listener(workspace_group_handle, this); } +auto WorkspaceGroup::fill_persistent_workspaces() -> void { + if (config_["persistent_workspaces"].isObject() && !workspace_manager_.all_outputs()) { + const Json::Value &p_workspaces = config_["persistent_workspaces"]; + const std::vector p_workspaces_names = p_workspaces.getMemberNames(); + + for (const std::string &p_w_name : p_workspaces_names) { + const Json::Value &p_w = p_workspaces[p_w_name]; + if (p_w.isArray() && !p_w.empty()) { + // Adding to target outputs + for (const Json::Value &output : p_w) { + if (output.asString() == bar_.output->name) { + persistent_workspaces_.push_back(p_w_name); + break; + } + } + } else { + // Adding to all outputs + persistent_workspaces_.push_back(p_w_name); + } + } + } +} + +auto WorkspaceGroup::create_persistent_workspaces() -> void { + for (const std::string &p_w_name : persistent_workspaces_) { + auto new_id = ++workspace_global_id; + workspaces_.push_back( + std::make_unique(bar_, config_, *this, nullptr, new_id, p_w_name)); + spdlog::debug("Workspace {} created", new_id); + } +} + auto WorkspaceGroup::active_only() const -> bool { return workspace_manager_.active_only(); } auto WorkspaceGroup::creation_delayed() const -> bool { return workspace_manager_.creation_delayed(); @@ -228,8 +260,13 @@ WorkspaceGroup::~WorkspaceGroup() { auto WorkspaceGroup::handle_workspace_create(zext_workspace_handle_v1 *workspace) -> void { auto new_id = ++workspace_global_id; - workspaces_.push_back(std::make_unique(bar_, config_, *this, workspace, new_id)); + workspaces_.push_back(std::make_unique(bar_, config_, *this, workspace, new_id, "")); spdlog::debug("Workspace {} created", new_id); + if (!persistent_created_) { + fill_persistent_workspaces(); + create_persistent_workspaces(); + persistent_created_ = true; + } } auto WorkspaceGroup::handle_remove() -> void { @@ -328,13 +365,16 @@ auto WorkspaceGroup::sort_workspaces() -> void { auto WorkspaceGroup::remove_button(Gtk::Button &button) -> void { box_.remove(button); } Workspace::Workspace(const Bar &bar, const Json::Value &config, WorkspaceGroup &workspace_group, - zext_workspace_handle_v1 *workspace, uint32_t id) + zext_workspace_handle_v1 *workspace, uint32_t id, std::string name) : bar_(bar), config_(config), workspace_group_(workspace_group), workspace_handle_(workspace), - id_(id) { - add_workspace_listener(workspace, this); + id_(id), + name_(name) { + if (workspace) { + add_workspace_listener(workspace, this); + } auto config_format = config["format"]; @@ -401,9 +441,13 @@ auto Workspace::handle_state(const std::vector &state) -> void { } auto Workspace::handle_remove() -> void { - zext_workspace_handle_v1_destroy(workspace_handle_); - workspace_handle_ = nullptr; - workspace_group_.remove_workspace(id_); + if (workspace_handle_) { + zext_workspace_handle_v1_destroy(workspace_handle_); + workspace_handle_ = nullptr; + } + if (!persistent_) { + workspace_group_.remove_workspace(id_); + } } auto add_or_remove_class(Glib::RefPtr context, bool condition, @@ -487,6 +531,29 @@ auto Workspace::handle_name(const std::string &name) -> void { workspace_group_.set_need_to_sort(); } name_ = name; + spdlog::debug("Workspace {} added to group {}", name, workspace_group_.id()); + + make_persistent(); + handle_duplicate(); +} + +auto Workspace::make_persistent() -> void { + auto p_workspaces = workspace_group_.persistent_workspaces(); + + if (std::find(p_workspaces.begin(), p_workspaces.end(), name_) != p_workspaces.end()) { + persistent_ = true; + } +} + +auto Workspace::handle_duplicate() -> void { + auto duplicate = + std::find_if(workspace_group_.workspaces().begin(), workspace_group_.workspaces().end(), + [this](const std::unique_ptr &g) { + return g->get_name() == name_ && g->id() != id_; + }); + if (duplicate != workspace_group_.workspaces().end()) { + workspace_group_.remove_workspace(duplicate->get()->id()); + } } auto Workspace::handle_coordinates(const std::vector &coordinates) -> void {