Tape :
sudo nano /etc/nixos/customConfig/vortex.nix
Recopiez/collez le code fourni dans le fichier.
(Vous pouvez faire un clic droit dans le terminal, puis cliquer sur « Coller ».)
Code à recopier (Vous avez un bouton à droite du code pour copier le bloc en entier.)
# gaming/vortex.nix
# ---- Vortex — Nexus Mods ----
{
pkgs,
...
}:
let
# ---- umu ----
umu = pkgs.umu-launcher;
# ---- commande ----
vortex = pkgs.writeShellScriptBin "vortex" ''
set -euo pipefail
# ---- outils ----
CURL="${pkgs.curl}/bin/curl"
JQ="${pkgs.jq}/bin/jq"
UMU="${umu}/bin/umu-run"
PYTHON="${pkgs.python3}/bin/python3"
XDG_MIME="${pkgs.xdg-utils}/bin/xdg-mime"
UPDATE_DESKTOP="${pkgs.desktop-file-utils}/bin/update-desktop-database"
NOTIFY="${pkgs.libnotify}/bin/notify-send"
# ---- préfixe ----
COMPAT="''${XDG_DATA_HOME:-$HOME/.local/share}/vortex"
PFX="$COMPAT/pfx"
CACHE="''${XDG_CACHE_HOME:-$HOME/.cache}/vortex"
DOTNET_URL="''${DOTNET_URL:-https://builds.dotnet.microsoft.com/dotnet/WindowsDesktop/9.0.13/windowsdesktop-runtime-9.0.13-win-x64.exe}"
# ---- messages ----
note() { printf '==> %s\n' "$*"; }
die() { printf 'erreur: %s\n' "$*" >&2; exit 1; }
notify() {
"$NOTIFY" -a Vortex "$@" >/dev/null 2>&1 || true
}
# ---- environnement ----
scrub_env() {
unset GI_TYPELIB_PATH GTK_PATH GIO_EXTRA_MODULES GIO_MODULE_DIR || true
unset GSETTINGS_SCHEMA_DIR NIX_GSETTINGS_OVERRIDES_DIR NIX_PROFILES || true
unset GDM_X_SERVER_EXTRA_ARGS || true
unset XDG_DATA_DIRS XDG_CONFIG_DIRS || true
unset QT_PLUGIN_PATH QML2_IMPORT_PATH QTWEBKIT_PLUGIN_PATH || true
unset QT_AUTO_SCREEN_SCALE_FACTOR QT_SCREEN_SCALE_FACTORS || true
unset QT_QPA_PLATFORMTHEME QT_STYLE_OVERRIDE || true
unset QT_WAYLAND_DISABLE_WINDOWDECORATION QT_IM_MODULE || true
unset KDEDIRS KDE_FULL_SESSION KDE_SESSION_VERSION || true
unset KDE_SESSION_UID KDE_APPLICATIONS_AS_SCOPE || true
unset XCURSOR_PATH INFOPATH MANPATH TERMINFO_DIRS LIBEXEC_PATH || true
unset PERLLIB PERL5LIB PYTHONPATH || true
}
# ---- steam ----
find_steam_root() {
local d
for d in \
"$HOME/.local/share/Steam" \
"$HOME/.steam/steam" \
"$HOME/.steam/root"
do
if [[ -d "$d/steamapps" ]]; then
printf '%s\n' "$d"
return 0
fi
done
return 1
}
# ---- proton ----
find_proton() {
local steam root tool d ge_list=() official_list=()
for d in \
"$HOME/.config/heroic/tools/proton/Proton-GE-GLF" \
"$HOME/.local/share/Steam/compatibilitytools.d/Proton-GE-GLF" \
"$HOME/.steam/root/compatibilitytools.d/Proton-GE-GLF"
do
if [[ -x "$d/proton" ]]; then
printf '%s\n' "$d"
return 0
fi
done
steam="$(find_steam_root)" || return 1
local -a roots=("$steam")
if [[ -f "$steam/steamapps/libraryfolders.vdf" ]]; then
while IFS= read -r root; do
[[ -n "$root" && -d "$root" ]] && roots+=("$root")
done < <("$PYTHON" - "$steam/steamapps/libraryfolders.vdf" <<'PY'
import re, sys
text = open(sys.argv[1], encoding="utf-8", errors="replace").read()
for path in re.findall(r'"path"\s+"([^"]+)"', text):
print(path)
PY
)
fi
for root in "''${roots[@]}"; do
if [[ -d "$root/compatibilitytools.d" ]]; then
for d in "$root/compatibilitytools.d"/*; do
[[ -x "$d/proton" ]] || continue
case "$(basename "$d")" in
GE-Proton*|GE-Proton) ge_list+=("$d") ;;
*) official_list+=("$d") ;;
esac
done
fi
if [[ -d "$root/steamapps/common" ]]; then
for d in "$root/steamapps/common"/Proton*; do
[[ -x "$d/proton" ]] || continue
official_list+=("$d")
done
fi
done
if [[ ''${#ge_list[@]} -gt 0 ]]; then
printf '%s\n' "''${ge_list[@]}" | sort -V | tail -n 1
return 0
fi
if [[ ''${#official_list[@]} -gt 0 ]]; then
printf '%s\n' "''${official_list[@]}" | sort -V | tail -n 1
return 0
fi
return 1
}
# ---- vortex.exe ----
find_exe() {
local c
for c in \
"$PFX/drive_c/Program Files/Black Tree Gaming Ltd/Vortex/Vortex.exe" \
"$PFX/drive_c/Program Files/Vortex/Vortex.exe"
do
if [[ -f "$c" ]]; then
printf '%s\n' "$c"
return 0
fi
done
return 1
}
# ---- lancement ----
run_umu() {
local proton="''${1-}"
shift
local shared patched
shared="$COMPAT/wine-tmp"
mkdir -p "$COMPAT" "$shared"
patched="$COMPAT/umu-run"
if [[ ! -x "$patched" || "$UMU" -nt "$patched" ]]; then
sed "s|^ --tmpfs /tmp\$| --bind \"$shared\" /tmp|" "$UMU" > "$patched"
chmod +x "$patched"
fi
grep -q -F -- "--bind \"$shared\" /tmp" "$patched" || die "Partage /tmp impossible."
scrub_env
export GAMEID="umu-vortex"
export SteamGameId="umu-vortex"
export STORE="none"
export STEAM_COMPAT_DATA_PATH="$COMPAT"
export WINEPREFIX="$PFX"
export WINEDLLOVERRIDES="winemenubuilder.exe=d"
export PROTON_USE_XALIA=0
# run : évite waitforexitandrun qui reste coincé si un wineserver zombie tourne
export PROTON_VERB="''${PROTON_VERB:-run}"
# X11 seulement : sinon Electron/Wine démarre sans fenêtre sur Wayland
unset WAYLAND_DISPLAY || true
unset GDK_BACKEND || true
unset QT_QPA_PLATFORM || true
unset NIXOS_OZONE_WL || true
export GDK_BACKEND=x11
export QT_QPA_PLATFORM=xcb
export ELECTRON_OZONE_PLATFORM_HINT=x11
if [[ -n "$proton" && -x "$proton/proton" ]]; then
export PROTONPATH="$proton"
else
unset PROTONPATH || true
fi
"$patched" "$@"
}
# ---- nettoyage zombies ----
cleanup_zombies() {
local self=$$ pid
# Ne pas se tuer soi-même : sinon OOM + fenêtre invisible à cause des clones
while read -r pid; do
[[ -z "$pid" || "$pid" == "$self" ]] && continue
kill "$pid" >/dev/null 2>&1 || true
done < <(pgrep -f '/bin/vortex' || true)
pkill -f 'Vortex\.exe' >/dev/null 2>&1 || true
pkill -f 'Program Files/Vortex' >/dev/null 2>&1 || true
pkill -f 'wineserver -w' >/dev/null 2>&1 || true
sleep 1
while read -r pid; do
[[ -z "$pid" || "$pid" == "$self" ]] && continue
kill -9 "$pid" >/dev/null 2>&1 || true
done < <(pgrep -f '/bin/vortex' || true)
pkill -9 -f 'Vortex\.exe' >/dev/null 2>&1 || true
pkill -9 -f 'Program Files/Vortex' >/dev/null 2>&1 || true
rm -f "$PFX/drive_c/users/steamuser/AppData/Roaming/Vortex/lockfile" 2>/dev/null || true
}
# ---- bibliothèques ----
link_steam() {
local proton="''${1:-}"
local fake="$PFX/drive_c/Program Files (x86)/Steam"
local dos="$PFX/dosdevices"
local steam vdf
mkdir -p "$fake/steamapps" "$fake/config" "$dos"
: > "$fake/steam.exe"
if ! steam="$(find_steam_root)"; then
note "Steam introuvable."
elif [[ ! -f "$steam/steamapps/libraryfolders.vdf" ]]; then
note "libraryfolders.vdf absent."
else
vdf="$steam/steamapps/libraryfolders.vdf"
"$PYTHON" - "$vdf" "$fake/steamapps/libraryfolders.vdf" "$fake/config/libraryfolders.vdf" "$dos" <<'PY'
import os, re, sys
src, out_apps, out_cfg, dos = sys.argv[1:5]
text = open(src, encoding="utf-8", errors="replace").read()
paths = []
seen = set()
def conv(match):
path = match.group(1)
if path.startswith("/") and path not in seen:
seen.add(path)
paths.append(path)
if path.startswith("/"):
path = "Z:" + path.replace("/", "\\")
return f'"path"\t\t"{path}"'
converted = re.sub(r'"path"\s+"([^"]+)"', conv, text)
for dest in (out_apps, out_cfg):
os.makedirs(os.path.dirname(dest), exist_ok=True)
with open(dest, "w", encoding="utf-8") as fh:
fh.write(converted)
letters = list("jklmnopqrstuvwxy")
used = 0
for path in paths:
common = os.path.join(path, "steamapps", "common")
if not os.path.isdir(common) or used >= len(letters):
continue
link = os.path.join(dos, f"{letters[used]}:")
if os.path.isdir(link) and not os.path.islink(link):
print(f" {letters[used]}: déjà un dossier, ignoré")
used += 1
continue
if os.path.lexists(link):
os.remove(link)
os.symlink(common, link)
print(f" {letters[used]}: -> {common}")
used += 1
PY
if [[ -n "$proton" ]]; then
run_umu "$proton" reg add 'HKCU\Software\Valve\Steam' /v SteamPath /t REG_SZ /d 'C:\Program Files (x86)\Steam' /f \
|| note "Registre SteamPath non écrit."
run_umu "$proton" reg add 'HKCU\Software\Valve\Steam' /v SteamExe /t REG_SZ /d 'C:\Program Files (x86)\Steam\steam.exe' /f \
|| true
run_umu "$proton" reg add 'HKCU\Software\Wine' /v Version /t REG_SZ /d win10 /f || true
fi
fi
link_launchers "$proton"
note "Jeux liés."
}
# ---- lanceurs ----
link_launchers() {
local proton="''${1:-}"
local dos="$PFX/dosdevices"
local list="$CACHE/launchers.tsv"
local kind app path
mkdir -p "$dos" "$CACHE"
"$PYTHON" - "$dos" "$list" <<'PY'
import json, os, sys
home = os.environ["HOME"]
dos, out = sys.argv[1:3]
lines = []
parents = []
seen = set()
def remember(path):
path = os.path.realpath(path)
if os.path.isdir(path) and path not in seen:
seen.add(path)
parents.append(path)
def win(path):
return "Z:" + os.path.realpath(path).replace("/", "\\")
gog = os.path.join(home, ".config/heroic/gog_store/installed.json")
if os.path.isfile(gog):
for game in json.load(open(gog, encoding="utf-8")).get("installed") or []:
if game.get("is_dlc"):
continue
path = game.get("install_path") or ""
app = str(game.get("appName") or "")
if app and path and os.path.isdir(path):
lines.append(f"GOG\t{app}\t{win(path)}")
remember(os.path.dirname(os.path.realpath(path)))
leg = os.path.join(home, ".config/heroic/legendaryConfig/legendary/installed.json")
if os.path.isfile(leg):
data = json.load(open(leg, encoding="utf-8"))
items = data if isinstance(data, list) else []
if isinstance(data, dict):
items = data.get("installed") or [
v for v in data.values() if isinstance(v, dict)
]
for game in items:
if not isinstance(game, dict):
continue
path = game.get("install_path") or game.get("install_dir") or ""
if path and os.path.isdir(path):
remember(os.path.dirname(os.path.realpath(path)))
db = os.path.join(home, ".local/share/lutris/pga.db")
if os.path.isfile(db):
import sqlite3
con = sqlite3.connect(db)
try:
for directory, service, service_id, installed in con.execute(
"SELECT directory, service, service_id, installed FROM games"
):
if not installed or not directory or not os.path.isdir(directory):
continue
parent = os.path.dirname(os.path.realpath(directory))
if parent and parent != "/":
remember(parent)
if (service or "").lower() == "gog" and service_id:
lines.append(f"GOG\t{service_id}\t{win(directory)}")
finally:
con.close()
faugus = os.path.join(home, ".config/faugus-launcher/config.json")
if os.path.isfile(faugus):
path = json.load(open(faugus, encoding="utf-8")).get("default-prefix") or ""
if path and os.path.isdir(path):
remember(path)
games = os.path.join(home, ".config/faugus-launcher/games.json")
if os.path.isfile(games):
def walk(node):
if isinstance(node, dict):
for key, value in node.items():
if key.lower() in {"path", "prefix", "install_path", "game_path", "folder"} \
and isinstance(value, str) and value.startswith("/") and os.path.isdir(value):
remember(value)
else:
walk(value)
elif isinstance(node, list):
for item in node:
walk(item)
walk(json.load(open(games, encoding="utf-8")))
used = set()
if os.path.isdir(dos):
for name in os.listdir(dos):
if len(name) == 2 and name.endswith(":"):
used.add(name[0].lower())
letters = [c for c in "jklmnopqrstuvwxy" if c not in used]
for path in parents:
if not letters:
break
letter = letters.pop(0)
link = os.path.join(dos, f"{letter}:")
if os.path.isdir(link) and not os.path.islink(link):
print(f" {letter}: dossier, ignoré")
continue
if os.path.lexists(link):
os.remove(link)
os.symlink(path, link)
print(f" {letter}: -> {path}")
stage = os.path.join(path, "Vortex")
try:
os.makedirs(os.path.join(stage, "staging"), exist_ok=True)
os.makedirs(os.path.join(stage, "downloads"), exist_ok=True)
lines.append(f"STAGE\t{stage}")
except OSError as err:
print(f" staging ignoré: {err}")
with open(out, "w", encoding="utf-8") as fh:
fh.write("".join(f"{line}\n" for line in lines))
PY
[[ -f "$list" ]] || return 0
while IFS=$'\t' read -r kind app path; do
[[ -n "$kind" ]] || continue
case "$kind" in
GOG)
[[ -n "$proton" && -n "$app" && -n "$path" ]] || continue
run_umu "$proton" reg add "HKLM\\Software\\GOG.com\\Games\\$app" /v path /t REG_SZ /d "$path" /f || true
run_umu "$proton" reg add "HKLM\\Software\\WOW6432Node\\GOG.com\\Games\\$app" /v path /t REG_SZ /d "$path" /f || true
note "GOG $app"
;;
STAGE)
note "staging $app"
;;
esac
done < "$list"
}
# ---- nxm ----
register_nxm() {
"$XDG_MIME" default vortex.desktop x-scheme-handler/nxm || true
"$XDG_MIME" default vortex.desktop x-scheme-handler/nxm-protocol || true
if [[ -d "$HOME/.local/share/applications" ]]; then
"$UPDATE_DESKTOP" "$HOME/.local/share/applications" || true
fi
"$UPDATE_DESKTOP" || true
}
# ---- téléchargement ----
download() {
local url="$1" dest="$2"
if [[ -f "$dest" && "''${VORTEX_FORCE_DOWNLOAD:-}" != 1 ]]; then
note "Déjà téléchargé : $dest"
return 0
fi
note "Téléchargement : $url"
"$CURL" -fL --retry 3 --retry-delay 2 -o "$dest.partial" "$url"
mv -f "$dest.partial" "$dest"
}
# ---- installation ----
do_install() {
local proton="" ver url setup dotnet
mkdir -p "$CACHE" "$COMPAT"
notify "Installation de Vortex" "Téléchargement de la dernière version stable…"
if proton="$(find_proton)"; then
note "Proton : $proton"
else
note "Aucun Proton Steam trouvé. umu va télécharger GE-Proton au premier lancement."
proton=""
fi
if [[ -n "''${VORTEX_VERSION:-}" ]]; then
ver="''${VORTEX_VERSION#v}"
url="https://github.com/Nexus-Mods/Vortex/releases/download/v''${ver}/vortex-setup-''${ver}.exe"
else
note "Recherche de la dernière release stable…"
local api
api="$("$CURL" -fsSL \
-H "Accept: application/vnd.github+json" \
-H "User-Agent: glf-vortex-install" \
https://api.github.com/repos/Nexus-Mods/Vortex/releases/latest)"
ver="$("$JQ" -er '.tag_name' <<<"$api")"
ver="''${ver#v}"
url="$("$JQ" -er '[.assets[].browser_download_url | select(test("vortex-setup-.*\\.exe$"))][0]' <<<"$api")"
[[ -n "$url" && "$url" != null ]] || die "Installeur Windows introuvable dans la release $ver."
fi
note "Vortex $ver"
setup="$CACHE/vortex-setup-$ver.exe"
dotnet="$CACHE/windowsdesktop-runtime-9.0.13-win-x64.exe"
download "$url" "$setup"
download "$DOTNET_URL" "$dotnet"
note "Préfixe : $PFX"
note "Runtime .NET 9 Desktop (9.0.13)…"
run_umu "$proton" "$dotnet" /install /quiet /norestart || note "Le runtime a renvoyé une erreur ; l’installeur Vortex embarque le sien."
note "Windows 10 dans le préfixe (Vortex 1.8+)."
run_umu "$proton" reg add 'HKCU\Software\Wine' /v Version /t REG_SZ /d win10 /f || true
note "Installation silencieuse de Vortex (/S)…"
run_umu "$proton" "$setup" /S || note "L’installeur a renvoyé un code non nul ; vérification du binaire…"
find_exe >/dev/null || die "Vortex.exe introuvable dans $PFX. Relance avec VORTEX_FORCE_DOWNLOAD=1 vortex install"
printf '%s\n' "$ver" > "$COMPAT/version" # version installée
note "Liaison des jeux…"
link_steam "$proton"
register_nxm
notify "Vortex est installé" "vortex"
printf 'Vortex %s\n%s\n' "$ver" "$PFX"
}
# ---- démarrage ----
vortex_running() {
local line
while IFS= read -r line; do
[[ "$line" == *--type=* ]] && continue
[[ "$line" == *Vortex.exe* ]] && return 0
done < <(pgrep -af -- 'Vortex\.exe' 2>/dev/null || true)
return 1
}
# Transmet un nxm:// au Vortex déjà ouvert / Hand an nxm:// to the running Vortex
send_nxm() {
local proton="$1" exe="$2" url="$3" pid i
cd "$(dirname "$exe")"
# via umu, en arrière-plan, sans le verrou (9>&-) / via umu, background, without the lock fd
PROTON_VERB=run run_umu "$proton" "$exe" -d "$url" >> "$COMPAT/nxm.log" 2>&1 9>&- &
pid=$!
# attente max 6 s puis on passe au lien suivant, sans kill / wait max 6s then move on, no kill
for i in 1 2 3 4 5 6; do
kill -0 "$pid" >/dev/null 2>&1 || break
sleep 1
done
disown "$pid" >/dev/null 2>&1 || true
}
# ---- mise à jour auto ----
check_update() {
local proton="$1" cur="" latest api url setup
# désactivable avec VORTEX_NO_UPDATE=1 / can be disabled with VORTEX_NO_UPDATE=1
[[ -z "''${VORTEX_NO_UPDATE:-}" && -z "''${VORTEX_VERSION:-}" ]] || return 0
if [[ -f "$COMPAT/version" ]]; then cur="$(<"$COMPAT/version")"; fi
# timeout 5s, hors ligne = on passe / 5s timeout, offline = skip
api="$("$CURL" -fsS --max-time 5 \
-H "Accept: application/vnd.github+json" \
-H "User-Agent: glf-vortex-install" \
https://api.github.com/repos/Nexus-Mods/Vortex/releases/latest)" || return 0
latest="$("$JQ" -er '.tag_name' <<<"$api")" || return 0
latest="''${latest#v}"
[[ "$latest" != "$cur" ]] || return 0
url="$("$JQ" -er '[.assets[].browser_download_url | select(test("vortex-setup-.*\\.exe$"))][0]' <<<"$api")" || return 0
[[ -n "$url" && "$url" != null ]] || return 0
note "Mise à jour Vortex : ''${cur:-inconnue} -> $latest"
notify "Vortex" "Mise à jour vers $latest…"
setup="$CACHE/vortex-setup-$latest.exe"
mkdir -p "$CACHE"
download "$url" "$setup" || return 0
run_umu "$proton" "$setup" /S || note "Mise à jour en erreur / update failed"
printf '%s\n' "$latest" > "$COMPAT/version"
}
do_launch() {
local proton exe
exe="$(find_exe)" || die "Vortex n’est pas installé. Lance : vortex install"
proton="$(find_proton || true)"
# pas de MAJ si Vortex tourne déjà
if ! vortex_running; then check_update "$proton"; fi
cd "$(dirname "$exe")"
if [[ "''${1:-}" == nxm://* || "''${1:-}" == nxm-protocol://* ]]; then
if vortex_running; then
local queue="$COMPAT/nxm.queue" lock="$COMPAT/nxm.lock" url
mkdir -p "$COMPAT"
printf '%s\n' "$1" >> "$queue"
(
flock 9 || exit 0
while true; do
mapfile -t urls < "$queue" || true
: > "$queue"
[[ ''${#urls[@]} -eq 0 ]] && break
for url in "''${urls[@]}"; do
[[ -n "$url" ]] || continue
send_nxm "$proton" "$exe" "$url"
done
done
) 9>"$lock" >/dev/null 2>&1 &
disown || true
else
printf '%s nxm sans Vortex actif, relance\n' "$(date +%T)" >> "$COMPAT/nxm.log"
notify "Vortex" "Ouverture…"
cleanup_zombies
PROTON_VERB=run run_umu "$proton" "$exe" -d "$1"
fi
elif [[ $# -gt 0 ]]; then
cleanup_zombies
notify "Vortex" "Ouverture…"
run_umu "$proton" "$exe" "$@"
else
cleanup_zombies
notify "Vortex" "Ouverture…"
run_umu "$proton" "$exe"
fi
}
# ---- commandes ----
cmd="''${1:-}"
case "$cmd" in
install)
do_install
;;
link-steam|link)
link_steam "$(find_proton || true)"
;;
help|-h|--help)
cat <<EOF
vortex
vortex install
vortex link-steam
EOF
;;
nxm://*|nxm-protocol://*)
if find_exe >/dev/null; then
do_launch "$@"
else
notify "Vortex n’est pas installé" "Lance d’abord : vortex install"
die "Vortex n’est pas installé. Lance : vortex install"
fi
;;
*)
if find_exe >/dev/null; then
do_launch "$@"
else
note "Vortex n’est pas encore installé. Installation…"
do_install
do_launch "$@"
fi
;;
esac
'';
# ---- icône ----
vortexIcon = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/Nexus-Mods/Vortex/master/assets/images/vortex.png";
hash = "sha256-SUaJlRM+s/V/KNmd+oCQIZ8d85Oz+F75Yi2VDBwtlU0=";
};
# ---- raccourci ----
vortexDesktop = pkgs.stdenvNoCC.mkDerivation {
name = "vortex-desktop";
dontUnpack = true;
nativeBuildInputs = [ pkgs.copyDesktopItems ];
desktopItems = [
(pkgs.makeDesktopItem {
name = "vortex";
desktopName = "Vortex";
comment = "Gestionnaire de mods Nexus Mods";
exec = "vortex %u";
icon = "com.nexusmods.vortex";
terminal = false;
categories = [ "Game" "Utility" ];
mimeTypes = [
"x-scheme-handler/nxm"
"x-scheme-handler/nxm-protocol"
];
startupWMClass = "vortex";
})
];
installPhase = ''
runHook preInstall
mkdir -p \
$out/share/icons/hicolor/256x256/apps \
$out/share/icons/Tela-circle/scalable/apps
cp ${vortexIcon} $out/share/icons/hicolor/256x256/apps/com.nexusmods.vortex.png
cp ${vortexIcon} $out/share/icons/Tela-circle/scalable/apps/com.nexusmods.vortex.png
runHook postInstall
'';
};
in
{
# ---- paquets ----
environment.systemPackages = [
vortex
vortexDesktop
umu
];
}
Ensuite :
Ctrl + X pour quitter
Faire O pour confirmer l'enregistrement
Entrée pour confirmer
Ouvre ensuite :
sudo nano /etc/nixos/customConfig/default.nix
Dans imports :
imports = [
./vortex.nix
];
Ensuite :
Ctrl + X -> O -> Entrée
Faite :
glf-update --switch
L’icône Vortex apparaît dans le menu. Le programme n’est pas encore téléchargé.
Clique sur l’icône Vortex dans le menu.
La première fois, le téléchargement et l’installation se font tout seuls. Comptez plusieurs minutes. Le bureau reste en Wayland. Seule la fenêtre de Vortex passe par XWayland.
Steam, Heroic (GOG et Epic), Lutris et Faugus déjà installés sont reliés tout seuls. Rien d’autre à faire.
Dans Vortex : compte Nexus, déploiement Hardlink, dossier de staging sur le même disque que le jeu.
Les liens « Download with manager » (nxm://) ouvrent Vortex.
Si besoin, le terminal :
vortex
Icone
DÉSINSTALLATION
Retire l’import dans default.nix :
./vortex.nix
Supprime le fichier :
sudo rm -f /etc/nixos/customConfig/vortex.nix
Puis :
glf-update --switch
Ça enlève la commande vortex et le raccourci du menu.
Ce qui reste à supprimer manuellement si voulu :
~/.local/share/vortex (préfixe Proton + Vortex)
~/.cache/vortex (installeurs téléchargés)
rm -rf ~/.local/share/vortex
rm -rf ~/.cache/vortex

