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 ——
0x01–0xFE,棘轮模式下滚轮被甩到该速度(以 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
| Function | HID++ fn | Signature | Returns |
|---|---|---|---|
get_capabilities | 0 | () | SmartShiftEnhancedInfo |
get_ratchet_control_mode | 1 | () | SmartShiftEnhancedStatus |
set_ratchet_control_mode | 2 | (change: SmartShiftEnhancedStatusChange) | SmartShiftEnhancedStatus |
All methods are async and return Result<…, Hidpp20Error>.
Types
SmartShiftEnhancedInfo
Capability and default values for enhanced SmartShift.
| Field | Type | Description |
|---|---|---|
capabilities | SmartShiftEnhancedCapabilities | Supported capabilities. |
auto_disengage_default | u8 | Default automatic disengage threshold. |
default_tunable_torque | u8 | Default tunable torque, as a percentage of maximum force. |
max_force | u8 | Maximum force in gram-force units. |
SmartShiftEnhancedStatus
Current enhanced SmartShift status.
| Field | Type | Description |
|---|---|---|
wheel_mode | WheelMode | Current requested wheel mode. |
auto_disengage | u8 | Automatic disengage threshold. |
current_tunable_torque | u8 | Current 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.
| Field | Type | Description |
|---|---|---|
wheel_mode | Option<WheelMode> | Wheel mode to apply, or None to leave unchanged. |
auto_disengage | Option<NonZeroU8> | Automatic disengage threshold, or None to leave unchanged. HID++ encodes 0 as "do not change", so writable values must be non-zero. |
tunable_torque | Option<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.
| Flag | Bit/Value | Description |
|---|---|---|
TUNABLE_TORQUE | bit 0 | The device supports tunable ratchet torque. |
WheelMode
Represents the ratchet mode of the scroll wheel (re-exported from 0x2110).
| Variant | Value | Description |
|---|---|---|
Freespin | 1 | Free-spin wheel mode. |
Ratchet | 2 | Ratchet 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):
| Byte | Field | Notes |
|---|---|---|
| 0 | capabilities | Bitfield — bit 0 = TUNABLE_TORQUE |
| 1 | auto_disengage_default | Default auto-disengage threshold |
| 2 | default_tunable_torque | Default torque as % of max force |
| 3 | max_force | Maximum force in gram-force units |
get_ratchet_control_mode (fn 1)
Request: [0x00, 0x00, 0x00] (no parameters)
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 | wheel_mode | 1 = Freespin, 2 = Ratchet; unknown values fall back to Ratchet |
| 1 | auto_disengage | Current threshold (0x01–0xFE; 0xFF = always ratchet) |
| 2 | current_tunable_torque | Current torque as % of max force |
set_ratchet_control_mode (fn 2)
Request: [wheel_mode, auto_disengage, tunable_torque]
| Byte | Source | Notes |
|---|---|---|
| 0 | change.wheel_mode as u8 | 0 = do not change, 1 = Freespin, 2 = Ratchet |
| 1 | change.auto_disengage as u8 | 0 = do not change (NonZeroU8 enforces this) |
| 2 | change.tunable_torque as u8 | 0 = 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);
}