# OpenLogi Actions for Controlling DPI Presets: Cycle and Set Methods Explained

> Discover OpenLogi actions CycleDpiPresets and SetDpiPreset to easily control your mouse DPI settings. Learn how to cycle or set specific presets for your OpenLogi device.

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

---

**OpenLogi defines two primary actions for DPI management—`CycleDpiPresets` to rotate through configured sensitivity levels and `SetDpiPreset(u8)` to jump directly to a specific zero-based index—both implemented in the core Action enum and translated into HID++ commands at runtime.**

The AprilNEA/OpenLogi repository provides an open-source framework for configuring Logitech peripherals without proprietary software. The OpenLogi actions for controlling DPI presets enable precise mouse sensitivity management through Rust-based bindings that communicate directly with hardware via the HID++ protocol.

## The Core DPI Action Variants

In [`crates/openlogi-core/src/binding/action.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/action.rs), the `Action` enum exposes two specific variants for manipulating DPI settings. These variants belong to the **DPI category** and integrate with the Actions Ring interface for button binding.

### CycleDpiPresets

This action rotates sequentially through the device's configured DPI preset list (e.g., P1 through P7). When triggered, it advances the current sensitivity setting to the next entry in the onboard memory sequence, wrapping to the beginning after reaching the final preset.

### SetDpiPreset(u8)

This action accepts a `u8` parameter representing a **zero-based index** into the DPI preset list. When invoked with `Action::SetDpiPreset(2)`, the device immediately switches to the third configured preset. The runtime clamps out-of-range indices automatically, ensuring the operation never fails due to invalid input.

## HID++ Protocol Implementation

The translation from high-level actions to device-specific commands occurs through the `openlogi-hidpp` crate. The file [`crates/openlogi-hidpp/src/feature/adjustable_dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/adjustable_dpi.rs) implements the standard HID++ Adjustable DPI feature, while [`crates/openlogi-hidpp/src/feature/extended_dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/extended_dpi.rs) handles advanced functionality including range validation and status LED synchronization.

When a bound button triggers either DPI action, the agent synthesizes the appropriate HID++ packets through these feature implementations, enabling hardware-level control without vendor-specific drivers.

## Practical Code Examples

Here is how to construct and execute DPI actions using the OpenLogi core library:

```rust
use openlogi_core::binding::action::Action;

// 1️⃣ Cycle through DPI presets sequentially
let cycle_action = Action::CycleDpiPresets;

// 2️⃣ Jump directly to preset #3 (zero-based index 2)
let set_action = Action::SetDpiPreset(2);

// Execute via the platform-agnostic injector
openlogi_inject::execute(&cycle_action)
    .expect("Failed to cycle DPI presets");
openlogi_inject::execute(&set_action)
    .expect("Failed to set DPI preset");

```

The `openlogi_inject::execute` function, defined in [`crates/openlogi-inject/src/inject.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject.rs), maps each `Action` variant to OS-level event synthesis and HID++ transmissions, handling the platform-specific implementation details transparently.

## Summary

- OpenLogi provides exactly two DPI control actions: `CycleDpiPresets` and `SetDpiPreset(u8)`.
- Both variants are defined in [`crates/openlogi-core/src/binding/action.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/action.rs) and clamp out-of-range indices at runtime.
- The `openlogi-hidpp` crate translates these actions into standard HID++ commands via [`adjustable_dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/adjustable_dpi.rs) and [`extended_dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/extended_dpi.rs).
- Execution occurs through `openlogi_inject::execute`, which handles platform-specific event synthesis and hardware communication.

## Frequently Asked Questions

### How do I cycle through DPI presets programmatically in OpenLogi?

Use the `Action::CycleDpiPresets` variant from `openlogi_core::binding::action::Action`. This triggers a sequential rotation through the device's configured DPI list and is executed via `openlogi_inject::execute` according to the AprilNEA/OpenLogi source code.

### What happens if I pass an invalid index to SetDpiPreset?

The runtime clamps out-of-range indices to valid bounds automatically. The `SetDpiPreset(u8)` action accepts a zero-based index, and if the value exceeds available presets, the system adjusts it to the maximum valid index rather than returning an error.

### Which source files handle DPI action execution in OpenLogi?

The action definitions reside in [`crates/openlogi-core/src/binding/action.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/binding/action.rs). HID++ protocol translation occurs in [`crates/openlogi-hidpp/src/feature/adjustable_dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/adjustable_dpi.rs) and [`crates/openlogi-hidpp/src/feature/extended_dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/extended_dpi.rs), while platform execution is managed by [`crates/openlogi-inject/src/inject.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-inject/src/inject.rs).

### Are these DPI actions available in the OpenLogi user interface?

Yes. Both `CycleDpiPresets` and `SetDpiPreset` belong to the DPI category and appear in the Actions Ring interface, allowing users to bind physical mouse buttons to these specific sensitivity control functions.