OpenLogi DPI Preset Cycling and Set-Preset Implementation Strategy
OpenLogi implements DPI preset cycling through a persistent config.toml store, a per-device runtime cycle index map, and discrete actions (CycleDpiPresets and SetDpiPreset) that dispatch SetDpi IPC commands to the device agent.
OpenLogi is an open-source mouse configuration platform written in Rust that manages DPI preset workflows through a layered architecture separating desktop UI state management from low-level agent runtime execution. The implementation strategy persists preset configurations per-device in the user's local configuration while maintaining an in-memory dpi_cycle index to track the current preset position during hardware-triggered cycling operations.
DPI Preset Storage and Persistence Strategy
OpenLogi persists DPI presets per-device in the user's config.toml file. When users create, remove, or reorder presets through the desktop interface, the application invokes AppState::commit_dpi_presets in crates/openlogi-desktop/src/state/dpi.rs.
This method accepts a Vec<Dpi> representing the ordered preset list and performs a transactional update. It writes the new preset vector into the configuration via config.set_dpi_presets, passing the persistent device key and the preset collection. The operation concludes with persist_and_reload("DPI presets"), which commits the change to disk and updates an internal hook map to ensure subsequent cycling operations observe the modified preset order.
pub fn commit_dpi_presets(&mut self, presets: Vec<Dpi>) {
// … get the persistent device key …
self.config.edit(|config| config.set_dpi_presets(&key, presets));
self.persist_and_reload("DPI presets"); // push to the hook map
}
To add a new preset snapshot via the UI's "+" chip:
let mut presets = state.dpi_presets();
presets.push(state.dpi()); // snapshot current DPI
state.commit_dpi_presets(presets); // persist and update hook map
Runtime Cycle Index Management
The OpenLogi agent runtime maintains the cycling state independently of the UI. It stores the current cycle position in a thread-safe dpi_cycle map defined in crates/openlogi-agent-core/src/runtime.rs as RwLock<HashMap<DeviceKey, usize>>.
This structure maps each DeviceKey to its current preset index. When the runtime processes a CycleDpiPresets action, it acquires a write lock on the map, retrieves the preset list for the target device, selects the preset at the stored index, and dispatches a SetDpi IPC command to the physical device. After applying the DPI value, the runtime increments the index with wrap-around logic (resetting to zero when reaching the end of the preset vector).
match action {
Action::CycleDpiPresets => match self.dpi_cycle.write() {
// read the preset list, apply the next one, advance the index
// (implementation details omitted for brevity)
},
Action::SetDpiPreset(i) => match self.dpi_cycle.write() {
// directly apply the preset at position `i`
},
…
}
Action Type Definitions and IPC Dispatch
The core binding module in crates/openlogi-core/src/binding/action.rs defines the action protocol supporting both cycling and direct preset selection. The Action enum includes two DPI-related variants:
pub enum Action {
…,
CycleDpiPresets,
SetDpiPreset(u8), // payload = preset index
}
CycleDpiPresets triggers sequential traversal through the preset list using the runtime cycle index, while SetDpiPreset(u8) accepts a zero-based preset index as payload and bypasses the cycle logic to apply a specific preset immediately.
When the agent runtime receives either action type, it resolves the appropriate preset from the device configuration, constructs a SetDpi IPC command with the target DPI values, and transmits it to the mouse firmware.
To trigger cycling programmatically:
// Triggered by the “Cycle DPI Presets” binding
let action = Action::CycleDpiPresets;
agent_runtime.handle_action(action);
To set a specific preset directly (e.g., preset 2):
// The UI sends the preset index (zero‑based) as payload
let action = Action::SetDpiPreset(2);
agent_runtime.handle_action(action);
Thumb-Wheel Hardware Integration
Physical input mapping occurs in crates/openlogi-desktop/src/features/mouse/thumbwheel.rs. This module binds thumb-wheel gestures to the CycleDpiPresets action, allowing users to cycle through configured presets using the mouse's physical thumb-wheel without interacting with the desktop UI.
The mapping treats both forward and backward thumb-wheel directions as CycleDpiPresets invocations, relying on the runtime's wrap-around index logic to handle directionality and boundary conditions.
Summary
- Persistent Storage: DPI presets are stored per-device in
config.tomland committed viaAppState::commit_dpi_presetsincrates/openlogi-desktop/src/state/dpi.rs. - Runtime State: The agent maintains a
dpi_cyclemap (RwLock<HashMap<DeviceKey, usize>>) incrates/openlogi-agent-core/src/runtime.rsto track the current preset index per device. - Action Protocol: Two distinct actions—
CycleDpiPresetsandSetDpiPreset(u8)—handle sequential cycling versus direct preset selection, both dispatchingSetDpiIPC commands. - Hardware Binding: The thumb-wheel implementation in
crates/openlogi-desktop/src/features/mouse/thumbwheel.rsmaps physical gestures to theCycleDpiPresetsaction for hardware-triggered preset switching.
Frequently Asked Questions
How does OpenLogi handle DPI preset persistence across application restarts?
OpenLogi writes DPI preset configurations to the user's config.toml file via the commit_dpi_presets method. This method uses config.set_dpi_presets to update the stored configuration and calls persist_and_reload to ensure the runtime's hook map reflects the latest preset order immediately after the write operation completes.
What is the difference between CycleDpiPresets and SetDpiPreset actions?
CycleDpiPresets advances the runtime's internal cycle index, applies the preset at that position, and increments the index with wrap-around logic. SetDpiPreset(u8) accepts a specific zero-based index as an argument, ignores the cycle index, and immediately applies the preset at the requested position without modifying the cycle state.
Where is the current DPI preset index stored during runtime?
The current preset index for each device is stored in the dpi_cycle field within crates/openlogi-agent-core/src/runtime.rs. This field is a RwLock<HashMap<DeviceKey, usize>> that provides thread-safe access to the cycling state, allowing concurrent reads during UI updates and exclusive writes during action processing.
Can the thumb-wheel cycle backward through DPI presets?
Yes. The thumb-wheel implementation in crates/openlogi-desktop/src/features/mouse/thumbwheel.rs maps both forward and backward wheel directions to the CycleDpiPresets action. The runtime's wrap-around index logic in the agent handles directional cycling, ensuring that decrementing from index zero moves to the last preset in the vector.
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 →