core: move to sdbus-cpp2 (#278)

* core: move to sdbus-cpp2

* oopsie LMAO

* thing

* nix/overlays: add sdbus overlay

---------

Co-authored-by: Mihai Fufezan <mihai@fufexan.net>
This commit is contained in:
Vaxry 2024-10-22 18:45:24 +01:00 committed by GitHub
parent fb9c8d665a
commit 5c72a7fea1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 161 additions and 251 deletions

View file

@ -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)

View file

@ -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=";
};
});
};
}

View file

@ -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()) {
;
}
}

View file

@ -20,6 +20,7 @@
#include "wlr-screencopy-unstable-v1.hpp"
#include "../includes.hpp"
#include "../dbusDefines.hpp"
#include <mutex>

5
src/dbusDefines.hpp Normal file
View file

@ -0,0 +1,5 @@
#pragma once
#include <sdbus-c++/sdbus-c++.h>
typedef std::tuple<uint32_t, std::unordered_map<std::string, sdbus::Variant>> dbUasv;

View file

@ -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();
}

View file

@ -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<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> 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<std::string, sdbus::Variant>{};
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<DBusShortcut> shortcuts, std::string appID,
std::unordered_map<std::string, sdbus::Variant> opts) {
Debug::log(LOG, "[globalshortcuts] Bind keys:");
Debug::log(LOG, "[globalshortcuts] | {}", sessionHandle.c_str());
std::vector<DBusShortcut> shortcuts;
std::vector<DBusShortcut> shortcutsToReturn;
call >> shortcuts;
const auto PSESSION = getSession(sessionHandle);
if (!PSESSION) {
Debug::log(ERR, "[globalshortcuts] No session?");
return;
return {1, {}};
}
std::vector<DBusShortcut> shortcutsToReturn;
PSESSION->registered = true;
for (auto& s : shortcuts) {
const auto* PSHORTCUT = registerShortcut(PSESSION, s);
std::unordered_map<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> 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<DBusShortcut> shortcuts;
for (auto& s : PSESSION->keybinds) {
std::unordered_map<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> data;
data["shortcuts"] = shortcuts;
data["shortcuts"] = sdbus::Variant{shortcuts};
reply << (uint32_t)0;
reply << data;
reply.send();
return {0, data};
}
CGlobalShortcutsPortal::CGlobalShortcutsPortal(SP<CCHyprlandGlobalShortcutsManagerV1> mgr) {
@ -191,14 +161,19 @@ CGlobalShortcutsPortal::CGlobalShortcutsPortal(SP<CCHyprlandGlobalShortcutsManag
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, "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<std::string, sdbus::Variant> m) {
return onCreateSession(o1, o2, s, m);
}),
sdbus::registerMethod("BindShortcuts")
.implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::vector<DBusShortcut> v1, std::string s1,
std::unordered_map<std::string, sdbus::Variant> 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::ObjectPath, std::string, uint64_t, std::unordered_map<std::string, sdbus::Variant>>(),
sdbus::registerSignal("Deactivated").withParameters<sdbus::ObjectPath, std::string, uint64_t, std::unordered_map<std::string, sdbus::Variant>>(),
sdbus::registerSignal("ShortcutsChanged").withParameters<sdbus::ObjectPath, std::unordered_map<std::string, std::unordered_map<std::string, sdbus::Variant>>>())
.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<std::string, sdbus::Variant>{};
m_pObject->emitSignal(signal);
m_pObject->emitSignal("Activated").onInterface(INTERFACE_NAME).withArguments(PSESSION->sessionHandle, pKeybind->id, time, std::unordered_map<std::string, sdbus::Variant>{});
}
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<std::string, sdbus::Variant>{};
m_pObject->emitSignal(signal);
m_pObject->emitSignal("Deactivated").onInterface(INTERFACE_NAME).withArguments(PSESSION->sessionHandle, pKeybind->id, time, std::unordered_map<std::string, sdbus::Variant>{});
}

View file

