OpenLogi

0x2110 · smartShift

Read or write the scroll wheel mode (free-spin or ratchet) and the speed threshold at which the wheel automatically disengages into free-spin.

The original smartShift scroll-wheel feature. getRatchetControlMode (function 0) reads the current wheel mode, the auto-disengage speed threshold, and its factory default; setRatchetControlMode (function 1) writes them back. Fields passed as None (or 0 for the byte values) are left unchanged by the device.

  • wheelModeFreespin (1) or Ratchet (2); reflects the software-set or button-set mode, not the transient auto-disengage state.
  • autoDisengage0x010xFE, quarter-turns per second at which a ratchet-mode wheel releases into free-spin; 0xFF keeps the ratchet permanently engaged.
  • autoDisengageDefault — the factory-default threshold stored alongside the active value.

Note: OpenLogi's SmartShift panel and ToggleSmartShift action drive the newer 0x2111 smartShiftEnhanced variant instead.

Spec: Logitech HID++ 2.0 — smartShift. Used by: Typed wrapper in openlogi-hidpp.

Function reference

The SmartShiftFeature wrapper (0x2110) exposes:

Methods

FunctionHID++ fnSignatureReturns
get_ratchet_control_mode0()RatchetControlMode
set_ratchet_control_mode1(wheel_mode: Option<WheelMode>, auto_disengage: Option<u8>, auto_disengage_default: Option<u8>)()

All methods are async and return Result<…, Hidpp20Error>.

Types

RatchetControlMode

Represents the ratchet control mode of the mouse wheel.

FieldTypeDescription
wheel_modeWheelModeThe mode the wheel is currently set to. Does not reflect the transient auto-disengage state.
auto_disengageu8Quarter-turns per second at which the wheel automatically disengages. 0xff disables automatic disengagement (permanent ratchet).
auto_disengage_defaultu8The factory-default value of auto_disengage.

WheelMode

Represents the ratchet mode of the scroll wheel.

VariantValueDescription
Freespin1Free-spin wheel mode.
Ratchet2Ratchet wheel mode.

Wire format

Both functions send a 3-byte short-report request payload. The response is accessed via extend_payload(), which always returns a 16-byte array (zero-padded from a short response); only bytes 0–2 carry meaningful data for get_ratchet_control_mode.

get_ratchet_control_mode (fn 0)

Request: [0x00, 0x00, 0x00] — no parameters; all bytes are zero.

Response (byte → field):

ByteFieldNotes
0wheel_modeWheelMode enum: 1 = Freespin, 2 = Ratchet
1auto_disengageQuarter-turns/s threshold; 0xFF = permanent ratchet
2auto_disengage_defaultFactory-default value of auto_disengage

set_ratchet_control_mode (fn 1)

Request: [wheel_mode_byte, auto_disengage_byte, auto_disengage_default_byte]

ByteSourceNotes
0wheel_mode.map_or(0, u8::from)0 = leave unchanged; 1 = Freespin, 2 = Ratchet
1auto_disengage.unwrap_or(0)0 = leave unchanged; 0x010xFE = threshold; 0xFF = permanent
2auto_disengage_default.unwrap_or(0)0 = leave unchanged; same range as byte 1

Response: not used (the device echoes the written values but the wrapper discards them).

Usage (Rust)

use hidpp::{device::Device, feature::smartshift::SmartShiftFeature};

// device: &mut Device, already created via Device::new(channel, index)
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<SmartShiftFeature>() {
    // Read current mode
    let mode = feat.get_ratchet_control_mode().await?;
    println!("wheel_mode={:?}, auto_disengage={}", mode.wheel_mode, mode.auto_disengage);

    // Switch to free-spin, keep the auto_disengage threshold unchanged
    feat.set_ratchet_control_mode(
        Some(hidpp::feature::smartshift::WheelMode::Freespin),
        None,
        None,
    ).await?;
}

On this page