summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hyprctl/hw-protocols/hyprpaper_core.xml32
-rw-r--r--hyprctl/src/hyprpaper/Hyprpaper.cpp92
2 files changed, 104 insertions, 20 deletions
diff --git a/hyprctl/hw-protocols/hyprpaper_core.xml b/hyprctl/hw-protocols/hyprpaper_core.xml
index fa2edc0a..3d26a102 100644
--- a/hyprctl/hw-protocols/hyprpaper_core.xml
+++ b/hyprctl/hw-protocols/hyprpaper_core.xml
@@ -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>
diff --git a/hyprctl/src/hyprpaper/Hyprpaper.cpp b/hyprctl/src/hyprpaper/Hyprpaper.cpp
index 7c74d7ce..93f4182a 100644
--- a/hyprctl/src/hyprpaper/Hyprpaper.cpp
+++ b/hyprctl/src/hyprpaper/Hyprpaper.cpp
@@ -4,6 +4,7 @@
#include <optional>
#include <format>
#include <filesystem>
+#include <print>
#include <hyprpaper_core-client.hpp>
@@ -15,7 +16,7 @@ using namespace std::string_literals;
constexpr const char* SOCKET_NAME = ".hyprpaper.sock";
static SP<CCHyprpaperCoreImpl> g_coreImpl;
-constexpr const uint32_t PROTOCOL_VERSION_SUPPORTED = 1;
+constexpr const uint32_t PROTOCOL_VERSION_SUPPORTED = 2;
//
static hyprpaperCoreWallpaperFitMode fitFromString(const std::string_view& sv) {
@@ -53,21 +54,7 @@ static std::expected<std::string, std::string> getFullPath(const std::string_vie
return resolvePath(sv);
}
-std::expected<void, std::string> Hyprpaper::makeHyprpaperRequest(const std::string_view& rq) {
- if (!rq.contains(' '))
- return std::unexpected("Invalid request");
-
- if (!rq.starts_with("/hyprpaper "))
- return std::unexpected("Invalid request");
-
- std::string_view LHS, RHS;
- auto spacePos = rq.find(' ', 12);
- LHS = rq.substr(11, spacePos - 11);
- RHS = rq.substr(spacePos + 1);
-
- if (LHS != "wallpaper")
- return std::unexpected("Unknown hyprpaper request");
-
+static std::expected<void, std::string> doWallpaper(const std::string_view& RHS) {
CVarList2 args(std::string{RHS}, 0, ',');
const std::string MONITOR = std::string{args[0]};
@@ -99,7 +86,7 @@ std::expected<void, std::string> Hyprpaper::makeHyprpaperRequest(const std::stri
if (!socket)
return std::unexpected("can't send: failed to connect to hyprpaper (is it running?)");
- g_coreImpl = makeShared<CCHyprpaperCoreImpl>(1);
+ g_coreImpl = makeShared<CCHyprpaperCoreImpl>(PROTOCOL_VERSION_SUPPORTED);
socket->addImplementation(g_coreImpl);
@@ -111,7 +98,7 @@ std::expected<void, std::string> Hyprpaper::makeHyprpaperRequest(const std::stri
if (!spec)
return std::unexpected("can't send: hyprpaper doesn't have the spec?!");
- auto manager = makeShared<CCHyprpaperCoreManagerObject>(socket->bindProtocol(g_coreImpl->protocol(), PROTOCOL_VERSION_SUPPORTED));
+ auto manager = makeShared<CCHyprpaperCoreManagerObject>(socket->bindProtocol(g_coreImpl->protocol(), std::min(PROTOCOL_VERSION_SUPPORTED, spec->specVer())));
if (!manager)
return std::unexpected("wire error: couldn't create manager");
@@ -150,3 +137,72 @@ std::expected<void, std::string> Hyprpaper::makeHyprpaperRequest(const std::stri
return {};
}
+
+static std::expected<void, std::string> doListActive() {
+ const auto RTDIR = getenv("XDG_RUNTIME_DIR");
+
+ if (!RTDIR || RTDIR[0] == '\0')
+ return std::unexpected("can't send: no XDG_RUNTIME_DIR");
+
+ const auto HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE");
+
+ if (!HIS || HIS[0] == '\0')
+ return std::unexpected("can't send: no HYPRLAND_INSTANCE_SIGNATURE (not running under hyprland)");
+
+ auto socketPath = RTDIR + "/hypr/"s + HIS + "/"s + SOCKET_NAME;
+
+ auto socket = Hyprwire::IClientSocket::open(socketPath);
+
+ if (!socket)
+ return std::unexpected("can't send: failed to connect to hyprpaper (is it running?)");
+
+ g_coreImpl = makeShared<CCHyprpaperCoreImpl>(PROTOCOL_VERSION_SUPPORTED);
+
+ socket->addImplementation(g_coreImpl);
+
+ if (!socket->waitForHandshake())
+ return std::unexpected("can't send: wire handshake failed");
+
+ auto spec = socket->getSpec(g_coreImpl->protocol()->specName());
+
+ if (!spec)
+ return std::unexpected("can't send: hyprpaper doesn't have the spec?!");
+
+ if (spec->specVer() < 2)
+ return std::unexpected("can't send: hyprpaper protocol version too low (hyprpaper too old)");
+
+ auto manager = makeShared<CCHyprpaperCoreManagerObject>(socket->bindProtocol(g_coreImpl->protocol(), std::min(PROTOCOL_VERSION_SUPPORTED, spec->specVer())));
+
+ if (!manager)
+ return std::unexpected("wire error: couldn't create manager");
+
+ auto status = makeShared<CCHyprpaperStatusObject>(manager->sendGetStatusObject());
+
+ status->setActiveWallpaper([](const char* mon, const char* wp) { std::println("{}: {}", mon, wp); });
+
+ socket->roundtrip();
+
+ return {};
+}
+
+std::expected<void, std::string> Hyprpaper::makeHyprpaperRequest(const std::string_view& rq) {
+ if (!rq.contains(' '))
+ return std::unexpected("Invalid request");
+
+ if (!rq.starts_with("/hyprpaper "))
+ return std::unexpected("Invalid request");
+
+ std::string_view LHS, RHS;
+ auto spacePos = rq.find(' ', 12);
+ LHS = rq.substr(11, spacePos - 11);
+ RHS = rq.substr(spacePos + 1);
+
+ if (LHS == "wallpaper")
+ return doWallpaper(RHS);
+ else if (LHS == "listactive")
+ return doListActive();
+ else
+ return std::unexpected("invalid hyprpaper request");
+
+ return {};
+}