diff --git a/AutoStart/AutoStart-Flatpak.cpp b/AutoStart/AutoStart-Flatpak.cpp new file mode 100644 index 000000000..2e87bab0a --- /dev/null +++ b/AutoStart/AutoStart-Flatpak.cpp @@ -0,0 +1,158 @@ +/*---------------------------------------------------------*\ +| AutoStart-Flatpak.cpp | +| | +| Autostart implementation for Linux via Flatpak Portal | +| | +| Adam Honse 04 Sep 2026 | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#include "AutoStart-Flatpak.h" +#include + +AutoStart::AutoStart(std::string name) +{ + InitAutoStart(name); +} + +void AutoStart::InitAutoStart(std::string name) +{ + app_name = name; +} + +bool AutoStart::CallBackgroundPortal(bool enable, const AutoStartInfo& autostart_info) +{ + GError* error = nullptr; + GDBusConnection* connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, &error); + + if(!connection) + { + if(error) + { + g_error_free(error); + } + + return false; + } + + /*-----------------------------------------------------*\ + | FreeDesktop Background Portal parameters | + \*-----------------------------------------------------*/ + const char* bus_name = "org.freedesktop.portal.Desktop"; + const char* object_path = "/org/freedesktop/portal/desktop"; + const char* interface_name = "org.freedesktop.portal.Background"; + const char* method_name = "RequestBackground"; + + /*-----------------------------------------------------*\ + | Build the options dictionary (vardict) required by | + | the Portal | + \*-----------------------------------------------------*/ + GVariantBuilder options_builder; + g_variant_builder_init(&options_builder, G_VARIANT_TYPE_VARDICT); + + /*-----------------------------------------------------*\ + | Reason shown to the user in the system settings / | + | permission prompt | + \*-----------------------------------------------------*/ + std::string reason_str = "Allow " + app_name + " to launch automatically at startup."; + g_variant_builder_add(&options_builder, "{sv}", "reason", g_variant_new_string(reason_str.c_str())); + + /*-----------------------------------------------------*\ + | Toggle the autostart feature state | + \*-----------------------------------------------------*/ + g_variant_builder_add(&options_builder, "{sv}", "autostart", g_variant_new_boolean(enable)); + + if(enable) + { + /*-------------------------------------------------*\ + | Pass command-line arguments to the background | + | request | + \*-------------------------------------------------*/ + GVariantBuilder arg_builder; + g_variant_builder_init(&arg_builder, G_VARIANT_TYPE("as")); + + /*-------------------------------------------------*\ + | Add the primary executable path inside the | + | Flatpak sandbox | + \*-------------------------------------------------*/ + g_variant_builder_add(&arg_builder, "s", GetExePath().c_str()); + + /*-------------------------------------------------*\ + | Append any additional arguments provided by | + | OpenRGB's autostart config | + \*-------------------------------------------------*/ + if(!autostart_info.args.empty()) + { + g_variant_builder_add(&arg_builder, "s", autostart_info.args.c_str()); + } + + GVariant* commandline_args = g_variant_builder_end(&arg_builder); + g_variant_builder_add(&options_builder, "{sv}", "commandline", commandline_args); + } + + /*-----------------------------------------------------*\ + | An empty string window handle is used since this is a | + | background configuration request | + \*-----------------------------------------------------*/ + const char* parent_window = ""; + GVariant* options = g_variant_builder_end(&options_builder); + + /*-----------------------------------------------------*\ + | Bundle parameters: (s a{sv}) -> Parent window handle, | + | Options dictionary | + \*-----------------------------------------------------*/ + GVariant* parameters = g_variant_new("(s@a{sv})", parent_window, options); + GVariant* reply; + + reply = g_dbus_connection_call_sync(connection, bus_name, object_path, interface_name, method_name, parameters, G_VARIANT_TYPE("(o)"), G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error); + + g_object_unref(connection); + + if(error) + { + g_error_free(error); + return false; + } + + if(reply) + { + g_variant_unref(reply); + return true; + } + + return false; +} + +bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info) +{ + return CallBackgroundPortal(true, autostart_info); +} + +bool AutoStart::DisableAutoStart() +{ + return CallBackgroundPortal(false); +} + +bool AutoStart::IsAutoStartEnabled() +{ + /*-----------------------------------------------------*\ + | The FreeDesktop Background Portal does not provide a | + | stateless status getter. Sandbox permissions are | + | securely managed and persisted internally by the | + | host's portal service. To implement a true state | + | track here, OpenRGB will need to manage a local | + | boolean flag inside its own configuration files (e.g. | + | OpenRGB.json). | + \*-----------------------------------------------------*/ + return false; +} + +std::string AutoStart::GetExePath() +{ + /*-----------------------------------------------------*\ + | Flatpak applications always run from this specific | + | exported path hierarchy | + \*-----------------------------------------------------*/ + return "/app/bin/openrgb"; +} diff --git a/AutoStart/AutoStart-Flatpak.h b/AutoStart/AutoStart-Flatpak.h new file mode 100644 index 000000000..a40a9b396 --- /dev/null +++ b/AutoStart/AutoStart-Flatpak.h @@ -0,0 +1,31 @@ +/*---------------------------------------------------------*\ +| AutoStart-Flatpak.h | +| | +| Autostart implementation for Linux via Flatpak Portal | +| | +| Adam Honse 04 Sep 2026 | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include "AutoStart.h" + +class AutoStart : public AutoStartInterface +{ +public: + AutoStart(std::string name); + + bool DisableAutoStart(); + bool EnableAutoStart(AutoStartInfo autostart_info); + bool IsAutoStartEnabled(); + std::string GetExePath(); + +private: + void InitAutoStart(std::string name); + bool CallBackgroundPortal(bool enable, const AutoStartInfo& autostart_info = {}); + + std::string app_name; +}; diff --git a/AutoStart/AutoStart.h b/AutoStart/AutoStart.h index 73e613b96..2e8d7ede1 100644 --- a/AutoStart/AutoStart.h +++ b/AutoStart/AutoStart.h @@ -40,9 +40,15 @@ protected: #include "AutoStart-Windows.h" #endif +#ifdef FLATPAK_BUILD +#include "AutoStart-Flatpak.h" +#endif + #ifdef __linux__ +#ifndef FLATPAK_BUILD #include "AutoStart-Linux.h" #endif +#endif #ifdef __APPLE__ #include "AutoStart-MacOS.h" diff --git a/OpenRGB.pro b/OpenRGB.pro index 19167a225..ed9c9ae23 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -489,12 +489,23 @@ contains(QMAKE_PLATFORM, linux) { HEADERS += \ dependencies/NVFC/nvapi.h \ i2c_smbus/Linux/i2c_smbus_linux.h \ - AutoStart/AutoStart-Linux.h \ SPDAccessor/EE1004Accessor_Linux.h \ SPDAccessor/SPD5118Accessor_Linux.h \ SuspendResume/SuspendResume_Linux_FreeBSD.h \ super_io/super_io.h \ + #-------------------------------------------------------------------------------------------# + # AutoStart implementation - Flatpak uses portal-based autostart, Linux uses desktop files # + # Auto-detect Flatpak build environment via /.flatpak-info file # + #-------------------------------------------------------------------------------------------# + exists(/.flatpak-info) { + HEADERS += AutoStart/AutoStart-Flatpak.h + DEFINES += FLATPAK_BUILD + PKGCONFIG += gio-2.0 + } else { + HEADERS += AutoStart/AutoStart-Linux.h + } + INCLUDEPATH += \ dependencies/NVFC \ i2c_smbus/Linux \ @@ -559,13 +570,22 @@ contains(QMAKE_PLATFORM, linux) { i2c_smbus/Linux/i2c_smbus_linux.cpp \ scsiapi/scsiapi_linux.c \ serial_port/find_usb_serial_port_linux.cpp \ - AutoStart/AutoStart-Linux.cpp \ SPDAccessor/EE1004Accessor_Linux.cpp \ SPDAccessor/SPD5118Accessor_Linux.cpp \ SuspendResume/SuspendResume_Linux_FreeBSD.cpp \ startup/main_FreeBSD_Linux_MacOS.cpp \ super_io/super_io.cpp \ + #-------------------------------------------------------------------------------------------# + # AutoStart implementation - Flatpak uses portal-based autostart, Linux uses desktop files # + # Auto-detect Flatpak build environment via /.flatpak-info file # + #-------------------------------------------------------------------------------------------# + exists(/.flatpak-info) { + SOURCES += AutoStart/AutoStart-Flatpak.cpp + } else { + SOURCES += AutoStart/AutoStart-Linux.cpp + } + #-------------------------------------------------------------------------------------------# # Set up install paths # # These install paths are used for AppImage and .deb packaging #