@ -3,6 +3,7 @@
#include <sdbus-c++/sdbus-c++.h>
#include "hyprland-global-shortcuts-v1.hpp"
#include "../shared/Session.hpp"
#include "../dbusDefines.hpp"
struct SKeybind {
SKeybind(SP<CCHyprlandGlobalShortcutV1> shortcut);
@ -15,9 +16,12 @@ class CGlobalShortcutsPortal {
public:
CGlobalShortcutsPortal(SP<CCHyprlandGlobalShortcutsManagerV1> mgr);
void onCreateSession(sdbus::MethodCall& call);
void onBindShortcuts(sdbus::MethodCall& call);
void onListShortcuts(sdbus::MethodCall& call);
using DBusShortcut = sdbus::Struct<std::string, std::unordered_map<std::string, sdbus::Variant>>;
dbUasv onCreateSession(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::unordered_map<std::string, sdbus::Variant> opts);
dbUasv onBindShortcuts(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::vector<DBusShortcut> shortcuts, std::string appID,
std::unordered_map<std::string, sdbus::Variant> opts);
dbUasv onListShortcuts(sdbus::ObjectPath sessionHandle, sdbus::ObjectPath requestHandle);
void onActivated(SKeybind* pKeybind, uint64_t time);
void onDeactivated(SKeybind* pKeybind, uint64_t time);
@ -42,12 +46,10 @@ class CGlobalShortcutsPortal {
std::unique_ptr<sdbus::IObject> m_pObject;
using DBusShortcut = sdbus::Struct<std::string, std::unordered_map<std::string, sdbus::Variant>>;
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"};
};

View file

@ -16,33 +16,24 @@ static sdbus::Struct<std::string, uint32_t, sdbus::Variant> 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<std::string, uint32_t, sdbus::Variant>{"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<std::string, sdbus::Variant> 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<std::string, sdbus::Variant>{};
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<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> 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<std::string, sdbus::Variant>{};
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<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> 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<sdbus::Struct<uint32_t, std::unordered_map<std::string, sdbus::Variant>>> streams;
@ -298,11 +257,9 @@ void CScreencopyPortal::onStart(sdbus::MethodCall& call) {
streamData["source_type"] = sdbus::Variant{uint32_t{type}};
streams.emplace_back(sdbus::Struct<uint32_t, std::unordered_map<std::string, sdbus::Variant>>{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<CCZwlrScreencopyManagerV1> 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<std::string, sdbus::Variant> m1) {
return onCreateSession(o1, o2, s1, m1);
}),
sdbus::registerMethod("SelectSources")
.implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::string s1, std::unordered_map<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> 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<CPipewireConnection>();

View file

@ -6,6 +6,7 @@
#include "../shared/ScreencopyShared.hpp"
#include <gbm.h>
#include "../shared/Session.hpp"
#include "../dbusDefines.hpp"
#include <chrono>
enum cursorModes {
@ -55,9 +56,10 @@ class CScreencopyPortal {
void appendToplevelExport(SP<CCHyprlandToplevelExportManagerV1>);
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<std::string, sdbus::Variant> opts);
dbUasv onSelectSources(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::unordered_map<std::string, sdbus::Variant> opts);
dbUasv onStart(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::string parentWindow,
std::unordered_map<std::string, sdbus::Variant> opts);
struct SSession {
std::string appid;
@ -123,8 +125,8 @@ class CScreencopyPortal {
SP<CCHyprlandToplevelExportManagerV1> 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;
};

View file

@ -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<std::string, sdbus::Variant> 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<uint8_t, 3> 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<std::string, sdbus::Variant> results;
results["color"] = sdbus::Struct<double, double, double>(r / 255.0, g / 255.0, b / 255.0);
results["color"] = sdbus::Variant{sdbus::Struct<double, double, double>(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<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> results;
results["color"] = sdbus::Struct<double, double, double>(r, g, b);
results["color"] = sdbus::Variant{sdbus::Struct<double, double, double>(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<std::string, sdbus::Variant> m) {
return onScreenshot(o, s1, s2, m);
}),
sdbus::registerMethod("PickColor").implementedAs([this](sdbus::ObjectPath o, std::string s1, std::string s2, std::unordered_map<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> options;
call >> options;
dbUasv CScreenshotPortal::onScreenshot(sdbus::ObjectPath requestHandle, std::string appID, std::string parentWindow, std::unordered_map<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> 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<std::string, sdbus::Variant> 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);
}

View file

@ -1,17 +1,18 @@
#pragma once
#include <sdbus-c++/sdbus-c++.h>
#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<std::string, sdbus::Variant> options);
dbUasv onPickColor(sdbus::ObjectPath requestHandle, std::string appID, std::string parentWindow, std::unordered_map<std::string, sdbus::Variant> options);
private:
std::unique_ptr<sdbus::IObject> 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"};
};

View file

@ -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<SDBusSession> createDBusSession(sdbus::ObjectPath handle) {
@ -36,9 +34,7 @@ std::unique_ptr<SDBusSession> 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<SDBusRequest> 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;
}

@ -1 +1 @@
Subproject commit 0eda85574546d19d9f06d6d5418bc192b3846f96
Subproject commit b7d85f936d622299ee57966c2b2aefde5e4f3684