How to Set Up SmartShift on Logitech Mice Using OpenLogi
OpenLogi enables SmartShift configuration on Logitech mice by implementing HID++ 2.0 features 0x2110 and 0x2111, allowing you to toggle wheel modes and adjust auto-disengage sensitivity through both Rust APIs and CLI commands.
OpenLogi is an open-source Rust library that provides low-level control over Logitech HID++ 2.0 devices. When you need to set up SmartShift on Logitech mice using OpenLogi, you gain access to automatic wheel-mode switching capabilities that work across both legacy and enhanced hardware implementations.
How SmartShift Works in OpenLogi
SmartShift (the automatic wheel-mode switch between free-spin and ratchet) is implemented through two HID++ 2.0 feature IDs: 0x2110 (legacy) and 0x2111 (enhanced). The library automatically detects which feature your mouse supports and opens the appropriate interface.
The core logic resides in crates/openlogi-device/src/write/smartshift.rs. This module normalizes both feature variants onto the public SmartShiftMode enum and handles the underlying protocol differences transparently. When writing configurations, the code checks for transient errors that can arise from concurrent HID++ traffic and implements automatic retry logic with a short delay.
CLI Configuration Commands
The openlogi CLI provides the diag smartshift subcommand (implemented in crates/openlogi-cli/src/cmd/diag/smartshift.rs) for immediate device configuration without writing code.
Toggle Between Free and Ratchet Modes
To switch the wheel mode and verify the change, run:
openlogi diag smartshift
This reads the current status, flips the mode, writes it back, and restores the original state after verification.
Set Auto-Disengage Sensitivity
To adjust the threshold that triggers automatic mode switching while preserving the current wheel mode:
openlogi diag smartshift --sensitivity 30
Persistent Mode Changes
To toggle the mode and leave it in the new state (useful for visual verification):
openlogi diag smartshift --leave-flipped
Programmatic Control with the Rust API
For integration into applications, the openlogi_hid crate exposes three primary functions that interact with the device route.
Reading Current Status
Use get_smartshift_status to retrieve the current mode, auto-disengage value, and tunable torque data:
use openlogi_hid::get_smartshift_status;
use openlogi_device::DeviceRoute;
// Assume `route` points to the target mouse
let status = get_smartshift_status(&route).await?;
println!("Current mode: {:?}", status.mode);
Toggling SmartShift Modes
The toggle_smartshift function flips between Free and Ratchet modes while preserving sensitivity settings:
use openlogi_hid::{toggle_smartshift, get_smartshift_status};
use openlogi_device::DeviceRoute;
let before = get_smartshift_status(&route).await?;
println!("Current mode: {:?}", before.mode);
let new_mode = toggle_smartshift(&route).await?;
println!("Toggled to: {:?}", new_mode);
let after = get_smartshift_status(&route).await?;
assert_ne!(before.mode, after.mode);
Configuring Sensitivity Values
To set a custom auto-disengage threshold, use set_smartshift_sensitivity with a SmartShiftAutoDisengage value. The value must be non-zero, as 0 is rejected by the device:
use openlogi_hid::{set_smartshift_sensitivity, SmartShiftAutoDisengage};
use openlogi_device::DeviceRoute;
let value = SmartShiftAutoDisengage::from(20u8);
let status = set_smartshift_sensitivity(&route, value).await?;
println!("New sensitivity: {}", status.auto_disengage);
Error Handling and Concurrency Safety
All write operations in smartshift.rs first verify whether the device already matches the desired configuration using status_matches_desired. This prevents unnecessary HID++ transactions.
When the library encounters transient errors from concurrent HID++ traffic (issue #485), it automatically retries once after the TRANSIENT_RETRY_DELAY interval. This makes the operation robust against race conditions with other software accessing the device simultaneously.
Summary
- OpenLogi implements SmartShift through HID++ 2.0 features 0x2110 (legacy) and 0x2111 (enhanced) in
crates/openlogi-device/src/write/smartshift.rs. - The CLI provides
openlogi diag smartshiftwith flags for--sensitivityand--leave-flippedfor immediate configuration. - The Rust API exposes
get_smartshift_status,toggle_smartshift, andset_smartshift_sensitivitythrough theopenlogi_hidcrate. - All operations include transient error handling with automatic retry logic to ensure reliable device communication.
- Configuration changes preserve existing settings unless explicitly overwritten.
Frequently Asked Questions
What HID++ protocol features does OpenLogi use to control SmartShift?
OpenLogi uses HID++ 2.0 feature 0x2110 for legacy SmartShift implementations and 0x2111 for enhanced versions. The library automatically detects which feature your mouse supports and normalizes both onto the SmartShiftMode enum in crates/openlogi-core/src/hid/smartshift.rs.
How do I check if my mouse supports SmartShift before attempting configuration?
Call get_smartshift_status(&route).await? from the openlogi_hid crate. If the device does not support SmartShift, the function will return an error indicating the feature is unavailable. The CLI command openlogi diag smartshift performs this check automatically before attempting writes.
What values are valid for the auto-disengage sensitivity setting?
The sensitivity value must be a NonZeroU8 (1-255). The value 0 is rejected by the device. In practice, values between 10 and 50 provide noticeable differences in auto-disengage behavior, though the exact acceptable range depends on your specific Logitech mouse model.
Does OpenLogi handle concurrent access from Logitech Options or other software?
Yes. The write logic in smartshift.rs checks for status_matches_desired before writing and implements a retry mechanism with TRANSIENT_RETRY_DELAY for transient errors. This handles race conditions that occur when Logitech Options or other HID++ clients access the device simultaneously.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →