From 8a7df4675a46e3ee8a047a2ee3b261df263ca8f2 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sun, 17 Jul 2022 14:17:54 +0200 Subject: [PATCH] added unload --- src/Hyprpaper.cpp | 41 ++++++++++++++++++++++++++++++++++ src/Hyprpaper.hpp | 1 + src/config/ConfigManager.cpp | 13 +++++++++++ src/config/ConfigManager.hpp | 1 + src/helpers/PoolBuffer.hpp | 1 + src/ipc/Socket.cpp | 2 +- src/render/WallpaperTarget.cpp | 4 ++++ src/render/WallpaperTarget.hpp | 2 ++ 8 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/Hyprpaper.cpp b/src/Hyprpaper.cpp index 455c847..7d86548 100644 --- a/src/Hyprpaper.cpp +++ b/src/Hyprpaper.cpp @@ -65,6 +65,46 @@ bool CHyprpaper::isPreloaded(const std::string& path) { return false; } +void CHyprpaper::unloadWallpaper(const std::string& path) { + bool found = false; + + for (auto& [ewp, cls] : m_mWallpaperTargets) { + if (ewp == path) { + // found + found = true; + break; + } + } + + if (!found) { + Debug::log(LOG, "Cannot unload a target that was not loaded!"); + return; + } + + // clean buffers + for (auto it = m_vBuffers.begin(); it != m_vBuffers.end(); it++) { + + if (it->get()->pTarget->m_szPath != path) + continue; + + + const auto PRELOADPATH = it->get()->name; + + Debug::log(LOG, "Unloading target %s, preload path %s", path.c_str(), PRELOADPATH.c_str()); + + std::filesystem::remove(PRELOADPATH); + + destroyBuffer(it->get()); + + it = m_vBuffers.erase(it); + + if (it == m_vBuffers.end()) + break; + } + + m_mWallpaperTargets.erase(path); // will free the cairo surface +} + void CHyprpaper::preloadAllWallpapersFromConfig() { if (g_pConfigManager->m_dRequestedPreloads.empty()) return; @@ -320,6 +360,7 @@ void CHyprpaper::createBuffer(SPoolBuffer* pBuffer, int32_t w, int32_t h, uint32 pBuffer->surface = cairo_image_surface_create_for_data((unsigned char*)DATA, CAIRO_FORMAT_ARGB32, w, h, STRIDE); pBuffer->cairo = cairo_create(pBuffer->surface); pBuffer->pixelSize = Vector2D(w, h); + pBuffer->name = name; } void CHyprpaper::destroyBuffer(SPoolBuffer* pBuffer) { diff --git a/src/Hyprpaper.hpp b/src/Hyprpaper.hpp index 04d71f2..f87ffed 100644 --- a/src/Hyprpaper.hpp +++ b/src/Hyprpaper.hpp @@ -44,6 +44,7 @@ public: void recheckMonitor(SMonitor*); void ensurePoolBuffersPresent(); SPoolBuffer* getPoolBuffer(SMonitor*, CWallpaperTarget*); + void unloadWallpaper(const std::string&); std::mutex m_mtTickMutex; private: diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 95f0150..4bb7d7b 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -93,6 +93,8 @@ void CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& handleWallpaper(COMMAND, VALUE); else if (COMMAND == "preload") handlePreload(COMMAND, VALUE); + else if (COMMAND == "unload") + handleUnload(COMMAND, VALUE); else parseError = "unknown keyword " + COMMAND; } @@ -140,3 +142,14 @@ void CConfigManager::handlePreload(const std::string& COMMAND, const std::string m_dRequestedPreloads.emplace_back(WALLPAPER); } + +void CConfigManager::handleUnload(const std::string& COMMAND, const std::string& VALUE) { + auto WALLPAPER = VALUE; + + if (WALLPAPER[0] == '~') { + static const char* const ENVHOME = getenv("HOME"); + WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1); + } + + g_pHyprpaper->unloadWallpaper(WALLPAPER); +} diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index b5c8c3a..684a42a 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -19,6 +19,7 @@ private: void handleWallpaper(const std::string&, const std::string&); void handlePreload(const std::string&, const std::string&); + void handleUnload(const std::string&, const std::string&); friend class CIPCSocket; }; diff --git a/src/helpers/PoolBuffer.hpp b/src/helpers/PoolBuffer.hpp index 6b2042e..e6db3c5 100644 --- a/src/helpers/PoolBuffer.hpp +++ b/src/helpers/PoolBuffer.hpp @@ -10,6 +10,7 @@ struct SPoolBuffer { cairo_t* cairo = nullptr; void* data = nullptr; size_t size = 0; + std::string name = ""; CWallpaperTarget* pTarget = nullptr; Vector2D pixelSize; diff --git a/src/ipc/Socket.cpp b/src/ipc/Socket.cpp index de4a70b..ad42af0 100644 --- a/src/ipc/Socket.cpp +++ b/src/ipc/Socket.cpp @@ -99,7 +99,7 @@ void CIPCSocket::mainThreadParseRequest() { Debug::log(LOG, "Received a request: %s", copy.c_str()); // parse - if (copy.find("wallpaper") == 0 || copy.find("preload") == 0) { + if (copy.find("wallpaper") == 0 || copy.find("preload") == 0 || copy.find("unload") == 0) { g_pConfigManager->parseError = ""; // reset parse error g_pConfigManager->parseKeyword(copy.substr(0, copy.find_first_of(' ')), copy.substr(copy.find_first_of(' ') + 1)); diff --git a/src/render/WallpaperTarget.cpp b/src/render/WallpaperTarget.cpp index 8079d07..73678e8 100644 --- a/src/render/WallpaperTarget.cpp +++ b/src/render/WallpaperTarget.cpp @@ -1,5 +1,9 @@ #include "WallpaperTarget.hpp" +CWallpaperTarget::~CWallpaperTarget() { + cairo_surface_destroy(m_pCairoSurface); +} + void CWallpaperTarget::create(const std::string& path) { m_szPath = path; diff --git a/src/render/WallpaperTarget.hpp b/src/render/WallpaperTarget.hpp index 85f8fe4..b80d6cd 100644 --- a/src/render/WallpaperTarget.hpp +++ b/src/render/WallpaperTarget.hpp @@ -5,6 +5,8 @@ class CWallpaperTarget { public: + + ~CWallpaperTarget(); void create(const std::string& path); void render();