0x6501 · gestures2
The legacy gesture-descriptor table — how OpenLogi finds and diverts the MX Master 2S thumb wheel, which predates the dedicated 0x2150 feature.
0x6501 gestures2 is Logitech's legacy gesture-configuration feature: a device
publishes a descriptor table of gesture ids, each flagged as present, enabled,
and — sometimes — divertable to the host.
OpenLogi implements exactly the slice it needs: the MX Master 2S exposes its
horizontal thumb wheel as gesture id 46 under 0x6501, not through the newer
dedicated 0x2150 thumbwheel feature. The
wrapper walks the descriptor table to find that gesture, works out its diversion
index, and can divert or restore it.
Spec: Logitech HID++ 2.0 — x6501 gestures2 (partial). Used by: thumb wheel capture on legacy MX mice.
Function reference
The Gestures2Feature wrapper (0x6501) exposes:
Methods
| Function | HID++ fn | Signature | Returns |
|---|---|---|---|
thumbwheel | 0 (paged) | () | Option<ThumbwheelGesture> |
has_thumbwheel | 0 (paged) | () | bool |
thumbwheel_diverted | 0, 3 | () | Option<bool> |
set_thumbwheel_diverted | 0, 4 | (diverted: bool) | bool |
All are async and return Result<…, Hidpp20Error>. Merely exposing 0x6501
is not enough to assume a thumb wheel: touchpads and other gesture devices expose
the feature without one, which is why every call starts from the descriptor
table.
Types
ThumbwheelGesture
| Field | Type | Description |
|---|---|---|
diversion_index | Option<u16> | Sequential index among gestures that advertise the divertable bit. None means gesture 46 exists but cannot be diverted. |
Constants
| Name | Value | Description |
|---|---|---|
THUMBWHEEL_GESTURE_ID | 46 | The gestures2 id of the horizontal thumb wheel. |
Wire format
Descriptor scan (fn 0)
Request: [hi, lo, 0x00] — the big-endian index of the first descriptor field
on this page. The response carries up to eight two-byte fields:
| Byte | Meaning |
|---|---|
| high | 0x01 marks the end of the table. Bit 7 set marks a gesture entry; bit 1 marks it divertable. |
| low | The gesture id. |
The walk advances eight fields at a time, counting divertable gestures as it goes: that running count is the diversion index of the next divertable gesture. It stops at the end marker, at gesture 46, or after 1024 fields; the bound stops a malformed table from causing an unbounded probe loop.
Diversion state (fn 3) and write (fn 4)
The diversion bit for index i lives at byte i >> 3, mask 1 << (i & 7):
| Function | Payload | Notes |
|---|---|---|
| 3 (read) | [offset, 0x01, mask] | Response byte 0 AND mask → currently diverted. |
| 4 (write) | [offset, 0x01, mask, value] | value is mask to divert, 0 to restore. Needs a long HID++ report. |
Usage (Rust)
use hidpp::{device::Device, feature::gestures2::Gestures2Feature};
// device: &mut Device, already created via Device::new(channel, index)
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<Gestures2Feature>() {
if feat.has_thumbwheel().await? {
// Divert the wheel to the host; false when it isn't divertable.
let diverted = feat.set_thumbwheel_diverted(true).await?;
println!("thumb wheel diverted: {diverted}");
}
}See also: 0x2150 thumbwheel, 0x6500 gestures1.