How DPI Control with Presets is Implemented in OpenLogi

OpenLogi implements DPI control with presets by storing per-device configurations in 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 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 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.
// 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:

  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.
  3. Hardware Communication – Dispatches an IPC command to the agent via Command::SetDpi(route, dpi) defined in crates/openlogi-ipc/src/ipc.rs.
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 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, and dispatches the IPC command.

Preset Chip Interaction

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

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, 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 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 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.

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 →