From b3ee94d87ae4606c042fc4dd739c54285038d802 Mon Sep 17 00:00:00 2001 From: Anthony Ruhier Date: Sat, 24 Feb 2024 23:57:07 +0100 Subject: [PATCH 1/2] Improve hyprland/workspaces persistency logic Fixes #2945 Split the config and rule persistency in 2 attributes, one storing the persistency as set in Waybar's config, the other one storing the persistency as set in Hyprland. It fixes some conflicts between the persistency state of a workspace as set in Waybar's config and its dynamic state in Hyprland. It allows to remove a persistent workspace in Waybar if this workspace is removed from Hyprland and if the workspace is not set as persistent in Waybar's config. --- include/modules/hyprland/workspaces.hpp | 12 +++++-- src/modules/hyprland/workspaces.cpp | 43 +++++++++++++++++-------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index 8d46b1a1..41870077 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -70,14 +70,17 @@ class Workspace { std::string output() const { return m_output; }; bool isActive() const { return m_isActive; }; bool isSpecial() const { return m_isSpecial; }; - bool isPersistent() const { return m_isPersistent; }; + bool isPersistent() const { return m_isPersistentRule || m_isPersistentConfig; }; + bool isPersistentConfig() const { return m_isPersistentConfig; }; + bool isPersistentRule() const { return m_isPersistentRule; }; bool isVisible() const { return m_isVisible; }; bool isEmpty() const { return m_windows == 0; }; bool isUrgent() const { return m_isUrgent; }; bool handleClicked(GdkEventButton* bt) const; void setActive(bool value = true) { m_isActive = value; }; - void setPersistent(bool value = true) { m_isPersistent = value; }; + void setPersistentRule(bool value = true) { m_isPersistentRule = value; }; + void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; }; void setUrgent(bool value = true) { m_isUrgent = value; }; void setVisible(bool value = true) { m_isVisible = value; }; void setWindows(uint value) { m_windows = value; }; @@ -101,7 +104,10 @@ class Workspace { uint m_windows; bool m_isActive = false; bool m_isSpecial = false; - bool m_isPersistent = false; + // m_isPersistentRule represents the persistent state in hyprland + bool m_isPersistentRule = false; + // m_isPersistentConfig represents the persistent state in the Waybar config + bool m_isPersistentConfig = false; bool m_isUrgent = false; bool m_isVisible = false; diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 3e393121..882e3806 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -349,7 +349,7 @@ void Workspaces::onWorkspaceCreated(std::string const &workspaceName, (showSpecial() || !name.starts_with("special")) && !isDoubleSpecial(workspaceName)) { for (Json::Value const &rule : workspaceRules) { if (rule["workspaceString"].asString() == workspaceName) { - workspaceJson["persistent"] = rule["persistent"].asBool(); + workspaceJson["persistent-rule"] = rule["persistent"].asBool(); break; } } @@ -587,8 +587,7 @@ std::optional Workspace::closeWindow(WindowAddress const &addr) { void Workspaces::createWorkspace(Json::Value const &workspace_data, Json::Value const &clients_data) { auto workspaceName = workspace_data["name"].asString(); - spdlog::debug("Creating workspace {}, persistent: {}", workspaceName, - workspace_data["persistent"].asBool() ? "true" : "false"); + spdlog::debug("Creating workspace {}", workspaceName); // avoid recreating existing workspaces auto workspace = std::find_if( @@ -600,7 +599,22 @@ void Workspaces::createWorkspace(Json::Value const &workspace_data, if (workspace != m_workspaces.end()) { // don't recreate workspace, but update persistency if necessary - (*workspace)->setPersistent(workspace_data["persistent"].asBool()); + const auto keys = workspace_data.getMemberNames(); + + const auto *k = "persistent-rule"; + if (std::find(keys.begin(), keys.end(), k) != keys.end()) { + spdlog::debug("Set dynamic persistency of workspace {} to: {}", workspaceName, + workspace_data[k].asBool() ? "true" : "false"); + (*workspace)->setPersistentRule(workspace_data[k].asBool()); + } + + k = "persistent-config"; + if (std::find(keys.begin(), keys.end(), k) != keys.end()) { + spdlog::debug("Set config persistency of workspace {} to: {}", workspaceName, + workspace_data[k].asBool() ? "true" : "false"); + (*workspace)->setPersistentConfig(workspace_data[k].asBool()); + } + return; } @@ -624,8 +638,8 @@ void Workspaces::removeWorkspace(std::string const &name) { return; } - if ((*workspace)->isPersistent()) { - spdlog::trace("Not removing persistent workspace {}", name); + if ((*workspace)->isPersistentConfig()) { + spdlog::trace("Not removing config persistent workspace {}", name); return; } @@ -633,7 +647,7 @@ void Workspaces::removeWorkspace(std::string const &name) { m_workspaces.erase(workspace); } -Json::Value createPersistentWorkspaceData(std::string const &name, std::string const &monitor) { +Json::Value createMonitorWorkspaceData(std::string const &name, std::string const &monitor) { spdlog::trace("Creating persistent workspace: {} on monitor {}", name, monitor); Json::Value workspaceData; try { @@ -646,7 +660,6 @@ Json::Value createPersistentWorkspaceData(std::string const &name, std::string c workspaceData["name"] = name; workspaceData["monitor"] = monitor; workspaceData["windows"] = 0; - workspaceData["persistent"] = true; return workspaceData; } @@ -699,7 +712,8 @@ void Workspaces::loadPersistentWorkspacesFromConfig(Json::Value const &clientsJs } for (auto const &workspace : persistentWorkspacesToCreate) { - auto const workspaceData = createPersistentWorkspaceData(workspace, m_bar.output->name); + auto workspaceData = createMonitorWorkspaceData(workspace, m_bar.output->name); + workspaceData["persistent-config"] = true; m_workspacesToCreate.emplace_back(workspaceData, clientsJson); } } @@ -724,7 +738,8 @@ void Workspaces::loadPersistentWorkspacesFromWorkspaceRules(const Json::Value &c // 3. no monitor is specified in the rule => assume it needs to be persistent on every monitor if (allOutputs() || m_bar.output->name == monitor || monitor.empty()) { // => persistent workspace should be shown on this monitor - auto workspaceData = createPersistentWorkspaceData(workspace, m_bar.output->name); + auto workspaceData = createMonitorWorkspaceData(workspace, m_bar.output->name); + workspaceData["persistent-rule"] = true; m_workspacesToCreate.emplace_back(workspaceData, clientsJson); } else { m_workspacesToRemove.emplace_back(workspace); @@ -774,10 +789,9 @@ void Workspaces::initializeWorkspaces() { if (m_persistentWorkspaceConfig.isObject()) { // a persistent workspace config is defined, so use that instead of workspace rules loadPersistentWorkspacesFromConfig(clientsJson); - } else { - // no persistent workspaces config defined, use Hyprland's workspace rules - loadPersistentWorkspacesFromWorkspaceRules(clientsJson); } + // load Hyprland's workspace rules + loadPersistentWorkspacesFromWorkspaceRules(clientsJson); } void Workspaces::extendOrphans(int workspaceId, Json::Value const &clientsJson) { @@ -812,7 +826,8 @@ Workspace::Workspace(const Json::Value &workspace_data, Workspaces &workspace_ma m_output(workspace_data["monitor"].asString()), // TODO:allow using monitor desc m_windows(workspace_data["windows"].asInt()), m_isActive(true), - m_isPersistent(workspace_data["persistent"].asBool()) { + m_isPersistentRule(workspace_data["persistent-rule"].asBool()), + m_isPersistentConfig(workspace_data["persistent-config"].asBool()) { if (m_name.starts_with("name:")) { m_name = m_name.substr(5); } else if (m_name.starts_with("special")) { From d6d4d87cf7516817197f070ecd1c9a396ea0ac03 Mon Sep 17 00:00:00 2001 From: Anthony Ruhier Date: Mon, 26 Feb 2024 00:05:12 +0100 Subject: [PATCH 2/2] Attributes doc format fix from the review Co-authored-by: Tuur Vanhoutte <4633209+zjeffer@users.noreply.github.com> --- include/modules/hyprland/workspaces.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index 41870077..91ea1653 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -104,10 +104,8 @@ class Workspace { uint m_windows; bool m_isActive = false; bool m_isSpecial = false; - // m_isPersistentRule represents the persistent state in hyprland - bool m_isPersistentRule = false; - // m_isPersistentConfig represents the persistent state in the Waybar config - bool m_isPersistentConfig = false; + bool m_isPersistentRule = false; // represents the persistent state in hyprland + bool m_isPersistentConfig = false; // represents the persistent state in the Waybar config bool m_isUrgent = false; bool m_isVisible = false;