This prevents a number of issues where devices are enumerated but not actually able to be opened, like https://github.com/libsdl-org/SDL/issues/5781.
We currently leave the devices open, allowing us to more easily do controller feature detection, protocol negotiation, detect dropped Bluetooth connections, etc. with the expectation that the application is likely to open the controllers shortly.
Unfortunately the only way to detect this is to actually try opening a device, so we wait until the application tries, and then stop enumerating afterwards.
Fixes https://github.com/libsdl-org/SDL/issues/5781
Touching HID devices with keyboard usages will trigger a keyboard capture
permission prompt on macOS 11+. See #4887
Like the IOKit joystick backend, we accept HID devices that have joystick,
gamepad, or multi-axis controller usages. We also allow the Valve VID for
the Steam Controller, just like the Windows HIDAPI implementation does.
This prevents conflicts with hidapi linked with applications, as well as allowing applications to make use of HIDAPI on Android and other platforms that might not normally have an implementation available.
The function we currently use, IOHIDDeviceRegisterRemovalCallback(), often
fails on Catalina with a "__CFRunLoopModeFindSourceForMachPort returned NULL"
error message. Once a removal callback is missed, we will eventually crash when
the joystick is closed attempting to use the invalid IOHIDDeviceRef.
https://forums.developer.apple.com/thread/124444
If you enable this, you'll need to link with CoreBluetooth.framework and add something like this to your Info.plist:
<key>NSBluetoothPeripheralUsageDescription</key>
<string>MyApp would like to remain connected to nearby bluetooth Game Controllers and Game Pads even when you're not using the app.</string>