8.6 KiB
Integrations Spec
Overview
MangoTune implements four integrations accessible from the Integrations page. Each integration is independent — a missing tool shows a "not available" state for that section only, without affecting the rest of the app.
1. GameMode Integration
What is GameMode? A daemon by Feral Interactive that applies CPU governor,
scheduler, and I/O priority optimizations when games run. MangoHud can display
whether GameMode is currently active via the gamemode=1 config option.
Detection
// src/integrations/gamemode.rs
pub struct GameModeStatus {
pub daemon_installed: bool, // gamemoded binary found
pub ctl_installed: bool, // gamemodectl binary found
pub daemon_running: bool, // gamemoded process in process list
pub current_clients: u32, // number of active gamemoded clients
}
fn detect() -> GameModeStatus
Detection steps:
which gamemoded— setsdaemon_installedwhich gamemodectl— setsctl_installed- Check process list via
sysinfoforgamemoded— setsdaemon_running - If ctl installed: run
gamemodectl statusand parse client count
UI (on Integrations page)
AdwPreferencesGroup "GameMode"
description: "Feral Interactive GameMode performance optimization daemon"
AdwActionRow "Status"
subtitle: "gamemoded process"
[suffix] label: "Running (3 clients)" / "Stopped" / "Not installed"
AdwSwitchRow "Show GameMode status in overlay"
subtitle: "Sets gamemode=1 in current config"
(bound to the gamemode config option)
AdwActionRow "Enable GameMode for all Steam games"
subtitle: "Adds %command% to default Steam launch options helper"
[suffix] GtkButton "Configure"
No direct daemon control
MangoTune does NOT start/stop gamemoded. It only shows status and helps the user configure the launch options. Provide a tooltip: "Start/stop GameMode via your system service manager (systemctl --user start gamemoded)."
2. Steam Launch Option Helper
Purpose: Generate the correct launch option string for Steam games so that MangoHud (and optionally GameMode) is injected automatically.
Detection
pub struct SteamStatus {
pub installed: bool,
pub flatpak: bool, // true if running as Flatpak
pub running: bool,
pub steam_root: Option<PathBuf>,
pub localconfig_path: Option<PathBuf>,
}
Detection steps:
- Check
which steamandflatpak list | grep com.valvesoftware.Steam - Find Steam root:
- Native:
~/.steam/steam/or~/.local/share/Steam/ - Flatpak:
~/.var/app/com.valvesoftware.Steam/.steam/steam/
- Native:
- Find
userdata/{userId}/config/localconfig.vdf
Launch Option Generator UI
AdwPreferencesGroup "Steam Launch Options"
AdwComboRow "Inject method"
options: [
"mangohud {command}", ← standard
"MANGOHUD=1 %command%", ← env var method
"MANGOHUD_CONFIGFILE=~/.config/... %command%", ← explicit config
"gamemoderun mangohud %command%", ← with GameMode
"gamemoderun mangemoderun mangohud %command%", ← with GameMode (flatpak)
]
AdwEntryRow (read-only)
title: "Generated launch option"
[Shows generated string based on above selection]
[suffix] GtkButton "Copy to clipboard"
AdwActionRow "Instructions"
subtitle: "In Steam: right-click game → Properties → Launch Options → paste above"
Important note for Flatpak Steam
If Flatpak Steam is detected, the generated command uses the correct Flatpak-aware prefix and warns the user that MangoHud must also be installed inside the Flatpak sandbox or as a Flatpak extension.
DO NOT write to localconfig.vdf
MangoTune does NOT modify Steam's localconfig.vdf directly — too fragile and risky. The user copies the generated string manually. This is deliberate and safe.
3. Lutris Integration
Purpose: Help users configure MangoHud for games managed by Lutris.
Detection
pub struct LutrisStatus {
pub installed: bool,
pub flatpak: bool,
pub config_dir: Option<PathBuf>, // ~/.config/lutris/
pub games: Vec<LutrisGame>,
}
pub struct LutrisGame {
pub name: String,
pub slug: String,
pub config_path: PathBuf, // ~/.config/lutris/games/{slug}.yml
pub runner: String,
}
Detection steps:
which lutrisorflatpak list | grep net.lutris.Lutris- Enumerate
~/.config/lutris/games/*.yml— parse YAML for name, slug, runner fields. Use a simple line-by-line parser (avoid heavy YAML dep — these files are simple).
UI
AdwPreferencesGroup "Lutris"
AdwActionRow "Status"
[suffix] "Installed" / "Not found"
(if installed):
AdwComboRow "Game"
[lists all detected Lutris games]
AdwSwitchRow "Enable MangoHud for selected game"
subtitle: "Adds mangohud to the game's Lutris runner configuration"
AdwActionRow "Open game config in Lutris"
[suffix] GtkButton "Open Lutris"
AdwPreferencesGroup (informational)
AdwActionRow
subtitle: "MangoTune can enable MangoHud in Lutris game configs.
Per-game MangoHud config files will be placed at:
~/.config/MangoHud/{game-slug}.conf"
[suffix] GtkButton "Create per-game config"
Config modification approach for Lutris
When "Enable MangoHud for selected game" is toggled ON:
- Read
~/.config/lutris/games/{slug}.yml - Find or create the
system:section - Set
mangohud: trueunder thesystem:key - Write back (preserve all other content, modify only the mangohud line)
- Show toast: "MangoHud enabled for {game name}. Restart Lutris if it's open."
When toggled OFF: set mangohud: false.
4. Heroic Games Launcher Integration
Purpose: Help users configure MangoHud for games managed by Heroic (Epic Games, GOG, and Amazon Prime on Linux).
Detection
pub struct HeroicStatus {
pub installed: bool,
pub flatpak: bool,
pub config_dir: Option<PathBuf>,
pub games: Vec<HeroicGame>,
}
pub struct HeroicGame {
pub title: String,
pub app_name: String, // Heroic's internal ID
pub store: HeroicStore, // Epic, GOG, Amazon
pub config_path: PathBuf, // ~/.config/heroic/GamesConfig/{app_name}.json
}
pub enum HeroicStore { Epic, Gog, Amazon }
Detection steps:
which heroicorflatpak list | grep com.heroicgameslauncher.hgl- Config dirs to check:
- Native:
~/.config/heroic/ - Flatpak:
~/.var/app/com.heroicgameslauncher.hgl/config/heroic/
- Native:
- Enumerate
GamesConfig/*.json— each file = one game config. - Parse JSON: extract
title,appName, store type from file content.
Heroic Game Config JSON structure (relevant fields)
{
"appName": "AppId",
"title": "Game Title",
"enviromentOptions": [
{ "key": "MANGOHUD", "value": "1" }
],
"wrapperOptions": [
{ "exe": "mangohud", "args": "" }
]
}
UI
AdwPreferencesGroup "Heroic Games Launcher"
AdwActionRow "Status"
[suffix] "Installed (Flatpak)" / "Not found"
AdwComboRow "Game"
[lists games grouped by store if > 5 games]
AdwSwitchRow "Enable MangoHud via wrapper"
subtitle: "Adds mangohud as a wrapper in Heroic game settings"
AdwSwitchRow "Enable MangoHud via environment"
subtitle: "Sets MANGOHUD=1 in game environment variables"
AdwActionRow "Per-game config"
subtitle: "~/.config/MangoHud/{app_name}.conf"
[suffix] GtkButton "Create / Edit"
Config modification approach for Heroic
When "Enable MangoHud via wrapper" is toggled ON:
- Read
~/.config/heroic/GamesConfig/{app_name}.json(handle Flatpak path too) - Parse JSON using
serde_json - Add
{ "exe": "mangohud", "args": "" }towrapperOptionsif not present - Write back with pretty-printing
- Show toast: "MangoHud wrapper enabled. Restart Heroic if it's open."
When toggled OFF: remove the mangohud entry from wrapperOptions.
Environment method similarly adds/removes { "key": "MANGOHUD", "value": "1" }.
Integration Page Layout
AdwPreferencesPage "Integrations"
icon-name: "insert-object-symbolic"
[One AdwPreferencesGroup per integration, as described above]
AdwPreferencesGroup "Global MangoHud Enable"
description: "Enable MangoHud system-wide for all applications"
AdwExpanderRow "Auto-enable method"
AdwSwitchRow "Via ~/.config/environment.d/mangohud.conf (recommended, user-scoped)"
AdwSwitchRow "Via ~/.bashrc (shell sessions only)"
AdwSwitchRow "Via /etc/environment (system-wide, requires sudo)"
[Shows currently active method with green checkmark]
[Warning: "System-wide enable may break some applications. Per-game is preferred."]