diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-05-11 20:06:53 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-05-12 14:14:05 +0200 |
commit | 576ca447625b27327186095d02cfce3dca0f2504 (patch) | |
tree | 49dc85cc42b71c6c61d55ad2de392568c21f0d8f /platform/linuxbsd | |
parent | ab2c3712e2abea6488aef03f2cf57f1a64b095d3 (diff) |
Linux: Don't use udev for joypad hotloading when running in a sandbox
udev doesn't work in sandboxes, notably the new Steam container runtime
as found notably on the Steam Deck, and in Flatpak/Snap packages.
Like SDL does, when we detect such a containerized environment, we fall
back to parsing `/dev/input` directly.
See smcv's comments in #76879 for details.
Fixes #76879.
(cherry picked from commit 788cb74cc676627b6c9b7e29a47200141cca92ff)
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r-- | platform/linuxbsd/joypad_linux.cpp | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp index 0256af0a59..219e6fd252 100644 --- a/platform/linuxbsd/joypad_linux.cpp +++ b/platform/linuxbsd/joypad_linux.cpp @@ -32,6 +32,8 @@ #include "joypad_linux.h" +#include "core/os/os.h" + #include <dirent.h> #include <errno.h> #include <fcntl.h> @@ -72,6 +74,26 @@ void JoypadLinux::Joypad::reset() { events.clear(); } +// This function is derived from SDL: +// https://github.com/libsdl-org/SDL/blob/main/src/core/linux/SDL_sandbox.c#L28-L45 +static bool detect_sandbox() { + if (access("/.flatpak-info", F_OK) == 0) { + return true; + } + + // For Snap, we check multiple variables because they might be set for + // unrelated reasons. This is the same thing WebKitGTK does. + if (OS::get_singleton()->has_environment("SNAP") && OS::get_singleton()->has_environment("SNAP_NAME") && OS::get_singleton()->has_environment("SNAP_REVISION")) { + return true; + } + + if (access("/run/host/container-manager", F_OK) == 0) { + return true; + } + + return false; +} + JoypadLinux::JoypadLinux(Input *in) { #ifdef UDEV_ENABLED #ifdef SOWRAP_ENABLED @@ -80,11 +102,19 @@ JoypadLinux::JoypadLinux(Input *in) { #else int dylibloader_verbose = 0; #endif - use_udev = initialize_libudev(dylibloader_verbose) == 0; - if (use_udev) { - print_verbose("JoypadLinux: udev enabled and loaded successfully."); + if (detect_sandbox()) { + // Linux binaries in sandboxes / containers need special handling because + // libudev doesn't work there. So we need to fallback to manual parsing + // of /dev/input in such case. + use_udev = false; + print_verbose("JoypadLinux: udev enabled, but detected incompatible sandboxed mode. Falling back to /dev/input to detect joypads."); } else { - print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads."); + use_udev = initialize_libudev(dylibloader_verbose) == 0; + if (use_udev) { + print_verbose("JoypadLinux: udev enabled and loaded successfully."); + } else { + print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads."); + } } #endif #else |