OpenLogi

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

FunctionHID++ fnSignatureReturns
thumbwheel0 (paged)()Option<ThumbwheelGesture>
has_thumbwheel0 (paged)()bool
thumbwheel_diverted0, 3()Option<bool>
set_thumbwheel_diverted0, 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

FieldTypeDescription
diversion_indexOption<u16>Sequential index among gestures that advertise the divertable bit. None means gesture 46 exists but cannot be diverted.

Constants

NameValueDescription
THUMBWHEEL_GESTURE_ID46The 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:

ByteMeaning
high0x01 marks the end of the table. Bit 7 set marks a gesture entry; bit 1 marks it divertable.
lowThe 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):

FunctionPayloadNotes
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.

On this page