mangohud-logger/mangohud-logger.sh
Gavin Nugent fc2f702fb2 Initial commit: mangohud-logger toggle script
One-touch toggle for MangoHud CSV logging on Linux gaming-launcher systems
(DeckShift, super-alt-S, gamescope-session-plus). Manages three files
idempotently: MangoHud.conf block, environment.d MANGOHUD=1, and a
gamescope-session-plus user override that fixes Steam's mangoapp/MANGOHUD_CONFIGFILE
suppression.
2026-05-18 14:35:26 +01:00

167 lines
6.2 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# mangohud-logger — toggle MangoHud CSV logging on/off
#
# Just run it: if logging is off it gets switched on, if it's already on
# it gets switched off.
#
# What it manages on enable:
# 1. ~/.config/MangoHud/MangoHud.conf
# → appends a marker block with output_folder, autostart_log, etc.
# → keeps your existing keys; overrides `no_display` while logging
# (autostart_log rides on the render hook that no_display disables).
# 2. ~/.config/environment.d/95-mangohud-logger.conf
# → contains MANGOHUD=1 so the Vulkan layer auto-loads into every
# game (gamescope sessions, Steam, native Vulkan apps).
# Picked up by systemd-user at next session login.
#
# Logs land in the user's Downloads folder under "mango-logs"
# (honours XDG_DOWNLOAD_DIR from ~/.config/user-dirs.dirs, else ~/Downloads).
set -euo pipefail
readonly MARKER_BEGIN="# >>> mangohud-logger BEGIN >>>"
readonly MARKER_END="# <<< mangohud-logger END <<<"
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/MangoHud"
CONFIG_FILE="$CONFIG_DIR/MangoHud.conf"
ENV_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/environment.d"
ENV_FILE="$ENV_DIR/95-mangohud-logger.conf"
GS_SESSION_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/gamescope-session-plus/sessions.d"
GS_SESSION_FILE="$GS_SESSION_DIR/steam"
GS_OWNED_MARKER="# Written by mangohud-logger."
# Resolve Downloads via xdg-user-dir if available, else the user-dirs.dirs file,
# else fall back to ~/Downloads. This makes the script work on non-English locales.
if command -v xdg-user-dir >/dev/null 2>&1; then
DOWNLOADS_DIR="$(xdg-user-dir DOWNLOAD)"
elif [[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" ]]; then
# shellcheck disable=SC1090,SC1091
source "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs"
DOWNLOADS_DIR="${XDG_DOWNLOAD_DIR:-$HOME/Downloads}"
else
DOWNLOADS_DIR="$HOME/Downloads"
fi
LOG_DIR="$DOWNLOADS_DIR/mango-logs"
err() { printf '\033[31merror:\033[0m %s\n' "$*" >&2; }
info() { printf '\033[36m::\033[0m %s\n' "$*"; }
ok() { printf '\033[32m✓\033[0m %s\n' "$*"; }
warn() { printf '\033[33m!\033[0m %s\n' "$*"; }
if ! command -v mangohud >/dev/null 2>&1; then
err "mangohud is not installed — install it first (e.g. 'sudo pacman -S mangohud lib32-mangohud')."
exit 1
fi
mkdir -p "$CONFIG_DIR"
[[ -f "$CONFIG_FILE" ]] || : > "$CONFIG_FILE"
if grep -qF "$MARKER_BEGIN" "$CONFIG_FILE"; then
# Currently enabled → strip the block and remove the env file.
tmp=$(mktemp)
awk -v b="$MARKER_BEGIN" -v e="$MARKER_END" '
$0 == b { skip = 1; next }
$0 == e { skip = 0; next }
!skip { print }
' "$CONFIG_FILE" > "$tmp"
# Trim trailing blank lines the block may have left behind.
sed -i -e :a -e '/^\s*$/{$d;N;ba' -e '}' "$tmp"
mv "$tmp" "$CONFIG_FILE"
env_removed=0
if [[ -f "$ENV_FILE" ]]; then
rm -f "$ENV_FILE"
env_removed=1
fi
# Only remove the gamescope session override if WE wrote it.
gs_removed=0
if [[ -f "$GS_SESSION_FILE" ]] && head -1 "$GS_SESSION_FILE" | grep -qF "$GS_OWNED_MARKER"; then
rm -f "$GS_SESSION_FILE"
gs_removed=1
fi
ok "MangoHud logging disabled"
info "existing logs kept in: $LOG_DIR"
if (( env_removed )); then
info "removed: $ENV_FILE"
info "MANGOHUD env var stays set in the *current* session until logout"
fi
if (( gs_removed )); then
info "removed: $GS_SESSION_FILE"
fi
else
# Currently disabled → append the config block + write the env file.
# Check for pre-existing manual log keys *before* we write, so the warning is accurate.
manual_log_keys=0
if grep -qE '^\s*(output_folder|autostart_log|log_duration|log_interval|toggle_logging)\s*=' "$CONFIG_FILE"; then
manual_log_keys=1
fi
mkdir -p "$LOG_DIR"
{
[[ -s "$CONFIG_FILE" ]] && printf '\n'
printf '%s\n' "$MARKER_BEGIN"
printf '# Added by mangohud-logger — remove this block to disable logging.\n'
printf 'output_folder=%s\n' "$LOG_DIR"
printf 'autostart_log=1\n'
printf 'log_duration=0\n'
printf 'log_interval=100\n'
printf 'toggle_logging=Shift_L+F2\n'
# Override any earlier `no_display` — MangoHud's autostart_log rides on the
# render hook, which `no_display` disables. Without this, logs never start.
printf 'no_display=0\n'
printf '%s\n' "$MARKER_END"
} >> "$CONFIG_FILE"
mkdir -p "$ENV_DIR"
cat > "$ENV_FILE" <<EOF
$GS_OWNED_MARKER Delete this file (or re-run the script) to remove.
# Makes the Vulkan loader inject MangoHud into every game so autostart_log fires.
MANGOHUD=1
EOF
# gamescope-session-plus override — only write if file is absent or already ours,
# so we never trample a user-written override.
gs_action=""
if [[ ! -f "$GS_SESSION_FILE" ]] || head -1 "$GS_SESSION_FILE" | grep -qF "$GS_OWNED_MARKER"; then
mkdir -p "$GS_SESSION_DIR"
cat > "$GS_SESSION_FILE" <<EOF
$GS_OWNED_MARKER
# Sourced AFTER /usr/share/gamescope-session-plus/sessions.d/steam (last wins).
#
# Without this:
# 1. The system steam session script exports MANGOHUD_CONFIGFILE pointing to a
# temp file containing only "no_display", which suppresses our user
# ~/.config/MangoHud/MangoHud.conf and so autostart_log/output_folder
# never take effect. Unsetting the var falls back to the user file.
# 2. STEAM_USE_MANGOAPP=1 makes Steam ask gamescope to use the mangoapp
# compositor overlay instead of the in-game MangoHud Vulkan layer.
# The Vulkan layer is the one that writes CSV logs.
unset MANGOHUD_CONFIGFILE
export STEAM_USE_MANGOAPP=0
export STEAM_MANGOAPP_PRESETS_SUPPORTED=0
EOF
gs_action="written"
else
gs_action="left alone (you have a custom override at $GS_SESSION_FILE)"
fi
if (( manual_log_keys )); then
warn "pre-existing log-related keys found in config — they may override ours."
fi
ok "MangoHud logging enabled"
info "log folder: $LOG_DIR"
info "toggle key: Shift+F2 (during a game)"
info "config file: $CONFIG_FILE"
info "env file: $ENV_FILE (MANGOHUD=1)"
info "gamescope override: $GS_SESSION_FILE ($gs_action)"
info "note: while logging is on, the HUD becomes visible during games"
info " (autostart_log needs the render hook that no_display disables)"
warn "log out and back in (or restart your gamescope session) so the env var takes effect."
fi