What Is SmartShift in OpenLogi and How to Configure It

SmartShift is OpenLogi's implementation of the HID++ 0x2110 feature that controls your mouse scroll-wheel behavior, allowing you to switch between free-spin and ratchet modes with configurable auto-disengage timeouts.

SmartShift in OpenLogi gives you low-level control over Logitech SmartShift-enabled mice through the HID++ protocol. This open-source feature, maintained in the AprilNEA/OpenLogi repository, exposes ratchet control parameters that let you define exactly how your scroll wheel behaves across different applications and workflows.

Understanding SmartShift in OpenLogi

What Is SmartShift (HID++ Feature 0x2110)

SmartShift is the OpenLogi implementation of the HID++ SmartShift feature (feature ID 0x2110). It controls the scroll-wheel behavior, letting the wheel operate in either free-spin mode (continuous scrolling) or ratchet mode (click-by-click tactile feedback), with an optional auto-disengage timeout that automatically returns the wheel to free-spin after inactivity.

The feature exposes three core ratchet control parameters:

  • WheelMode (Freespin = 0x01, Ratchet = 0x02): The base operating mode of the wheel.
  • auto_disengage: Number of quarter-turns per second required to automatically leave ratchet mode. Set to 0xff to disable auto-disengage and maintain permanent ratchet.
  • auto_disengage_default: The factory default value for auto-disengage behavior.

Architecture Overview

The SmartShift implementation spans four architectural layers in the OpenLogi codebase:

  1. HID++ Protocol Layer (crates/openlogi-hidpp/src/feature/smartshift.rs): Defines SmartShiftFeature and implements raw HID++ calls.
  2. Device Abstraction Layer (crates/openlogi-device/src/write/smartshift.rs): Provides high-level write helpers for applying settings to connected devices.
  3. Desktop State Layer (crates/openlogi-desktop/src/state/smartshift.rs): Persists current configuration for the UI and session management.
  4. UI Integration Layer (crates/openlogi-desktop/src/features/pointer/smartshift.rs): Connects user interface controls to real-time device updates.

How to Configure SmartShift

TOML Configuration File

Configure SmartShift persistently via the OpenLogi TOML configuration file. Each device supports a [smartshift] table under its receiver/slot entry:

[devices."receiver:aa:bb:cc:dd:slot:1".smartshift]
wheel_mode = "ratchet"          # "freespin" or "ratchet"

auto_disengage = 0x10           # 0x01-0xFE = quarter-turns/sec, 0xFF = permanent ratchet

auto_disengage_default = 0x10   # factory default (optional)

When OpenLogi starts, it reads this table, builds a RatchetControlMode struct, and pushes values to the mouse via the SmartShiftFeature::set_ratchet_control_mode async method.

Programmatic Configuration (Rust)

Query the current SmartShift mode from your Rust application:

use openlogi_hidpp::feature::SmartShiftFeature;

// `feature` is a previously-created SmartShiftFeature instance
let mode = feature.get_ratchet_control_mode().await?;
println!(
    "Wheel: {:?}, auto-disengage: {}, default: {}",
    mode.wheel_mode, mode.auto_disengage, mode.auto_disengage_default
);

Set the wheel to ratchet mode with permanent ratchet (no auto-disengage):

use openlogi_hidpp::feature::SmartShiftFeature;
use openlogi_hidpp::feature::WheelMode;
use std::num::NonZeroU8;

// `feature` is a previously-created SmartShiftFeature instance
feature
    .set_ratchet_control_mode(
        Some(WheelMode::Ratchet),   // wheel mode
        Some(NonZeroU8::new(0xFF).unwrap()), // auto-disengage = permanent ratchet
        None,                       // keep default for the factory value
    )
    .await?;

CLI Configuration

Query current settings via the diagnostic command:

openlogi-cli diag smartshift --device receiver:aabbccdd:slot:1

Set the wheel to free-spin mode with disabled auto-disengage:

openlogi-cli diag smartshift --device receiver:aabbccdd:slot:1 \
    --wheel-mode freespin --auto-disengage 0xFF

Implementation Details

HID++ Feature Layer

The SmartShiftFeature struct in crates/openlogi-hidpp/src/feature/smartshift.rs implements the raw protocol calls. It provides get_ratchet_control_mode() to read current parameters and set_ratchet_control_mode() to write new configurations directly to the device firmware.

Device Write Path

crates/openlogi-device/src/write/smartshift.rs abstracts the low-level HID++ calls into device-specific write operations. This layer handles the async communication pipeline and error translation between the protocol layer and the application state.

Desktop State and UI Integration

crates/openlogi-desktop/src/state/smartshift.rs maintains the RatchetControlMode state for the UI thread, while crates/openlogi-desktop/src/features/pointer/smartshift.rs bridges user interactions to the device layer. Changes made through the UI or CLI propagate immediately through SmartShiftFeature::set_ratchet_control_mode without requiring application restarts.

Summary

  • SmartShift (HID++ feature 0x2110) controls scroll-wheel behavior in OpenLogi-compatible mice.
  • Two modes: Freespin (continuous) and Ratchet (tactile clicks), with optional auto-disengage thresholds.
  • Configuration: Set via TOML config file, Rust API (get_ratchet_control_mode/set_ratchet_control_mode), or CLI (openlogi-cli diag smartshift).
  • Key files: Protocol layer (smartshift.rs), device writer (write/smartshift.rs), desktop state (state/smartshift.rs), and CLI diagnostic (cmd/diag/smartshift.rs).
  • Auto-disengage: Values 0x01-0xFE specify quarter-turns per second to exit ratchet; 0xFF disables auto-disengage permanently.

Frequently Asked Questions

What mice support SmartShift configuration in OpenLogi?

SmartShift targets HID++ devices exposing feature ID 0x2110. The OpenLogi implementation is hardware-agnostic at the protocol layer, but your physical mouse must natively support Logitech's SmartShift mechanism for the settings to affect scroll-wheel behavior.

What are valid values for the auto_disengage parameter?

The auto_disengage parameter accepts hexadecimal values 0x01 through 0xFE to define the quarter-turns per second threshold required to automatically exit ratchet mode. Setting this to 0xFF disables auto-disengage entirely, maintaining permanent ratchet mode regardless of scroll velocity.

How does OpenLogi persist SmartShift settings between sessions?

OpenLogi persists configuration through the TOML configuration file. The desktop state layer (crates/openlogi-desktop/src/state/smartshift.rs) reads this file at startup and applies the stored RatchetControlMode values to connected devices via SmartShiftFeature::set_ratchet_control_mode.

Can I change SmartShift modes while OpenLogi is running?

Yes. The desktop UI feature layer reacts to configuration changes in real-time. You can modify settings via the CLI (openlogi-cli diag smartshift) or programmatically through the Rust API, and changes propagate immediately to the device without requiring application restarts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →