protocol/IPC: add a status object (#313)

This commit is contained in:
Vaxry 2026-02-10 19:13:14 +00:00 committed by GitHub
parent 2ea222ee34
commit 9df6ba9e9f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 68 additions and 8 deletions

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="hyprpaper_core" version="1">
<protocol name="hyprpaper_core" version="2">
<copyright>
BSD 3-Clause License
@ -31,7 +31,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</copyright>
<object name="hyprpaper_core_manager" version="1">
<object name="hyprpaper_core_manager" version="2">
<description summary="manager object">
This is the core manager object for hyprpaper operations
</description>
@ -62,6 +62,13 @@
Destroys this object. Children remain alive until destroyed.
</description>
</c2s>
<c2s name="get_status_object" since="2">
<description summary="Get a status object">
Creates a status object
</description>
<returns iface="hyprpaper_status"/>
</c2s>
</object>
<enum name="wallpaper_fit_mode">
@ -141,4 +148,25 @@
</description>
</c2s>
</object>
<object name="hyprpaper_status" version="2">
<description summary="status object">
This is an object which will emit various status updates.
</description>
<s2c name="active_wallpaper">
<description summary="Active wallpaper state">
Sends the active wallpaper for a given monitor. This will be emitted
immediately after binding, and then every time the path changes.
</description>
<arg name="monitor" type="varchar" summary="monitor name"/>
<arg name="path" type="varchar" summary="wallpaper path"/>
</s2c>
<c2s name="destroy" destructor="true">
<description summary="Destroy this object">
Destroys this object.
</description>
</c2s>
</object>
</protocol>

View file

@ -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<CHyprpaperCoreImpl> g_coreImpl;
@ -114,7 +115,7 @@ CSocket::CSocket() {
if (!m_socket)
return;
g_coreImpl = makeShared<CHyprpaperCoreImpl>(1, [this](SP<Hyprwire::IObject> obj) {
g_coreImpl = makeShared<CHyprpaperCoreImpl>(HP_PROTO_VERSION, [this](SP<Hyprwire::IObject> obj) {
auto manager = m_managers.emplace_back(makeShared<CHyprpaperCoreManagerObject>(std::move(obj)));
manager->setDestroy([this, weak = WP<CHyprpaperCoreManagerObject>{manager}] { std::erase(m_managers, weak); });
@ -127,6 +128,18 @@ CSocket::CSocket() {
m_wallpaperObjects.emplace_back(makeShared<CWallpaperObject>(
makeShared<CHyprpaperWallpaperObject>(m_socket->createObject(weak->getObject()->client(), weak->getObject(), "hyprpaper_wallpaper", id))));
});
manager->setGetStatusObject([this, weak = WP<CHyprpaperCoreManagerObject>{manager}](uint32_t id) {
if (!weak)
return;
auto x =
m_statusObjects.emplace_back(makeShared<CHyprpaperStatusObject>(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());
}
}

View file

@ -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<Hyprwire::IServerSocket> m_socket;
@ -38,6 +39,7 @@ namespace IPC {
std::vector<SP<CHyprpaperCoreManagerObject>> m_managers;
std::vector<SP<CWallpaperObject>> m_wallpaperObjects;
std::vector<SP<CHyprpaperStatusObject>> m_statusObjects;
friend class CWallpaperObject;
};

View file

@ -73,6 +73,8 @@ CWallpaperTarget::CWallpaperTarget(SP<Hyprtoolkit::IBackend> backend, SP<Hyprtoo
->fitMode(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<Hyprtoolkit::CTimer> self, void*) { onRepeatTimer(); }, nullptr);
IPC::g_IPCSocket->onWallpaperChanged(m_monitorName, m_lastPath);
}
void CUI::registerOutput(const SP<Hyprtoolkit::IOutput>& mon) {
@ -224,3 +230,7 @@ void CUI::targetChanged(const SP<Hyprtoolkit::IOutput>& mon) {
m_targets.emplace_back(makeShared<CWallpaperTarget>(m_backend, mon, TARGET->get().paths, toFitMode(TARGET->get().fitMode), TARGET->get().timeout));
}
const std::vector<SP<CWallpaperTarget>>& CUI::targets() {
return m_targets;
}

View file

@ -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<Hyprtoolkit::IBackend> backend();
bool run();
SP<Hyprtoolkit::IBackend> backend();
const std::vector<SP<CWallpaperTarget>>& targets();
private:
void targetChanged(const SP<Hyprtoolkit::IOutput>& mon);