Fix hotplugging in Logitech HID++ by using a lambda callback to un-list used IDs

This commit is contained in:
Dmitry Kychanov
2026-09-01 22:30:23 -05:00
committed by Adam Honse
parent eb535f43c8
commit 8f701ee147
3 changed files with 23 additions and 5 deletions
@@ -824,6 +824,16 @@ static bool HIDPP20ClaimDevice(const std::string& device_id)
return hidpp20_claimed_devices.insert(device_id).second;
}
/*---------------------------------------------------------*\
| Free the device claim when the device is unplugged |
\*---------------------------------------------------------*/
static bool HIDPP20UnclaimDevice(const std::string& device_id)
{
std::lock_guard<std::mutex> lock(hidpp20_registry_mutex);
return hidpp20_claimed_devices.erase(device_id);
}
/*---------------------------------------------------------*\
| Watchers own threads and a node handle, so they have to |
| be stopped before the process exits. |
@@ -1206,7 +1216,7 @@ static bool HIDPP20LookupTarget(const std::string& node_path, uint8_t index, HID
| lighting; both leave the target on file, so a device |
| that was asleep is built when its dongle reports it. |
\*---------------------------------------------------------*/
static RGBController_LogitechHIDPP20* HIDPP20BuildController(const HIDPP20BuildTarget& target)
static RGBController_LogitechHIDPP20* HIDPP20BuildController(const HIDPP20BuildTarget& target, const std::string& device_id="")
{
HIDPP20BuildClaim claim(target.node_path, target.index);
@@ -1292,7 +1302,7 @@ static RGBController_LogitechHIDPP20* HIDPP20BuildController(const HIDPP20BuildT
{
controller->Initialize();
RGBController_LogitechHIDPP20* rgb_controller = new RGBController_LogitechHIDPP20(controller);
RGBController_LogitechHIDPP20* rgb_controller = new RGBController_LogitechHIDPP20(controller, [device_id](){HIDPP20UnclaimDevice(device_id);});
/*-------------------------------------------------*\
| Reader and power threads from the start, so we |
@@ -1395,7 +1405,7 @@ static DetectedControllers HIDPP20Create(hid_device_info* info, const std::strin
HIDPP20RecordTarget(target);
RGBController_LogitechHIDPP20* rgb_controller = HIDPP20BuildController(target);
RGBController_LogitechHIDPP20* rgb_controller = HIDPP20BuildController(target, device_id);
if(rgb_controller != nullptr)
{
@@ -856,9 +856,10 @@ static const Kb8080Strip* FindKb8080Strip(uint16_t pid_wired, uint16_t pid_wirel
return(nullptr);
}
RGBController_LogitechHIDPP20::RGBController_LogitechHIDPP20(LogitechHIDPP20Controller* controller_ptr)
RGBController_LogitechHIDPP20::RGBController_LogitechHIDPP20(LogitechHIDPP20Controller* controller_ptr, std::function<void ()> callback)
{
controller = controller_ptr;
shutdown_callback = callback;
const HIDPP20DeviceCapabilities& caps = controller->GetCapabilities();
@@ -1367,6 +1368,11 @@ RGBController_LogitechHIDPP20::~RGBController_LogitechHIDPP20()
{
controller->StopPowerManager();
if(shutdown_callback)
{
shutdown_callback();
}
Shutdown();
delete controller;
@@ -15,7 +15,7 @@
class RGBController_LogitechHIDPP20 : public RGBController
{
public:
RGBController_LogitechHIDPP20(LogitechHIDPP20Controller* controller_ptr);
RGBController_LogitechHIDPP20(LogitechHIDPP20Controller* controller_ptr, std::function<void()> shutdown_callback);
~RGBController_LogitechHIDPP20();
void SetupZones();
@@ -116,4 +116,6 @@ private:
| Parallel to led_to_zone_id; 0x8080 path only. |
\*-----------------------------------------------------*/
std::vector<std::pair<uint16_t, uint8_t>> led_to_keytype_keyid_8080;
std::function<void()> shutdown_callback;
};