Handle joystick hotplug fallback and avoid stale gamepad matches
Some checks are pending
Build / setup (push) Waiting to run
Build / build-appimage (push) Blocked by required conditions
Build / build-steamlink (push) Blocked by required conditions
Build / build-windows-macos (push) Blocked by required conditions

This commit is contained in:
Joey Yakimowich-Payne 2026-02-12 01:52:03 -07:00
commit cf652190a3

View file

@ -52,7 +52,7 @@ SdlInputHandler::findStateForGamepad(SDL_JoystickID id)
int i;
for (i = 0; i < MAX_GAMEPADS; i++) {
if (m_GamepadState[i].jsId == id) {
if (m_GamepadState[i].controller != nullptr && m_GamepadState[i].jsId == id) {
SDL_assert(!m_MultiController || m_GamepadState[i].index == i);
return &m_GamepadState[i];
}
@ -618,15 +618,17 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
return;
}
SDL_JoystickID jsId = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller));
// SDL_CONTROLLERDEVICEADDED can be reported multiple times for the same
// gamepad in rare cases, because SDL doesn't fixup the device index in
// the SDL_CONTROLLERDEVICEADDED event if an unopened gamepad disappears
// before we've processed the add event.
for (int i = 0; i < MAX_GAMEPADS; i++) {
if (m_GamepadState[i].controller == controller) {
if (m_GamepadState[i].controller != nullptr && m_GamepadState[i].jsId == jsId) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Received duplicate add event for controller index: %d",
event->which);
"Received duplicate add event for joystick instance ID: %d",
jsId);
SDL_GameControllerClose(controller);
return;
}
@ -682,7 +684,7 @@ void SdlInputHandler::handleControllerDeviceEvent(SDL_ControllerDeviceEvent* eve
}
state->controller = controller;
state->jsId = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(state->controller));
state->jsId = jsId;
hapticCaps = 0;
#if SDL_VERSION_ATLEAST(2, 0, 18)
@ -886,7 +888,14 @@ void SdlInputHandler::handleJoystickArrivalEvent(SDL_JoyDeviceEvent* event)
{
SDL_assert(event->type == SDL_JOYDEVICEADDED);
if (!SDL_IsGameController(event->which)) {
if (SDL_IsGameController(event->which)) {
SDL_ControllerDeviceEvent controllerEvent = {};
controllerEvent.type = SDL_CONTROLLERDEVICEADDED;
controllerEvent.which = event->which;
handleControllerDeviceEvent(&controllerEvent);
return;
}
char guidStr[33];
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(event->which),
guidStr, sizeof(guidStr));
@ -909,7 +918,6 @@ void SdlInputHandler::handleJoystickArrivalEvent(SDL_JoyDeviceEvent* event)
SDL_GetError());
}
}
}
void SdlInputHandler::handleJoystickRemovalEvent(SDL_JoyDeviceEvent* event)
{