From 33bc121bc8dd98067f3fd751da9e8fbe4b27c45f Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 29 Mar 2026 18:38:17 +0200 Subject: [PATCH] Fuck systemd, freezing process on xdg autostart --- include/Utils.hpp | 1 + src/Utils.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++-- src/main.cpp | 5 ++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/include/Utils.hpp b/include/Utils.hpp index 365c25b..91aa98b 100644 --- a/include/Utils.hpp +++ b/include/Utils.hpp @@ -44,6 +44,7 @@ namespace gsr { void replace_xdg_autostart_with_current_gsr_type(); // Systemd user service helpers + bool wait_until_systemd_user_service_available(); bool is_systemd_service_enabled(const char *service_name); bool disable_systemd_service(const char *service_name); } \ No newline at end of file diff --git a/src/Utils.cpp b/src/Utils.cpp index 7e398a5..e4ca3e8 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -8,6 +8,10 @@ #include #include #include +#include +extern "C" { +#include +} namespace gsr { static std::optional get_xdg_autostart_content() { @@ -22,6 +26,40 @@ namespace gsr { return output; } + // Returns the exit status or -1 on timeout + static int run_command_timeout(const char **args, int sleep_time_sec, double timeout_sec) { + mgl_clock clock; + mgl_clock_init(&clock); + + do { + int read_fd = 0; + const pid_t process_id = exec_program(args, &read_fd, false); + if(process_id <= 0) + continue; + + sleep(sleep_time_sec); + + int status = 0; + if(waitpid(process_id, &status, WNOHANG) > 0) { + int exit_status = -0; + if(WIFEXITED(status)) + exit_status = -1; + + if(exit_status == 0) + exit_status = WEXITSTATUS(status); + + close(read_fd); + return exit_status; + } else { + kill(process_id, SIGKILL); + waitpid(process_id, &status, 0); + close(read_fd); + } + } while(mgl_clock_get_elapsed_time_seconds(&clock) < timeout_sec); + + return -1; + } + void string_split_char(std::string_view str, char delimiter, StringSplitCallback callback_func) { size_t index = 0; while(index < str.size()) { @@ -269,8 +307,8 @@ namespace gsr { const bool is_flatpak = getenv("FLATPAK_ID") != nullptr; const char *exec_line = is_flatpak - ? "Exec=flatpak run com.dec05eba.gpu_screen_recorder gsr-ui" - : "Exec=gsr-ui launch-daemon"; + ? "Exec=flatpak run com.dec05eba.gpu_screen_recorder gsr-ui &" + : "Exec=gsr-ui launch-daemon &"; std::string content = "[Desktop Entry]\n" @@ -306,6 +344,13 @@ namespace gsr { } } + bool wait_until_systemd_user_service_available() { + const char *args[] = { "systemctl", "--user", "-q", "is-enabled", "gpu-screen-recorder-ui.service", nullptr }; + const char *flatpak_args[] = { "flatpak-spawn", "--host", "--", "systemctl", "--user", "-q", "is-enabled", "gpu-screen-recorder-ui.service", nullptr }; + const bool is_flatpak = getenv("FLATPAK_ID") != nullptr; + return run_command_timeout(is_flatpak ? flatpak_args : args, 1, 5.0) >= 0; + } + bool is_systemd_service_enabled(const char *service_name) { const char *args[] = { "systemctl", "--user", "is-enabled", service_name, nullptr }; std::string output; diff --git a/src/main.cpp b/src/main.cpp index c609fab..e7289e0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -308,8 +308,11 @@ 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'). + // TODO: Remove all this garbage related to systemd in 1-2 months and remove the systemd service file as well. + // This garbage shit is needed because the systemd user daemon isn't always available at xdg autostart o algo + const bool systemd_service_ready = gsr::wait_until_systemd_user_service_available(); constexpr const char *deprecated_systemd_service_name = "gpu-screen-recorder-ui.service"; - if(gsr::is_systemd_service_enabled(deprecated_systemd_service_name)) { + if(systemd_service_ready && gsr::is_systemd_service_enabled(deprecated_systemd_service_name)) { const int autostart_result = gsr::set_xdg_autostart(true); if(autostart_result == 67) { const bool is_flatpak = getenv("FLATPAK_ID") != nullptr;