From 8a701808a61b5cc3211e7eb0fbac635a0cb98d4b Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 29 May 2026 12:07:16 -0700
Subject: [PATCH] Fixed Steam Controller not detected on macOS under Steam
---
src/hidapi/mac/hid.c | 12 ++++--------
src/joystick/SDL_gamepad.c | 6 ------
src/joystick/apple/SDL_mfijoystick.m | 2 +-
src/joystick/darwin/SDL_iokitjoystick.c | 11 ++++-------
4 files changed, 9 insertions(+), 22 deletions(-)
diff --git a/src/hidapi/mac/hid.c b/src/hidapi/mac/hid.c
index e58b9a990f9d4..79d86bee19c81 100644
--- a/src/hidapi/mac/hid.c
+++ b/src/hidapi/mac/hid.c
@@ -605,14 +605,10 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev,
#endif
#ifdef HIDAPI_USING_SDL_RUNTIME
- if (IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDVirtualHIDevice)) == kCFBooleanTrue) {
- /* Steam virtual gamepads always have kIOHIDVirtualHIDevice property unlike real devices */
- if (SDL_IsJoystickSteamVirtualGamepad(dev_vid, dev_pid, dev_version)) {
- const char *allow_steam_virtual_gamepad = SDL_getenv_unsafe("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD");
- if (!SDL_GetStringBoolean(allow_steam_virtual_gamepad, false)) {
- free(cur_dev);
- return NULL;
- }
+ if (SDL_IsJoystickSteamVirtualGamepad(dev_vid, dev_pid, dev_version)) {
+ if (IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDVirtualHIDevice)) != kCFBooleanTrue) {
+ /* This is a real Xbox 360 controller, adjust the version so it's not detected as a Steam virtual gamepad */
+ dev_version = 1;
}
}
#endif
diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c
index 90924582f2c6b..0a660c56336e5 100644
--- a/src/joystick/SDL_gamepad.c
+++ b/src/joystick/SDL_gamepad.c
@@ -3292,11 +3292,6 @@ bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version
}
}
-#ifdef SDL_PLATFORM_MACOS
- // On macOS do nothing here since we detect Steam virtual gamepads
- // in IOKit HID backends to ensure accuracy.
- // See joystick/darwin/SDL_iokitjoystick.c and hidapi/mac/hid.c.
-#else
const char *hint = SDL_getenv_unsafe("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD");
bool allow_steam_virtual_gamepad = SDL_GetStringBoolean(hint, false);
#ifdef SDL_PLATFORM_WIN32
@@ -3312,7 +3307,6 @@ bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version
if (SDL_IsJoystickSteamVirtualGamepad(vendor_id, product_id, version)) {
return !allow_steam_virtual_gamepad;
}
-#endif
if (SDL_allowed_gamepads.num_included_entries > 0) {
if (SDL_VIDPIDInList(vendor_id, product_id, &SDL_allowed_gamepads)) {
diff --git a/src/joystick/apple/SDL_mfijoystick.m b/src/joystick/apple/SDL_mfijoystick.m
index ef3cf00329208..63dfef8233817 100644
--- a/src/joystick/apple/SDL_mfijoystick.m
+++ b/src/joystick/apple/SDL_mfijoystick.m
@@ -1773,7 +1773,7 @@ bool IOS_SupportedHIDDevice(IOHIDDeviceRef device)
}
if (IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVirtualHIDevice)) == kCFBooleanTrue) {
- // Steam virtual gamepads always have kIOHIDVirtualHIDevice property unlike real devices, and are also not exposed as GCController
+ // Steam virtual gamepads always have kIOHIDVirtualHIDevice property unlike real devices, and are also not supported as GCController
return false;
}
diff --git a/src/joystick/darwin/SDL_iokitjoystick.c b/src/joystick/darwin/SDL_iokitjoystick.c
index 7e36391f42012..b88258f18da40 100644
--- a/src/joystick/darwin/SDL_iokitjoystick.c
+++ b/src/joystick/darwin/SDL_iokitjoystick.c
@@ -516,13 +516,10 @@ static bool GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
return false;
}
- if (IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDVirtualHIDevice)) == kCFBooleanTrue) {
- // Steam virtual gamepads always have kIOHIDVirtualHIDevice property unlike real devices
- if (SDL_IsJoystickSteamVirtualGamepad(vendor, product, version)) {
- const char *allow_steam_virtual_gamepad = SDL_getenv_unsafe("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD");
- if (!SDL_GetStringBoolean(allow_steam_virtual_gamepad, false)) {
- return false;
- }
+ if (SDL_IsJoystickSteamVirtualGamepad(vendor, product, version)) {
+ if (IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDVirtualHIDevice)) != kCFBooleanTrue) {
+ // This is a real Xbox 360 controller, adjust the version so it's not detected as a Steam virtual gamepad
+ version = 1;
}
}