Initial import

This commit is contained in:
2026-03-30 22:51:56 -04:00
commit 08e2910b9d
103 changed files with 35475 additions and 0 deletions
+149
View File
@@ -0,0 +1,149 @@
# Config Resolution & Priority System
## MangoHud's Config Priority Order (highest to lowest)
When MangoHud loads, it resolves configuration from multiple sources. Later sources
override earlier ones. **Highest priority wins for any given option.**
```
Priority 5 (HIGHEST) — Environment variable override
$MANGOHUD_CONFIG="key=value,key2=value2"
Also: $MANGOHUD_CONFIGFILE="/path/to/custom.conf"
Priority 4 — App-local config (same directory as the game executable)
{game_directory}/MangoHud.conf
Priority 3 — Per-app XDG config (named after the process)
$XDG_CONFIG_HOME/MangoHud/{appname}.conf
(default: ~/.config/MangoHud/{appname}.conf)
Priority 2 — Global XDG user config
$XDG_CONFIG_HOME/MangoHud/MangoHud.conf
(default: ~/.config/MangoHud/MangoHud.conf)
Priority 1 (LOWEST) — MangoHud compiled defaults
(no file, built into the library)
```
## Discovery Algorithm for `config::resolver`
```
fn discover() -> Vec<ConfigLayer>:
1. Check environment:
a. Read $MANGOHUD_CONFIGFILE — if set and path exists, record as Priority 5b
b. Read $MANGOHUD_CONFIG — if set, parse inline key=value pairs as Priority 5a
Note: 5a overrides 5b which overrides all file-based configs
2. Determine XDG config home:
a. Use $XDG_CONFIG_HOME if set and non-empty
b. Otherwise use $HOME/.config
c. If neither available: warn and skip file-based discovery
3. Enumerate known config files in priority order:
a. {XDG_CONFIG_HOME}/MangoHud/MangoHud.conf (global)
b. {XDG_CONFIG_HOME}/MangoHud/*.conf (all per-app configs found)
c. Scan common game directories for MangoHud.conf:
- $HOME/.steam/steam/steamapps/common/*/
- $HOME/.local/share/Steam/steamapps/common/*/
- $HOME/Games/*/
- $HOME/.var/app/com.valvesoftware.Steam/data/Steam/steamapps/common/*/
(Flatpak Steam)
4. For each discovered config file:
- Record: path, source_type, priority_rank, file_exists, last_modified
- Parse if exists
5. Build conflict map:
For each option key found in more than one layer:
- Record which layer provides the winning value
- Record which layers are shadowed
- Mark as "conflict" in the UI
```
## ConfigLayer Struct
```rust
pub struct ConfigLayer {
pub path: Option<PathBuf>, // None for env-var inline configs
pub source_type: LayerSource,
pub priority: u8, // 1=lowest (compiled default) to 5=highest (env)
pub exists: bool,
pub is_editable: bool, // false for env-var layers
pub last_modified: Option<SystemTime>,
pub config: Option<AnnotatedConfig>,
}
pub enum LayerSource {
CompiledDefault,
GlobalXdg, // ~/.config/MangoHud/MangoHud.conf
PerAppXdg(String), // ~/.config/MangoHud/{appname}.conf — stores appname
AppLocal(PathBuf), // {game_dir}/MangoHud.conf
EnvFile(PathBuf), // $MANGOHUD_CONFIGFILE
EnvInline(String), // $MANGOHUD_CONFIG inline value
}
```
## Conflict Detection Rules
A **conflict** exists when:
- An option is explicitly set in two or more layers with different values.
- OR an env var (`$MANGOHUD_CONFIG` or `$MANGOHUD_CONFIGFILE`) is set AND any file-based config also sets the same option — the env always wins but the user may not realize it.
A **shadow** occurs when:
- A lower-priority layer sets an option that a higher-priority layer also sets.
The lower-priority setting is "shadowed" (has no effect at runtime).
## UI: Visual Cascade (CSS Specificity Style)
The Conflicts page (`ui/pages/conflicts.rs`) renders a vertical stack of layers,
highest priority at top. For each layer:
```
┌─────────────────────────────────────────────────────────┐
│ 🔴 ENV: $MANGOHUD_CONFIG [not editable]│
│ gpu_stats=0 fps_limit=120 text_color=FF0000 │
├─────────────────────────────────────────────────────────┤
│ 🟡 Per-App: ~/.config/MangoHud/cs2.conf [Edit] │
│ fps_limit=60 ← SHADOWED by ENV above │
│ gpu_temp=1 cpu_temp=1 ram=1 │
├─────────────────────────────────────────────────────────┤
│ 🟢 Global: ~/.config/MangoHud/MangoHud.conf [Edit] │
│ fps_limit=0 ← SHADOWED by cs2.conf and ENV │
│ font_size=24 position=top-left background_alpha=0.5 │
└─────────────────────────────────────────────────────────┘
```
Color coding:
- 🔴 Red badge = env var override (cannot edit in app, show value only)
- 🟡 Yellow badge = per-app or app-local config
- 🟢 Green badge = global config
- Grey strikethrough text = shadowed (ineffective) option
Clicking an option in any layer:
- If editable layer: jumps to that option in the config editor with that layer selected
- If env-var layer: shows tooltip explaining how to unset the env var
## Creating New Config Files
When user clicks "+ New Config":
1. Ask: Global, Per-App (enter app name), or App-Local (browse for directory)?
2. If Per-App: validate app name (alphanumeric + hyphens/underscores only)
3. Create file with header comment block:
```
### MangoHud configuration - managed by MangoTune
### Created: {date}
### App: {appname or "global"}
```
4. Add to resolver's layer stack immediately.
5. Set as the active editing target.
## Config File Write Safety
Before writing any config to disk:
1. Run full validation pass — abort if any errors.
2. Create a backup: `{original_path}.mangotune.bak` (overwrite if exists).
3. Write to `{original_path}.mangotune.tmp`.
4. On success: atomically rename tmp → original.
5. On failure: restore from backup, show error toast.
6. Never write a partial/corrupt file.