MX Master 4 on Logi Bolt fails to initialize on boot with default 500 ms io_timeout
Summary
The Logitech MX Master 4 connected through a Logi Bolt receiver may fail to initialize in logid during boot when using the default io_timeout of 500 ms.
The mouse itself remains fully usable as a normal pointer device, but logid does not initialize it, so configured functionality such as gestures, remapped buttons, SmartShift and thumb-wheel actions is unavailable.
Increasing the global io_timeout from the default 500 ms to 3000 ms completely resolves the issue on my system.
This appears to be closely related to #463, which describes similar initialization problems with an MX Master 3S connected through Logi Bolt.
Environment
Operating system
openSUSE Tumbleweed
logiops version
Current main at the time of testing:
Verified both in the source tree and with the installed binary:
$ git describe --always --tags
v0.3.5-7-ge157995
$ logid --version
v0.3.5-7-ge157995
Current commit:
e157995 Merge pull request #502 from LucasDondo/patch-1
The installed /usr/bin/logid was built from this same source revision.
Hardware
- Logitech MX Master 4
- Logitech MX Keys S
- Logitech Logi Bolt Receiver
- Both devices paired to the same Bolt receiver
Receiver USB ID:
$ lsusb | grep -i logitech
Bus 003 Device 005: ID 046d:c548 Logitech, Inc. Logi Bolt Receiver
The receiver is detected as:
Configuration
The relevant device configuration is an MX Master 4 configuration using several HID++ features, including:
- DPI configuration
- SmartShift
- thumb wheel diversion
- remappable buttons
- gestures
For example:
devices: ({
name: "MX Master 4";
dpi: 1200;
smartshift: {
on: true;
threshold: 30;
};
hiresscroll: {
hires: false;
};
...
});
Without changing the global timeout, this configuration works correctly whenever the mouse is successfully initialized.
Problem after boot
After boot, the logid service starts normally and detects the Bolt receiver.
However, it may only initialize the MX Keys S:
Aug 07 08:15:39 systemd[1]: Started Logitech Configuration Daemon.
Aug 07 08:15:39 logid[1680]: [INFO] Detected receiver at /dev/hidraw3
Aug 07 08:15:40 logid[1680]: [INFO] Device found: MX Keys S on /dev/hidraw3:3
There is no corresponding:
Device found: MX Master 4
The important detail is that the MX Master 4 itself still works normally as a mouse.
Pointer movement, clicking and normal scrolling work.
However, none of the logid functionality configured for the mouse works:
- gestures do not work
- remapped buttons do not work
- configured SmartShift actions do not work
- configured thumb-wheel actions do not work
So this does not appear to be a USB input or Bolt connectivity failure in general. It specifically appears to affect HID++ initialization by logid.
libinput behaviour
The mouse is visible to libinput through the Bolt receiver even while logid has failed to initialize it.
For example:
-event0 DEVICE_ADDED Logitech USB Receiver
-event1 DEVICE_ADDED Logitech USB Receiver Mouse
-event2 DEVICE_ADDED Logitech USB Receiver Consumer Control
-event3 DEVICE_ADDED Logitech USB Receiver System Control
-event6 DEVICE_ADDED Logitech USB Receiver
-event21 DEVICE_ADDED LogiOps Virtual Input
Moving the MX Master 4 generates normal pointer events:
event1 POINTER_MOTION ...
event1 POINTER_MOTION ...
event1 POINTER_MOTION ...
This confirms that the mouse and receiver are operational even when the HID++ initialization performed by logid has failed.
Debug output
Stopping the service and running logid manually in verbose mode:
sudo systemctl stop logid
sudo logid -v
initially produces:
[DEBUG] Unsupported device /dev/hidraw0 ignored
[DEBUG] Unsupported device /dev/hidraw1 ignored
[DEBUG] Unsupported device /dev/hidraw2 ignored
[INFO] Detected receiver at /dev/hidraw3
[DEBUG] Unsupported device /dev/hidraw4 ignored
[DEBUG] /dev/hidraw3:2 timed out, waiting for input from device to initialize.
[DEBUG] /dev/hidraw3:3 timed out, waiting for input from device to initialize.
At this point the MX Master 4 is still usable as a normal mouse, but it is not initialized by logiops.
Reconnect behaviour
Changing the Easy-Switch channel on the MX Master 4 and switching back immediately causes logid to recognize the mouse:
[INFO] Device found: MX Master 4 on /dev/hidraw3:2
It then correctly enumerates its HID++ capabilities:
[DEBUG] /dev/hidraw3:2 remappable buttons:
[DEBUG] CID | reprog? | fn key? | mouse key? | gesture support?
[DEBUG] 0x50 | | | YES |
[DEBUG] 0x51 | | | YES |
[DEBUG] 0x52 | YES | | YES | YES
[DEBUG] 0x53 | YES | | YES | YES
[DEBUG] 0x56 | YES | | YES | YES
[DEBUG] 0xc3 | YES | | YES | YES
[DEBUG] 0xc4 | YES | | YES | YES
[DEBUG] 0xd7 | YES | | | YES
[DEBUG] 0x1a0| YES | | YES | YES
The thumb wheel is also detected correctly:
[DEBUG] Thumb wheel detected (0x2150), capabilities:
[DEBUG] timestamp | touch | proximity | single tap
[DEBUG] YES | YES | NO | NO
[DEBUG] Thumb wheel resolution: native (20), diverted (120)
After that, all configured gestures and button actions work immediately.
Physically disconnecting and reconnecting the Bolt receiver also causes both devices to initialize correctly:
[INFO] Receiver on /dev/hidraw3 disconnected
[INFO] Detected receiver at /dev/hidraw3
[INFO] Device found: MX Master 4 on /dev/hidraw3:2
[INFO] Device found: MX Keys S on /dev/hidraw3:3
Restarting logid alone is not a reliable workaround
Restarting the service does not necessarily solve the problem:
sudo systemctl restart logid
The receiver may again be detected while only the keyboard is initialized.
A real reconnect / wake-up event from the mouse reliably causes initialization.
This initially made the problem look like a Bolt reconnect issue.
Source-code investigation
The default timeout is defined in:
src/logid/Configuration.h
as:
static constexpr double io_timeout = 500;
When initialization times out, Receiver.cpp catches the TimeoutError:
} catch (TimeoutError& e) {
if (!event.fromTimeoutCheck)
logPrintf(DEBUG, "%s:%d timed out, waiting for input from device to"
" initialize.", _path.c_str(), event.index);
waitForDevice(event.index);
}
So after the first initialization attempt times out, logiops calls:
waitForDevice(event.index);
Looking at ReceiverMonitor::waitForDevice():
void ReceiverMonitor::waitForDevice(hidpp::DeviceIndex index) {
const std::lock_guard lock(_wait_mutex);
if (!_waiters.count(index)) {
_waiters.emplace(index, _receiver->rawDevice()->addEventHandler(
{[index](const std::vector<uint8_t>& report) -> bool {
/* Connection events should be handled by connect_ev_handler */
auto sub_id = report[Offset::SubID];
return report[Offset::DeviceIndex] == index &&
sub_id != Receiver::DeviceConnection &&
sub_id != Receiver::DeviceDisconnection;
},
[self_weak = _self, index](
[[maybe_unused]] const std::vector<uint8_t>& report) {
hidpp::DeviceConnectionEvent event{};
event.withPayload = false;
event.linkEstablished = true;
event.index = index;
event.fromTimeoutCheck = true;
run_task([self_weak, event]() {
if (auto self = self_weak.lock())
self->_addHandler(event);
});
}
}));
}
}
My understanding is therefore:
- Receiver enumeration discovers the device.
- Initial HID++ communication with the MX Master 4 does not complete within 500 ms.
- A
TimeoutError occurs.
logid switches to waitForDevice().
- Normal pointer movement continues to work via the standard receiver mouse interface.
- That pointer activity apparently does not produce the HID++ report required by the waiter.
- A real reconnect / Easy-Switch event causes sufficient HID++ activity.
_addHandler() is executed again and initialization succeeds.
Workaround / fix
The configuration schema supports a global io_timeout:
std::optional<double> io_timeout;
Setting:
before the devices section completely resolves the problem:
io_timeout: 3000.0;
devices: ({
name: "MX Master 4";
...
});
With this configuration, after restarting logid:
Aug 07 08:38:27 systemd[1]: Started Logitech Configuration Daemon.
Aug 07 08:38:27 logid[26035]: [INFO] Detected receiver at /dev/hidraw3
Aug 07 08:38:29 logid[26035]: [INFO] Device found: MX Master 4 on /dev/hidraw3:2
Aug 07 08:38:30 logid[26035]: [INFO] Device found: MX Keys S on /dev/hidraw3:3
Most importantly, this also works after an actual reboot.
The MX Master 4 is initialized automatically and all configured gestures work immediately without:
- moving the mouse during daemon startup
- switching Easy-Switch channels
- power cycling the mouse
- unplugging the Bolt receiver
- manually restarting
logid
Result
Default configuration
Result:
Bolt receiver detected
MX Keys S detected
MX Master 4 sometimes times out
MX Master 4 logiops configuration not active
Increased timeout
Result:
Bolt receiver detected
MX Master 4 detected
MX Keys S detected
All MX Master 4 logiops functionality active
This has been reproducible on my system.
Possible causes / potential solutions
Based on the above testing, it appears that 500 ms may simply be too short for some Bolt-connected devices to answer the initial HID++ requests, especially during system startup.
Potential solutions might be:
-
Increase the default io_timeout.
For example, raising it from 500 ms to something in the 2000–3000 ms range.
-
Retry device initialization after a timeout.
Instead of immediately relying entirely on waitForDevice(), retry the initial HID++ communication a small number of times.
For example:
initial attempt
↓ timeout
wait briefly
↓
retry
↓ timeout
wait briefly
↓
retry
↓
fall back to waitForDevice()
This may avoid increasing the timeout globally for every HID++ operation.
-
Use a larger timeout specifically during receiver/device initialization.
The normal 500 ms timeout might still be desirable for regular communication after the device has been initialized.
-
Improve the waitForDevice() retry trigger.
The MX Master 4 remains fully functional as a pointer while waitForDevice() is active, but ordinary mouse activity apparently does not trigger the HID++ event needed to retry initialization.
A short initialization-specific retry mechanism may therefore be preferable to simply increasing every I/O timeout.
Related issue
This looks very similar to #463 ("MX Master 3S with Bolt not detected").
That issue describes an MX Master 3S connected through Bolt which is not reliably detected at startup and can be recovered by mouse activity / power cycling.
Later comments in #463 also report successful workarounds using an increased global io_timeout.
The MX Master 4 appears to exhibit the same underlying behaviour.
The additional observations here are:
- reproduced with an MX Master 4
- reproduced on current
main (v0.3.5-7-ge157995)
- default 500 ms timeout confirmed in the current source
- timeout path traced through
Receiver.cpp and ReceiverMonitor::waitForDevice()
- 3000 ms is sufficient on this system
- verified after a full reboot
- no receiver reconnect or mouse power cycle is required with the increased timeout
I'm happy to provide additional verbose logs, test patches or test an initialization/retry change on the MX Master 4 + Bolt setup if useful.
MX Master 4 on Logi Bolt fails to initialize on boot with default 500 ms
io_timeoutSummary
The Logitech MX Master 4 connected through a Logi Bolt receiver may fail to initialize in
logidduring boot when using the defaultio_timeoutof 500 ms.The mouse itself remains fully usable as a normal pointer device, but
logiddoes not initialize it, so configured functionality such as gestures, remapped buttons, SmartShift and thumb-wheel actions is unavailable.Increasing the global
io_timeoutfrom the default 500 ms to 3000 ms completely resolves the issue on my system.This appears to be closely related to #463, which describes similar initialization problems with an MX Master 3S connected through Logi Bolt.
Environment
Operating system
openSUSE Tumbleweed
logiops version
Current
mainat the time of testing:Verified both in the source tree and with the installed binary:
Current commit:
The installed
/usr/bin/logidwas built from this same source revision.Hardware
Receiver USB ID:
The receiver is detected as:
Configuration
The relevant device configuration is an MX Master 4 configuration using several HID++ features, including:
For example:
devices: ({ name: "MX Master 4"; dpi: 1200; smartshift: { on: true; threshold: 30; }; hiresscroll: { hires: false; }; ... });Without changing the global timeout, this configuration works correctly whenever the mouse is successfully initialized.
Problem after boot
After boot, the
logidservice starts normally and detects the Bolt receiver.However, it may only initialize the MX Keys S:
There is no corresponding:
The important detail is that the MX Master 4 itself still works normally as a mouse.
Pointer movement, clicking and normal scrolling work.
However, none of the
logidfunctionality configured for the mouse works:So this does not appear to be a USB input or Bolt connectivity failure in general. It specifically appears to affect HID++ initialization by
logid.libinput behaviour
The mouse is visible to libinput through the Bolt receiver even while
logidhas failed to initialize it.For example:
Moving the MX Master 4 generates normal pointer events:
This confirms that the mouse and receiver are operational even when the HID++ initialization performed by
logidhas failed.Debug output
Stopping the service and running
logidmanually in verbose mode:initially produces:
At this point the MX Master 4 is still usable as a normal mouse, but it is not initialized by logiops.
Reconnect behaviour
Changing the Easy-Switch channel on the MX Master 4 and switching back immediately causes
logidto recognize the mouse:It then correctly enumerates its HID++ capabilities:
The thumb wheel is also detected correctly:
After that, all configured gestures and button actions work immediately.
Physically disconnecting and reconnecting the Bolt receiver also causes both devices to initialize correctly:
Restarting
logidalone is not a reliable workaroundRestarting the service does not necessarily solve the problem:
sudo systemctl restart logidThe receiver may again be detected while only the keyboard is initialized.
A real reconnect / wake-up event from the mouse reliably causes initialization.
This initially made the problem look like a Bolt reconnect issue.
Source-code investigation
The default timeout is defined in:
as:
When initialization times out,
Receiver.cppcatches theTimeoutError:So after the first initialization attempt times out, logiops calls:
waitForDevice(event.index);Looking at
ReceiverMonitor::waitForDevice():My understanding is therefore:
TimeoutErroroccurs.logidswitches towaitForDevice()._addHandler()is executed again and initialization succeeds.Workaround / fix
The configuration schema supports a global
io_timeout:std::optional<double> io_timeout;Setting:
io_timeout: 3000.0;before the
devicessection completely resolves the problem:With this configuration, after restarting
logid:Most importantly, this also works after an actual reboot.
The MX Master 4 is initialized automatically and all configured gestures work immediately without:
logidResult
Default configuration
Result:
Increased timeout
io_timeout: 3000.0;Result:
This has been reproducible on my system.
Possible causes / potential solutions
Based on the above testing, it appears that 500 ms may simply be too short for some Bolt-connected devices to answer the initial HID++ requests, especially during system startup.
Potential solutions might be:
Increase the default
io_timeout.For example, raising it from 500 ms to something in the 2000–3000 ms range.
Retry device initialization after a timeout.
Instead of immediately relying entirely on
waitForDevice(), retry the initial HID++ communication a small number of times.For example:
This may avoid increasing the timeout globally for every HID++ operation.
Use a larger timeout specifically during receiver/device initialization.
The normal 500 ms timeout might still be desirable for regular communication after the device has been initialized.
Improve the
waitForDevice()retry trigger.The MX Master 4 remains fully functional as a pointer while
waitForDevice()is active, but ordinary mouse activity apparently does not trigger the HID++ event needed to retry initialization.A short initialization-specific retry mechanism may therefore be preferable to simply increasing every I/O timeout.
Related issue
This looks very similar to #463 ("MX Master 3S with Bolt not detected").
That issue describes an MX Master 3S connected through Bolt which is not reliably detected at startup and can be recovered by mouse activity / power cycling.
Later comments in #463 also report successful workarounds using an increased global
io_timeout.The MX Master 4 appears to exhibit the same underlying behaviour.
The additional observations here are:
main(v0.3.5-7-ge157995)Receiver.cppandReceiverMonitor::waitForDevice()I'm happy to provide additional verbose logs, test patches or test an initialization/retry change on the MX Master 4 + Bolt setup if useful.