From 9df6ba9e9f5c330fe673ba852b51b487353d658d Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Tue, 10 Feb 2026 19:13:14 +0000 Subject: [PATCH] protocol/IPC: add a status object (#313) --- hw-protocols/hyprpaper_core.xml | 32 ++++++++++++++++++++++++++++++-- src/ipc/IPC.cpp | 23 +++++++++++++++++++++-- src/ipc/IPC.hpp | 2 ++ src/ui/UI.cpp | 12 +++++++++++- src/ui/UI.hpp | 7 ++++--- 5 files changed, 68 insertions(+), 8 deletions(-) diff --git a/hw-protocols/hyprpaper_core.xml b/hw-protocols/hyprpaper_core.xml index fa2edc0..3d26a10 100644 --- a/hw-protocols/hyprpaper_core.xml +++ b/hw-protocols/hyprpaper_core.xml @@ -1,5 +1,5 @@ - + BSD 3-Clause License @@ -31,7 +31,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + This is the core manager object for hyprpaper operations @@ -62,6 +62,13 @@ Destroys this object. Children remain alive until destroyed. + + + + Creates a status object + + + @@ -141,4 +148,25 @@ + + + + This is an object which will emit various status updates. + + + + + Sends the active wallpaper for a given monitor. This will be emitted + immediately after binding, and then every time the path changes. + + + + + + + + Destroys this object. + + + diff --git a/src/ipc/IPC.cpp b/src/ipc/IPC.cpp index c54aa08..052b1b5 100644 --- a/src/ipc/IPC.cpp +++ b/src/ipc/IPC.cpp @@ -8,7 +8,8 @@ using namespace IPC; using namespace std::string_literals; -constexpr const char* SOCKET_NAME = ".hyprpaper.sock"; +constexpr const char* SOCKET_NAME = ".hyprpaper.sock"; +constexpr const size_t HP_PROTO_VERSION = 2; static SP g_coreImpl; @@ -114,7 +115,7 @@ CSocket::CSocket() { if (!m_socket) return; - g_coreImpl = makeShared(1, [this](SP obj) { + g_coreImpl = makeShared(HP_PROTO_VERSION, [this](SP obj) { auto manager = m_managers.emplace_back(makeShared(std::move(obj))); manager->setDestroy([this, weak = WP{manager}] { std::erase(m_managers, weak); }); @@ -127,6 +128,18 @@ CSocket::CSocket() { m_wallpaperObjects.emplace_back(makeShared( makeShared(m_socket->createObject(weak->getObject()->client(), weak->getObject(), "hyprpaper_wallpaper", id)))); }); + + manager->setGetStatusObject([this, weak = WP{manager}](uint32_t id) { + if (!weak) + return; + + auto x = + m_statusObjects.emplace_back(makeShared(m_socket->createObject(weak->getObject()->client(), weak->getObject(), "hyprpaper_status", id))); + + for (const auto& m : g_ui->targets()) { + x->sendActiveWallpaper(m->m_monitorName.c_str(), m->m_lastPath.c_str()); + } + }); }); m_socket->addImplementation(g_coreImpl); @@ -145,3 +158,9 @@ void CSocket::onRemovedDisplay(const std::string& sv) { m->sendRemoveMonitor(sv.c_str()); } } + +void CSocket::onWallpaperChanged(const std::string& mon, const std::string& path) { + for (const auto& so : m_statusObjects) { + so->sendActiveWallpaper(mon.c_str(), path.c_str()); + } +} diff --git a/src/ipc/IPC.hpp b/src/ipc/IPC.hpp index b1491e1..7968e40 100644 --- a/src/ipc/IPC.hpp +++ b/src/ipc/IPC.hpp @@ -30,6 +30,7 @@ namespace IPC { void onNewDisplay(const std::string& sv); void onRemovedDisplay(const std::string& sv); + void onWallpaperChanged(const std::string& mon, const std::string& path); private: SP m_socket; @@ -38,6 +39,7 @@ namespace IPC { std::vector> m_managers; std::vector> m_wallpaperObjects; + std::vector> m_statusObjects; friend class CWallpaperObject; }; diff --git a/src/ui/UI.cpp b/src/ui/UI.cpp index c73d07d..87538e3 100644 --- a/src/ui/UI.cpp +++ b/src/ui/UI.cpp @@ -73,6 +73,8 @@ CWallpaperTarget::CWallpaperTarget(SP backend, SPfitMode(fitMode) ->commence(); + m_lastPath = path.front(); + m_image->setPositionMode(Hyprtoolkit::IElement::HT_POSITION_ABSOLUTE); m_image->setPositionFlag(Hyprtoolkit::IElement::HT_POSITION_FLAG_CENTER, true); @@ -115,8 +117,10 @@ void CWallpaperTarget::onRepeatTimer() { ASSERT(m_imagesData); + m_lastPath = m_imagesData->nextImage(); + m_image->rebuild() - ->path(m_imagesData->nextImage()) + ->path(std::string{m_lastPath}) ->size({Hyprtoolkit::CDynamicSize::HT_SIZE_PERCENT, Hyprtoolkit::CDynamicSize::HT_SIZE_PERCENT, {1.F, 1.F}}) ->sync(true) ->fitMode(m_imagesData->fitMode) @@ -124,6 +128,8 @@ void CWallpaperTarget::onRepeatTimer() { m_timer = m_backend->addTimer(std::chrono::milliseconds(std::chrono::seconds(m_imagesData->timeout)), [this](ASP self, void*) { onRepeatTimer(); }, nullptr); + + IPC::g_IPCSocket->onWallpaperChanged(m_monitorName, m_lastPath); } void CUI::registerOutput(const SP& mon) { @@ -224,3 +230,7 @@ void CUI::targetChanged(const SP& mon) { m_targets.emplace_back(makeShared(m_backend, mon, TARGET->get().paths, toFitMode(TARGET->get().fitMode), TARGET->get().timeout)); } + +const std::vector>& CUI::targets() { + return m_targets; +} diff --git a/src/ui/UI.hpp b/src/ui/UI.hpp index 6b8940a..774dc84 100644 --- a/src/ui/UI.hpp +++ b/src/ui/UI.hpp @@ -24,7 +24,7 @@ class CWallpaperTarget { CWallpaperTarget(CWallpaperTarget&) = delete; CWallpaperTarget(CWallpaperTarget&&) = delete; - std::string m_monitorName; + std::string m_monitorName, m_lastPath; private: void onRepeatTimer(); @@ -46,8 +46,9 @@ class CUI { CUI(); ~CUI(); - bool run(); - SP backend(); + bool run(); + SP backend(); + const std::vector>& targets(); private: void targetChanged(const SP& mon);