From 91b6c3b90c25e5fd5b4941edd65b93287dc4ea22 Mon Sep 17 00:00:00 2001 From: Arkazzae Date: Fri, 23 Oct 2026 11:33:19 +0200 Subject: [PATCH 1/2] Use Wine's default prefix for games added by hand --- .SRCINFO | 2 + CHANGELOG.md | 5 + PKGBUILD | 2 + README.md | 4 +- patches/0038-linux-default-wine-prefix.patch | 103 +++++++++++++++++++ 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 patches/0038-linux-default-wine-prefix.patch diff --git a/.SRCINFO b/.SRCINFO index 2038afe..4353fdc 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -94,6 +94,7 @@ pkgbase = vortex-linux source = 0035-linux-backslash-archive-paths.patch source = 0036-linux-appimage-nxm-links.patch source = 0037-linux-case-consistent-folders.patch + source = 0038-linux-default-wine-prefix.patch source = vortex.sh source = vortex.desktop source = README.md @@ -146,6 +147,7 @@ pkgbase = vortex-linux sha512sums = SKIP sha512sums = SKIP sha512sums = SKIP + sha512sums = SKIP sha512sums = 935db5c6cee19f2c016e67168bfae7b491044735de76c673abb3b125dd325fd5e779d7efe12ba80178d46689ae70a25e558a3fa846417d44c5f4ca256e7f4bf2 sha512sums = e3f31d298a2b674b54c7fc89fb3f06d9645fc5879a54f2ebf2ea20e9ee7ae55f1bfe3284c1f90a591d6be2d6bcd251790ddc27771d65303e7a6a56d331df4632 sha512sums = 2161dfa1cf027cdc074de7195b5f206b17ebd829ae415b9e7c9ee5f06d3952b6583030022dbe0d6e9221b5c577c411d7cd5322241f6d2299d9c886641215699b diff --git a/CHANGELOG.md b/CHANGELOG.md index 2309c06..244d292 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ publishes a new Vortex version, taking any pending notes with it. ## Unreleased +- A game added by hand, outside Steam and Heroic, runs in Wine's default + prefix (`$WINEPREFIX` or `~/.wine`) instead of failing with "The game's Wine + prefix is unavailable". The message now also says where to set a different + prefix: edit the game on the Dashboard, Environment Variables. (#22) + ## 2.9.0-2 - 2026-10-22 - Mods whose archives use Windows backslashes between folders install diff --git a/PKGBUILD b/PKGBUILD index 01bf657..2843385 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -138,6 +138,7 @@ _patches=( '0035-linux-backslash-archive-paths.patch' '0036-linux-appimage-nxm-links.patch' '0037-linux-case-consistent-folders.patch' + '0038-linux-default-wine-prefix.patch' ) source=( @@ -211,6 +212,7 @@ sha512sums=( 'SKIP' 'SKIP' 'SKIP' + 'SKIP' # Keep integrity checks for binaries downloaded outside this repository. '935db5c6cee19f2c016e67168bfae7b491044735de76c673abb3b125dd325fd5e779d7efe12ba80178d46689ae70a25e558a3fa846417d44c5f4ca256e7f4bf2' 'e3f31d298a2b674b54c7fc89fb3f06d9645fc5879a54f2ebf2ea20e9ee7ae55f1bfe3284c1f90a591d6be2d6bcd251790ddc27771d65303e7a6a56d331df4632' diff --git a/README.md b/README.md index 76d8211..3e596a1 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,9 @@ The selected game determines which prefix Vortex uses. Steam’s per-game Proton selection takes precedence over its default selection. Heroic’s game settings select Wine, Proton or UMU; Flatpak tools run inside the Heroic Flatpak. -For a manually added Wine game, set `WINEPREFIX` in its environment settings. +A game added by hand runs in Wine's default prefix, `$WINEPREFIX` or `~/.wine`. +For another prefix, edit the game on the Dashboard and set `WINEPREFIX` under +Environment Variables. `VORTEX_COMPAT_PREFIXES` can list additional prefixes, separated by colons, for lookups without a selected game. If several prefixes match, Vortex reports the ambiguity instead of choosing by modification time. diff --git a/patches/0038-linux-default-wine-prefix.patch b/patches/0038-linux-default-wine-prefix.patch new file mode 100644 index 0000000..5a53498 --- /dev/null +++ b/patches/0038-linux-default-wine-prefix.patch @@ -0,0 +1,103 @@ +diff --git a/src/renderer/src/util/compatibilityPaths.ts b/src/renderer/src/util/compatibilityPaths.ts +--- a/src/renderer/src/util/compatibilityPaths.ts ++++ b/src/renderer/src/util/compatibilityPaths.ts +@@ -85,9 +85,21 @@ function resolveGamePrefix(game: CompatibilityGame): string | null | undefined { + return installation.prefix; + } + } ++ if (!game.store) return defaultWinePrefix(); + return undefined; + } + ++/** ++ * A game added by hand has no store to ask, so it lives where plain Wine runs ++ * everything: $WINEPREFIX, or ~/.wine when that isn't set. ++ */ ++function defaultWinePrefix(): string | undefined { ++ const prefix = path.resolve( ++ expandHome(process.env.WINEPREFIX || path.join(os.homedir(), ".wine")), ++ ); ++ return fs.existsSync(path.join(prefix, "drive_c")) ? prefix : undefined; ++} ++ + interface IUserPathMapping { + linuxRoot: string; + windowsRoot: string[]; +@@ -329,7 +341,7 @@ export function resolveExtensionUserPathSync(input: string): string { + function unavailablePrefix(): Error { + return Object.assign( + new Error( +- "The selected game's Wine/Proton user profile is unavailable. Launch the game once, or configure its WINEPREFIX.", ++ "The selected game's Wine/Proton user profile is unavailable. Launch the game once, or edit the game on the Dashboard and set WINEPREFIX under Environment Variables.", + ), + { code: "ENOENT" }, + ); +diff --git a/src/renderer/src/util/compatibilitySelection.test.ts b/src/renderer/src/util/compatibilitySelection.test.ts +--- a/src/renderer/src/util/compatibilitySelection.test.ts ++++ b/src/renderer/src/util/compatibilitySelection.test.ts +@@ -172,6 +172,30 @@ describe.runIf(process.platform === "linux")("selected compatibility prefix", () + expect(resolveWindowsUserPathSync(path.join(documents, relative))).toBe(expected); + }); + ++ it("uses Wine's default prefix for a game added by hand", () => { ++ vi.stubEnv("WINEPREFIX", ""); ++ const wine = path.join(home, ".wine"); ++ const user = path.join(wine, "drive_c/users", os.userInfo().username); ++ fs.mkdirSync(path.join(user, "Documents"), { recursive: true }); ++ const game = { path: path.join(home, "Games/Example"), executable: "Example.exe" }; ++ setCompatibilityGameProvider(() => game); ++ expect(resolveWindowsUserPathSync(path.join(documents, relative))).toBe( ++ path.join(user, "Documents", relative), ++ ); ++ ++ const exported = path.join(home, "exported-prefix"); ++ fs.mkdirSync(path.join(exported, "drive_c/users/steamuser/Documents"), { recursive: true }); ++ vi.stubEnv("WINEPREFIX", exported); ++ resetCompatibilityPathCache(); ++ expect(resolveWindowsUserPathSync(path.join(documents, relative))).toBe( ++ path.join(exported, "drive_c/users/steamuser/Documents", relative), ++ ); ++ ++ // A store game that wasn't launched yet keeps asking for its own prefix. ++ setCompatibilityGameProvider(() => ({ ...game, store: "steam" })); ++ expect(() => resolveWindowsUserPathSync(path.join(documents, relative))).toThrow(/unavailable/); ++ }); ++ + it("keeps native game paths and Vortex state outside Proton", () => { + const gamePath = path.join(home, "native"); + fs.mkdirSync(gamePath); +diff --git a/src/renderer/src/util/linux/gameTools.test.ts b/src/renderer/src/util/linux/gameTools.test.ts +--- a/src/renderer/src/util/linux/gameTools.test.ts ++++ b/src/renderer/src/util/linux/gameTools.test.ts +@@ -171,6 +171,19 @@ describe.runIf(process.platform === "linux")("game tool runner", () => { + resolveGameTool("Tool.exe", [], { env: { WINEPREFIX: path.join(root, "missing") } }), + ).rejects.toThrow(/prefix is unavailable/); + }); ++ it("runs a game added by hand in Wine's default prefix", async () => { ++ vi.stubEnv("WINEPREFIX", ""); ++ const manual = { path: path.join(root, "Games/Example"), executable: "Example.exe" }; ++ const game = path.join(manual.path, manual.executable); ++ write(game, "MZ"); ++ await expect(resolveGameTool(game, [], {}, manual)).rejects.toThrow(/Environment Variables/); ++ fs.mkdirSync(path.join(root, ".wine/drive_c"), { recursive: true }); ++ resetCompatibilityPathCache(); ++ const command = await resolveGameTool(game, [], {}, manual); ++ expect(command.executable).toBe("wine"); ++ expect(command.args).toEqual([game]); ++ expect(command.options.env.WINEPREFIX).toBe(path.join(root, ".wine")); ++ }); + it("does not launch a Steam tool in a different Wine prefix", async () => { + proton("Proton 10.0"); + const other = path.join(root, "other"); +diff --git a/src/renderer/src/util/linux/gameTools.ts b/src/renderer/src/util/linux/gameTools.ts +--- a/src/renderer/src/util/linux/gameTools.ts ++++ b/src/renderer/src/util/linux/gameTools.ts +@@ -47,7 +47,7 @@ export async function resolveGameTool( + const prefix = options.env?.WINEPREFIX ?? selectedGamePrefix(game); + if (!prefix || !fs.existsSync(path.join(prefix, "drive_c"))) { + throw new Error( +- "The game's Wine prefix is unavailable. Launch the game once or configure WINEPREFIX for this tool.", ++ "The game's Wine prefix is unavailable. Launch the game once, or edit the game or tool on the Dashboard and set WINEPREFIX under Environment Variables.", + ); + } + if (game?.store === "steam") { From ff045f99eae43932b8d6f7a2136c0b3c7fad74a2 Mon Sep 17 00:00:00 2001 From: Arkazzae Date: Fri, 23 Oct 2026 11:33:19 +0200 Subject: [PATCH 2/2] Release 2.9.0-3 --- .SRCINFO | 2 +- PKGBUILD | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.SRCINFO b/.SRCINFO index 4353fdc..5cc1cf8 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,7 +1,7 @@ pkgbase = vortex-linux pkgdesc = Community build of Vortex with generic Linux compatibility patches pkgver = 2.9.0 - pkgrel = 2 + pkgrel = 3 url = https://github.com/Arkazzae/VortexLinux install = vortex.install arch = x86_64 diff --git a/PKGBUILD b/PKGBUILD index 2843385..b97d519 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -2,7 +2,7 @@ pkgname=vortex-linux pkgver=2.9.0 -pkgrel=2 +pkgrel=3 pkgdesc="Community build of Vortex with generic Linux compatibility patches" arch=('x86_64') url="https://github.com/Arkazzae/VortexLinux"