From b03a4341e3144851d953eb367025f83d7fef51b5 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 12 Feb 2026 02:06:12 -0700 Subject: [PATCH] Poll SDL device list to recover missing hotplug events --- app/streaming/input/gamepad.cpp | 27 +++++++++++++++++++++++++++ app/streaming/input/input.h | 2 ++ app/streaming/session.cpp | 1 + 3 files changed, 30 insertions(+) diff --git a/app/streaming/input/gamepad.cpp b/app/streaming/input/gamepad.cpp index 2a4038a7..375bc5ac 100644 --- a/app/streaming/input/gamepad.cpp +++ b/app/streaming/input/gamepad.cpp @@ -97,6 +97,33 @@ SdlInputHandler::ensureStateForGamepad(SDL_JoystickID id) return findStateForGamepad(id); } +void SdlInputHandler::pollForMissingGamepads() +{ + cleanupDetachedGamepads(); + + const int joystickCount = SDL_NumJoysticks(); + for (int deviceIndex = 0; deviceIndex < joystickCount; deviceIndex++) { + if (!SDL_IsGameController(deviceIndex)) { + continue; + } + + SDL_JoystickID jsId = SDL_JoystickGetDeviceInstanceID(deviceIndex); + if (jsId < 0 || findStateForGamepad(jsId) != nullptr) { + continue; + } + + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, + "Polling recovered missing gamepad add event (device index: %d, instance ID: %d)", + deviceIndex, + jsId); + + SDL_ControllerDeviceEvent controllerEvent = {}; + controllerEvent.type = SDL_CONTROLLERDEVICEADDED; + controllerEvent.which = deviceIndex; + handleControllerDeviceEvent(&controllerEvent); + } +} + void SdlInputHandler::cleanupDetachedGamepads() { for (int i = 0; i < MAX_GAMEPADS; i++) { diff --git a/app/streaming/input/input.h b/app/streaming/input/input.h index c306441c..b0890b31 100644 --- a/app/streaming/input/input.h +++ b/app/streaming/input/input.h @@ -118,6 +118,8 @@ public: void handleJoystickRemovalEvent(SDL_JoyDeviceEvent* event); + void pollForMissingGamepads(); + void sendText(QString& string); void rumble(uint16_t controllerNumber, uint16_t lowFreqMotor, uint16_t highFreqMotor); diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index c2a6b380..6ddc736a 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -2206,6 +2206,7 @@ void Session::exec() // issues that could cause indefinite timeouts, delayed joystick detection, // and other problems. if (!SDL_WaitEventTimeout(&event, 1000)) { + m_InputHandler->pollForMissingGamepads(); updateEffectiveAudioMuteState(); presence.runCallbacks(); continue;