docs: refresh preview update guidance and repo map

This documents the current preview apply contract, updates the project
map to match the live code paths, and adds the local scratchpad issue
tracking reminder to the workspace instructions.
This commit is contained in:
2026-03-31 17:23:13 -04:00
parent 7e95b7f95f
commit a36c02bbf7
3 changed files with 571 additions and 7 deletions
+5
View File
@@ -5,3 +5,8 @@
- Treat `PROJECT_MAP.md` as the primary orientation file for code structure, hot paths, feature ownership, and known issues.
- Update `PROJECT_MAP.md` when commands, modules, feature areas, persistence contracts, or major known issues change.
- After any meaningful structural or user-facing change, append a short one-line entry to the `PROJECT_MAP.md` change log.
## Local Testing Notes
- Periodically check the local-only `testing-notes.md` scratchpad during bug-fix work, especially before asking what to do next.
- When `testing-notes.md` contains unresolved items that belong in tracker form, convert them into Gitea issues and then rewrite the file back to its scratchpad prompt.
- Do not re-add `testing-notes.md` to git; it is intentionally local-only.
+8 -7
View File
@@ -1,6 +1,6 @@
# PROJECT_MAP.md
# Auto-generated project index. Update this file whenever you add, remove, or significantly change a file or feature.
# Last updated: 2026-03-28 - the old single-file Studio preview binary has been replaced with a socket-driven `mangotune-preview` companion under `src/bin/mangotune-preview/`, MangoTune now passes studio defaults through env vars and hot-reloads the preview over a Unix socket instead of only relying on CLI args/restarts, the dashboard/help/docs have been updated to match the new preview contract, MangoHud option help still comes from a verified `docs/MANGOHUD_OPTION_BEHAVIOR.md` reference cross-checked against a local upstream source snapshot plus upstream README/config docs, the schema/validator follow MangoHud semantics more closely (unsigned `offset_x`/`offset_y`, flexible xkb-style keybind validation, legacy warning for `benchmark_percentiles`, upstream `preset` as a list-valued special option, the full documented option surface now represented in the live schema, threshold-color toggles now declare the supporting metric/value/color dependencies they actually need, MangoTune strips the mistaken standalone `gpu_load` / `cpu_load` keys because MangoHud itself rejects them as top-level options, rewrites stale profile aliases like `compact`/`stretch` into modern `hud_compact`/`horizontal_stretch`, default-on MangoHud flags now serialize as explicit `=0` when disabled, and negative legacy offsets are normalized back to unsigned values), Studio preview sessions still calibrate against the actual scaled window size after launch, preview-only right-anchor emulation remains in place because fully native right-side positions regressed horizontal preview visibility, horizontal auto-layout previews still get a bounded width estimate, ordinary Studio config edits now rewrite the temp `MANGOHUD_CONFIGFILE` and rely on MangoHud's file watcher instead of restarting the window, those live preview writes are GTK-debounced to reduce churn, preset/profile/revert-style config replacements now use the same live-apply path where possible, the save menu now includes reset-to-defaults, restore-latest-safety-backup, and a real `Switch Active Config…` action, resetting still rebuilds a sane MangoTune baseline config instead of leaving an effectively empty config, explicit config switching now changes the actual editable target in `state.config.path` with save/discard guarding instead of overloading the layer-stack strip, the unreliable preview-docking preference has been removed from the UI, backup-style helper `.conf` files are filtered out of the detected per-app layer list, the top config strip now refreshes into a read-only layer-stack summary with detected conflict counts instead of a static status label or fake selector, Studio preview now exposes direct renderer controls for scene, FPS cap, particle count, particle size, repeated GPU passes, CPU interaction steps, VRAM pressure, VSync, and pause state instead of the older derived `load + advanced` model, with lower defaults (`Dark` scene, `120 FPS` cap, `1000` particles, `0.03` particle size, `1` pass, `0` VRAM pressure, `0` CPU interaction) so the built-in preview starts safely on faster GPUs and stays visually spread instead of collapsing into a tiny edge-on cluster; the particle renderer now uses standard alpha blending instead of additive bloom so larger particles remain readable against the darker scene, and the scene selector is exposed in the dashboard while also updating the running preview over the socket, app toasts now clear older queued messages and use shorter lifetimes by default, palette-style color fields get swatch controls outside the dedicated colors page too, unset swatches render as neutral placeholders instead of alarming red defaults, comma-separated palette entry fields now live in a fixed editor cluster with stable width instead of collapsing around short values, swatch edits now commit through the same validation/save-state path as text edits, section badges now share a tighter mono sizing system, the dashboard profile picker remembers the last selected profile and mirrors that choice into the save-name field, numeric controls now use compact explicit spin-button fields with typed/pasted junk filtered at the editable layer, the Layer Conflicts page now explains what counts as a true layer collision and gives a concrete repro recipe, the dashboard save menu now offers explicit config-target switching while the top strip stays a read-only layer-stack summary keyed to the actual active file, the new `HUD Order` page under `Tools` reorders currently enabled visible HUD blocks by moving their real config lines up and down with live preview refresh, and the dashboard preset buttons now load the real `Benchmark` / `Competitive` / `Performance` / `Streaming` profile files into the current workspace when those profiles exist, with the older built-in mappings kept only as fallback safety
# Last updated: 2026-03-31 - preview update behavior is now documented and partially centralized around shared live-apply helpers (`docs/PREVIEW_UPDATE_MAP.md`, `src/ui/pages/mod.rs`), the top config strip uses an inline target picker instead of the old switch-config dialog, per-app config creation now supports a searchable bundled game-config database (`data/game_config_db.toml`) with documented maintenance workflow, the `HUD Order` page still reorders real HUD groups with live preview sync but currently uses explicit up/down controls after drag-and-drop proved unstable, MangoTune profiles are now framed as real MangoHud `.conf` files applied into the active target, and the shell/menu/popup surfaces have been tightened and moved onto app-owned compact popover/layout hooks instead of relying on stock roomy menu chrome
---
@@ -34,6 +34,7 @@ dashboard control change -> in-memory config updates -> `src/preview/mod.rs` wri
| `ROADMAP.md` | Tactical roadmap | Tracks current UX direction, near-term milestones, and preview-renderer follow-up |
| `docs/MANGOHUD_OPTION_BEHAVIOR.md` | Verified MangoHud reference | Cross-checked against a local upstream source snapshot plus upstream `README.md` and `data/MangoHud.conf`; covers parsing/defaults/positioning rules, special-case options like `preset`, and the full currently documented option surface MangoTune now represents |
| `docs/MANGOHUD_POSITION_LAB.md` | Direct MangoHud test notes | Documents the native MangoHud position lab, expected semantics, isolated-Xorg workflow on `arch.lan`, and the right-alignment test matrix |
| `docs/PREVIEW_UPDATE_MAP.md` | Preview update contract | Maps which UI paths use debounced live apply, immediate live apply, restart, or preview-runtime-only updates, and records the current consistency rules |
| `data/` | Desktop app assets | Desktop entry, metainfo, schema, icon, CSS |
| `data/com.mangotune.MangoTune.gschema.xml` | GSettings schema | Window/app preferences, launcher defaults, remembered profile selection, and studio renderer tuning defaults such as load/FPS/VSync |
| `data/style.css` | App styling | Global CSS hooks for badges, compact dashboard cards, tool-page shells, custom control-row styling, and the newer sharper redesign-inspired visual treatment across shell chrome, sidebar/search/header controls, split/content surfaces, stock-ish GTK surfaces, custom unsaved-changes dialog chrome, section headers, chips, cards, rows, inputs, and callouts, now with a tighter shared mono badge system plus less rounding and denser spacing across the main shells, darker themed container seams between header/sidebar/content areas, plus a distinct active-conflict tint in the layer-stack strip |
@@ -46,7 +47,7 @@ dashboard control change -> in-memory config updates -> `src/preview/mod.rs` wri
| `src/lib.rs` | Library root | Re-exports core modules for app/tests |
| `src/debug_log.rs` | In-app diagnostics buffer | Shared recent-log ring buffer used by the app shell and config parser, with copy/clear support for the Debug page |
| `src/app.rs` | Application bootstrap | GTK/libadwaita app setup, CSS load, startup detection |
| `src/window.rs` | Main shell | App state, header/actions, sidebar, accordion-style section navigation, async config-bar layer discovery, visible-page rebuilds with scroll-position preservation, calmer config-bar language that now frames the strip as a detected read-only layer stack summary instead of an editable target selector, periodic layer-summary refresh with real detected-conflict counts, narrower default sizing and a slimmer sidebar so the app fits better on typical 16:9 desktops, dashboard-first startup without restoring the last visited page, a clearer header-led save/reload/revert/close flow, reset-to-defaults and restore-latest-safety-backup menu actions alongside safety backups, an explicit `Switch Active Config…` flow that lets users move the real editable target between the writable global/per-app XDG configs with save/discard guarding, a sane MangoTune baseline for reset instead of an empty config, selective app-preference reset for preview/backup defaults, a save-menu `Auto backup on save` toggle instead of a mostly-empty Preferences screen, explicit shell styling hooks for the header/sidebar/config strip, and an Adwaita in-app unsaved-changes alert sheet instead of a standalone popup window |
| `src/window.rs` | Main shell | App state, header/actions, sidebar, accordion-style section navigation, async config-bar layer discovery, visible-page rebuilds with scroll-position preservation, a top config strip that now acts as an inline active-target picker plus read-only layer-stack summary, periodic layer-summary refresh with real detected-conflict counts, narrower default sizing and a slimmer sidebar so the app fits better on typical 16:9 desktops, dashboard-first startup without restoring the last visited page, a clearer header-led save/reload/revert/close flow, reset-to-defaults and restore-latest-safety-backup menu actions alongside safety backups, real target switching between writable global/per-app XDG configs with save/discard guarding, a sane MangoTune baseline for reset instead of an empty config, selective app-preference reset for preview/backup defaults, a save-menu `Auto backup on save` toggle instead of a mostly-empty Preferences screen, explicit shell styling hooks for the header/sidebar/config strip, app-owned compact popovers for the top-bar menus, and an Adwaita in-app unsaved-changes alert sheet instead of a standalone popup window |
| `src/preview/` | Managed live preview | Preview-session state, temp preview config writing, start/reload/restart/stop flow |
| `src/preview/mod.rs` | Preview controller | Uses a temporary preview config and launches the actual preview/test process directly, including persisted studio load/FPS/VSync settings, live socket-driven Studio runtime updates for load/FPS/VSync/VRAM/particle/pause controls, temp-config live-apply for ordinary Studio edits without signaling/restarting the process, safer studio restart behavior for window-size changes, legacy flag normalization before preview writes, explicit `horizontal_stretch=0` serialization for stretch-off sessions, effective HUD-width-based preview sizing, preview-only bounded widths for horizontal auto-layout sessions, per-metric auto-width estimation with separate sparse compact/non-compact tuning, preview-only right-anchor emulation for horizontal right-aligned layouts, and Studio-only post-launch window-size calibration so fractional desktop scaling does not throw off width-sensitive preview placement |
| `src/config/normalize.rs` | Legacy option cleanup | Shared normalization for old flag/bool encodings like `key=0`/`key=1`, normalization of old negative offsets back to unsigned values, plus cleanup for the mistaken standalone `gpu_load` / `cpu_load` keys; reused by save/load/profile/preview flows |
@@ -67,8 +68,8 @@ dashboard control change -> in-memory config updates -> `src/preview/mod.rs` wri
| `src/ui/` | UI layer | Page builders and reusable widgets |
| `src/ui/toast.rs` | Toast helper | Shared short-lived toast helper that dismisses older queued messages and gives errors/warnings a slightly longer lifetime |
| `src/ui/widgets/tool_page.rs` | Shared page/window scaffolds | Owns the shared page frame/header, section shells, callouts, and now the reusable utility-window shell used by raw editor and small modal-style utility windows so spacing/frame rules stay consistent |
| `src/ui/pages/mod.rs` | Page registry | Sidebar structure, navigation-page factory, current-config snapshots, shared live-preview helper, calmer section naming/order, a debounce-backed temp-config apply path for ordinary Studio edits, explicit restart flow that can still pass the current preview width into preview refreshes, and a saveable-config gate so invalid intermediate edits do not crash the preview |
| `src/ui/pages/overview.rs` | Dashboard page | Dashboard now uses the same flat page-header scaffold and outer spacing as the rest of the app, while focusing on quick everyday tuning: `Layout & Position`, `Make It Readable`, `Show These Metrics`, a compact profile utility strip with icon actions, and a single-line status strip at the bottom. Live Preview and Presets now live on their own dedicated pages under `Start`, while the dashboard keeps MangoHud-faithful unsigned offsets and the most common metric/appearance toggles |
| `src/ui/pages/mod.rs` | Page registry | Sidebar structure, navigation-page factory, current-config snapshots, search-result routing, and the shared preview-update helpers that now define the two main MangoHud config refresh modes: debounced live apply and immediate live apply |
| `src/ui/pages/overview.rs` | Dashboard page | Dashboard now uses the same flat page-header scaffold and outer spacing as the rest of the app, while focusing on quick everyday tuning: `Layout & Position`, `Make It Readable`, `Show These Metrics`, a compact profile utility strip with icon actions, and a single-line status strip at the bottom. Live Preview and Presets now live on their own dedicated pages under `Start`, while the dashboard keeps MangoHud-faithful unsigned offsets, uses live apply for the common metric/appearance toggles, and separates Studio runtime controls from true preview-window restart cases |
| `src/ui/pages/live_preview.rs` | Live Preview page | Dedicated `Start` page for Studio preview launch/apply/restart/stop, preview window size, scene selection, and direct runtime tuning controls without touching the saved MangoHud config, using the same flat page-header scaffold and spacing rules as the rest of the app |
| `src/ui/pages/presets_page.rs` | Presets page | Dedicated `Start` page for loading the practical starter presets/profile-backed overlay shapes without mixing them into the preview workflow, using the same flat page-header scaffold and spacing rules as the rest of the app |
| `src/ui/pages/debug.rs` | Debug page | Tool-page style diagnostics surface with a live recent-log view, current in-memory config snapshot, and clipboard actions for support/debugging |
@@ -178,9 +179,9 @@ dashboard control change -> in-memory config updates -> `src/preview/mod.rs` wri
---
## ⚠️ Known Issues / Tech Debt
- The dedicated preview renderer is still early and could use even richer scene/load presets plus deeper in-preview UI polish
- The preview renderer still needs more ambitious scene design and richer in-window guidance beyond the current first pass
- UI test coverage is limited; large UX changes currently rely heavily on manual validation
- Right-side horizontal HUD placement still needs one more deliberate real-user validation pass for the remaining edge cases
- Main-window geometry drift on XFCE/X11 is only mitigated, not root-caused yet; see `docs/WINDOW_GEOMETRY_INVESTIGATION.md`
- UI test coverage is still light, so larger GTK interaction changes continue to rely heavily on manual validation
---
+558
View File
@@ -0,0 +1,558 @@
# 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