Skip to content

Commit

Permalink
Replace IOHIDDeviceRegisterRemovalCallback with IOHIDManagerRegisterD…
Browse files Browse the repository at this point in the history
…eviceRemovalCallback to fix gamepad disconnection callback on macOS Catalina.

(cherry picked from commit 6b23e36)
  • Loading branch information
bruvzg authored and akien-mga committed Mar 6, 2020
1 parent 6752e08 commit 8eb193d
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
20 changes: 13 additions & 7 deletions platform/osx/joypad_osx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,8 @@ void joypad::add_hid_elements(CFArrayRef p_array) {
CFArrayApplyFunction(p_array, range, hid_element_added, this);
}

static void joypad_removed_callback(void *ctx, IOReturn result, void *sender) {
int id = (intptr_t)ctx;
self->_device_removed(id);
static void joypad_removed_callback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject) {
self->_device_removed(res, ioHIDDeviceObject);
}

static void joypad_added_callback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject) {
Expand Down Expand Up @@ -261,16 +260,15 @@ void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
#endif
device_list.push_back(new_joypad);
}
IOHIDDeviceRegisterRemovalCallback(p_device, joypad_removed_callback, (void *)(intptr_t)new_joypad.id);
IOHIDDeviceScheduleWithRunLoop(p_device, CFRunLoopGetCurrent(), GODOT_JOY_LOOP_RUN_MODE);
}

void JoypadOSX::_device_removed(int p_id) {
void JoypadOSX::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) {

int device = get_joy_index(p_id);
int device = get_joy_ref(p_device);
ERR_FAIL_COND(device == -1);

input->joy_connection_changed(p_id, false, "");
input->joy_connection_changed(device_list[device].id, false, "");
device_list.write[device].free();
device_list.remove(device);
}
Expand Down Expand Up @@ -516,6 +514,13 @@ int JoypadOSX::get_joy_index(int p_id) const {
return -1;
}

int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const {
for (int i = 0; i < device_list.size(); i++) {
if (device_list[i].device_ref == p_device) return i;
}
return -1;
}

bool JoypadOSX::have_device(IOHIDDeviceRef p_device) const {
for (int i = 0; i < device_list.size(); i++) {
if (device_list[i].device_ref == p_device) {
Expand Down Expand Up @@ -558,6 +563,7 @@ void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const {

IOHIDManagerSetDeviceMatchingMultiple(hid_manager, p_matching_array);
IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, joypad_added_callback, NULL);
IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, joypad_removed_callback, NULL);
IOHIDManagerScheduleWithRunLoop(hid_manager, runloop, GODOT_JOY_LOOP_RUN_MODE);

while (CFRunLoopRunInMode(GODOT_JOY_LOOP_RUN_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) {
Expand Down
3 changes: 2 additions & 1 deletion platform/osx/joypad_osx.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class JoypadOSX {
bool configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy);

int get_joy_index(int p_id) const;
int get_joy_ref(IOHIDDeviceRef p_device) const;

void poll_joypads() const;
void setup_joypad_objects();
Expand All @@ -115,7 +116,7 @@ class JoypadOSX {
void process_joypads();

void _device_added(IOReturn p_res, IOHIDDeviceRef p_device);
void _device_removed(int p_id);
void _device_removed(IOReturn p_res, IOHIDDeviceRef p_device);

JoypadOSX();
~JoypadOSX();
Expand Down

0 comments on commit 8eb193d

Please sign in to comment.