diff --git a/src/hidapi/configure.ac b/src/hidapi/configure.ac index c6747f906ac48..c3d3dbc1b1dbb 100644 --- a/src/hidapi/configure.ac +++ b/src/hidapi/configure.ac @@ -79,7 +79,7 @@ case $host in backend="mac" os="darwin" threads="pthreads" - LIBS="${LIBS} -framework IOKit -framework CoreFoundation" + LIBS="${LIBS} -framework IOKit -framework CoreFoundation -framework AppKit" ;; *-freebsd*) AC_MSG_RESULT([ (FreeBSD back-end)]) diff --git a/src/hidapi/mac/Makefile-manual b/src/hidapi/mac/Makefile-manual index 5399b5a70fc62..16052d143fc58 100644 --- a/src/hidapi/mac/Makefile-manual +++ b/src/hidapi/mac/Makefile-manual @@ -14,7 +14,7 @@ COBJS=hid.o CPPOBJS=../hidtest/hidtest.o OBJS=$(COBJS) $(CPPOBJS) CFLAGS+=-I../hidapi -Wall -g -c -LIBS=-framework IOKit -framework CoreFoundation +LIBS=-framework IOKit -framework CoreFoundation -framework AppKit hidtest: $(OBJS) diff --git a/src/hidapi/mac/hid.c b/src/hidapi/mac/hid.c index 0dbe4227d21c3..b45767333740b 100644 --- a/src/hidapi/mac/hid.c +++ b/src/hidapi/mac/hid.c @@ -37,6 +37,9 @@ #define VALVE_USB_VID 0x28DE +/* As defined in AppKit.h, but we don't need the entire AppKit for a single constant. */ +extern const double NSAppKitVersionNumber; + /* Barrier implementation because Mac OSX doesn't have pthread_barrier. It also doesn't have clock_gettime(). So much for POSIX and SUSv2. This implementation came from Brent Priddy and was posted on @@ -131,6 +134,7 @@ struct hid_device_list_node }; static IOHIDManagerRef hid_mgr = 0x0; +static int is_macos_10_10_or_greater = 0; static struct hid_device_list_node *device_list = 0x0; static hid_device *new_hid_device(void) @@ -485,6 +489,7 @@ static int init_hid_manager(void) int HID_API_EXPORT hid_init(void) { if (!hid_mgr) { + is_macos_10_10_or_greater = (NSAppKitVersionNumber >= 1343); /* NSAppKitVersionNumber10_10 */ return init_hid_manager(); } @@ -1138,8 +1143,10 @@ void HID_API_EXPORT hid_close(hid_device *dev) if (!dev) return; - /* Disconnect the report callback before close. */ - if (!dev->disconnected) { + /* Disconnect the report callback before close. + See comment below. + */ + if (is_macos_10_10_or_greater || !dev->disconnected) { IOHIDDeviceRegisterInputReportCallback( dev->device_handle, dev->input_report_buf, dev->max_input_report_len, NULL, dev); @@ -1162,8 +1169,14 @@ void HID_API_EXPORT hid_close(hid_device *dev) /* Close the OS handle to the device, but only if it's not been unplugged. If it's been unplugged, then calling - IOHIDDeviceClose() will crash. */ - if (!dev->disconnected) { + IOHIDDeviceClose() will crash. + + UPD: The crash part was true in/until some version of macOS. + Starting with macOS 10.15, there is an opposite effect in some environments: + crash happenes if IOHIDDeviceClose() is not called. + Not leaking a resource in all tested environments. + */ + if (is_macos_10_10_or_greater || !dev->disconnected) { IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone); }