OpenLogi
Features

0x2150 · thumbwheel

Horizontal thumb-wheel control — query capabilities, divert rotation events from HID to HID++, and read touch and tap status.

The horizontal thumb wheel on MX-line mice. getThumbwheelInfo reports its capabilities (resolution, native vs divertable, default direction); getThumbwheelStatus reads the current reporting mode; setThumbwheelReporting diverts the wheel so its rotation is delivered to OpenLogi as events instead of native scrolling. While diverted, the feature emits status updates carrying the rotation delta plus touch / tap flags.

OpenLogi diverts the thumb wheel to drive horizontal scroll and the ThumbwheelScrollUp / ThumbwheelScrollDown bindings, scaled by the thumb-wheel sensitivity setting.

Spec: Logitech HID++ 2.0 — x2150 thumbwheel. Used by: thumb-wheel bindings.

Function reference

The ThumbwheelFeature wrapper (0x2150) exposes:

Methods

FunctionHID++ fnSignatureReturns
get_thumbwheel_info0()ThumbwheelInfo
get_thumbwheel_status1()ThumbwheelStatus
set_thumbwheel_reporting2(mode: ThumbwheelReportingMode, invert_direction: bool)()
listenevent()async_channel::Receiver<ThumbwheelEvent>

get_thumbwheel_info, get_thumbwheel_status, and set_thumbwheel_reporting are async and return Result<…, Hidpp20Error>. listen is synchronous and returns a receiver directly.

Types

ThumbwheelInfo

Information about the thumbwheel as reported by get_thumbwheel_info.

FieldTypeDescription
native_resolutionu16Number of ratchets generated per revolution in native (HID) mode.
diverted_resolutionu16Number of rotation increments generated per revolution in diverted (HID++) mode.
time_unitu16Timestamp unit in microseconds for ThumbwheelStatusUpdate::time_elapsed. 0 if ThumbwheelCapabilities::time_stamp is not supported.
default_directionThumbwheelDirectionThe default rotation direction.
capabilitiesThumbwheelCapabilitiesThe capabilities of the thumbwheel.

ThumbwheelCapabilities

The capabilities the thumbwheel may support.

FieldTypeDescription
time_stampboolWhether the thumbwheel supports emitting the elapsed time between two events via ThumbwheelStatusUpdate::time_elapsed.
touchboolWhether the thumbwheel is equipped with a touch sensor.
proxyboolWhether the thumbwheel is equipped with a proximity sensor.
single_tapboolWhether the thumbwheel supports detecting single taps.

ThumbwheelDirection

Determines which rotation direction produces a positive value in ThumbwheelStatusUpdate::rotation. Direction descriptors (LeftOrBack, RightOrFront) are specific to device orientation.

VariantValueDescription
PositiveWhenLeftOrBack0Positive rotation means left/back for this device orientation.
PositiveWhenRightOrFront1Positive rotation means right/front for this device orientation.

ThumbwheelStatus

Current thumbwheel status as reported by get_thumbwheel_status.

FieldTypeDescription
reporting_modeThumbwheelReportingModeThe mode how thumbwheel events are reported (native/HID or diverted/HID++).
direction_invertedboolWhether the default direction is inverted.
touchboolWhether the user is currently touching the thumbwheel. Only meaningful if ThumbwheelCapabilities::touch is supported.
proxyboolWhether the user is currently close to the thumbwheel. Only meaningful if ThumbwheelCapabilities::proxy is supported.

ThumbwheelReportingMode

The mode how the thumbwheel reports its events.

VariantValueDescription
Native0Thumbwheel events are reported only to the native HID channel.
Diverted1Thumbwheel events are reported only to the diverted HID++ channel. Required for listen to receive events.

Events

ThumbwheelFeature implements EmittingFeature<ThumbwheelEvent>. Call listen() to obtain an async_channel::Receiver<ThumbwheelEvent>. Events are only delivered when the thumbwheel is in ThumbwheelReportingMode::Diverted.

