Files
Lumotia/docs/architecture-map/02-tauri-runtime/system-tray.md
Jake 26c7307607
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
agent: lumotia-rebrand — docs, scripts, root config, residuals
Phase 9 of the rebrand cascade. Sweep covers everything the Phase 8
frontend pass deliberately skipped: docs/, root markdown, scripts,
Cargo.toml descriptions, code comments that survived earlier
word-boundary sed, plus a handful of identifiers caught on the final
verify pass.

transcription-app changes:
- README.md, HANDOVER.md, KNOWN-ISSUES.md, run.sh — magnotia/Magnotia
  -> lumotia/Lumotia.
- docs/ — sweep across all subdirs except docs/handovers/ (preserved
  as immutable audit trail). Includes architecture-map references
  to magnotia_core::*, magnotia_storage::*, etc. now pointing at
  lumotia_*; dev-setup.md tracing output examples (lumotia_startup
  target); brief/ + superpowers/ + issues/ + whisper-ecosystem/ +
  audit/.
- Cargo.toml descriptions on 9 crates (core, audio, cloud-providers,
  hotkey, llm, mcp, plus referenced others).
- crates/core/src/{error,hardware,recommendation,paths}.rs +
  crates/audio/src/wav.rs + crates/llm/src/model_manager.rs +
  crates/cloud-providers/src/keystore.rs + crates/mcp/src/lib.rs —
  doc comments and a model-manager user-agent string.
- Caught on final pass: BroadcastChannel("magnotia_task_sync") -> ...
  ("lumotia_task_sync"); magnotia_locale i18n localStorage key
  renamed + migration shim added; CSS keyframe names
  magnotiaPulse / magnotiaBar / magnotiaFade renamed in the design-
  system kit; magnotia_viewer_item / magnotia_viewer_mode handoff
  keys renamed in HistoryPage + viewer/+page.svelte; src/assets/
  wordmark.svg text.
- src-tauri/src/lib.rs comment cleanup ("magnotia era" was sed'd
  to "lumotia era" earlier — restored).

Preserved (intentional):
- crates/core/src/paths.rs — keeps "magnotia" / "Magnotia" / ".magnotia"
  legacy detection strings in legacy_and_target_paths() so the
  migration shim can still find user data from the magnotia era.
- src/lib/stores/{page,focusTimer}.svelte.ts + src/lib/i18n/index.ts
  — migration call sites reference the legacy magnotia keys
  deliberately.
- docs/handovers/ — historical audit trail.

cargo build --workspace passes. npm run check: 0 errors / 0 warnings
(3958 files). cargo test --workspace: 339 pass / 0 fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 12:38:03 +01:00

57 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: System tray
type: architecture-map-page
slice: 02-tauri-runtime
last_verified: 2026/05/09
---
# System tray
> **Where you are:** [Architecture map](../README.md) → [Tauri runtime](README.md) → System tray
**Plain English summary.** Builds the desktop tray icon that lives in the system status area. The tray menu has Show, a disabled status row, an Evening wind-down shortcut (Phase 5 ritual), and Quit. Left-clicking the icon shows and focuses the main window.
## At a glance
- Path: `src-tauri/src/tray.rs`.
- LOC: 73.
- Compile gate: `#[cfg(not(target_os = "android"))]` — Android has no tray surface (declared at the `mod tray` line in `src-tauri/src/lib.rs:5`).
- Tauri commands exposed: none. The tray is set up imperatively from `lib.rs::run` setup hook.
- Events emitted: `lumotia:open-wind-down` (no payload) when the user clicks the wind-down menu item (`src-tauri/src/tray.rs:51`).
- Depends on: `tauri::image::Image`, `tauri::menu::{MenuBuilder, MenuItemBuilder}`, `tauri::tray::TrayIconBuilder`, `tauri::{Emitter, Manager}`. No workspace crates.
- Called from frontend at: the frontend layout listens for `lumotia:open-wind-down` and routes to the wind-down page.
## What's in here
### `setup(app)` (`src-tauri/src/tray.rs:6`)
Builds the menu items: `show`, `status` (disabled, label "Ready"), `wind-down`, `quit`. Assembles them into a `MenuBuilder` with separators between groups. Falls back to a 1×1 transparent icon if `default_window_icon()` is None (which would be a packaging failure in production builds).
Wires three handlers:
- `on_menu_event` (`src-tauri/src/tray.rs:37`):
- `show``window.show(); window.set_focus();`
- `wind-down` → show + focus + emit `lumotia:open-wind-down`.
- `quit``app.exit(0)`.
- All other ids fall through.
- `on_tray_icon_event` (`src-tauri/src/tray.rs:58`): a left-click brings the main window forward. Right-click is left to the platform default (which opens the menu).
The tray icon's tooltip is `"Lumotia — Ready"`. The status menu item has label `"Ready"` and is disabled (the `enabled(false)` builder call leaves it visible but unclickable).
## Data flow
Out only: clicks on the tray menu either hide/show the window directly or fire one event to the frontend (`lumotia:open-wind-down`). The tray does not read any state.
## Watch-outs
- The status menu item is hard-coded "Ready". There is no wiring to update it dynamically as the engine moves between idle / loading / recording. If you want a live status, you'll need to retain a `TrayIcon` handle in `AppState` (or somewhere similar) so a command can call `set_tooltip` / update the menu item text.
- The icon comes from `app.default_window_icon()` which is the packaged bundle icon (set in `tauri.conf.json` `bundle.icon`). Replacing the tray icon means re-running `tauri icon` or shipping a separate tray PNG.
- The `lumotia:open-wind-down` event payload is `()` — the frontend just needs to know "navigate to the wind-down page", and the page itself decides whether to render the ritual or a "you have not enabled this yet" stub.
- Close-to-tray (intercepting `WindowEvent::CloseRequested`) lives in `lib.rs::run` setup hook (`src-tauri/src/lib.rs:282`), not here. The two halves are split because the close-to-tray handler needs the cloned `WebviewWindow`.
## See also
- [App lifecycle](app-lifecycle.md) — `tray::setup(app)` is called at the end of the setup hook (`src-tauri/src/lib.rs:315`), and the close-to-tray handler in setup is what makes the tray useful.
- [Tauri config](tauri-config.md) — bundle icon list feeds the tray.
- [Capabilities and ACL](capabilities-and-acl.md) — the main capability includes `core:window:allow-show` / `allow-set-focus` / `allow-hide`, which are what the tray's menu actions implicitly rely on through Tauri's IPC layer.