Files
mangotune/scripts/mangohud-position-lab.sh
T
2026-03-30 23:06:06 -04:00

117 lines
3.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
mangohud-position-lab.sh <config> [app] [output_dir]
Examples:
mangohud-position-lab.sh ~/.config/mangotune/profiles/zz_test_right_sparse_top.conf glxgears
mangohud-position-lab.sh ~/.config/mangotune/profiles/zz_test_right_full_top.conf vkcube /tmp/mh-lab
Notes:
- This runs MangoHud directly, outside MangoTune's preview pipeline.
- OpenGL uses MANGOHUD_DLSYM=1.
- If xdotool/import are installed and a real X11 session is available, a screenshot
and basic window geometry will be written to the output directory.
- Override DISPLAY/XAUTHORITY/WAIT_SECS/WIDTH/HEIGHT from the environment when needed.
EOF
}
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" || $# -lt 1 ]]; then
usage
exit 0
fi
CONFIG_PATH="$1"
APP="${2:-glxgears}"
OUTPUT_DIR="${3:-/tmp/mangohud-position-lab}"
DISPLAY_VALUE="${DISPLAY:-:0}"
XAUTH_VALUE="${XAUTHORITY:-$HOME/.Xauthority}"
WAIT_SECS="${WAIT_SECS:-4}"
WIDTH="${WIDTH:-1400}"
HEIGHT="${HEIGHT:-760}"
mkdir -p "$OUTPUT_DIR"
rm -f "$OUTPUT_DIR"/run.log "$OUTPUT_DIR"/window.geom "$OUTPUT_DIR"/window.png \
"$OUTPUT_DIR"/screen.png "$OUTPUT_DIR"/window_from_screen.png
if [[ ! -f "$CONFIG_PATH" ]]; then
echo "Config not found: $CONFIG_PATH" >&2
exit 2
fi
cleanup() {
if [[ -n "${PID:-}" ]]; then
kill "$PID" 2>/dev/null || true
wait "$PID" 2>/dev/null || true
fi
}
trap cleanup EXIT
case "$APP" in
glxgears)
MATCH_NAME="glxgears"
DISPLAY="$DISPLAY_VALUE" \
XAUTHORITY="$XAUTH_VALUE" \
MANGOHUD_CONFIGFILE="$CONFIG_PATH" \
MANGOHUD_DLSYM=1 \
mangohud glxgears -geometry "${WIDTH}x${HEIGHT}" >"$OUTPUT_DIR/run.log" 2>&1 &
;;
vkcube)
MATCH_NAME="Vkcube"
DISPLAY="$DISPLAY_VALUE" \
XAUTHORITY="$XAUTH_VALUE" \
MANGOHUD_CONFIGFILE="$CONFIG_PATH" \
WGPU_BACKEND="${WGPU_BACKEND:-gl}" \
mangohud vkcube --width "$WIDTH" --height "$HEIGHT" >"$OUTPUT_DIR/run.log" 2>&1 &
;;
*)
echo "Unsupported app: $APP" >&2
exit 2
;;
esac
PID=$!
echo "pid=$PID" >>"$OUTPUT_DIR/run.log"
printf 'display=%s\nxauthority=%s\nwidth=%s\nheight=%s\n' \
"$DISPLAY_VALUE" "$XAUTH_VALUE" "$WIDTH" "$HEIGHT" >>"$OUTPUT_DIR/run.log"
sleep "$WAIT_SECS"
if command -v xwininfo >/dev/null 2>&1; then
DISPLAY="$DISPLAY_VALUE" XAUTHORITY="$XAUTH_VALUE" \
xwininfo -root -tree >"$OUTPUT_DIR/xwininfo.tree" 2>/dev/null || true
fi
if command -v xdotool >/dev/null 2>&1; then
WINDOW_ID="$(DISPLAY="$DISPLAY_VALUE" XAUTHORITY="$XAUTH_VALUE" xdotool search --name "$MATCH_NAME" 2>/dev/null | tail -n1 || true)"
else
WINDOW_ID=""
fi
if [[ -n "$WINDOW_ID" ]]; then
echo "window_id=$WINDOW_ID" >>"$OUTPUT_DIR/run.log"
DISPLAY="$DISPLAY_VALUE" XAUTHORITY="$XAUTH_VALUE" \
xdotool getwindowgeometry --shell "$WINDOW_ID" >"$OUTPUT_DIR/window.geom" 2>/dev/null || true
if command -v import >/dev/null 2>&1; then
DISPLAY="$DISPLAY_VALUE" XAUTHORITY="$XAUTH_VALUE" \
import -window "$WINDOW_ID" "$OUTPUT_DIR/window.png" 2>/dev/null || true
DISPLAY="$DISPLAY_VALUE" XAUTHORITY="$XAUTH_VALUE" \
import -window root "$OUTPUT_DIR/screen.png" 2>/dev/null || true
if [[ -f "$OUTPUT_DIR/window.geom" ]] && [[ -f "$OUTPUT_DIR/screen.png" ]] && command -v convert >/dev/null 2>&1; then
# Crop the full-screen capture back down to the app window bounds. This preserves overlays
# when the compositor draws them separately from the client window content.
# shellcheck disable=SC1090
. "$OUTPUT_DIR/window.geom"
if [[ -n "${WIDTH:-}" && -n "${HEIGHT:-}" && -n "${X:-}" && -n "${Y:-}" ]]; then
convert "$OUTPUT_DIR/screen.png" -crop "${WIDTH}x${HEIGHT}+${X}+${Y}" +repage \
"$OUTPUT_DIR/window_from_screen.png" 2>/dev/null || true
fi
fi
fi
fi
echo "Wrote artifacts to $OUTPUT_DIR"