Initial import
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user