From e91513a5e8953cfbb69320d94e495ccf2d4d58f3 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 22 Apr 2024 15:50:01 +0100 Subject: [PATCH] pluginapi: unregister callbacks on lost ptrs --- src/plugins/PluginAPI.cpp | 4 ++-- src/plugins/PluginAPI.hpp | 8 ++++++-- src/plugins/PluginSystem.cpp | 2 +- src/plugins/PluginSystem.hpp | 24 ++++++++++++------------ 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/plugins/PluginAPI.cpp b/src/plugins/PluginAPI.cpp index c89918f5..4f40694c 100644 --- a/src/plugins/PluginAPI.cpp +++ b/src/plugins/PluginAPI.cpp @@ -20,7 +20,7 @@ APICALL std::shared_ptr HyprlandAPI::registerCallbackDynamic(H return nullptr; auto PFN = g_pHookSystem->hookDynamic(event, fn, handle); - PLUGIN->registeredCallbacks.emplace_back(std::make_pair<>(event, PFN)); + PLUGIN->registeredCallbacks.emplace_back(std::make_pair<>(event, std::weak_ptr(PFN))); return PFN; } @@ -31,7 +31,7 @@ APICALL bool HyprlandAPI::unregisterCallback(HANDLE handle, std::shared_ptrunhook(fn); - std::erase_if(PLUGIN->registeredCallbacks, [&](const auto& other) { return other.second == fn; }); + std::erase_if(PLUGIN->registeredCallbacks, [&](const auto& other) { return other.second.lock() == fn; }); return true; } diff --git a/src/plugins/PluginAPI.hpp b/src/plugins/PluginAPI.hpp index 62db8e3b..78f88c21 100644 --- a/src/plugins/PluginAPI.hpp +++ b/src/plugins/PluginAPI.hpp @@ -137,15 +137,19 @@ namespace HyprlandAPI { Pointer will be free'd by Hyprland on unregisterCallback(). returns: a pointer to the newly allocated function. nullptr on fail. + + WARNING: Losing this pointer will unregister the callback! */ - APICALL std::shared_ptr registerCallbackDynamic(HANDLE handle, const std::string& event, HOOK_CALLBACK_FN fn); + APICALL [[nodiscard]] std::shared_ptr registerCallbackDynamic(HANDLE handle, const std::string& event, HOOK_CALLBACK_FN fn); /* Unregisters a callback. If the callback was dynamic, frees the memory. returns: true on success, false on fail + + Deprecated: just reset the pointer you received with registerCallbackDynamic */ - APICALL bool unregisterCallback(HANDLE handle, std::shared_ptr fn); + APICALL [[deprecated]] bool unregisterCallback(HANDLE handle, std::shared_ptr fn); /* Calls a hyprctl command. diff --git a/src/plugins/PluginSystem.cpp b/src/plugins/PluginSystem.cpp index ae87aedb..95a82dde 100644 --- a/src/plugins/PluginSystem.cpp +++ b/src/plugins/PluginSystem.cpp @@ -121,7 +121,7 @@ void CPluginSystem::unloadPlugin(const CPlugin* plugin, bool eject) { // save these two for dlclose and a log, // as erase_if will kill the pointer - const auto PLNAME = plugin->name; + const auto PLNAME = plugin->name; const auto PLHANDLE = plugin->m_pHandle; std::erase_if(m_vLoadedPlugins, [&](const auto& other) { return other->m_pHandle == PLHANDLE; }); diff --git a/src/plugins/PluginSystem.hpp b/src/plugins/PluginSystem.hpp index c618489a..944434fa 100644 --- a/src/plugins/PluginSystem.hpp +++ b/src/plugins/PluginSystem.hpp @@ -8,22 +8,22 @@ class IHyprWindowDecoration; class CPlugin { public: - std::string name = ""; - std::string description = ""; - std::string author = ""; - std::string version = ""; + std::string name = ""; + std::string description = ""; + std::string author = ""; + std::string version = ""; - std::string path = ""; + std::string path = ""; - bool m_bLoadedWithConfig = false; + bool m_bLoadedWithConfig = false; - HANDLE m_pHandle = nullptr; + HANDLE m_pHandle = nullptr; - std::vector registeredLayouts; - std::vector registeredDecorations; - std::vector>> registeredCallbacks; - std::vector registeredDispatchers; - std::vector> registeredHyprctlCommands; + std::vector registeredLayouts; + std::vector registeredDecorations; + std::vector>> registeredCallbacks; + std::vector registeredDispatchers; + std::vector> registeredHyprctlCommands; }; class CPluginSystem {