OpenLogi
功能(Features)

0x2111 · smartShiftEnhanced

增强版 SmartShift——读取或写入当代 MX 系列鼠标的滚轮模式、自动脱开速度阈值与可调棘轮扭矩。

SmartShift Enhanced 滚轮功能,MX Master 3 / 3S / 4 及大多数当代 MX 系列鼠标上的变体,也是 OpenLogi 的 SmartShift 面板与 ToggleSmartShift 动作实际驱动的那个。getStatus(function 1)读取滚轮模式、自动脱开阈值与可调扭矩值;setStatus(function 2)将它们写回。设备会把这三者持久化在自己的非易失性存储中。

  • wheelMode —— 1 自由滚动(无阻力),2 棘轮(带段落感)。
  • autoDisengage —— 0x010xFE,棘轮模式下滚轮被甩到该速度(以 0.25 转/秒为步进)之上时会脱开进入自由滚动,即 SmartShift 阈值。0xFF 表示永久保持棘轮咬合。
  • 可调扭矩 —— 棘轮阻力,以设备最大值的百分比表示,不支持时为 0;会被读取并原样回写,使得调整模式或阈值时不扰动它。

原始的 0x2110 smartShift 使用不同的函数表——vendored 的 hidpp 库实现的是那个——但 OpenLogi 驱动的是增强版 0x2111 变体。

规格: Logitech HID++ 2.0 —— x2111 smartShift Enhanced用于: SmartShift 面板、ToggleSmartShift

Function reference

The SmartShiftEnhancedFeature wrapper (0x2111) exposes:

Methods

FunctionHID++ fnSignatureReturns
get_capabilities0()SmartShiftEnhancedInfo
get_ratchet_control_mode1()SmartShiftEnhancedStatus
set_ratchet_control_mode2(change: SmartShiftEnhancedStatusChange)SmartShiftEnhancedStatus

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

Types

SmartShiftEnhancedInfo

Capability and default values for enhanced SmartShift.

FieldTypeDescription
capabilitiesSmartShiftEnhancedCapabilitiesSupported capabilities.
auto_disengage_defaultu8Default automatic disengage threshold.
default_tunable_torqueu8Default tunable torque, as a percentage of maximum force.
max_forceu8Maximum force in gram-force units.

SmartShiftEnhancedStatus

Current enhanced SmartShift status.

FieldTypeDescription
wheel_modeWheelModeCurrent requested wheel mode.
auto_disengageu8Automatic disengage threshold.
current_tunable_torqueu8Current tunable torque, as a percentage of maximum force.

SmartShiftEnhancedStatusChange

Enhanced SmartShift status update. None fields are encoded as 0 ("do not change") on the wire.

FieldTypeDescription
wheel_modeOption<WheelMode>Wheel mode to apply, or None to leave unchanged.
auto_disengageOption<NonZeroU8>Automatic disengage threshold, or None to leave unchanged. HID++ encodes 0 as "do not change", so writable values must be non-zero.
tunable_torqueOption<NonZeroU8>Tunable torque, or None to leave unchanged. HID++ encodes 0 as "do not change", so writable values must be non-zero.

SmartShiftEnhancedCapabilities

Capabilities reported by SmartShiftWheelEnhanced.

FlagBit/ValueDescription
TUNABLE_TORQUEbit 0The device supports tunable ratchet torque.

WheelMode

Represents the ratchet mode of the scroll wheel (re-exported from 0x2110).

VariantValueDescription
Freespin1Free-spin wheel mode.
Ratchet2Ratchet wheel mode.

Wire format

All three functions use a 3-byte request payload and return a 16-byte long-message response. Fields absent from a set call are encoded as 0 (the documented "do not change" sentinel).

get_capabilities (fn 0)

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

Response (byte → field):

ByteFieldNotes
0capabilitiesBitfield — bit 0 = TUNABLE_TORQUE
1auto_disengage_defaultDefault auto-disengage threshold
2default_tunable_torqueDefault torque as % of max force
3max_forceMaximum force in gram-force units

get_ratchet_control_mode (fn 1)

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

Response (byte → field):

ByteFieldNotes
0wheel_mode1 = Freespin, 2 = Ratchet; unknown values fall back to Ratchet
1auto_disengageCurrent threshold (0x010xFE; 0xFF = always ratchet)
2current_tunable_torqueCurrent torque as % of max force

set_ratchet_control_mode (fn 2)

Request: [wheel_mode, auto_disengage, tunable_torque]

ByteSourceNotes
0change.wheel_mode as u80 = do not change, 1 = Freespin, 2 = Ratchet
1change.auto_disengage as u80 = do not change (NonZeroU8 enforces this)
2change.tunable_torque as u80 = do not change (NonZeroU8 enforces this)

Response layout is identical to get_ratchet_control_mode — the device echoes back the resulting state.

Usage (Rust)

use hidpp::{
    device::Device,
    feature::smartshift_enhanced::{SmartShiftEnhancedFeature, SmartShiftEnhancedStatusChange},
    feature::smartshift::WheelMode,
};
use std::num::NonZeroU8;

// device: &mut Device, already created via Device::new(channel, index)
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<SmartShiftEnhancedFeature>() {
    let info = feat.get_capabilities().await?;
    println!("max force: {}gf, default threshold: {}", info.max_force, info.auto_disengage_default);

    let status = feat.get_ratchet_control_mode().await?;
    println!("wheel mode: {:?}, threshold: {}", status.wheel_mode, status.auto_disengage);

    // Switch to ratchet and raise the auto-disengage threshold to 50
    let updated = feat.set_ratchet_control_mode(SmartShiftEnhancedStatusChange {
        wheel_mode: Some(WheelMode::Ratchet),
        auto_disengage: NonZeroU8::new(50),
        tunable_torque: None, // leave unchanged
    }).await?;
    println!("new threshold: {}", updated.auto_disengage);
}

本页目录