diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 3f7141e..38e6405 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -14,7 +14,7 @@ body:
attributes:
label: ProtonShift version
description: "Check the app's About dialog or `electron/package.json`."
- placeholder: "0.8.5"
+ placeholder: "0.8.6"
validations:
required: true
@@ -101,6 +101,8 @@ body:
options:
- AppImage
- .deb package
+ - .rpm package
+ - Flatpak
- Running from source (pnpm dev)
- Other
validations:
diff --git a/.gitignore b/.gitignore
index d5218b5..928c1e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,9 @@
node_modules/
.pnpm-store/
+# Vendored Python wheels for packaged Electron (generated by pnpm run vendor-python)
+electron/python-vendor/
+
# Build outputs — Electron
electron/dist/
electron/out/
diff --git a/README.md b/README.md
index 522e9a4..afb1057 100644
--- a/README.md
+++ b/README.md
@@ -212,24 +212,37 @@ Multiple visual themes with light and dark variants, switchable from the nav bar
## Installation
-**Target:** Pop!_OS, Ubuntu 22.04+, Linux Mint, elementary OS.
+Grab the latest package for your distro from the [Releases](https://github.com/I4cTime/protonshift/releases) page.
-Grab the latest **AppImage** or **.deb** from the [Releases](https://github.com/I4cTime/protonshift/releases) page.
-
-### AppImage
+### AppImage (any distro)
```bash
chmod +x ProtonShift-*.AppImage
./ProtonShift-*.AppImage
```
-### .deb
+### .deb (Ubuntu, Pop!_OS, Mint, elementary OS)
```bash
sudo dpkg -i ProtonShift-*.deb
```
-Requires Python 3.12+ (included as a dependency in the .deb).
+### .rpm (Fedora, openSUSE, RHEL)
+
+```bash
+sudo dnf install ProtonShift-*.rpm
+# or on openSUSE:
+sudo zypper install ProtonShift-*.rpm
+```
+
+### Flatpak
+
+```bash
+flatpak install ProtonShift-*.flatpak
+flatpak run io.github.protonshift
+```
+
+Official builds bundle the Python API stack (FastAPI, Uvicorn, VDF, etc.) beside the app. You only need **Python 3.12+** available as `python3` (the `.deb` already depends on it).
---
diff --git a/assets/io.github.protonshift.metainfo.xml b/assets/io.github.protonshift.metainfo.xml
index 04c6698..8d31acb 100644
--- a/assets/io.github.protonshift.metainfo.xml
+++ b/assets/io.github.protonshift.metainfo.xml
@@ -26,6 +26,7 @@
io.github.protonshift.desktop
https://github.com/I4cTime/protonshift
+
diff --git a/electron/main.ts b/electron/main.ts
index 253a71f..3e6b12d 100644
--- a/electron/main.ts
+++ b/electron/main.ts
@@ -42,7 +42,13 @@ function getPythonCommand(): { cmd: string; args: string[]; env: NodeJS.ProcessE
const resourcesPath = process.resourcesPath;
const srcDir = path.join(resourcesPath, "python", "src");
- env.PYTHONPATH = srcDir + (env.PYTHONPATH ? `:${env.PYTHONPATH}` : "");
+ const vendorDir = path.join(resourcesPath, "python", "vendor");
+ const pyPathParts: string[] = [];
+ if (fs.existsSync(vendorDir)) {
+ pyPathParts.push(vendorDir);
+ }
+ pyPathParts.push(srcDir);
+ env.PYTHONPATH = pyPathParts.join(":") + (env.PYTHONPATH ? `:${env.PYTHONPATH}` : "");
return {
cmd: "python3",
args: ["-m", "game_setup_hub.api", "--port", "0"],
@@ -69,9 +75,7 @@ function startPython(): Promise {
});
pythonProcess.stderr?.on("data", (data: Buffer) => {
- if (isDev) {
- console.error("[python]", data.toString().trim());
- }
+ console.error("[python]", data.toString().trim());
});
pythonProcess.on("error", (err) => {
diff --git a/electron/package.json b/electron/package.json
index 3220897..8042260 100644
--- a/electron/package.json
+++ b/electron/package.json
@@ -1,6 +1,6 @@
{
"name": "protonshift",
- "version": "0.8.5",
+ "version": "0.8.6",
"description": "Linux game configuration toolkit",
"main": "dist/main.js",
"scripts": {
@@ -9,9 +9,12 @@
"build:renderer": "pnpm --filter protonshift-renderer build",
"build:electron": "tsc",
"build": "pnpm run build:renderer && pnpm run build:electron",
- "dist": "pnpm run build && electron-builder --publish never",
- "dist:appimage": "pnpm run build && electron-builder --linux AppImage --publish never",
- "dist:deb": "pnpm run build && electron-builder --linux deb --publish never"
+ "vendor-python": "bash scripts/vendor-python-deps.sh",
+ "dist": "pnpm run vendor-python && pnpm run build && electron-builder --publish never",
+ "dist:appimage": "pnpm run vendor-python && pnpm run build && electron-builder --linux AppImage --publish never",
+ "dist:deb": "pnpm run vendor-python && pnpm run build && electron-builder --linux deb --publish never",
+ "dist:rpm": "pnpm run vendor-python && pnpm run build && electron-builder --linux rpm --publish never",
+ "dist:flatpak": "pnpm run vendor-python && pnpm run build && electron-builder --linux flatpak --publish never"
},
"packageManager": "pnpm@10.32.1",
"pnpm": {
@@ -62,10 +65,15 @@
{
"from": "../assets",
"to": "assets"
+ },
+ {
+ "from": "python-vendor",
+ "to": "python/vendor",
+ "filter": ["**/*"]
}
],
"linux": {
- "target": ["AppImage", "deb"],
+ "target": ["AppImage", "deb", "rpm", "flatpak"],
"category": "Game",
"icon": "../assets",
"desktop": {
@@ -79,6 +87,33 @@
"deb": {
"depends": ["python3 (>= 3.12)"],
"maintainer": "I4cTime "
+ },
+ "rpm": {
+ "depends": ["python3 >= 3.12"],
+ "fpm": ["--rpm-summary", "Linux game configuration toolkit"]
+ },
+ "flatpak": {
+ "baseVersion": "24.08",
+ "runtime": "org.freedesktop.Platform",
+ "runtimeVersion": "24.08",
+ "sdk": "org.freedesktop.Sdk",
+ "finishArgs": [
+ "--share=ipc",
+ "--share=network",
+ "--socket=x11",
+ "--socket=wayland",
+ "--socket=pulseaudio",
+ "--filesystem=home:ro",
+ "--filesystem=~/.steam:ro",
+ "--filesystem=~/.local/share/Steam:ro",
+ "--filesystem=~/.config/heroic:ro",
+ "--filesystem=~/.local/share/lutris:ro",
+ "--filesystem=~/.config/MangoHud",
+ "--filesystem=~/.config/environment.d",
+ "--filesystem=~/.config/protonshift",
+ "--device=dri",
+ "--talk-name=org.freedesktop.Flatpak"
+ ]
}
}
}
diff --git a/electron/python-runtime-requirements.txt b/electron/python-runtime-requirements.txt
new file mode 100644
index 0000000..6e318a9
--- /dev/null
+++ b/electron/python-runtime-requirements.txt
@@ -0,0 +1,4 @@
+# Bundled into the AppImage/deb for packaged runs (see scripts/vendor-python-deps.sh).
+fastapi>=0.115,<1
+uvicorn[standard]>=0.34,<1
+vdf>=1.2
diff --git a/electron/renderer/package.json b/electron/renderer/package.json
index 564b5da..3eb1011 100644
--- a/electron/renderer/package.json
+++ b/electron/renderer/package.json
@@ -1,6 +1,6 @@
{
"name": "protonshift-renderer",
- "version": "0.8.5",
+ "version": "0.8.6",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
diff --git a/electron/scripts/vendor-python-deps.sh b/electron/scripts/vendor-python-deps.sh
new file mode 100755
index 0000000..90b5328
--- /dev/null
+++ b/electron/scripts/vendor-python-deps.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+set -euo pipefail
+ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+TARGET="${ROOT}/python-vendor"
+REQ="${ROOT}/python-runtime-requirements.txt"
+rm -rf "${TARGET}"
+python3 -m pip install -r "${REQ}" -t "${TARGET}" --upgrade
+echo "Vendored Python deps into ${TARGET}"
diff --git a/pyproject.toml b/pyproject.toml
index 76bc343..0131dff 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "protonshift"
-version = "0.8.5"
+version = "0.8.6"
description = "Linux game configuration toolkit: GPU, launch options, Proton, env vars"
readme = "README.md"
requires-python = ">=3.12"
diff --git a/src/game_setup_hub/__init__.py b/src/game_setup_hub/__init__.py
index 520cc5f..e972e93 100644
--- a/src/game_setup_hub/__init__.py
+++ b/src/game_setup_hub/__init__.py
@@ -1,3 +1,3 @@
"""ProtonShift — game configuration for Pop!_OS, Ubuntu, and related distros."""
-__version__ = "0.8.5"
+__version__ = "0.8.6"
diff --git a/src/game_setup_hub/api.py b/src/game_setup_hub/api.py
index dc53fc8..2979c17 100644
--- a/src/game_setup_hub/api.py
+++ b/src/game_setup_hub/api.py
@@ -324,7 +324,7 @@ class StatusResponse(BaseModel):
# App setup
# ---------------------------------------------------------------------------
-app = FastAPI(title="ProtonShift API", version="0.8.5")
+app = FastAPI(title="ProtonShift API", version="0.8.6")
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
# Locks for serializing writes to shared resources
diff --git a/src/game_setup_hub/app.py b/src/game_setup_hub/app.py
index 9331f14..4642910 100644
--- a/src/game_setup_hub/app.py
+++ b/src/game_setup_hub/app.py
@@ -1032,7 +1032,7 @@ def on_about(_action, _param):
about = Adw.AboutWindow(
transient_for=win,
application_name="ProtonShift",
- version="0.8.5",
+ version="0.8.6",
developer_name="ProtonShift",
website="https://github.com/protonshift/protonshift",
application_icon="io.github.protonshift",