refactor: replace systemd autostart with XDG autostart

This commit is contained in:
cherrybtw
2026-03-23 22:36:13 +01:00
committed by dec05eba
parent 4e5a073854
commit 651782a3a3
10 changed files with 123 additions and 69 deletions

View File

@@ -1352,15 +1352,23 @@ namespace gsr {
if(exit_status == 0)
return;
if(exit_status == 127) {
if(enable)
show_notification(TR("Failed to add GPU Screen Recorder to system startup.\nThis option only works on systems that use systemd.\nYou have to manually add \"gsr-ui\" to system startup on systems that uses another init system."), 7.0, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
} else {
if(enable)
show_notification(TR("Failed to add GPU Screen Recorder to system startup"), notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
else
show_notification(TR("Failed to remove GPU Screen Recorder from system startup"), notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
if(exit_status == 67) {
show_notification(
TR("To enable autorun: install and configure 'dex' (recommended), or manually add 'gsr-ui launch-daemon' to your desktop autostart entries."),
10.0,
mgl::Color(255, 255, 255),
mgl::Color(255, 0, 0),
NotificationType::NOTICE,
nullptr,
NotificationLevel::ERROR
);
return;
}
if(enable)
show_notification(TR("Failed to add GPU Screen Recorder to system startup"), notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
else
show_notification(TR("Failed to remove GPU Screen Recorder from system startup"), notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
};
settings_page->on_click_exit_program_button = [this](const char *reason) {
@@ -1857,9 +1865,7 @@ namespace gsr {
else
exit_reason = "exit";
const char *args[] = { "systemctl", "disable", "--user", "gpu-screen-recorder-ui", nullptr };
std::string stdout_str;
exec_program_on_host_get_stdout(args, stdout_str);
set_xdg_autostart(false);
exit();
}

View File

@@ -6,6 +6,7 @@
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
#include "../include/Process.hpp"
namespace gsr {
void string_split_char(std::string_view str, char delimiter, StringSplitCallback callback_func) {
@@ -238,4 +239,63 @@ namespace gsr {
}
return result;
}
bool is_xdg_autostart_enabled() {
const char *args[] = {
"/bin/sh", "-c",
"cat \"${XDG_CONFIG_HOME:-$HOME/.config}/autostart/gpu-screen-recorder-ui.desktop\"",
nullptr
};
std::string output;
if(exec_program_on_host_get_stdout(args, output, true) != 0)
return false;
return output.find("Hidden=true") == std::string::npos;
}
int set_xdg_autostart(bool enable) {
const char *xdg_current_desktop = getenv("XDG_CURRENT_DESKTOP");
if(!xdg_current_desktop || strlen(xdg_current_desktop) == 0) {
std::string output;
const char *check_dex_args[] = { "/bin/sh", "-c", "command -v dex", nullptr };
if(exec_program_on_host_get_stdout(check_dex_args, output, true) != 0)
return 67;
}
const char *exec_line = (getenv("FLATPAK_ID") != nullptr)
? "Exec=flatpak run com.dec05eba.gpu_screen_recorder gsr-ui launch-daemon"
: "Exec=gsr-ui launch-daemon";
std::string content =
"[Desktop Entry]\n"
"Type=Application\n"
"Name=GPU Screen Recorder\n"
"GenericName=Screen recorder\n"
"Comment=A ShadowPlay-like screen recorder for Linux\n"
"Icon=gpu-screen-recorder\n" +
std::string(exec_line) + "\n" +
"Terminal=false\n" +
"Hidden=" + (enable ? "false" : "true") + "\n";
std::string shell_cmd =
"p=\"${XDG_CONFIG_HOME:-$HOME/.config}/autostart/gpu-screen-recorder-ui.desktop\" && "
"mkdir -p \"$(dirname \"$p\")\" && "
"printf '" + content + "' > \"$p\"";
const char *args[] = { "/bin/sh", "-c", shell_cmd.c_str(), nullptr };
std::string dummy;
return exec_program_on_host_get_stdout(args, dummy, true);
}
bool is_systemd_service_enabled(const char *service_name) {
const char *args[] = { "systemctl", "--user", "is-enabled", service_name, nullptr };
std::string output;
return exec_program_on_host_get_stdout(args, output, false) == 0;
}
bool disable_systemd_service(const char *service_name) {
const char *args[] = { "systemctl", "--user", "disable", service_name, nullptr };
std::string output;
return exec_program_on_host_get_stdout(args, output, false) == 0;
}
}

View File

@@ -3,6 +3,7 @@
#include "../../include/Overlay.hpp"
#include "../../include/Theme.hpp"
#include "../../include/Process.hpp"
#include "../../include/Utils.hpp"
#include "../../include/Translation.hpp"
#include "../../include/gui/GsrPage.hpp"
#include "../../include/gui/PageStack.hpp"
@@ -180,9 +181,7 @@ namespace gsr {
else
return false;
const char *args[] = { "systemctl", enable ? "enable" : "disable", "--user", "gpu-screen-recorder-ui", nullptr };
std::string stdout_str;
const int exit_status = exec_program_on_host_get_stdout(args, stdout_str);
const int exit_status = set_xdg_autostart(enable);
if(on_startup_changed)
on_startup_changed(enable, exit_status);
return exit_status == 0;
@@ -633,10 +632,7 @@ namespace gsr {
else
tint_color_radio_button_ptr->set_selected_item(config.main_config.tint_color);
const char *args[] = { "systemctl", "is-enabled", "--quiet", "--user", "gpu-screen-recorder-ui", nullptr };
std::string stdout_str;
const int exit_status = exec_program_on_host_get_stdout(args, stdout_str);
startup_radio_button_ptr->set_selected_item(exit_status == 0 ? "start_on_system_startup" : "dont_start_on_system_startup", false, false);
startup_radio_button_ptr->set_selected_item(is_xdg_autostart_enabled() ? "start_on_system_startup" : "dont_start_on_system_startup", false, false);
enable_keyboard_hotkeys_radio_button_ptr->set_selected_item(config.main_config.hotkeys_enable_option, false, false);
enable_joystick_hotkeys_radio_button_ptr->set_selected_item(config.main_config.joystick_hotkeys_enable_option, false, false);

View File

@@ -1,5 +1,6 @@
#include "../include/GsrInfo.hpp"
#include "../include/Overlay.hpp"
#include "../include/Utils.hpp"
#include "../include/gui/Utils.hpp"
#include "../include/Process.hpp"
#include "../include/Rpc.hpp"
@@ -117,47 +118,6 @@ static void rpc_add_commands(gsr::Rpc *rpc, gsr::Overlay *overlay) {
});
}
static void install_flatpak_systemd_service() {
const bool systemd_service_exists = system(
"data_home=$(flatpak-spawn --host -- /bin/sh -c 'echo \"${XDG_DATA_HOME:-$HOME/.local/share}\"') && "
"flatpak-spawn --host -- ls \"$data_home/systemd/user/gpu-screen-recorder-ui.service\"") == 0;
if(systemd_service_exists)
return;
bool service_install_successful = (system(
"data_home=$(flatpak-spawn --host -- /bin/sh -c 'echo \"${XDG_DATA_HOME:-$HOME/.local/share}\"') && "
"flatpak-spawn --host -- install -Dm644 /var/lib/flatpak/app/com.dec05eba.gpu_screen_recorder/current/active/files/share/gpu-screen-recorder/gpu-screen-recorder-ui.service \"$data_home/systemd/user/gpu-screen-recorder-ui.service\"") == 0);
service_install_successful &= (system("flatpak-spawn --host -- systemctl --user daemon-reload") == 0);
if(service_install_successful)
fprintf(stderr, "Info: the systemd service file was missing. It has now been installed\n");
else
fprintf(stderr, "Error: the systemd service file is missing and failed to install it again\n");
}
static void remove_flatpak_systemd_service() {
char systemd_service_path[PATH_MAX];
const char *xdg_data_home = getenv("XDG_DATA_HOME");
const char *home = getenv("HOME");
if(xdg_data_home) {
snprintf(systemd_service_path, sizeof(systemd_service_path), "%s/systemd/user/gpu-screen-recorder-ui.service", xdg_data_home);
} else if(home) {
snprintf(systemd_service_path, sizeof(systemd_service_path), "%s/.local/share/systemd/user/gpu-screen-recorder-ui.service", home);
} else {
fprintf(stderr, "Error: failed to get user home directory\n");
return;
}
if(access(systemd_service_path, F_OK) != 0)
return;
remove(systemd_service_path);
system("systemctl --user daemon-reload");
fprintf(stderr, "Info: conflicting flatpak version of the systemd service for gsr-ui was found at \"%s\", it has now been removed\n", systemd_service_path);
}
static bool is_flatpak() {
return getenv("FLATPAK_ID") != nullptr;
}
static void set_display_server_environment_variables() {
// Some users dont have properly setup environments (no display manager that does systemctl --user import-environment DISPLAY WAYLAND_DISPLAY)
@@ -278,11 +238,6 @@ int main(int argc, char **argv) {
return 1;
}
if(is_flatpak())
install_flatpak_systemd_service();
else
remove_flatpak_systemd_service();
// Stop nvidia driver from buffering frames
setenv("__GL_MaxFramesAllowed", "1", true);
// If this is set to 1 then cuGraphicsGLRegisterImage will fail for egl context with error: invalid OpenGL or DirectX context,
@@ -346,6 +301,24 @@ int main(int argc, char **argv) {
rpc_add_commands(rpc.get(), overlay.get());
// Evacuating from lennart's botnet to XDG (a.k.a. 'the spec that nobody actually follows').
constexpr const char *deprecated_systemd_service_name = "gpu-screen-recorder-ui.service";
if(gsr::is_systemd_service_enabled(deprecated_systemd_service_name)) {
const int autostart_result = gsr::set_xdg_autostart(true);
if(autostart_result == 67) {
overlay->show_notification(
TR("GPU Screen Recorder UI autostart via systemd is deprecated.\nTo migrate: install and configure 'dex' (recommended),\nor manually add 'gsr-ui launch-daemon' to your desktop autostart entries."),
10.0, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0),
gsr::NotificationType::NOTICE, nullptr, gsr::NotificationLevel::ERROR);
} else {
gsr::disable_systemd_service(deprecated_systemd_service_name);
overlay->show_notification(
TR("GPU Screen Recorder UI startup has been switched from systemd service to XDG autostart."),
8.0, mgl::Color(255, 255, 255), gsr::get_color_theme().tint_color,
gsr::NotificationType::NOTICE, nullptr, gsr::NotificationLevel::INFO);
}
}
// TODO: Add hotkeys in Overlay when using x11 global hotkeys. The hotkeys in Overlay should duplicate each key that is used for x11 global hotkeys.
std::string exit_reason;