Improvements for Hyprland workspace

1. Utilize `m_mutex` to safeguard member fields of `hyprland::Workspaces` as they are modified by multiple threads, including the event listener thread and UI thread. This applies to all member fields, not just `m_workspacesToCreate`.

2. Tidy up the create/remove workspace code.
pull/2813/head
yangyingchao 2024-01-05 13:49:11 +08:00
parent 4b20f522f0
commit a34e3ccc86
2 changed files with 20 additions and 22 deletions

View File

@ -161,6 +161,8 @@ class Workspaces : public AModule, public EventHandler {
int windowRewritePriorityFunction(std::string const& window_rule); int windowRewritePriorityFunction(std::string const& window_rule);
void doUpdate();
bool m_allOutputs = false; bool m_allOutputs = false;
bool m_showSpecial = false; bool m_showSpecial = false;
bool m_activeOnly = false; bool m_activeOnly = false;

View File

@ -4,11 +4,8 @@
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <algorithm> #include <algorithm>
#include <charconv>
#include <memory> #include <memory>
#include <shared_mutex>
#include <string> #include <string>
#include <thread>
#include <utility> #include <utility>
#include <variant> #include <variant>
@ -16,8 +13,6 @@
namespace waybar::modules::hyprland { namespace waybar::modules::hyprland {
std::shared_mutex workspaceCreateSmtx;
int Workspaces::windowRewritePriorityFunction(std::string const &window_rule) { int Workspaces::windowRewritePriorityFunction(std::string const &window_rule) {
// Rules that match against title are prioritized // Rules that match against title are prioritized
// Rules that don't specify if they're matching against either title or class are deprioritized // 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 // remove workspaces that wait to be removed
unsigned int currentRemoveWorkspaceNum = 0; for (auto &elem : m_workspacesToRemove) {
for (const std::string &workspaceToRemove : m_workspacesToRemove) { removeWorkspace(elem);
removeWorkspace(workspaceToRemove);
currentRemoveWorkspaceNum++;
}
for (unsigned int i = 0; i < currentRemoveWorkspaceNum; i++) {
m_workspacesToRemove.erase(m_workspacesToRemove.begin());
} }
m_workspacesToRemove.clear();
// add workspaces that wait to be created // add workspaces that wait to be created
std::shared_lock<std::shared_mutex> workspaceCreateShareLock(workspaceCreateSmtx); for (auto &elem : m_workspacesToCreate) {
unsigned int currentCreateWorkspaceNum = 0; createWorkspace(elem);
for (Json::Value const &workspaceToCreate : m_workspacesToCreate) {
createWorkspace(workspaceToCreate);
currentCreateWorkspaceNum++;
}
for (unsigned int i = 0; i < currentCreateWorkspaceNum; i++) {
m_workspacesToCreate.erase(m_workspacesToCreate.begin());
} }
m_workspacesToCreate.clear();
// get all active workspaces // get all active workspaces
auto monitors = gIPC->getSocket1JsonReply("monitors"); auto monitors = gIPC->getSocket1JsonReply("monitors");
@ -231,7 +225,10 @@ auto Workspaces::update() -> void {
m_windowsToCreate.clear(); m_windowsToCreate.clear();
m_windowsToCreate = notCreated; m_windowsToCreate = notCreated;
}
auto Workspaces::update() -> void {
doUpdate();
AModule::update(); AModule::update();
} }
@ -305,7 +302,6 @@ void Workspaces::onWorkspaceCreated(std::string const &payload) {
if (name == payload && if (name == payload &&
(allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) && (allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) &&
(showSpecial() || !name.starts_with("special")) && !isDoubleSpecial(payload)) { (showSpecial() || !name.starts_with("special")) && !isDoubleSpecial(payload)) {
std::unique_lock<std::shared_mutex> workspaceCreateUniqueLock(workspaceCreateSmtx);
m_workspacesToCreate.push_back(workspaceJson); m_workspacesToCreate.push_back(workspaceJson);
break; break;
} }