diff --git a/CMakeLists.txt b/CMakeLists.txt index 66773db..2812d2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ pkg_check_modules( hyprwayland-scanner>=0.4.2) # check whether we can find sdbus-c++ through pkg-config -pkg_check_modules(SDBUS IMPORTED_TARGET sdbus-c++) +pkg_check_modules(SDBUS IMPORTED_TARGET sdbus-c++>=2.0.0) if(NOT SDBUS_FOUND) include_directories("subprojects/sdbus-cpp/include/") add_subdirectory(subprojects/sdbus-cpp EXCLUDE_FROM_ALL) diff --git a/nix/overlays.nix b/nix/overlays.nix index 016cf73..447c77e 100644 --- a/nix/overlays.nix +++ b/nix/overlays.nix @@ -22,6 +22,7 @@ in { inputs.hyprland-protocols.overlays.default inputs.hyprutils.overlays.default inputs.hyprwayland-scanner.overlays.default + self.overlays.sdbuscpp ]); xdg-desktop-portal-hyprland = lib.composeManyExtensions [ (final: prev: { @@ -32,4 +33,17 @@ in { }; }) ]; + + sdbuscpp = final: prev: { + sdbus-cpp = prev.sdbus-cpp.overrideAttrs (self: super: { + version = "2.0.0"; + + src = final.fetchFromGitHub { + owner = "Kistler-group"; + repo = "sdbus-cpp"; + rev = "refs/tags/v${self.version}"; + hash = "sha256-W8V5FRhV3jtERMFrZ4gf30OpIQLYoj2yYGpnYOmH2+g="; + }; + }); + }; } diff --git a/src/core/PortalManager.cpp b/src/core/PortalManager.cpp index dd4992e..d091551 100644 --- a/src/core/PortalManager.cpp +++ b/src/core/PortalManager.cpp @@ -201,7 +201,7 @@ void CPortalManager::init() { m_iPID = getpid(); try { - m_pConnection = sdbus::createSessionBusConnection("org.freedesktop.impl.portal.desktop.hyprland"); + m_pConnection = sdbus::createSessionBusConnection(sdbus::ServiceName{"org.freedesktop.impl.portal.desktop.hyprland"}); } catch (std::exception& e) { Debug::log(CRIT, "Couldn't create the dbus connection ({})", e.what()); exit(1); @@ -367,7 +367,7 @@ void CPortalManager::startEventLoop() { m_mEventLock.lock(); if (pollfds[0].revents & POLLIN /* dbus */) { - while (m_pConnection->processPendingRequest()) { + while (m_pConnection->processPendingEvent()) { ; } } diff --git a/src/core/PortalManager.hpp b/src/core/PortalManager.hpp index 4474df0..915a14b 100644 --- a/src/core/PortalManager.hpp +++ b/src/core/PortalManager.hpp @@ -20,6 +20,7 @@ #include "wlr-screencopy-unstable-v1.hpp" #include "../includes.hpp" +#include "../dbusDefines.hpp" #include diff --git a/src/dbusDefines.hpp b/src/dbusDefines.hpp new file mode 100644 index 0000000..7667c28 --- /dev/null +++ b/src/dbusDefines.hpp @@ -0,0 +1,5 @@ +#pragma once + +#include + +typedef std::tuple> dbUasv; \ No newline at end of file diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index d3f4f42..336e450 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -58,9 +58,3 @@ bool inShellPath(const std::string& exec) { return std::ranges::any_of(paths, [&exec](std::string& path) { return access((path + "/" + exec).c_str(), X_OK) == 0; }); } - -void sendEmptyDbusMethodReply(sdbus::MethodCall& call, u_int32_t responseCode) { - auto reply = call.createReply(); - reply << (uint32_t)responseCode; - reply.send(); -} diff --git a/src/portals/GlobalShortcuts.cpp b/src/portals/GlobalShortcuts.cpp index f7cdf6c..a0b526e 100644 --- a/src/portals/GlobalShortcuts.cpp +++ b/src/portals/GlobalShortcuts.cpp @@ -65,15 +65,8 @@ SKeybind* CGlobalShortcutsPortal::registerShortcut(SSession* session, const DBus return PSHORTCUT; } -void CGlobalShortcutsPortal::onCreateSession(sdbus::MethodCall& call) { - sdbus::ObjectPath requestHandle, sessionHandle; - - call >> requestHandle; - call >> sessionHandle; - - std::string appID; - call >> appID; - +dbUasv CGlobalShortcutsPortal::onCreateSession(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, + std::unordered_map opts) { Debug::log(LOG, "[globalshortcuts] New session:"); Debug::log(LOG, "[globalshortcuts] | {}", requestHandle.c_str()); Debug::log(LOG, "[globalshortcuts] | {}", sessionHandle.c_str()); @@ -87,9 +80,6 @@ void CGlobalShortcutsPortal::onCreateSession(sdbus::MethodCall& call) { PSESSION->request = createDBusRequest(requestHandle); PSESSION->request->onDestroy = [PSESSION]() { PSESSION->request.release(); }; - std::unordered_map opts; - call >> opts; - for (auto& [k, v] : opts) { if (k == "shortcuts") { PSESSION->registered = true; @@ -104,59 +94,43 @@ void CGlobalShortcutsPortal::onCreateSession(sdbus::MethodCall& call) { } } - auto reply = call.createReply(); - reply << (uint32_t)0; - reply << std::unordered_map{}; - reply.send(); + return {0, {}}; } -void CGlobalShortcutsPortal::onBindShortcuts(sdbus::MethodCall& call) { - sdbus::ObjectPath sessionHandle, requestHandle; - call >> requestHandle; - call >> sessionHandle; - +dbUasv CGlobalShortcutsPortal::onBindShortcuts(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::vector shortcuts, std::string appID, + std::unordered_map opts) { Debug::log(LOG, "[globalshortcuts] Bind keys:"); Debug::log(LOG, "[globalshortcuts] | {}", sessionHandle.c_str()); - std::vector shortcuts; - std::vector shortcutsToReturn; - call >> shortcuts; - const auto PSESSION = getSession(sessionHandle); if (!PSESSION) { Debug::log(ERR, "[globalshortcuts] No session?"); - return; + return {1, {}}; } + std::vector shortcutsToReturn; + PSESSION->registered = true; for (auto& s : shortcuts) { const auto* PSHORTCUT = registerShortcut(PSESSION, s); std::unordered_map shortcutData; - shortcutData["description"] = PSHORTCUT->description; - shortcutData["trigger_description"] = ""; + shortcutData["description"] = sdbus::Variant{PSHORTCUT->description}; + shortcutData["trigger_description"] = sdbus::Variant{""}; shortcutsToReturn.push_back({PSHORTCUT->id, shortcutData}); } Debug::log(LOG, "[globalshortcuts] registered {} shortcuts", shortcuts.size()); - auto reply = call.createReply(); - std::unordered_map data; - data["shortcuts"] = shortcutsToReturn; + data["shortcuts"] = sdbus::Variant{shortcutsToReturn}; - reply << (uint32_t)0; - reply << data; - reply.send(); + return {0, data}; } -void CGlobalShortcutsPortal::onListShortcuts(sdbus::MethodCall& call) { - sdbus::ObjectPath sessionHandle, requestHandle; - call >> requestHandle; - call >> sessionHandle; - +dbUasv CGlobalShortcutsPortal::onListShortcuts(sdbus::ObjectPath sessionHandle, sdbus::ObjectPath requestHandle) { Debug::log(LOG, "[globalshortcuts] List keys:"); Debug::log(LOG, "[globalshortcuts] | {}", sessionHandle.c_str()); @@ -164,26 +138,22 @@ void CGlobalShortcutsPortal::onListShortcuts(sdbus::MethodCall& call) { if (!PSESSION) { Debug::log(ERR, "[globalshortcuts] No session?"); - return; + return {1, {}}; } std::vector shortcuts; for (auto& s : PSESSION->keybinds) { std::unordered_map opts; - opts["description"] = s->description; - opts["trigger_description"] = ""; + opts["description"] = sdbus::Variant{s->description}; + opts["trigger_description"] = sdbus::Variant{""}; shortcuts.push_back({s->id, opts}); } - auto reply = call.createReply(); - std::unordered_map data; - data["shortcuts"] = shortcuts; + data["shortcuts"] = sdbus::Variant{shortcuts}; - reply << (uint32_t)0; - reply << data; - reply.send(); + return {0, data}; } CGlobalShortcutsPortal::CGlobalShortcutsPortal(SP mgr) { @@ -191,14 +161,19 @@ CGlobalShortcutsPortal::CGlobalShortcutsPortal(SPgetConnection(), OBJECT_PATH); - m_pObject->registerMethod(INTERFACE_NAME, "CreateSession", "oosa{sv}", "ua{sv}", [&](sdbus::MethodCall c) { onCreateSession(c); }); - m_pObject->registerMethod(INTERFACE_NAME, "BindShortcuts", "ooa(sa{sv})sa{sv}", "ua{sv}", [&](sdbus::MethodCall c) { onBindShortcuts(c); }); - m_pObject->registerMethod(INTERFACE_NAME, "ListShortcuts", "oo", "ua{sv}", [&](sdbus::MethodCall c) { onListShortcuts(c); }); - m_pObject->registerSignal(INTERFACE_NAME, "Activated", "osta{sv}"); - m_pObject->registerSignal(INTERFACE_NAME, "Deactivated", "osta{sv}"); - m_pObject->registerSignal(INTERFACE_NAME, "ShortcutsChanged", "oa(sa{sv})"); - - m_pObject->finishRegistration(); + m_pObject + ->addVTable(sdbus::registerMethod("CreateSession") + .implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::string s, std::unordered_map m) { + return onCreateSession(o1, o2, s, m); + }), + sdbus::registerMethod("BindShortcuts") + .implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::vector v1, std::string s1, + std::unordered_map m2) { return onBindShortcuts(o1, o2, v1, s1, m2); }), + sdbus::registerMethod("ListShortcuts").implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2) { return onListShortcuts(o1, o2); }), + sdbus::registerSignal("Activated").withParameters>(), + sdbus::registerSignal("Deactivated").withParameters>(), + sdbus::registerSignal("ShortcutsChanged").withParameters>>()) + .forInterface(INTERFACE_NAME); Debug::log(LOG, "[globalshortcuts] registered"); } @@ -208,13 +183,7 @@ void CGlobalShortcutsPortal::onActivated(SKeybind* pKeybind, uint64_t time) { Debug::log(TRACE, "[gs] Session {} called activated on {}", PSESSION->sessionHandle.c_str(), pKeybind->id); - auto signal = m_pObject->createSignal(INTERFACE_NAME, "Activated"); - signal << PSESSION->sessionHandle; - signal << pKeybind->id; - signal << time; - signal << std::unordered_map{}; - - m_pObject->emitSignal(signal); + m_pObject->emitSignal("Activated").onInterface(INTERFACE_NAME).withArguments(PSESSION->sessionHandle, pKeybind->id, time, std::unordered_map{}); } void CGlobalShortcutsPortal::onDeactivated(SKeybind* pKeybind, uint64_t time) { @@ -222,11 +191,5 @@ void CGlobalShortcutsPortal::onDeactivated(SKeybind* pKeybind, uint64_t time) { Debug::log(TRACE, "[gs] Session {} called deactivated on {}", PSESSION->sessionHandle.c_str(), pKeybind->id); - auto signal = m_pObject->createSignal(INTERFACE_NAME, "Deactivated"); - signal << PSESSION->sessionHandle; - signal << pKeybind->id; - signal << time; - signal << std::unordered_map{}; - - m_pObject->emitSignal(signal); + m_pObject->emitSignal("Deactivated").onInterface(INTERFACE_NAME).withArguments(PSESSION->sessionHandle, pKeybind->id, time, std::unordered_map{}); } \ No newline at end of file diff --git a/src/portals/GlobalShortcuts.hpp b/src/portals/GlobalShortcuts.hpp index d57419d..cd2bb6b 100644 --- a/src/portals/GlobalShortcuts.hpp +++ b/src/portals/GlobalShortcuts.hpp @@ -3,6 +3,7 @@ #include #include "hyprland-global-shortcuts-v1.hpp" #include "../shared/Session.hpp" +#include "../dbusDefines.hpp" struct SKeybind { SKeybind(SP shortcut); @@ -15,12 +16,15 @@ class CGlobalShortcutsPortal { public: CGlobalShortcutsPortal(SP mgr); - void onCreateSession(sdbus::MethodCall& call); - void onBindShortcuts(sdbus::MethodCall& call); - void onListShortcuts(sdbus::MethodCall& call); + using DBusShortcut = sdbus::Struct>; - void onActivated(SKeybind* pKeybind, uint64_t time); - void onDeactivated(SKeybind* pKeybind, uint64_t time); + dbUasv onCreateSession(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::unordered_map opts); + dbUasv onBindShortcuts(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::vector shortcuts, std::string appID, + std::unordered_map opts); + dbUasv onListShortcuts(sdbus::ObjectPath sessionHandle, sdbus::ObjectPath requestHandle); + + void onActivated(SKeybind* pKeybind, uint64_t time); + void onDeactivated(SKeybind* pKeybind, uint64_t time); struct SSession { std::string appid; @@ -42,12 +46,10 @@ class CGlobalShortcutsPortal { std::unique_ptr m_pObject; - using DBusShortcut = sdbus::Struct>; + SSession* getSession(sdbus::ObjectPath& path); + SKeybind* getShortcutById(const std::string& appID, const std::string& shortcutId); + SKeybind* registerShortcut(SSession* session, const DBusShortcut& shortcut); - SSession* getSession(sdbus::ObjectPath& path); - SKeybind* getShortcutById(const std::string& appID, const std::string& shortcutId); - SKeybind* registerShortcut(SSession* session, const DBusShortcut& shortcut); - - const std::string INTERFACE_NAME = "org.freedesktop.impl.portal.GlobalShortcuts"; - const std::string OBJECT_PATH = "/org/freedesktop/portal/desktop"; + const sdbus::InterfaceName INTERFACE_NAME = sdbus::InterfaceName{"org.freedesktop.impl.portal.GlobalShortcuts"}; + const sdbus::ObjectPath OBJECT_PATH = sdbus::ObjectPath{"/org/freedesktop/portal/desktop"}; }; \ No newline at end of file diff --git a/src/portals/Screencopy.cpp b/src/portals/Screencopy.cpp index 2cf9a95..b418f23 100644 --- a/src/portals/Screencopy.cpp +++ b/src/portals/Screencopy.cpp @@ -16,33 +16,24 @@ static sdbus::Struct getFullRestoreStruct switch (data.type) { case TYPE_GEOMETRY: - case TYPE_OUTPUT: mapData["output"] = data.output; break; + case TYPE_OUTPUT: mapData["output"] = sdbus::Variant{data.output}; break; case TYPE_WINDOW: - mapData["windowHandle"] = (uint64_t)data.windowHandle->resource(); - mapData["windowClass"] = data.windowClass; + mapData["windowHandle"] = sdbus::Variant{(uint64_t)data.windowHandle->resource()}; + mapData["windowClass"] = sdbus::Variant{data.windowClass}; break; default: Debug::log(ERR, "[screencopy] wonk selection in token saving"); break; } - mapData["timeIssued"] = uint64_t(time(nullptr)); - mapData["token"] = std::string("todo"); - mapData["withCursor"] = cursor; + mapData["timeIssued"] = sdbus::Variant{uint64_t(time(nullptr))}; + mapData["token"] = sdbus::Variant{std::string("todo")}; + mapData["withCursor"] = sdbus::Variant{cursor}; sdbus::Variant restoreData{mapData}; return sdbus::Struct{"hyprland", 3, restoreData}; } -void CScreencopyPortal::onCreateSession(sdbus::MethodCall& call) { - sdbus::ObjectPath requestHandle, sessionHandle; - - g_pPortalManager->m_sHelpers.toplevel->activate(); - - call >> requestHandle; - call >> sessionHandle; - - std::string appID; - call >> appID; - +dbUasv CScreencopyPortal::onCreateSession(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, + std::unordered_map opts) { Debug::log(LOG, "[screencopy] New session:"); Debug::log(LOG, "[screencopy] | {}", requestHandle.c_str()); Debug::log(LOG, "[screencopy] | {}", sessionHandle.c_str()); @@ -66,21 +57,11 @@ void CScreencopyPortal::onCreateSession(sdbus::MethodCall& call) { PSESSION->request = createDBusRequest(requestHandle); PSESSION->request->onDestroy = [PSESSION]() { PSESSION->request.release(); }; - auto reply = call.createReply(); - reply << (uint32_t)0; - reply << std::unordered_map{}; - reply.send(); + return {0, {}}; } -void CScreencopyPortal::onSelectSources(sdbus::MethodCall& call) { - sdbus::ObjectPath requestHandle, sessionHandle; - - call >> requestHandle; - call >> sessionHandle; - - std::string appID; - call >> appID; - +dbUasv CScreencopyPortal::onSelectSources(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, + std::unordered_map options) { Debug::log(LOG, "[screencopy] SelectSources:"); Debug::log(LOG, "[screencopy] | {}", requestHandle.c_str()); Debug::log(LOG, "[screencopy] | {}", sessionHandle.c_str()); @@ -90,16 +71,10 @@ void CScreencopyPortal::onSelectSources(sdbus::MethodCall& call) { if (!PSESSION) { Debug::log(ERR, "[screencopy] SelectSources: no session found??"); - auto reply = call.createErrorReply(sdbus::Error{"NOSESSION", "No session found"}); - reply << (uint32_t)1; - reply.send(); - return; + throw sdbus::Error{sdbus::Error::Name{"NOSESSION"}, "No session found"}; + return {1, {}}; } - std::unordered_map options; - - call >> options; - struct { bool exists = false; std::string token, output; @@ -233,22 +208,11 @@ void CScreencopyPortal::onSelectSources(sdbus::MethodCall& call) { PSESSION->selection = SHAREDATA; - auto reply = call.createReply(); - reply << (uint32_t)(SHAREDATA.type == TYPE_INVALID ? 1 : 0); - reply << std::unordered_map{}; - reply.send(); + return {SHAREDATA.type == TYPE_INVALID ? 1 : 0, {}}; } -void CScreencopyPortal::onStart(sdbus::MethodCall& call) { - sdbus::ObjectPath requestHandle, sessionHandle; - - call >> requestHandle; - call >> sessionHandle; - - std::string appID, parentWindow; - call >> appID; - call >> parentWindow; - +dbUasv CScreencopyPortal::onStart(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::string parentWindow, + std::unordered_map opts) { Debug::log(LOG, "[screencopy] Start:"); Debug::log(LOG, "[screencopy] | {}", requestHandle.c_str()); Debug::log(LOG, "[screencopy] | {}", sessionHandle.c_str()); @@ -259,17 +223,12 @@ void CScreencopyPortal::onStart(sdbus::MethodCall& call) { if (!PSESSION) { Debug::log(ERR, "[screencopy] Start: no session found??"); - auto reply = call.createErrorReply(sdbus::Error{"NOSESSION", "No session found"}); - reply << (uint32_t)1; - reply.send(); - return; + throw sdbus::Error{sdbus::Error::Name{"NOSESSION"}, "No session found"}; + return {1, {}}; } startSharing(PSESSION); - auto reply = call.createReply(); - reply << (uint32_t)0; - std::unordered_map options; if (PSESSION->selection.allowToken) { @@ -288,7 +247,7 @@ void CScreencopyPortal::onStart(sdbus::MethodCall& call) { case TYPE_WORKSPACE: type = 1 << VIRTUAL; break; default: type = 0; break; } - options["source_type"] = type; + options["source_type"] = sdbus::Variant{type}; std::vector>> streams; @@ -298,11 +257,9 @@ void CScreencopyPortal::onStart(sdbus::MethodCall& call) { streamData["source_type"] = sdbus::Variant{uint32_t{type}}; streams.emplace_back(sdbus::Struct>{PSESSION->sharingData.nodeID, streamData}); - options["streams"] = streams; + options["streams"] = sdbus::Variant{streams}; - reply << options; - - reply.send(); + return {0, options}; } void CScreencopyPortal::startSharing(CScreencopyPortal::SSession* pSession) { @@ -628,14 +585,21 @@ CScreencopyPortal::SSession* CScreencopyPortal::getSession(sdbus::ObjectPath& pa CScreencopyPortal::CScreencopyPortal(SP mgr) { m_pObject = sdbus::createObject(*g_pPortalManager->getConnection(), OBJECT_PATH); - m_pObject->registerMethod(INTERFACE_NAME, "CreateSession", "oosa{sv}", "ua{sv}", [&](sdbus::MethodCall c) { onCreateSession(c); }); - m_pObject->registerMethod(INTERFACE_NAME, "SelectSources", "oosa{sv}", "ua{sv}", [&](sdbus::MethodCall c) { onSelectSources(c); }); - m_pObject->registerMethod(INTERFACE_NAME, "Start", "oossa{sv}", "ua{sv}", [&](sdbus::MethodCall c) { onStart(c); }); - m_pObject->registerProperty(INTERFACE_NAME, "AvailableSourceTypes", "u", [](sdbus::PropertyGetReply& reply) -> void { reply << (uint32_t)(VIRTUAL | MONITOR | WINDOW); }); - m_pObject->registerProperty(INTERFACE_NAME, "AvailableCursorModes", "u", [](sdbus::PropertyGetReply& reply) -> void { reply << (uint32_t)(HIDDEN | EMBEDDED); }); - m_pObject->registerProperty(INTERFACE_NAME, "version", "u", [](sdbus::PropertyGetReply& reply) -> void { reply << (uint32_t)(3); }); - - m_pObject->finishRegistration(); + m_pObject + ->addVTable(sdbus::registerMethod("CreateSession") + .implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::string s1, std::unordered_map m1) { + return onCreateSession(o1, o2, s1, m1); + }), + sdbus::registerMethod("SelectSources") + .implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::string s1, std::unordered_map m1) { + return onSelectSources(o1, o2, s1, m1); + }), + sdbus::registerMethod("Start").implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::string s1, std::string s2, + std::unordered_map m1) { return onStart(o1, o2, s1, s2, m1); }), + sdbus::registerProperty("AvailableSourceTypes").withGetter([]() { return uint32_t{VIRTUAL | MONITOR | WINDOW}; }), + sdbus::registerProperty("AvailableCursorModes").withGetter([]() { return uint32_t{HIDDEN | EMBEDDED}; }), + sdbus::registerProperty("version").withGetter([]() { return uint32_t{3}; })) + .forInterface(INTERFACE_NAME); m_sState.screencopy = mgr; m_pPipewire = std::make_unique(); diff --git a/src/portals/Screencopy.hpp b/src/portals/Screencopy.hpp index b9e0507..4b1019f 100644 --- a/src/portals/Screencopy.hpp +++ b/src/portals/Screencopy.hpp @@ -6,6 +6,7 @@ #include "../shared/ScreencopyShared.hpp" #include #include "../shared/Session.hpp" +#include "../dbusDefines.hpp" #include enum cursorModes { @@ -53,11 +54,12 @@ class CScreencopyPortal { public: CScreencopyPortal(SP); - void appendToplevelExport(SP); + void appendToplevelExport(SP); - void onCreateSession(sdbus::MethodCall& call); - void onSelectSources(sdbus::MethodCall& call); - void onStart(sdbus::MethodCall& call); + dbUasv onCreateSession(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::unordered_map opts); + dbUasv onSelectSources(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::unordered_map opts); + dbUasv onStart(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::string parentWindow, + std::unordered_map opts); struct SSession { std::string appid; @@ -123,8 +125,8 @@ class CScreencopyPortal { SP toplevel = nullptr; } m_sState; - const std::string INTERFACE_NAME = "org.freedesktop.impl.portal.ScreenCast"; - const std::string OBJECT_PATH = "/org/freedesktop/portal/desktop"; + const sdbus::InterfaceName INTERFACE_NAME = sdbus::InterfaceName{"org.freedesktop.impl.portal.ScreenCast"}; + const sdbus::ObjectPath OBJECT_PATH = sdbus::ObjectPath{"/org/freedesktop/portal/desktop"}; friend struct SSession; }; diff --git a/src/portals/Screenshot.cpp b/src/portals/Screenshot.cpp index 322b707..0cb8dff 100644 --- a/src/portals/Screenshot.cpp +++ b/src/portals/Screenshot.cpp @@ -8,14 +8,14 @@ std::string lastScreenshot; -void pickHyprPicker(sdbus::MethodCall& call) { +// +static dbUasv pickHyprPicker(sdbus::ObjectPath requestHandle, std::string appID, std::string parentWindow, std::unordered_map options) { const std::string HYPRPICKER_CMD = "hyprpicker --format=rgb --no-fancy"; std::string rgbColor = execAndGet(HYPRPICKER_CMD.c_str()); if (rgbColor.size() > 12) { Debug::log(ERR, "hyprpicker returned strange output: " + rgbColor); - sendEmptyDbusMethodReply(call, 1); - return; + return {1, {}}; } std::array colors{0, 0, 0}; @@ -26,8 +26,7 @@ void pickHyprPicker(sdbus::MethodCall& call) { if (next == std::string::npos) { Debug::log(ERR, "hyprpicker returned strange output: " + rgbColor); - sendEmptyDbusMethodReply(call, 1); - return; + return {1, {}}; } colors[i] = std::stoi(rgbColor.substr(0, next)); @@ -36,21 +35,17 @@ void pickHyprPicker(sdbus::MethodCall& call) { colors[2] = std::stoi(rgbColor); } catch (...) { Debug::log(ERR, "Reading RGB values from hyprpicker failed. This is likely a string to integer error."); - sendEmptyDbusMethodReply(call, 1); + return {1, {}}; } auto [r, g, b] = colors; std::unordered_map results; - results["color"] = sdbus::Struct(r / 255.0, g / 255.0, b / 255.0); + results["color"] = sdbus::Variant{sdbus::Struct(r / 255.0, g / 255.0, b / 255.0)}; - auto reply = call.createReply(); - - reply << (uint32_t)0; - reply << results; - reply.send(); + return {0, results}; } -void pickSlurp(sdbus::MethodCall& call) { +static dbUasv pickSlurp(sdbus::ObjectPath requestHandle, std::string appID, std::string parentWindow, std::unordered_map options) { const std::string PICK_COLOR_CMD = "grim -g \"$(slurp -p)\" -t ppm -"; std::string ppmColor = execAndGet(PICK_COLOR_CMD.c_str()); @@ -60,8 +55,7 @@ void pickSlurp(sdbus::MethodCall& call) { // check if we got a 1x1 PPM Image if (!ppmColor.starts_with("P6 1 1 ")) { Debug::log(ERR, "grim did not return a PPM Image for us."); - sendEmptyDbusMethodReply(call, 1); - return; + return {1, {}}; } // convert it to a rgb value @@ -88,45 +82,33 @@ void pickSlurp(sdbus::MethodCall& call) { b = ((byteString[4] << 8) | byteString[5]) / (maxVal * 1.0); } - auto reply = call.createReply(); - std::unordered_map results; - results["color"] = sdbus::Struct(r, g, b); + results["color"] = sdbus::Variant{sdbus::Struct(r, g, b)}; - reply << (uint32_t)0; - reply << results; - reply.send(); - } catch (...) { - Debug::log(ERR, "Converting PPM to RGB failed. This is likely a string to integer error."); - sendEmptyDbusMethodReply(call, 1); - } + return {0, results}; + } catch (...) { Debug::log(ERR, "Converting PPM to RGB failed. This is likely a string to integer error."); } + + return {1, {}}; } CScreenshotPortal::CScreenshotPortal() { m_pObject = sdbus::createObject(*g_pPortalManager->getConnection(), OBJECT_PATH); - m_pObject->registerMethod(INTERFACE_NAME, "Screenshot", "ossa{sv}", "ua{sv}", [&](sdbus::MethodCall c) { onScreenshot(c); }); - m_pObject->registerMethod(INTERFACE_NAME, "PickColor", "ossa{sv}", "ua{sv}", [&](sdbus::MethodCall c) { onPickColor(c); }); - - m_pObject->registerProperty(INTERFACE_NAME, "version", "u", [](sdbus::PropertyGetReply& reply) -> void { reply << (uint32_t)(2); }); - - m_pObject->finishRegistration(); + m_pObject + ->addVTable( + sdbus::registerMethod("Screenshot").implementedAs([this](sdbus::ObjectPath o, std::string s1, std::string s2, std::unordered_map m) { + return onScreenshot(o, s1, s2, m); + }), + sdbus::registerMethod("PickColor").implementedAs([this](sdbus::ObjectPath o, std::string s1, std::string s2, std::unordered_map m) { + return onPickColor(o, s1, s2, m); + }), + sdbus::registerProperty("version").withGetter([]() { return uint32_t{2}; })) + .forInterface(INTERFACE_NAME); Debug::log(LOG, "[screenshot] init successful"); } -void CScreenshotPortal::onScreenshot(sdbus::MethodCall& call) { - sdbus::ObjectPath requestHandle; - call >> requestHandle; - - std::string appID; - call >> appID; - - std::string parentWindow; - call >> parentWindow; - - std::unordered_map options; - call >> options; +dbUasv CScreenshotPortal::onScreenshot(sdbus::ObjectPath requestHandle, std::string appID, std::string parentWindow, std::unordered_map options) { Debug::log(LOG, "[screenshot] New screenshot request:"); Debug::log(LOG, "[screenshot] | {}", requestHandle.c_str()); @@ -146,7 +128,7 @@ void CScreenshotPortal::onScreenshot(sdbus::MethodCall& call) { const std::string SNAP_INTERACTIVE_CMD = "grim -g \"$(slurp)\" '" + FILE_PATH + "'"; std::unordered_map results; - results["uri"] = "file://" + FILE_PATH; + results["uri"] = sdbus::Variant{"file://" + FILE_PATH}; std::filesystem::remove(FILE_PATH); std::filesystem::create_directory(HYPR_DIR); @@ -163,21 +145,10 @@ void CScreenshotPortal::onScreenshot(sdbus::MethodCall& call) { uint32_t responseCode = std::filesystem::exists(FILE_PATH) ? 0 : 1; - auto reply = call.createReply(); - reply << responseCode; - reply << results; - reply.send(); + return {responseCode, results}; } -void CScreenshotPortal::onPickColor(sdbus::MethodCall& call) { - sdbus::ObjectPath requestHandle; - call >> requestHandle; - - std::string appID; - call >> appID; - - std::string parentWindow; - call >> parentWindow; +dbUasv CScreenshotPortal::onPickColor(sdbus::ObjectPath requestHandle, std::string appID, std::string parentWindow, std::unordered_map options) { Debug::log(LOG, "[screenshot] New PickColor request:"); Debug::log(LOG, "[screenshot] | {}", requestHandle.c_str()); @@ -188,13 +159,12 @@ void CScreenshotPortal::onPickColor(sdbus::MethodCall& call) { if (!slurpInstalled && !hyprPickerInstalled) { Debug::log(ERR, "Neither slurp nor hyprpicker found. We can't pick colors."); - sendEmptyDbusMethodReply(call, 1); - return; + return {1, {}}; } // use hyprpicker if installed, slurp as fallback if (hyprPickerInstalled) - pickHyprPicker(call); + return pickHyprPicker(requestHandle, appID, parentWindow, options); else - pickSlurp(call); + return pickSlurp(requestHandle, appID, parentWindow, options); } diff --git a/src/portals/Screenshot.hpp b/src/portals/Screenshot.hpp index b0f51de..b2ebabc 100644 --- a/src/portals/Screenshot.hpp +++ b/src/portals/Screenshot.hpp @@ -1,17 +1,18 @@ #pragma once #include +#include "../dbusDefines.hpp" class CScreenshotPortal { public: CScreenshotPortal(); - void onScreenshot(sdbus::MethodCall& call); - void onPickColor(sdbus::MethodCall& call); + dbUasv onScreenshot(sdbus::ObjectPath requestHandle, std::string appID, std::string parentWindow, std::unordered_map options); + dbUasv onPickColor(sdbus::ObjectPath requestHandle, std::string appID, std::string parentWindow, std::unordered_map options); private: std::unique_ptr m_pObject; - const std::string INTERFACE_NAME = "org.freedesktop.impl.portal.Screenshot"; - const std::string OBJECT_PATH = "/org/freedesktop/portal/desktop"; + const sdbus::InterfaceName INTERFACE_NAME = sdbus::InterfaceName{"org.freedesktop.impl.portal.Screenshot"}; + const sdbus::ObjectPath OBJECT_PATH = sdbus::ObjectPath{"/org/freedesktop/portal/desktop"}; }; diff --git a/src/shared/Session.cpp b/src/shared/Session.cpp index 2305afb..ea902e3 100644 --- a/src/shared/Session.cpp +++ b/src/shared/Session.cpp @@ -2,30 +2,28 @@ #include "../core/PortalManager.hpp" #include "../helpers/Log.hpp" -static void onCloseRequest(sdbus::MethodCall& call, SDBusRequest* req) { +static int onCloseRequest(SDBusRequest* req) { Debug::log(TRACE, "[internal] Close Request {}", (void*)req); if (!req) - return; - - auto r = call.createReply(); - r.send(); + return 0; req->onDestroy(); req->object.release(); + + return 0; } -static void onCloseSession(sdbus::MethodCall& call, SDBusSession* sess) { +static int onCloseSession(SDBusSession* sess) { Debug::log(TRACE, "[internal] Close Session {}", (void*)sess); if (!sess) - return; - - auto r = call.createReply(); - r.send(); + return 0; sess->onDestroy(); sess->object.release(); + + return 0; } std::unique_ptr createDBusSession(sdbus::ObjectPath handle) { @@ -36,9 +34,7 @@ std::unique_ptr createDBusSession(sdbus::ObjectPath handle) { pSession->object = sdbus::createObject(*g_pPortalManager->getConnection(), handle); - pSession->object->registerMethod("org.freedesktop.impl.portal.Session", "Close", "", "", [PSESSION](sdbus::MethodCall c) { onCloseSession(c, PSESSION); }); - - pSession->object->finishRegistration(); + pSession->object->addVTable(sdbus::registerMethod("Close").implementedAs([PSESSION]() { onCloseSession(PSESSION); })).forInterface("org.freedesktop.impl.portal.Session"); return pSession; } @@ -51,9 +47,7 @@ std::unique_ptr createDBusRequest(sdbus::ObjectPath handle) { pRequest->object = sdbus::createObject(*g_pPortalManager->getConnection(), handle); - pRequest->object->registerMethod("org.freedesktop.impl.portal.Request", "Close", "", "", [PREQUEST](sdbus::MethodCall c) { onCloseRequest(c, PREQUEST); }); - - pRequest->object->finishRegistration(); + pRequest->object->addVTable(sdbus::registerMethod("Close").implementedAs([PREQUEST]() { onCloseRequest(PREQUEST); })).forInterface("org.freedesktop.impl.portal.Request"); return pRequest; } \ No newline at end of file diff --git a/subprojects/sdbus-cpp b/subprojects/sdbus-cpp index 0eda855..b7d85f9 160000 --- a/subprojects/sdbus-cpp +++ b/subprojects/sdbus-cpp @@ -1 +1 @@ -Subproject commit 0eda85574546d19d9f06d6d5418bc192b3846f96 +Subproject commit b7d85f936d622299ee57966c2b2aefde5e4f3684