From 0c36f3a6b03345aa8e636f11962bc4ba82e01912 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Mon, 20 May 2019 17:19:21 +0200 Subject: [PATCH] Talk to the portal when running inside a flatpak When we detect that we are running inside a flatpak, talk to the flatpak portal D-Bus service instead of the session daemon. This is necessary because flatpak uses pid namespace isolation (see man pid_namespaces(7)) and thus the pid needs to be translated from the flatpak pid namespace to the host namespace. This translation is happening inside the GameMode xdg-desktop-portal. --- lib/client_impl.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/lib/client_impl.c b/lib/client_impl.c index 1c842d6..eea6329 100644 --- a/lib/client_impl.c +++ b/lib/client_impl.c @@ -36,6 +36,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include +#include #include #include @@ -44,9 +46,24 @@ POSSIBILITY OF SUCH DAMAGE. #define DAEMON_DBUS_PATH "/com/feralinteractive/GameMode" #define DAEMON_DBUS_IFACE "com.feralinteractive.GameMode" +#define PORTAL_DBUS_NAME "org.freedesktop.portal.Desktop" +#define PORTAL_DBUS_PATH "/org/freedesktop/portal/desktop" +#define PORTAL_DBUS_IFACE "org.freedesktop.portal.GameMode" + // Storage for error strings static char error_string[512] = { 0 }; +// Helper to check if we are running inside a flatpak +static int in_flatpak(void) +{ + struct stat sb; + int r; + + r = lstat("/.flatpak-info", &sb); + + return r == 0 && sb.st_size > 0; +} + // Simple requestor function for a gamemode static int gamemode_request(const char *function, int arg) { @@ -65,11 +82,18 @@ static int gamemode_request(const char *function, int arg) "Could not connect to bus: %s", strerror(-ret)); } else { + int native = !in_flatpak(); + + // If we are inside a flatpak we need to talk to the portal instead + const char *dest = native ? DAEMON_DBUS_NAME : PORTAL_DBUS_NAME; + const char *path = native ? DAEMON_DBUS_PATH : PORTAL_DBUS_PATH; + const char *iface = native ? DAEMON_DBUS_IFACE : PORTAL_DBUS_IFACE; + // Attempt to send the requested function ret = sd_bus_call_method(bus, - DAEMON_DBUS_NAME, - DAEMON_DBUS_PATH, - DAEMON_DBUS_IFACE, + dest, + path, + iface, function, &err, &msg, @@ -79,11 +103,12 @@ static int gamemode_request(const char *function, int arg) if (ret < 0) { snprintf(error_string, sizeof(error_string), - "Could not call method %s on com.feralinteractive.GameMode\n" + "Could not call method %s on %s\n" "\t%s\n" "\t%s\n" "\t%s\n", function, + dest, err.name, err.message, strerror(-ret));