Skip to content

Architecture

Onboard versus host-side configuration, the HID++ protocol layer, and how OpenLogi shares the device bus with Solaar and fwupd.

Architecture

The decision everything follows from

Logitech devices can be configured two ways, and choosing between them shapes the entire product.

Onboard configuration writes settings into the device's own flash. It survives reboots and works with no software running at all. But you are limited to the actions the firmware already implements, and inexpensive devices expose very little onboard storage.

Host-side interception uses HID++ diversion: the firmware is told to stop emitting a button's normal report and to send a notification instead, and the application then synthesises whatever the user actually mapped. This allows unlimited actions, per-application behaviour, macros and gestures — but it requires a running process, and diversion must be re-applied every time the device reconnects.

OpenLogi does both, and prefers onboard wherever the firmware supports it. A DPI change is written onboard, so it persists with OpenLogi closed. A button mapped to "open Figma" must be host-side, because no firmware has that concept.

The interface tells you which is which, because the difference is visible in behaviour: one survives a reboot without the app, the other does not.

Layers

┌──────────────────────────────────────────────────────────┐
│  Desktop window (Vue 3 + Vite)        user session       │
└───────────────┬──────────────────────────────────────────┘
                │  IPC
┌───────────────┴──────────────────────────────────────────┐
│  device service  ─ hotplug watch, connection state       │
│  button engine   ─ diversion, uinput emission            │
│  profile engine  ─ persistence, per-app switching        │
└───────────────┬──────────────────────────────────────────┘
                │  hidpp
┌───────────────┴──────────────────────────────────────────┐
│  /dev/hidraw*  (uaccess ACL)        /dev/uinput          │
└──────────────────────────────────────────────────────────┘

Nothing above runs as root. See Permissions.

Finding the device

Logitech's HID++ endpoints are located by the shape of the HID report descriptor rather than by matching product ids: the application looks for usage page 0xFF00 with report id 0x10 (7-byte short reports) or 0x11 (20-byte long reports).

This matters because the same physical mouse presents completely different USB identifiers depending on whether it is connected through a Bolt receiver, a Unifying receiver, Lightspeed, Bluetooth, or a cable. Matching on descriptor shape means all five paths resolve through one code path, and hardware released after this was written still works.

Capabilities are discovered, not hard-coded

On connection, the device is asked for its feature table. Panels in the interface appear because the hardware reported the matching feature — never because a model name appeared on a list.

FeatureCapability
0x0003Device information: firmware, serial
0x0005Device name and kind
0x1000Battery status and charging state
0x1001Battery voltage, for older devices
0x1004Unified battery reporting
0x1B04Reprogrammable controls and diversion
0x2201Adjustable DPI

The practical consequence: an unrecognised device is not unsupported. It shows exactly the controls it actually implements.

Sharing the bus

HID++ 2.0 requests carry a 4-bit software id, which the device echoes back in its reply. Several programs can therefore share one device without intercepting each other's responses — a reply is matched to the request that asked for it.

OpenLogi uses a software id distinct from the ones Solaar and fwupd use, so all three can run simultaneously. This is why you do not have to uninstall Solaar to try OpenLogi.

Delivering input

Diverted buttons arrive as 0x1B04 notifications. The button engine maps each to its configured action and emits it through /dev/uinput, a kernel virtual input device.

Working below the display server is what makes one implementation serve both Wayland and X11 — client-side injection such as XTEST does not work on Wayland at all.

Restoring state

A diverted button is completely dead to the desktop: no click reaches any application. Leaving one diverted after exit would look exactly like broken hardware.

OpenLogi therefore un-diverts every control on shutdown, from both a cleanup guard and a signal handler, and re-applies diversion whenever a device reconnects.