How Coco App Configures and Persists Autostart and Global Shortcuts
Coco App leverages Tauri's plugin architecture to bridge React UI commands with Rust-native OS integrations, persisting autostart preferences to a plain-text file and global shortcuts to a JSON-backed key-value store in the application config directory.
Coco App, an open-source search utility built by Infinite Labs, relies on Tauri's hybrid architecture to manage system-level behaviors. The application configures autostart (launch at login) and global shortcuts (system-wide hotkeys) through a deterministic flow that persists user preferences across restarts. This implementation spans TypeScript frontend handlers in src/commands/system.ts and Rust backend commands in src-tauri/src/autostart.rs and src-tauri/src/shortcut.rs.
Architecture Overview
Coco App runs on Tauri, which bridges a React-based UI with native Rust code. Two system-level features—autostart and global shortcuts—are handled through dedicated Tauri plugins and a tiny key-value store. The required plugins are declared in src-tauri/Cargo.toml: tauri-plugin-autostart for login-launch management, tauri-plugin-global-shortcut for hotkey registration, and tauri-plugin-store for JSON persistence.
Autostart Configuration and Persistence
Frontend Toggle Flow
When a user toggles autostart in the General Settings page, the UI invokes the change_autostart command. In src/components/Settings/GeneralSettings.tsx, the toggle handler calls change_autostart(true) or change_autostart(false) via Tauri's invoke API. This reaches the backend through the thin wrapper in src/commands/system.ts, which forwards the boolean state to the Rust command layer.
Rust Backend Implementation
The change_autostart command in src-tauri/src/autostart.rs interacts directly with the OS via tauri-plugin-autostart. The function retrieves the autolaunch manager using app.autolaunch(), then calls manager.enable() or manager.disable() based on the open parameter. This immediately updates the OS-level login item or registry entry without requiring a restart.
Persistence Mechanism
To survive app restarts and OS-level changes, the desired state is written to a plain-text file named autostart.txt in the application config directory (app_config_dir()). The Rust code uses std::fs::write(cfg_dir.join("autostart.txt"), open.to_string()) to persist the boolean. On subsequent launches, the current_autostart function reads this file to restore the user's choice, ensuring the UI reflects the persisted state even if the OS modified it externally.
Startup Consistency Check
During early startup, the setup module in src-tauri/src/setup/mod.rs calls autostart::ensure_autostart_state_consistent(&tauri_app_handle). This function compares the OS-reported autostart status against the value stored in autostart.txt and reconciles any mismatch, guaranteeing that the actual OS behavior aligns with the user's saved preference.
Global Shortcut Configuration and Persistence
Shortcut Management Flow
The shortcuts UI in GeneralSettings.tsx provides three primary operations: retrieving the current hotkey, updating it, and unregistering it. These map to get_current_shortcut, change_shortcut, and unregister_shortcut in src/commands/system.ts. Each function uses invoke to communicate with the Rust backend, passing the shortcut string (e.g., "ctrl+shift+space") for validation and registration.
Backend Registration and Storage
In src-tauri/src/shortcut.rs, the change_shortcut command validates the input using key.parse::<Shortcut>(), then persists it via tauri-plugin-store. The store writes to a JSON file in the config directory using the key coco_global_shortcut. After storing, the command calls _register_shortcut to activate the hotkey through tauri-plugin-global-shortcut, which binds the system-wide listener. The unregister_shortcut command removes the active registration without deleting the stored preference.
Default Shortcuts and Initialization
On first launch, shortcut::enable_shortcut checks the store for an existing entry. If none exists, it writes a platform-specific default: command+shift+space on macOS, or ctrl+shift+space on Windows and Linux. This initialization occurs in src-tauri/src/setup/mod.rs during backend_setup, ensuring the global shortcut is active immediately when the app starts.
Storage Locations and File Formats
Autostart preferences live in a plain-text file at <app_config_dir>/autostart.txt, containing the literal string "true" or "false". Global shortcuts persist as a JSON entry within <app_config_dir>/coco-app.store.json (managed by tauri-plugin-store) under the key coco_global_shortcut. Both paths resolve via tauri::api::path::app_config_dir(), making them portable across macOS, Windows, and Linux.
Implementation Examples
Toggle Autostart from the Frontend
import { change_autostart } from '@/commands/system';
// Enable launch at login
await change_autostart(true);
// Disable launch at login
await change_autostart(false);
Manage Global Shortcuts
import {
get_current_shortcut,
change_shortcut,
unregister_shortcut,
} from '@/commands/system';
// Read persisted shortcut
const current = await get_current_shortcut(); // "ctrl+shift+space"
// Update to a new hotkey
await change_shortcut('alt+space');
// Clear current registration
await unregister_shortcut();
Rust Autostart Logic
// src-tauri/src/autostart.rs
pub async fn change_autostart(app: tauri::AppHandle, open: bool) -> Result<(), String> {
let manager = app.autolaunch();
if open {
manager.enable()?;
} else {
manager.disable()?;
}
// Persist to autostart.txt
let cfg_dir = app.path().app_config_dir()?;
std::fs::create_dir_all(&cfg_dir)?;
std::fs::write(cfg_dir.join("autostart.txt"), open.to_string())?;
Ok(())
}
Rust Shortcut Registration
// src-tauri/src/shortcut.rs
pub async fn change_shortcut(
app: AppHandle,
_window: tauri::Window,
key: String,
) -> Result<(), String> {
let shortcut = key.parse::<Shortcut>()
.map_err(|_| format!("invalid shortcut {}", key))?;
// Persist to tauri-plugin-store
let store = app.get_store(COCO_TAURI_STORE)?;
store.set(COCO_GLOBAL_SHORTCUT, JsonValue::String(key));
// Register with tauri-plugin-global-shortcut
_register_shortcut(&app, shortcut);
Ok(())
}
Summary
- Autostart uses
tauri-plugin-autostartfor OS-level toggling and a customautostart.txtfile for state persistence, withensure_autostart_state_consistentreconciling drift during startup. - Global shortcuts rely on
tauri-plugin-global-shortcutfor hotkey registration andtauri-plugin-storefor JSON persistence using the keycoco_global_shortcut. - All configuration data lives in the Tauri application config directory, ensuring cross-platform portability.
- The initialization sequence in
src-tauri/src/setup/mod.rsrestores both autostart and shortcut states immediately when the backend launches.
Frequently Asked Questions
Where does Coco App store autostart settings?
Coco App writes the autostart boolean to a plain-text file named autostart.txt inside the Tauri application config directory, typically located at ~/.config/coco-app/ on Linux, ~/Library/Application Support/coco-app/ on macOS, or %APPDATA%\coco-app\ on Windows.
How does Coco App handle global shortcut conflicts?
If the requested shortcut is already registered by another application, the change_shortcut command in src-tauri/src/shortcut.rs will fail during the _register_shortcut call, returning an error to the frontend. The UI can then prompt the user to select a different combination.
What happens if the OS removes autostart permission?
During startup, ensure_autostart_state_consistent in src-tauri/src/autostart.rs detects the mismatch between the OS state and the autostart.txt file. If the OS has disabled autostart (e.g., via system settings), the function reconciles the file to match the actual OS state, ensuring the UI remains accurate.
Can users customize the default shortcut on first launch?
Yes. If no prior value exists in the store, enable_shortcut in src-tauri/src/shortcut.rs writes a platform-specific default (command+shift+space on macOS, ctrl+shift+space elsewhere) and immediately registers it. Users can override this default at any time through the General Settings UI, which updates the store and re-registers the hotkey dynamically.
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 →