Skip to content

Hotplug: HID_API_HOTPLUG_ENUMERATE should honour callback return value #793

@Youw

Description

@Youw

Summary

The hotplug callback documentation added in #790 specifies:

Return 0 to keep the callback registered. Return any non-zero value to have HIDAPI deregister the callback; no further events for this handle will be delivered, and the handle is freed as if hid_hotplug_deregister_callback() had been called. This applies to both live events and to the synthetic "arrived" events delivered during registration when HID_API_HOTPLUG_ENUMERATE is set.

The current implementation discards the return value during the synthetic initial-enumeration pass. In `libusb/hid.c` for example: https://github.com/libusb/hidapi/blob/connection-callback/libusb/hid.c#L1393

```c
(*hotplug_cb->callback)(hotplug_cb->handle, device, HID_API_HOTPLUG_EVENT_DEVICE_ARRIVED, hotplug_cb->user_data);
```

— return value is assigned to nothing; the callback cannot self-deregister during initial enumeration.

Why this matters

The natural idiom "find the first device matching this VID/PID, react to it, and stop listening" — `return 1` on match — silently fails when `HID_API_HOTPLUG_ENUMERATE` delivers the first match synchronously during `hid_hotplug_register_callback()`. Users write the obvious thing and get unexpected extra invocations.

Proposed fix

Treat the synthetic arrival events identically to live events: capture the return value, mark the callback for removal if non-zero, and stop delivering further synthetic events for it. All four backends share the same pattern.

Scope

  • `libusb/hid.c`, `linux/hid.c`, `mac/hid.c`, `windows/hid.c`
  • hidtest: consider a test case that self-deregisters from an ENUMERATE event.

Related


Drafted with Claude Code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    hotplugRelated to hotplug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions