diff --git a/include/modules/hyprland/backend.hpp b/include/modules/hyprland/backend.hpp index 51cbd8f..9401bf5 100644 --- a/include/modules/hyprland/backend.hpp +++ b/include/modules/hyprland/backend.hpp @@ -1,5 +1,5 @@ #pragma once -#include +#include #include #include #include @@ -7,11 +7,19 @@ #include namespace waybar::modules::hyprland { + +class EventHandler { +public: + virtual void onEvent(const std::string& ev) = 0; + virtual ~EventHandler() = default; +}; + class IPC { public: IPC() { startIPC(); } - void registerForIPC(const std::string&, std::function); + void registerForIPC(const std::string&, EventHandler*); + void unregisterForIPC(EventHandler*); std::string getSocket1Reply(const std::string& rq); @@ -20,7 +28,7 @@ class IPC { void parseIPC(const std::string&); std::mutex callbackMutex; - std::deque>> callbacks; + std::list> callbacks; }; inline std::unique_ptr gIPC; diff --git a/include/modules/hyprland/language.hpp b/include/modules/hyprland/language.hpp index bdf24ec..04fe382 100644 --- a/include/modules/hyprland/language.hpp +++ b/include/modules/hyprland/language.hpp @@ -7,10 +7,11 @@ namespace waybar::modules::hyprland { -class Language : public waybar::AButton { +class Language : public waybar::AButton, +public EventHandler { public: Language(const std::string&, const waybar::Bar&, const Json::Value&); - ~Language() = default; + ~Language(); auto update() -> void; diff --git a/include/modules/hyprland/window.hpp b/include/modules/hyprland/window.hpp index 1423aec..4b697cf 100644 --- a/include/modules/hyprland/window.hpp +++ b/include/modules/hyprland/window.hpp @@ -9,10 +9,11 @@ namespace waybar::modules::hyprland { -class Window : public waybar::ALabel { +class Window : public waybar::ALabel, + public EventHandler { public: Window(const std::string&, const waybar::Bar&, const Json::Value&); - ~Window() = default; + ~Window(); auto update() -> void; @@ -28,4 +29,4 @@ class Window : public waybar::ALabel { std::string lastView; }; -} // namespace waybar::modules::hyprland \ No newline at end of file +} // namespace waybar::modules::hyprland diff --git a/src/modules/hyprland/backend.cpp b/src/modules/hyprland/backend.cpp index ae73a25..7b9e573 100644 --- a/src/modules/hyprland/backend.cpp +++ b/src/modules/hyprland/backend.cpp @@ -95,15 +95,37 @@ void IPC::parseIPC(const std::string& ev) { for (auto& [eventname, handler] : callbacks) { if (eventname == request) { - handler(ev); + handler->onEvent(ev); } } } -void IPC::registerForIPC(const std::string& ev, std::function fn) { +void IPC::registerForIPC(const std::string& ev, EventHandler* ev_handler) { + if (!ev_handler) { + return; + } callbackMutex.lock(); - callbacks.emplace_back(std::make_pair(ev, fn)); + callbacks.emplace_back(std::make_pair(ev, ev_handler)); + + callbackMutex.unlock(); +} + +void IPC::unregisterForIPC(EventHandler* ev_handler) { + if (!ev_handler) { + return; + } + + callbackMutex.lock(); + + for(auto it = callbacks.begin(); it != callbacks.end(); ) { + auto it_current = it; + it++; + auto& [eventname, handler] = *it_current; + if (handler == ev_handler) { + callbacks.erase(it_current); + } + } callbackMutex.unlock(); } @@ -168,4 +190,4 @@ std::string IPC::getSocket1Reply(const std::string& rq) { return std::string(buffer); } -} // namespace waybar::modules::hyprland \ No newline at end of file +} // namespace waybar::modules::hyprland diff --git a/src/modules/hyprland/language.cpp b/src/modules/hyprland/language.cpp index 6583343..b6d7c0f 100644 --- a/src/modules/hyprland/language.cpp +++ b/src/modules/hyprland/language.cpp @@ -25,7 +25,13 @@ Language::Language(const std::string& id, const Bar& bar, const Json::Value& con AButton::update(); // register for hyprland ipc - gIPC->registerForIPC("activelayout", [&](const std::string& ev) { this->onEvent(ev); }); + gIPC->registerForIPC("activelayout", this); +} + +Language::~Language() { + gIPC->unregisterForIPC(this); + // wait for possible event handler to finish + std::lock_guard lg(mutex_); } auto Language::update() -> void { diff --git a/src/modules/hyprland/window.cpp b/src/modules/hyprland/window.cpp index d942cf6..3ab2b01 100644 --- a/src/modules/hyprland/window.cpp +++ b/src/modules/hyprland/window.cpp @@ -25,7 +25,13 @@ Window::Window(const std::string& id, const Bar& bar, const Json::Value& config) ALabel::update(); // register for hyprland ipc - gIPC->registerForIPC("activewindow", [&](const std::string& ev) { this->onEvent(ev); }); + gIPC->registerForIPC("activewindow", this); +} + +Window::~Window() { + gIPC->unregisterForIPC(this); + // wait for possible event handler to finish + std::lock_guard lg(mutex_); } auto Window::update() -> void { @@ -50,7 +56,9 @@ uint Window::getActiveWorkspaceID(std::string monitorName) { assert(json.isArray()); auto monitor = std::find_if(json.begin(), json.end(), [&](Json::Value monitor) { return monitor["name"] == monitorName; }); - assert(monitor != std::end(json)); + if(monitor == std::end(json)) { + return 0; + } return (*monitor)["activeWorkspace"]["id"].as(); } @@ -89,4 +97,4 @@ void Window::onEvent(const std::string& ev) { dp.emit(); } -} // namespace waybar::modules::hyprland \ No newline at end of file +} // namespace waybar::modules::hyprland