SteamOS: add flatpak support using steam.pipe (#283)

This commit is contained in:
AAGaming 2023-12-22 08:56:11 -05:00 committed by GitHub
parent 40b952d8bf
commit aa397d003c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 16 deletions

View file

@ -21,6 +21,7 @@ import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./
import { mainWin } from "./mainWindow"; import { mainWin } from "./mainWindow";
import { Settings } from "./settings"; import { Settings } from "./settings";
import { handle, handleSync } from "./utils/ipcWrappers"; import { handle, handleSync } from "./utils/ipcWrappers";
import { isDeckGameMode, showGamePage } from "./utils/steamOS";
import { isValidVencordInstall } from "./utils/vencordLoader"; import { isValidVencordInstall } from "./utils/vencordLoader";
handleSync(IpcEvents.GET_VENCORD_PRELOAD_FILE, () => join(VENCORD_FILES_DIR, "vencordDesktopPreload.js")); handleSync(IpcEvents.GET_VENCORD_PRELOAD_FILE, () => join(VENCORD_FILES_DIR, "vencordDesktopPreload.js"));
@ -47,11 +48,14 @@ handle(IpcEvents.SET_SETTINGS, (_, settings: typeof Settings.store, path?: strin
Settings.setData(settings, path); Settings.setData(settings, path);
}); });
handle(IpcEvents.RELAUNCH, () => { handle(IpcEvents.RELAUNCH, async () => {
const options: RelaunchOptions = { const options: RelaunchOptions = {
args: process.argv.slice(1).concat(["--relaunch"]) args: process.argv.slice(1).concat(["--relaunch"])
}; };
if (app.isPackaged && process.env.APPIMAGE) { if (isDeckGameMode) {
// We can't properly relaunch when running under gamescope, but we can at least navigate to our page in Steam.
await showGamePage();
} else if (app.isPackaged && process.env.APPIMAGE) {
execFile(process.env.APPIMAGE, options.args); execFile(process.env.APPIMAGE, options.args);
} else { } else {
app.relaunch(options); app.relaunch(options);

View file

@ -7,6 +7,7 @@
import { BrowserWindow, shell } from "electron"; import { BrowserWindow, shell } from "electron";
import { Settings } from "../settings"; import { Settings } from "../settings";
import { execSteamURL, isDeckGameMode, steamOpenURL } from "./steamOS";
export function makeLinksOpenExternally(win: BrowserWindow) { export function makeLinksOpenExternally(win: BrowserWindow) {
win.webContents.setWindowOpenHandler(({ url }) => { win.webContents.setWindowOpenHandler(({ url }) => {
@ -30,10 +31,21 @@ export function makeLinksOpenExternally(win: BrowserWindow) {
} }
// eslint-disable-next-line no-fallthrough // eslint-disable-next-line no-fallthrough
case "mailto:": case "mailto:":
case "steam:":
case "spotify:": case "spotify:":
if (isDeckGameMode) {
steamOpenURL(url);
} else {
shell.openExternal(url); shell.openExternal(url);
} }
break;
case "steam:":
if (isDeckGameMode) {
execSteamURL(url);
} else {
shell.openExternal(url);
}
break;
}
return { action: "deny" }; return { action: "deny" };
}); });

View file

@ -4,16 +4,13 @@
* Copyright (c) 2023 Vendicated and Vencord contributors * Copyright (c) 2023 Vendicated and Vencord contributors
*/ */
import { exec as callbackExec } from "child_process";
import { BrowserWindow, dialog } from "electron"; import { BrowserWindow, dialog } from "electron";
import { sleep } from "shared/utils/sleep"; import { writeFile } from "fs/promises";
import { promisify } from "util"; import { join } from "path";
import { MessageBoxChoice } from "../constants"; import { MessageBoxChoice } from "../constants";
import { Settings } from "../settings"; import { Settings } from "../settings";
const exec = promisify(callbackExec);
// Bump this to re-show the prompt // Bump this to re-show the prompt
const layoutVersion = 2; const layoutVersion = 2;
// Get this from "show details" on the profile after exporting as a shared personal layout or using share with community // Get this from "show details" on the profile after exporting as a shared personal layout or using share with community
@ -42,16 +39,28 @@ function getAppId(): string | null {
return null; return null;
} }
async function execSteamURL(url: string): Promise<void> { export async function execSteamURL(url: string): Promise<void> {
await exec(`steam -ifrunning ${url}`); // This doesn't allow arbitrary execution despite the weird syntax.
await writeFile(
join(process.env.HOME || "/home/deck", ".steam", "steam.pipe"),
// replace ' to prevent argument injection
`'${process.env.HOME}/.local/share/Steam/ubuntu12_32/steam' '-ifrunning' '${url.replaceAll("'", "%27")}'\n`,
"utf-8"
);
}
export async function steamOpenURL(url: string) {
await execSteamURL(`steam://openurl/${url}`);
}
export async function showGamePage() {
const appId = getAppId();
if (!appId) return;
await execSteamURL(`steam://nav/games/details/${appId}`);
} }
async function showLayout(appId: string) { async function showLayout(appId: string) {
await execSteamURL(`steam://controllerconfig/${appId}/${layoutId}`); execSteamURL(`steam://controllerconfig/${appId}/${layoutId}`);
// because the UI doesn't consistently reload after the data for the config has loaded...
// HOW HAS NOBODY AT VALVE RUN INTO THIS YET
await sleep(100);
await execSteamURL(`steam://controllerconfig/${appId}/${layoutId}`);
} }
export async function askToApplySteamLayout(win: BrowserWindow) { export async function askToApplySteamLayout(win: BrowserWindow) {