ThumbwheelEvent

VariantDescription
StatusUpdate(ThumbwheelStatusUpdate)Emitted whenever the thumbwheel status updates. Requires diverted reporting mode.

ThumbwheelStatusUpdate

FieldTypeDescription
rotationi16Rotation delta, relative to ThumbwheelInfo::native_resolution or ThumbwheelInfo::diverted_resolution.
time_elapsedu16Time elapsed since the last event, in units of ThumbwheelInfo::time_unit. 0 if timestamp capability is not supported.
rotation_statusThumbwheelRotationStatusStatus of the current rotation gesture.
touchboolWhether the user is touching the thumbwheel. Only set if ThumbwheelCapabilities::touch is supported.
proxyboolWhether the user is close to the thumbwheel. Only set if ThumbwheelCapabilities::proxy is supported.
single_tapboolWhether the user single-tapped the thumbwheel. Only set if ThumbwheelCapabilities::single_tap is supported.

ThumbwheelRotationStatus

VariantValueDescription
Inactive0The thumbwheel was not rotated.
Start1The thumbwheel rotation was started.
Active2The thumbwheel rotation is ongoing.
Stop3The thumbwheel was released.

Wire format

All three methods use a 3-byte request payload. Getter responses are read from the 16-byte extended payload returned by extend_payload(). The event payload is delivered by the message listener on function sub-id 0.

get_thumbwheel_info (fn 0)

Request: [0x00, 0x00, 0x00] (no parameters)

Response (byte → field):

BytesFieldNotes
0–1native_resolutionBig-endian u16
2–3diverted_resolutionBig-endian u16
4default_directionBit 0 only (& 1); 0 = PositiveWhenLeftOrBack, 1 = PositiveWhenRightOrFront
5capabilitiesBit 0 = time_stamp, bit 1 = touch, bit 2 = proxy, bit 3 = single_tap
6–7time_unitBig-endian u16; 0 when time_stamp capability is absent

get_thumbwheel_status (fn 1)

Request: [0x00, 0x00, 0x00] (no parameters)

Response (byte → field):

ByteFieldNotes
0reporting_mode0 = Native, 1 = Diverted
1flagsBit 0 = direction_inverted, bit 1 = touch, bit 2 = proxy

set_thumbwheel_reporting (fn 2)

Request: [mode, invert, 0x00]

ByteParameterNotes
0modeThumbwheelReportingMode as u8; 0 = Native, 1 = Diverted
1invert_direction1 if inverted, 0 otherwise
2Reserved, always 0x00

Response: ignored (no fields decoded).

StatusUpdate event (fn 0, sub-id 0)

Emitted by the device while in Diverted mode. The listener filters on function sub-id 0 via func.to_lo() != 0.

BytesFieldNotes
0–1rotationBig-endian i16 rotation delta
2–3time_elapsedBig-endian u16; 0 when timestamp capability is absent
4rotation_status0 = Inactive, 1 = Start, 2 = Active, 3 = Stop
5flagsBit 1 = touch, bit 2 = proxy, bit 3 = single_tap

Usage (Rust)

use hidpp::feature::thumbwheel::{ThumbwheelFeature, ThumbwheelReportingMode};

// mut device: Device, already created via Device::new(channel, index)
device.enumerate_features().await?;

if let Some(feat) = device.get_feature::<ThumbwheelFeature>() {
    let info = feat.get_thumbwheel_info().await?;
    println!("native res: {}, diverted res: {}", info.native_resolution, info.diverted_resolution);

    // Divert the thumbwheel so HID++ events are delivered instead of native scrolling.
    feat.set_thumbwheel_reporting(ThumbwheelReportingMode::Diverted, false).await?;

    // Subscribe to rotation events.
    let rx = feat.listen();
    while let Ok(event) = rx.recv().await {
        println!("{event:?}");
    }
}

On this page