# Preview Update Map This document maps how MangoTune updates the built-in live preview today: - what uses live apply - what falls back to restart - what intentionally restarts - what updates preview runtime only - what does not touch preview at all It also notes the main inconsistencies and the recommended direction. ## Core Paths ### 1. Debounced config live apply Code: - [mod.rs](/home/aaron/Programming/mangotune/src/ui/pages/mod.rs) - `refresh_live_preview_for_key(...)` Behavior: - used for most normal config edits - waits `180 ms` - if preview is running: - grabs current in-memory config - calls `preview.apply_live_config(&config)` - falls back to `preview.restart(&config)` if live apply fails Used by: - most schema-backed rows in shared widgets - most text-entry commit paths - most color rows - hotkey rows - typography font changes - many dashboard field edits through `maybe_reload_preview_for_key(...)` Intent: - cheap, smooth preview refresh for ordinary config edits ### 2. Immediate config live apply Code: - [mod.rs](/home/aaron/Programming/mangotune/src/ui/pages/mod.rs) - `apply_live_preview_now(...)` Behavior: - if preview is running: - cancels any pending debounced refresh - immediately calls `preview.apply_live_config(&config)` - falls back to `preview.restart(&config)` if live apply fails Used by: - dashboard metric chips - dashboard layout/style flag chips like: - `Compact` - `No margin` - `Horizontal` - `Outline` - shared switch/toggle rows Intent: - immediate visual response for simple on/off interactions ### 3. Explicit restart Code: - [overview.rs](/home/aaron/Programming/mangotune/src/ui/pages/overview.rs) - preview page `Restart` button - `maybe_restart_active_preview(...)` Behavior: - always restarts the preview process/window Used by: - explicit `Restart` button on `Live Preview` - Studio preview window size changes - width - height Intent: - for changes that need a fresh preview window/process ### 4. Preview runtime-only apply Code: - [overview.rs](/home/aaron/Programming/mangotune/src/ui/pages/overview.rs) - `maybe_apply_studio_preview_runtime(...)` Behavior: - does not push a MangoHud config rewrite - updates the Studio preview runtime knobs only Used by `Live Preview` runtime controls: - scene - studio scene - FPS cap - particle count - particle size - GPU passes - interaction steps - VRAM pressure - vsync - pause Intent: - update the preview workload/runtime without treating those as MangoHud config edits ### 5. Save/reload/apply-profile style preview apply Code: - [window.rs](/home/aaron/Programming/mangotune/src/window.rs) - `apply_preview_current_config(...)` Behavior: - if preview is running: - applies current in-memory config - falls back to restart on failure Used after bigger state changes: - revert/discard unsaved changes - undo-style restore of saved snapshot - redo - restore safety backup into state - reset to defaults - load config target from disk - reload active config from disk - profile apply/restore flows that replace current state Intent: - after whole-config replacement, immediately synchronize preview to the new state ## Where Each UI Surface Lands ## Shared Schema Widgets ### Switch rows Code: - [toggle_row.rs](/home/aaron/Programming/mangotune/src/ui/widgets/toggle_row.rs) - `build_switch_row(...)` Preview path: - `apply_live_preview_now(...)` Notes: - immediate - dependency enable/disable logic runs first - page may also refresh if dependent toggle state changed ### Spin rows Code: - [toggle_row.rs](/home/aaron/Programming/mangotune/src/ui/widgets/toggle_row.rs) - `build_spin_row(...)` Preview path: - `refresh_live_preview_for_key(...)` Notes: - debounced live apply - good fit for repeated numeric scrubbing ### Combo rows Code: - [toggle_row.rs](/home/aaron/Programming/mangotune/src/ui/widgets/toggle_row.rs) - `build_combo_row(...)` Preview path: - `refresh_live_preview_for_key(...)` Notes: - debounced ### Entry rows Code: - [toggle_row.rs](/home/aaron/Programming/mangotune/src/ui/widgets/toggle_row.rs) - `build_entry_row(...)` - `connect_entry_preview_commit(...)` Preview path: - on focus-leave / commit: - `refresh_live_preview_for_key(...)` Notes: - avoids thrashing on every keystroke - updates config/validation immediately - preview waits until commit ### Threshold triplet rows Code: - [toggle_row.rs](/home/aaron/Programming/mangotune/src/ui/widgets/toggle_row.rs) - `build_int_triplet_row(...)` - `connect_group_entry_preview_commit(...)` Preview path: - on leaving the whole triplet group: - `refresh_live_preview_for_key(...)` Notes: - correct behavior for grouped value editing ### Multi-select rows Code: - [toggle_row.rs](/home/aaron/Programming/mangotune/src/ui/widgets/toggle_row.rs) - `build_multi_select_row(...)` Preview path: - `refresh_live_preview_for_key(...)` Notes: - debounced-ish via helper timing, but effectively immediate enough per toggle ## Color Widgets ### Single color rows Code: - [color_row.rs](/home/aaron/Programming/mangotune/src/ui/widgets/color_row.rs) - `build_color_row(...)` Preview path: - entry: - commit on focus-leave via `refresh_live_preview_for_key(...)` - swatch: - immediate `refresh_live_preview_for_key(...)` ### Color list / threshold palette rows Code: - [color_row.rs](/home/aaron/Programming/mangotune/src/ui/widgets/color_row.rs) - `build_color_list_row(...)` Preview path: - entry triplets: - commit on leaving group via `refresh_live_preview_for_key(...)` - swatches: - immediate `refresh_live_preview_for_key(...)` ## Hotkeys Code: - [hotkey_row.rs](/home/aaron/Programming/mangotune/src/ui/widgets/hotkey_row.rs) - `apply_binding(...)` Preview path: - `refresh_live_preview_for_key(...)` Notes: - sensible - hotkeys should not require restart ## Typography Page Code: - [typography.rs](/home/aaron/Programming/mangotune/src/ui/pages/typography.rs) - `apply_font_value(...)` Preview path: - `refresh_live_preview_for_key(...)` Notes: - this is reasonable if MangoHud live apply can accept font-path changes - if users later report font changes only working after restart, this is one place to revisit ## Dashboard ### Position grid Code: - [overview.rs](/home/aaron/Programming/mangotune/src/ui/pages/overview.rs) - position button click handlers Preview path: - `maybe_reload_preview_for_key(...)` - delegates to `refresh_live_preview_for_key(...)` ### Scale/slider style controls Code: - [overview.rs](/home/aaron/Programming/mangotune/src/ui/pages/overview.rs) - various uses of `build_scale_control(...)` Preview path: - mostly `maybe_reload_preview_for_key(...)` Notes: - width also uses live apply right now on dashboard - that differs from Studio preview window width, which correctly restarts - this is okay because dashboard `width` is MangoHud HUD width, not preview window size ### Dashboard flag chips Code: - [overview.rs](/home/aaron/Programming/mangotune/src/ui/pages/overview.rs) - `build_flag_toggle(...)` Preview path: - `apply_live_preview_now(...)` Current examples: - `Compact` - `No margin` - `Horizontal` - `Outline` Notes: - this is now consistent with user expectation - earlier forced restart path was removed ### Dashboard metric chips Code: - [overview.rs](/home/aaron/Programming/mangotune/src/ui/pages/overview.rs) - `build_metric_toggle(...)` Preview path: - `apply_live_preview_now(...)` Notes: - immediate - dependency cascade logic runs first ### Dashboard color controls Code: - [overview.rs](/home/aaron/Programming/mangotune/src/ui/pages/overview.rs) - `build_color_control(...)` - `connect_dashboard_entry_preview_commit(...)` Preview path: - entry: - commit on focus-leave via `maybe_reload_preview_for_key(...)` - swatch: - immediate `maybe_reload_preview_for_key(...)` ## Live Preview Page ### Preview config buttons Code: - [overview.rs](/home/aaron/Programming/mangotune/src/ui/pages/overview.rs) Behavior: - `Start` - `preview.start(...)` - `Apply` - direct `preview.apply_live_config(&config)` - `Restart` - direct `preview.restart(&config)` - `Stop` - direct `preview.stop()` Notes: - this page is the canonical behavior reference - shared helpers should behave consistently with `Apply` ### Studio runtime controls Code: - [overview.rs](/home/aaron/Programming/mangotune/src/ui/pages/overview.rs) - `maybe_apply_studio_preview_runtime(...)` - `maybe_restart_active_preview(...)` Behavior split: - runtime-only live updates: - scene - studio scene - fps cap - particle count - particle size - gpu passes - interaction steps - vram pressure - vsync - pause - restart: - preview window width - preview window height Assessment: - this split is correct ## HUD Order Code: - [hud_order.rs](/home/aaron/Programming/mangotune/src/ui/pages/hud_order.rs) Preview path: - if preview is running: - direct `preview.apply_live_config(&config)` - fallback `preview.restart(&config)` - if preview is not running: - `refresh_live_preview_for_key(...)` Notes: - this now matches the current shared immediate-apply behavior - drag/drop was removed for now because it was causing native corruption - row movement via buttons is stable ## Window-Level Whole-State Flows Code: - [window.rs](/home/aaron/Programming/mangotune/src/window.rs) - `apply_preview_current_config(...)` Used by: - revert/discard - redo - restore backup - reset defaults - config target switch - reload from disk - similar whole-state replace flows Preview path: - direct `apply_live_config` - fallback `restart` Assessment: - correct - after a whole config replacement, immediate apply is the right default ## Inconsistencies Found ### 1. Shared helpers previously disagreed with `Live Preview -> Apply` Status: - fixed What was wrong: - shared helpers used to refuse preview updates when `validator::is_saveable(...)` was false - but the explicit `Apply` button on `Live Preview` did not - this created confusing “manual Apply works, normal controls do not” behavior Current state: - shared helpers now match the `Apply` button behavior ### 2. `HUD Order` had its own crash-prone interaction model Status: - mitigated, not fully ideal What changed: - drag/drop removed - explicit up/down controls now used Assessment: - behavior is stable now - drag/drop can be revisited later as a separate feature ### 3. Some edits are commit-on-leave while others are immediate Status: - mostly intentional Examples: - entry fields wait for commit/leave - toggles and swatches apply immediately Assessment: - this is good - text editing should not hot-apply every keystroke ### 4. Preview runtime controls and MangoHud config controls use different paths Status: - intentional and correct Assessment: - Studio runtime controls should stay separate from MangoHud config live apply ## Areas That Should Probably Stay As-Is - shared switch rows using immediate apply - shared spin/combo rows using debounced apply - text entry rows using commit-on-leave - Studio runtime controls using runtime-only apply - Studio window size using restart - whole-config replacement flows using immediate apply + restart fallback ## Areas Worth Watching ### 1. Font changes Current behavior: - live apply Potential issue: - if MangoHud does not reliably rebuild fonts on live apply, these may need explicit restart semantics later Current recommendation: - keep live apply unless users report failures ### 2. Very structural layout changes Current behavior: - dashboard shell flags now live-apply Assessment: - that is the desired behavior - only revisit if MangoHud itself proves some of these are not safely live-applicable ### 3. `HUD Order` Current behavior: - direct immediate apply + restart fallback Assessment: - correct - no reason to special-case restart-only here ## Recommended Direction ### Rule 1 Use live apply by default for MangoHud config edits. ### Rule 2 Use restart only when the preview window/process itself must be recreated. Current known restart-only cases that fit this rule: - Studio preview window width - Studio preview window height - explicit `Restart` button ### Rule 3 For typed text/group editors, commit preview updates on field/group exit rather than per keystroke. ### Rule 4 Keep `Live Preview -> Apply` as the canonical behavior reference. If a shared helper behaves differently from that button, the shared helper is probably the thing that is wrong. ## Suggested Follow-Up Cleanup These are code-cleanup ideas, not urgent bug fixes. 1. Centralize preview update intent into a small enum - `DebouncedApply` - `ImmediateApply` - `Restart` - `RuntimeOnly` 2. Replace direct ad hoc `preview.apply_live_config(...).or_else(restart)` call sites with one shared helper - currently duplicated in: - `mod.rs` - `overview.rs` - `hud_order.rs` - `window.rs` 3. Add a short code comment near `Live Preview -> Apply` - stating that it is the reference behavior shared helpers should match 4. Revisit drag-and-drop for `HUD Order` only as a separate stability task - not as part of normal preview semantics work