# What Is SmartShift in OpenLogi and How to Configure It

> Learn what SmartShift is in OpenLogi and how to configure its HID++ 2110 feature for custom scroll wheel behavior. Optimize your mouse experience today.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: how-to-guide
- Published: 2026-08-29

---

**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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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:

```toml
[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:

```rust
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):

```rust
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:

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

```

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

```bash
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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/state/smartshift.rs) maintains the `RatchetControlMode` state for the UI thread, while [`crates/openlogi-desktop/src/features/pointer/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/smartshift.rs)), device writer ([`write/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/write/smartshift.rs)), desktop state ([`state/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/state/smartshift.rs)), and CLI diagnostic ([`cmd/diag/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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.