# How DPI Control with Presets is Implemented in OpenLogi

> Discover how OpenLogi implements DPI control with presets. Explore per-device configurations, hardware discovery, and agent process application for advanced mouse settings.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: internals
- Published: 2026-09-12

---

**OpenLogi implements DPI control with presets by storing per-device configurations in [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml), discovering hardware capabilities via HID++ protocols, and applying settings through IPC commands to an agent process.**

OpenLogi manages DPI settings through a sophisticated preset system that bridges hardware capability detection with persistent user configuration. The implementation spans the desktop UI, core state management, and IPC communication layers to provide seamless device control according to the OpenLogi source code.

## HID++ Capability Discovery and Caching

### Querying Device Capabilities

When a device is selected, the system queries its HID++ DPI capabilities using feature code `AdjustableDpi` (`0x2201`) or `ExtendedAdjustableDpi` (`0x2202`). The agent returns capability metadata including `min`, `max`, `step`, and any non-uniform supported values. These capabilities are cached in `AppState::pointer.reads` as a `DpiStatus::Ready` record, enabling the UI to validate inputs before hardware communication.

### Normalization and Validation

Before applying any DPI value, the system validates against discovered capabilities using `DpiCapabilities::nearest()`. This ensures user inputs or preset values align with hardware-supported increments, preventing invalid configuration states.

## Persistent Preset Storage Architecture

### Per-Device Configuration Schema

DPI presets are stored per-device in the user's [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) under the key `Config::devices[<device-key>].dpi_presets`. If no presets exist for a device key, the system returns an empty vector rather than a default global list, maintaining isolation between different hardware profiles.

### State Management Interface

The `AppState` struct in [`crates/openlogi-desktop/src/state/dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/state/dpi.rs) provides the primary API for preset manipulation:

- **`dpi_presets()`** – Reads the saved list from configuration, returning `Vec<Dpi>` or an empty vector if uninitialized.
- **`commit_dpi_presets()`** – Replaces the stored list, invokes `Config::set_dpi_presets()`, and triggers `persist_and_reload()` to atomically update the TOML file.

```rust
// Load the current device's DPI presets (used by UI)
let presets = state.dpi_presets();          // → Vec<Dpi>

// Add the current DPI as a new preset (user clicks "+" chip)
let mut presets = state.dpi_presets();
presets.push(state.dpi());                 // current DPI value
state.commit_dpi_presets(presets);         // writes back to config.toml

```

## Applying DPI Settings to Devices

### The commit_dpi Execution Flow

When a user selects a preset or releases the DPI slider, `AppState::commit_dpi()` executes a three-phase persistence strategy defined in [`crates/openlogi-desktop/src/state/dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/state/dpi.rs):

1. **UI State Update** – Immediately sets `self.pointer.dpi = dpi` for responsive interface feedback.
2. **Configuration Persistence** – Retrieves the `persistent_config_key()` for the current device record and calls `Config::set_dpi()`, followed by `persist_and_reload("DPI")` to save to [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml).
3. **Hardware Communication** – Dispatches an IPC command to the agent via `Command::SetDpi(route, dpi)` defined in [`crates/openlogi-ipc/src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/ipc.rs).

```rust
pub fn commit_dpi(&mut self, dpi: Dpi) {
    self.pointer.dpi = dpi;                     // UI state
    if let Some(record) = self.current_record() {
        // Persist per‑device DPI
        if let Some(key) = record.persistent_config_key() {
            self.config.edit(|c| c.set_dpi(key, dpi));
            self.persist_and_reload("DPI");
        }
        // Send IPC command to the agent
        if let Some(route) = record.route.clone() {
            self.send_ipc(crate::services::ipc::Command::SetDpi(route, dpi));
        }
    }
}

```

### IPC Communication Layer

The `SetDpi` command transmits the target DPI value and device route to the background agent process. This separation of concerns ensures the UI remains responsive while the agent handles blocking HID++ write operations.

## UI Integration and Interaction Patterns

### Conditional Slider Activation

The DPI slider UI in [`crates/openlogi-desktop/src/features/pointer/dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/features/pointer/dpi.rs) remains disabled until capability discovery succeeds and `DpiStatus::Ready` is populated. This prevents users from interacting with controls before the system understands hardware limitations.

### Preview vs. Commit Pattern

The implementation distinguishes between transient preview values and committed hardware states:

- **Preview Phase** – During slider movement, values are stored via `set_dpi_preview()` without triggering hardware writes or configuration persistence.
- **Commit Phase** – Upon slider release or preset chip selection, `commit_dpi()` finalizes the change, updates [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml), and dispatches the IPC command.

### Preset Chip Interaction

Individual preset chips bind click handlers that invoke `commit_dpi()` with the stored preset value:

```rust
fn preset_chip(idx: usize, value: Dpi, ...) -> impl IntoElement {
    Button::new(("dpi-preset-apply", idx))
        .on_click(move |cx| {
            let mut state = AppState::try_read(cx).unwrap();
            state.commit_dpi(value);       // writes via IPC & updates UI
        })
}

```

## Summary

- **Capability Discovery** queries HID++ features `0x2201` or `0x2202` and caches results in `DpiStatus::Ready` before enabling UI controls.
- **Persistent Storage** maintains per-device preset lists in [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml), accessed via `AppState::dpi_presets()` and modified through `commit_dpi_presets()`.
- **Hardware Application** flows through `commit_dpi()`, which updates configuration state and dispatches `Command::SetDpi` via IPC to the agent.
- **UI Patterns** implement a preview/commit distinction for sliders and direct application for preset chips, with all values normalized using `DpiCapabilities::nearest()`.

## Frequently Asked Questions

### Where are DPI presets stored in OpenLogi?

DPI presets are stored per-device in the user's [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) file under the path `Config::devices[<device-key>].dpi_presets`. The system retrieves these via `AppState::dpi_presets()` and persists changes through `Config::set_dpi_presets()` followed by `persist_and_reload()`.

### How does OpenLogi detect supported DPI ranges?

OpenLogi discovers supported ranges by querying the device's HID++ capabilities using feature codes `AdjustableDpi` (`0x2201`) or `ExtendedAdjustableDpi` (`0x2202`). The returned metadata—including minimum, maximum, step values, and non-uniform supported points—is cached in `AppState::pointer.reads` as a `DpiStatus::Ready` record.

### What happens when I click a DPI preset chip?

Clicking a preset chip invokes `AppState::commit_dpi(preset)`, which immediately updates the UI state, persists the new DPI to [`config.toml`](https://github.com/AprilNEA/OpenLogi/blob/main/config.toml) using the device's persistent configuration key, and dispatches an IPC `SetDpi` command to the agent process to write the value to the hardware.

### Why does the DPI slider only activate after device selection?

The slider remains disabled until the system completes capability discovery and populates `DpiStatus::Ready`. This ensures the UI only accepts input values that the hardware actually supports, preventing invalid DPI configurations and ensuring `DpiCapabilities::nearest()` can normalize user inputs against verified device limits.