input/macOs: Call hid_open_path on the main thread

This commit is contained in:
Megamouse 2025-06-07 10:29:55 +02:00
parent e36f55ea41
commit ae38cef7b1
7 changed files with 37 additions and 35 deletions

View file

@ -513,17 +513,12 @@ PadHandlerBase::connection ds3_pad_handler::update_connection(const std::shared_
if (dev->hidDevice == nullptr) if (dev->hidDevice == nullptr)
{ {
#ifdef ANDROID if (hid_device* hid_dev = dev->open())
if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1))
#else
if (hid_device* hid_dev = hid_open_path(dev->path.c_str()))
#endif
{ {
if (hid_set_nonblocking(hid_dev, 1) == -1) if (hid_set_nonblocking(hid_dev, 1) == -1)
{ {
ds3_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); ds3_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev));
} }
dev->hidDevice = hid_dev;
} }
else else
{ {

View file

@ -837,19 +837,13 @@ PadHandlerBase::connection ds4_pad_handler::update_connection(const std::shared_
if (dev->hidDevice == nullptr) if (dev->hidDevice == nullptr)
{ {
// try to reconnect // try to reconnect
#ifdef ANDROID if (hid_device* hid_dev = dev->open())
if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1))
#else
if (hid_device* hid_dev = hid_open_path(dev->path.c_str()))
#endif
{ {
if (hid_set_nonblocking(hid_dev, 1) == -1) if (hid_set_nonblocking(hid_dev, 1) == -1)
{ {
ds4_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); ds4_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev));
} }
dev->hidDevice = hid_dev;
if (!dev->has_calib_data) if (!dev->has_calib_data)
{ {
dev->has_calib_data = GetCalibrationData(dev); dev->has_calib_data = GetCalibrationData(dev);

View file

@ -568,19 +568,13 @@ PadHandlerBase::connection dualsense_pad_handler::update_connection(const std::s
if (dev->hidDevice == nullptr) if (dev->hidDevice == nullptr)
{ {
// try to reconnect // try to reconnect
#ifdef ANDROID if (hid_device* hid_dev = dev->open())
if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1))
#else
if (hid_device* hid_dev = hid_open_path(dev->path.c_str()))
#endif
{ {
if (hid_set_nonblocking(hid_dev, 1) == -1) if (hid_set_nonblocking(hid_dev, 1) == -1)
{ {
dualsense_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); dualsense_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev));
} }
dev->hidDevice = hid_dev;
if (!dev->has_calib_data) if (!dev->has_calib_data)
{ {
dev->has_calib_data = get_calibration_data(dev); dev->has_calib_data = get_calibration_data(dev);

View file

@ -67,7 +67,7 @@ public:
{ {
error_code = hid_init(); error_code = hid_init();
hid_darwin_set_open_exclusive(0); hid_darwin_set_open_exclusive(0);
}); }, false);
#else #else
const int error_code = hid_init(); const int error_code = hid_init();
#endif #endif
@ -86,6 +86,28 @@ private:
std::mutex m_hid_mutex; std::mutex m_hid_mutex;
}; };
hid_device* HidDevice::open()
{
#ifdef ANDROID
hidDevice = hid_libusb_wrap_sys_device(path, -1);
#elif defined(__APPLE__)
std::unique_lock static_lock(s_hid_mutex, std::defer_lock);
if (!static_lock.try_lock())
{
// The enumeration thread is busy. If we lock and open the device, we might get input stutter on other devices.
return nullptr;
}
Emu.BlockingCallFromMainThread([this]()
{
hidDevice = hid_open_path(path.c_str());
}, false);
#else
hidDevice = hid_open_path(path.data());
#endif
return hidDevice;
}
void HidDevice::close() void HidDevice::close()
{ {
if (hidDevice) if (hidDevice)
@ -245,7 +267,7 @@ void hid_pad_handler<Device>::enumerate_devices()
} }
hid_free_enumeration(head); hid_free_enumeration(head);
#if defined(__APPLE__) #if defined(__APPLE__)
}); }, false);
#endif #endif
} }
#endif #endif
@ -333,6 +355,13 @@ void hid_pad_handler<Device>::update_devices()
#ifdef ANDROID #ifdef ANDROID
if (hid_device* dev = hid_libusb_wrap_sys_device(path, -1)) if (hid_device* dev = hid_libusb_wrap_sys_device(path, -1))
#elif defined(__APPLE__)
hid_device* dev = nullptr;
Emu.BlockingCallFromMainThread([&]()
{
dev = hid_open_path(path.c_str());
}, false);
if (dev)
#else #else
if (hid_device* dev = hid_open_path(path.c_str())) if (hid_device* dev = hid_open_path(path.c_str()))
#endif #endif

View file

@ -56,6 +56,7 @@ enum CalibIndex
class HidDevice : public PadDevice class HidDevice : public PadDevice
{ {
public: public:
hid_device* open();
void close(); void close();
hid_device* hidDevice{nullptr}; hid_device* hidDevice{nullptr};

View file

@ -434,17 +434,12 @@ PadHandlerBase::connection ps_move_handler::update_connection(const std::shared_
move_device->hidDevice = dev; move_device->hidDevice = dev;
} }
#else #else
#ifdef ANDROID if (hid_device* dev = move_device->open())
if (hid_device* dev = hid_libusb_wrap_sys_device(move_device->path, -1))
#else
if (hid_device* dev = hid_open_path(move_device->path.c_str()))
#endif
{ {
if (hid_set_nonblocking(dev, 1) == -1) if (hid_set_nonblocking(dev, 1) == -1)
{ {
move_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", move_device->path, hid_error(dev)); move_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", move_device->path, hid_error(dev));
} }
move_device->hidDevice = dev;
} }
#endif #endif
else else

View file

@ -239,22 +239,16 @@ PadHandlerBase::connection skateboard_pad_handler::update_connection(const std::
if (dev->hidDevice == nullptr) if (dev->hidDevice == nullptr)
{ {
// try to reconnect // try to reconnect
#ifdef ANDROID if (hid_device* hid_dev = dev->open())
if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1))
#else
if (hid_device* hid_dev = hid_open_path(dev->path.c_str()))
#endif
{ {
if (hid_set_nonblocking(hid_dev, 1) == -1) if (hid_set_nonblocking(hid_dev, 1) == -1)
{ {
skateboard_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); skateboard_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev));
} }
dev->hidDevice = hid_dev;
} }
else else
{ {
// nope, not there // nope, not there
skateboard_log.error("Device %s: disconnected", dev->path);
return connection::disconnected; return connection::disconnected;
} }
} }