mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-23 22:55:58 +01:00
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:
parent
fb9c8d665a
commit
5c72a7fea1
14 changed files with 161 additions and 251 deletions
|
@ -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)
|
||||
|
|
|
@ -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=";
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "wlr-screencopy-unstable-v1.hpp"
|
||||
|
||||
#include "../includes.hpp"
|
||||
#include "../dbusDefines.hpp"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
|
|
5
src/dbusDefines.hpp
Normal file
5
src/dbusDefines.hpp
Normal 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;
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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>{});
|
||||
}
|
|
@ -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"};
|
||||
};
|
|
@ -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>();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"};
|
||||
};
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue