From 1bf97f532e5aac74fe9e9ca61500c3e26b14422f Mon Sep 17 00:00:00 2001 From: Brenno Lemos Date: Wed, 24 Jan 2024 20:05:29 -0300 Subject: [PATCH] fix: special workspaces with the same name as regular workspaces caused the latter to be destroyed --- include/modules/hyprland/workspaces.hpp | 4 ++++ src/modules/hyprland/workspaces.cpp | 32 +++++++++++++++---------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index d2006fcc..1c4cf0ae 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -22,6 +22,9 @@ using WindowAddress = std::string; +static const std::string SPECIAL_QUALIFIER_PREFIX = "special:"; +static const int SPECIAL_QUALIFIER_PREFIX_LEN = SPECIAL_QUALIFIER_PREFIX.length(); + namespace waybar::modules::hyprland { class Workspaces; @@ -135,6 +138,7 @@ class Workspaces : public AModule, public EventHandler { void onEvent(const std::string& e) override; void updateWindowCount(); void sortWorkspaces(); + auto locateWorkspace(const std::string& workspaceName); void createWorkspace(Json::Value const& workspace_data, Json::Value const& clients_data = Json::Value::nullRef); void removeWorkspace(std::string const& name); diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index b05ce134..6717d7ac 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -514,16 +514,28 @@ std::optional Workspace::closeWindow(WindowAddress const &addr) { return std::nullopt; } +auto Workspaces::locateWorkspace(const std::string &workspaceName) { + bool isSpecial = workspaceName.starts_with(SPECIAL_QUALIFIER_PREFIX); + std::string unqualifiedWorkspaceName; + + if (isSpecial) { + unqualifiedWorkspaceName = workspaceName.substr(SPECIAL_QUALIFIER_PREFIX_LEN); + } + + return std::find_if( + m_workspaces.begin(), m_workspaces.end(), + [workspaceName, isSpecial, unqualifiedWorkspaceName](std::unique_ptr const &w) { + return (isSpecial && w->isSpecial() && unqualifiedWorkspaceName == w->name()) || + workspaceName == w->name(); + }); +} + void Workspaces::createWorkspace(Json::Value const &workspace_data, Json::Value const &clients_data) { // avoid recreating existing workspaces auto workspaceName = workspace_data["name"].asString(); - auto workspace = std::find_if( - m_workspaces.begin(), m_workspaces.end(), - [workspaceName](std::unique_ptr const &w) { - return (workspaceName.starts_with("special:") && workspaceName.substr(8) == w->name()) || - workspaceName == w->name(); - }); + + auto workspace = locateWorkspace(workspaceName); if (workspace != m_workspaces.end()) { if (workspace_data["persistent"].asBool() and !(*workspace)->isPersistent()) { @@ -541,10 +553,7 @@ void Workspaces::createWorkspace(Json::Value const &workspace_data, } void Workspaces::removeWorkspace(std::string const &name) { - auto workspace = - std::find_if(m_workspaces.begin(), m_workspaces.end(), [&](std::unique_ptr &x) { - return (name.starts_with("special:") && name.substr(8) == x->name()) || name == x->name(); - }); + auto workspace = locateWorkspace(name); if (workspace == m_workspaces.end()) { // happens when a workspace on another monitor is destroyed @@ -1016,9 +1025,6 @@ void WindowCreationPayload::clearWorkspaceName() { // special qualifier. The reasoning is that not all of Hyprland's IPC events // use this qualifier, so it's better to be consistent about our uses. - static const std::string SPECIAL_QUALIFIER_PREFIX = "special:"; - static const int SPECIAL_QUALIFIER_PREFIX_LEN = SPECIAL_QUALIFIER_PREFIX.length(); - if (m_workspaceName.starts_with(SPECIAL_QUALIFIER_PREFIX)) { m_workspaceName = m_workspaceName.substr( SPECIAL_QUALIFIER_PREFIX_LEN, m_workspaceName.length() - SPECIAL_QUALIFIER_PREFIX_LEN);