How to Set DPI for Logitech Mouse with OpenLogi: A Complete HID++ Protocol Guide

OpenLogi controls Logitech mouse DPI through the HID++ protocol by detecting either feature 0x2201 (AdjustableDpi) or 0x2202 (ExtendedAdjustableDpi), then writing values via the set_dpi() function while verifying the change against supported sensor capabilities.

OpenLogi provides a Rust-based interface for configuring Logitech peripherals at the firmware level. When you need to change your mouse sensitivity programmatically, the library negotiates with the device using Logitech's proprietary HID++ feature set to ensure compatibility across different sensor architectures.

Understanding the HID++ DPI Feature Detection

OpenLogi automatically probes for two distinct DPI management features when initializing a device connection. This detection logic, implemented in crates/openlogi-device/src/write/dpi.rs within the DpiFeature::open method, determines which protocol version your specific mouse model supports.

0x2201 (AdjustableDpi) represents the preferred implementation. This feature exposes DPI values as a flat list where each entry corresponds to a single sensor sensitivity setting. OpenLogi attempts to open this feature first because it offers broader compatibility with existing Logitech hardware.

0x2202 (ExtendedAdjustableDpi) serves as the fallback protocol. This extended feature supports independent X/Y axis DPI configurations and includes lift-off distance parameters. The library only uses this feature when 0x2201 is unavailable on the target device.

The DPI Control Workflow

Once DpiFeature::open establishes the correct feature handle, OpenLogi executes a three-phase workflow to manage sensitivity settings. Each phase maps to specific methods in the DPI module that handle the low-level HID++ communication.

Reading Current DPI Values

The DpiFeature::current_dpi() method retrieves the active sensitivity setting from the device. Depending on which feature was detected during initialization, this calls either get_sensor_dpi (for 0x2201) or get_sensor_dpi_parameters (for 0x2202) to read the hardware registers.

Querying Supported DPI Ranges

Before writing new values, DpiFeature::supported_dpi() obtains the complete list of valid DPI settings for your specific mouse model. For devices using the extended feature (0x2202), this method processes stepped ranges through the expand_dpi_ranges helper function to generate a flattened list of acceptable values.

Writing and Verifying New DPI

The DpiFeature::set_dpi() method handles the actual configuration change through the following sequence:

  1. Transmits the new DPI value using set_sensor_dpi (adjustable feature) or set_sensor_dpi_parameters (extended feature)
  2. Immediately reads the DPI back from the device to confirm the write succeeded
  3. Logs a warning if the reported value differs from the requested value, indicating the device clamped the input to the nearest supported step

Public API Methods

OpenLogi exposes DPI control through two primary async functions that abstract the feature detection and error handling logic.

set_dpi(backend, route, dpi) manages the complete write operation. This function opens a HID++ channel to the specified device, selects the appropriate feature (0x2201 or 0x2202), transmits the new Dpi value, and performs the verification read. The backend parameter implements the HidBackend trait, while route specifies the DeviceRoute targeting your specific mouse.

get_dpi_info(backend, route) returns comprehensive sensor capabilities. This function provides both the current active DPI and a DpiCapabilities structure containing the full vector of supported values, allowing applications to validate user input against hardware limits before attempting writes.

Practical Implementation Examples

You can interact with OpenLogi's DPI control either programmatically through the Rust library or via the bundled command-line interface.

Rust Library Integration

For custom applications or agents, import the DPI module and use the async API directly:

use openlogi_device::write::dpi::{set_dpi, get_dpi_info};
use openlogi_core::hid::dpi::Dpi;
use openlogi_agent_core::backend::HidBackend;
use openlogi_ipc::DeviceRoute;

async fn change_mouse_dpi(
    backend: &dyn HidBackend, 
    route: &DeviceRoute, 
    new_dpi: u16
) -> Result<(), WriteError> {
    // Convert raw value to the library's Dpi type
    let dpi = Dpi::new(new_dpi);
    
    // Write the DPI setting
    set_dpi(backend, route, dpi).await?;
    
    // Verify capabilities and confirm the change
    let info = get_dpi_info(backend, route).await?;
    println!("Current DPI: {}, supported values: {:?}", 
        info.current, info.capabilities.values());
    
    Ok(())
}

The Dpi type constructor in crates/openlogi-core/src/hid/dpi.rs handles validation, while the DpiInfo structure returned by get_dpi_info contains both the current value and the capabilities object.

Command-Line Interface

For end-user workflows, use the openlogi CLI commands without writing Rust code:


# List connected devices to find your mouse index

openlogi list

# Set device 0 to 1200 DPI

openlogi set-dpi --device 0 --value 1200

# Verify the configuration with diagnostic output

openlogi diag dpi --device 0

The set-dpi command in crates/openlogi-cli/src/cmd/mod.rs forwards your request to the set_dpi function, while diag dpi—implemented in crates/openlogi-cli/src/cmd/diag/dpi.rs—demonstrates the full read-write-read round-trip to confirm the device accepted the new sensitivity value.

Summary

  • OpenLogi automatically detects DPI features 0x2201 (preferred) or 0x2202 (extended fallback) in openlogi-device/src/write/dpi.rs
  • The DpiFeature::set_dpi() method writes values and verifies the device report matches the requested sensitivity
  • Use set_dpi() to change settings and get_dpi_info() to retrieve current values and supported ranges
  • The CLI provides openlogi set-dpi and openlogi diag dpi commands for non-programmatic access
  • All DPI types (Dpi, DpiCapabilities, DpiInfo) are defined in openlogi-core/src/hid/dpi.rs

Frequently Asked Questions

What is the difference between AdjustableDpi and ExtendedAdjustableDpi features?

The 0x2201 (AdjustableDpi) feature provides a simple flat list of DPI values per sensor, while 0x2202 (ExtendedAdjustableDpi) adds independent X/Y axis control and lift-off distance configuration using stepped ranges. OpenLogi attempts to use 0x2201 first for maximum compatibility, falling back to 0x2202 only when necessary.

Why does OpenLogi read the DPI back after writing it?

The library performs a verification read to ensure the hardware actually accepted the requested value. Some Logitech mice automatically clamp out-of-range values to the nearest supported step. If the read-back value differs from the write request, OpenLogi logs a warning indicating the device modified the input to match its supported capabilities.

Can I set different DPI values for X and Y axes?

Only mice exposing the 0x2202 (ExtendedAdjustableDpi) feature support independent X/Y axis configuration. When this feature is active, the set_sensor_dpi_parameters function accepts separate values for horizontal and vertical sensitivity. The standard 0x2201 feature applies a single value to both axes.

What happens if I request a DPI value my mouse doesn't support?

The device firmware will automatically adjust your request to the nearest valid value within its hardware limits. OpenLogi's verification step detects this discrepancy and reports it via logging or CLI output, allowing you to query the exact supported range using get_dpi_info() or openlogi diag dpi before attempting further modifications.

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 →