diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index a17c2db4..0109149e 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -161,6 +161,8 @@ class Workspaces : public AModule, public EventHandler { int windowRewritePriorityFunction(std::string const& window_rule); + void doUpdate(); + bool m_allOutputs = false; bool m_showSpecial = false; bool m_activeOnly = false; diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 74a09f80..3d8a5932 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -4,11 +4,8 @@ #include #include -#include #include -#include #include -#include #include #include @@ -16,8 +13,6 @@ namespace waybar::modules::hyprland { -std::shared_mutex workspaceCreateSmtx; - int Workspaces::windowRewritePriorityFunction(std::string const &window_rule) { // Rules that match against title are prioritized // Rules that don't specify if they're matching against either title or class are deprioritized @@ -153,27 +148,26 @@ auto Workspaces::registerIpc() -> void { } } -auto Workspaces::update() -> void { +/** + * Workspaces::doUpdate - update workspaces in UI thread. + * + * Note: some memberfields are modified by both UI thread and event listener thread, use m_mutex to + * protect these member fields, and lock should released before calling AModule::update(). + */ +void Workspaces::doUpdate() { + std::unique_lock lock(m_mutex); + // remove workspaces that wait to be removed - unsigned int currentRemoveWorkspaceNum = 0; - for (const std::string &workspaceToRemove : m_workspacesToRemove) { - removeWorkspace(workspaceToRemove); - currentRemoveWorkspaceNum++; - } - for (unsigned int i = 0; i < currentRemoveWorkspaceNum; i++) { - m_workspacesToRemove.erase(m_workspacesToRemove.begin()); + for (auto &elem : m_workspacesToRemove) { + removeWorkspace(elem); } + m_workspacesToRemove.clear(); // add workspaces that wait to be created - std::shared_lock workspaceCreateShareLock(workspaceCreateSmtx); - unsigned int currentCreateWorkspaceNum = 0; - for (Json::Value const &workspaceToCreate : m_workspacesToCreate) { - createWorkspace(workspaceToCreate); - currentCreateWorkspaceNum++; - } - for (unsigned int i = 0; i < currentCreateWorkspaceNum; i++) { - m_workspacesToCreate.erase(m_workspacesToCreate.begin()); + for (auto &elem : m_workspacesToCreate) { + createWorkspace(elem); } + m_workspacesToCreate.clear(); // get all active workspaces auto monitors = gIPC->getSocket1JsonReply("monitors"); @@ -231,7 +225,10 @@ auto Workspaces::update() -> void { m_windowsToCreate.clear(); m_windowsToCreate = notCreated; +} +auto Workspaces::update() -> void { + doUpdate(); AModule::update(); } @@ -305,7 +302,6 @@ void Workspaces::onWorkspaceCreated(std::string const &payload) { if (name == payload && (allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) && (showSpecial() || !name.starts_with("special")) && !isDoubleSpecial(payload)) { - std::unique_lock workspaceCreateUniqueLock(workspaceCreateSmtx); m_workspacesToCreate.push_back(workspaceJson); break; }