| name | desktop-utility-implementation |
| description | Implement or improve tray, quick popup, global shortcut, single-instance, and restore behavior for the Windows-first Tauri 2 app. |
desktop-utility-implementation skill
Use this skill for any work in src-tauri/src/utils/, window management, tray, menu, global shortcut, single-instance, or quick-popup behavior.
Companion files — read these too
.codex/skills/desktop-utility-implementation/tauri-file-map.md — every Tauri file with its role, key functions, and platform notes
Current native layer architecture
src-tauri/src/
lib.rs ← App entry: plugins, AppState, invoke_handler, menu/window events
main.rs ← Calls numpad_lib::run()
commands/
ai.rs ← AI Tauri commands
documents.rs ← Document CRUD commands
export.rs ← Export file-save command
utility.rs ← update_quick_calc_session, copy_text_to_clipboard
mod.rs ← pub mod declarations
services/
state.rs ← AppState { db_path, quick_calc_session }
document_repository.rs
document_service.rs
ai_service.rs ← AI streaming, enablement, key resolution
ai_settings_service.rs
ai_secret_service.rs ← OS keychain
ai_key_resolution.rs
ai_provider.rs ← AiProvider trait
openrouter_provider.rs
export_service.rs
settings_repository.rs
mod.rs
utils/
desktop.rs ← Window bootstrap, quick-popup reveal/toggle/hide
macos.rs ← macOS-only: menu bar icon, app menu, tray, default shortcut
clipboard.rs ← Native clipboard write
mod.rs
db/ ← SQLite init, migrations
Platform split — IMPORTANT
| Behavior | Windows | macOS |
|---|
| Transparent main window | ✓ native backdrop | ✗ not supported |
| Tray icon | tauri_plugin_tray | menu bar icon via macos.rs |
| App menu | System menu | Custom app_menu() in macos.rs |
| Global shortcut | tauri_plugin_global_shortcut | Registered in macos.rs |
| Quick popup window | quick_popup window | Same |
| Single-instance | tauri_plugin_single_instance (to add) | Same pattern |
Never add Windows-only APIs to the shared desktop.rs path. Isolate platform code in macos.rs (and a future windows.rs).
Quick popup flow
The quick popup is a separate Tauri window (quick_popup) that renders index.html?view=quick-popup:
Global shortcut triggered
→ tauri_plugin_global_shortcut callback (in macos.rs or windows equivalent)
→ calls utils::desktop::toggle_quick_popup(app_handle)
→ show/hide the quick_popup window
→ frontend QuickCalcScreen renders at ?view=quick-popup
→ user types expression → quick-calc-evaluation.ts evaluates deterministically
→ result shown → user copies or closes (Escape)
Frontend files:
src/features/quick-calc/QuickCalcScreen.tsx — popup UI
src/features/quick-calc/quick-calc-evaluation.ts — deterministic evaluator
src/features/quick-calc/quick-calc.native.ts — typed Tauri wrappers
AppState pattern
#[tauri::command]
pub async fn my_command(state: tauri::State<'_, AppState>) -> Result<(), String> {
let db_path = state.db_path.lock().await;
}
Tauri 2+ plugin registration pattern
tauri::Builder::default()
.plugin(tauri_plugin_store::Builder::default().build())
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_sql::Builder::default().build())
.setup(|app| { ... })
Command surface pattern
#[tauri::command]
pub async fn my_command(
param: String,
state: tauri::State<'_, AppState>,
) -> Result<MyResponse, String> {
services::my_service::do_work(¶m, &state)
.await
.map_err(|e| e.to_string())
}
Required workflow
- Read
tauri-file-map.md to locate the right file.
- Inspect
src-tauri/src/lib.rs for current plugin and command registration.
- Inspect
src-tauri/src/utils/desktop.rs for window behavior.
- Inspect
src-tauri/src/utils/macos.rs for macOS-specific behavior.
- Write an implementation plan if the change is complex.
- Implement with platform isolation in mind.
- Run
cd src-tauri && cargo check && cargo build.
- Run
npm run typecheck && npm run build.
- Update
docs/ARCHITECTURE.md and docs/API_CONTRACTS.md.
Constraints
- Only Tauri 2+ APIs — no Tauri 1.x patterns.
- Commands in
commands/ are thin wrappers — all logic in services/.
- Platform-specific code lives in
utils/macos.rs (or future utils/windows.rs).
- Never use global statics — use
AppState via tauri::State.
- Preserve single-instance, tray, popup, and shortcut on Windows.
- Do not add unit tests unless explicitly requested.
Docs to update
docs/ARCHITECTURE.md — for native layer changes
docs/API_CONTRACTS.md — for new/changed Tauri commands
docs/IMPLEMENTATION_ROADMAP.md — for desktop utility milestone progress
docs/STATUS_GAP_ANALYSIS.md — when gaps are resolved