Files

158 lines
5.6 KiB
Bash
Raw Permalink Normal View History

#!/bin/bash
set -euo pipefail
LOG_FILE="$HOME/.local/logs/session.log"
log() { echo "[$(date --iso-8601=seconds)] $*" | tee -a "$LOG_FILE"; }
CONF_FILE="$HOME/.config/gamescope/gamescope.conf"
[ -f "$CONF_FILE" ] && source "$CONF_FILE"
RESOLUTION=${RESOLUTION:-1920x1080}
WIDTH="${RESOLUTION%x*}"
HEIGHT="${RESOLUTION#*x}"
FRAMERATE=${FRAMERATE:-60}
export __GL_GSYNC_ALLOWED=1
export __GL_VRR_ALLOWED=1
export __GL_SHADER_DISK_CACHE=1
export __GL_SYNC_TO_VBLANK=0
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export LIBVA_DRIVER_NAME=nvidia
export NVD_BACKEND=direct
GAMESCOPE_BIN="$(command -v gamescope || true)"
if [ -z "$GAMESCOPE_BIN" ]; then
log "ERROR: gamescope not found in PATH"
exit 127
fi
HDR_FLAG=""
if [[ "$HDR_ENABLED" == "1" || "$HDR_ENABLED" == "true" || "$HDR_ENABLED" == "yes" ]]; then
HDR_FLAG="--hdr-enabled"
log "HDR flag added: --hdr-enabled"
else
log "HDR disabled, no HDR flag added"
fi
# Create run directory file for startup and stats sockets
# shellcheck disable=SC2030 # (broken warning)
tmpdir="$([[ -n ${XDG_RUNTIME_DIR+x} ]] && mktemp -p "$XDG_RUNTIME_DIR" -d -t gamescope.XXXXXXX)"
socket="${tmpdir:+$tmpdir/startup.socket}"
stats="${tmpdir:+$tmpdir/stats.pipe}"
# Fail early if we don't have a proper runtime directory setup
# shellcheck disable=SC2031 # (broken warning)
if [[ -z $tmpdir || -z ${XDG_RUNTIME_DIR+x} ]]; then
echo >&2 "!! Failed to find run directory in which to create stats session sockets (is \$XDG_RUNTIME_DIR set?)"
exit 0
fi
# Setup MangoHud config file in temp directory
export MANGOHUD_CONFIGFILE="${tmpdir:+$tmpdir/mangohud.config}"
# Initially write no_display to our config file
# so we don't get mangoapp showing up before Steam initializes
# on OOBE and stuff.
mkdir -p "$(dirname "$MANGOHUD_CONFIGFILE")"
echo "no_display" > "$MANGOHUD_CONFIGFILE"
# Chromium (and therefore Steam) ignore XCursor and use on the GTK config
kwriteconfig6 --file gtk-3.0/settings.ini --group Settings --key gtk-cursor-theme-name steam
# Workaround for Steam login issue while Steam client change propagates out of Beta
touch ~/.steam/root/config/SteamAppData.vdf || true
# Increase open file limit for gamescope session
ulimit -n 524288
# 1048576 = 1M - passing it like that omits the 'M' suffix - xargs removes whitespace
free_disk_space_megs=$(df ~/ --output=avail -B1048576 | sed -n '2 p' | xargs)
minimum_free_disk_space_needed_megs=500
if [[ "$free_disk_space_megs" -lt "$minimum_free_disk_space_needed_megs" ]]; then
echo >&2 "gamescope-session: not enough disk space to proceed, trying to find game to delete"
find ~/.local/share/Steam/steamapps/common/ -mindepth 1 -maxdepth 1 -type d -printf "%T@ %p\0" | sort -n -z | while IFS= read -r -d $'\0' line; do
timestamp=${line%% *}
game_folder=${line#* }
[[ -d $game_folder ]] || continue
acf=$(grep -F -- "$(basename -- "$game_folder")" ~/.local/share/Steam/steamapps/*.acf | grep \"installdir\" | cut -d: -f1)
[[ -e "$acf" ]] || continue
echo >&2 "gamescope-session: deleting $(basename "$game_folder")"
appid=$(basename "$acf" | cut -d_ -f2 | cut -d. -f1)
# TODO leave a note for Steam to display UI to explain what happened, if this logic stays
# intentionally leave compatdata; could be unclouded save files there
rm -rf --one-file-system -- "$game_folder" "$acf" ~/.local/share/Steam/steamapps/shadercache/"$appid"
free_disk_space_megs=$(df ~/ --output=avail -B1048576 | sed -n '2 p' | xargs)
[[ "$free_disk_space_megs" -lt "$minimum_free_disk_space_needed_megs" ]] || break
done
fi
export GAMESCOPE_STATS="$stats"
mkfifo -- "$stats"
mkfifo -- "$socket"
# Attempt to claim global session if we're the first one running (e.g. /run/1000/gamescope)
linkname="gamescope-stats"
# shellcheck disable=SC2031 # (broken warning)
sessionlink="${XDG_RUNTIME_DIR:+$XDG_RUNTIME_DIR/}${linkname}" # Account for XDG_RUNTIME_DIR="" (notfragileatall)
lockfile="$sessionlink".lck
exec 9>"$lockfile" # Keep as an fd such that the lock lasts as long as the session if it is taken
if flock -n 9 && rm -f "$sessionlink" && ln -sf "$tmpdir" "$sessionlink"; then
# Took the lock. Don't blow up if those commands fail, though.
echo >&2 "Claimed global gamescope stats session at \"$sessionlink\""
else
echo >&2 "!! Failed to claim global gamescope stats session"
fi
read_gamescope_env() {
log "Waiting for gamescope to provide DISPLAY and GAMESCOPE_WAYLAND_DISPLAY via socket..."
if read -r -t 3 response_x_display response_wl_display <> "$socket"; then
log "Received gamescope environment:"
log " DISPLAY=$response_x_display"
log " GAMESCOPE_WAYLAND_DISPLAY=$response_wl_display"
export DISPLAY="$response_x_display"
export GAMESCOPE_WAYLAND_DISPLAY="$response_wl_display"
# Sync environment variables to systemd, then notify we are ready to launch subsequent services
log "Storing gamescope environment for systemd..."
env > $XDG_RUNTIME_DIR/gamescope-environment
systemd-notify --ready
fi
}
# Spawned in parallel to read values from gamescope
(read_gamescope_env &)
log "Starting Gamescope session..."
# Build gamescope argument array for safe quoting and readability
GAMESCOPE_ARGS=(
--generate-drm-mode fixed
--fade-out-duration 200
--cursor-scale-height 720
-f
-W "$WIDTH" -H "$HEIGHT"
-w "$WIDTH" -h "$HEIGHT"
--rt --mangoapp -e -R "$socket" -T "$stats"
)
# Append HDR flag if enabled
if [ -n "${HDR_FLAG:-}" ]; then
GAMESCOPE_ARGS+=("$HDR_FLAG")
fi
export XDG_CURRENT_DESKTOP=gamescope
export XDG_SESSION_TYPE=wayland
export DESKTOP_SESSION=gamescope
log "Launching Gamescope: $GAMESCOPE_BIN ${GAMESCOPE_ARGS[*]} -- $*"
sudo setcap 'CAP_SYS_NICE=eip' "$GAMESCOPE_BIN"
exec "$GAMESCOPE_BIN" "${GAMESCOPE_ARGS[@]}" >>"$LOG_FILE" 2>&1