97 lines
3.6 KiB
TypeScript
97 lines
3.6 KiB
TypeScript
/*
|
|
* SPDX-License-Identifier: GPL-3.0
|
|
* Vesktop, a desktop app aiming to give you a snappier Discord Experience
|
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
|
*/
|
|
|
|
import { BrowserWindow, dialog } from "electron";
|
|
import { writeFile } from "fs/promises";
|
|
import { join } from "path";
|
|
|
|
import { MessageBoxChoice } from "../constants";
|
|
import { State } from "../settings";
|
|
|
|
// Bump this to re-show the prompt
|
|
const layoutVersion = 2;
|
|
// Get this from "show details" on the profile after exporting as a shared personal layout or using share with community
|
|
const layoutId = "3080264545"; // Vesktop Layout v2
|
|
const numberRegex = /^[0-9]*$/;
|
|
|
|
let steamPipeQueue = Promise.resolve();
|
|
|
|
export const isDeckGameMode = process.env.SteamOS === "1" && process.env.SteamGamepadUI === "1";
|
|
|
|
export function applyDeckKeyboardFix() {
|
|
if (!isDeckGameMode) return;
|
|
// Prevent constant virtual keyboard spam that eventually crashes Steam.
|
|
process.env.GTK_IM_MODULE = "None";
|
|
}
|
|
|
|
// For some reason SteamAppId is always 0 for non-steam apps so we do this insanity instead.
|
|
function getAppId(): string | null {
|
|
// /home/deck/.local/share/Steam/steamapps/shadercache/APPID/fozmediav1
|
|
const path = process.env.STEAM_COMPAT_MEDIA_PATH;
|
|
if (!path) return null;
|
|
const pathElems = path?.split("/");
|
|
const appId = pathElems[pathElems.length - 2];
|
|
if (appId.match(numberRegex)) {
|
|
console.log(`Got Steam App ID ${appId}`);
|
|
return appId;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function execSteamURL(url: string) {
|
|
// This doesn't allow arbitrary execution despite the weird syntax.
|
|
steamPipeQueue = steamPipeQueue.then(() =>
|
|
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 function steamOpenURL(url: string) {
|
|
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) {
|
|
execSteamURL(`steam://controllerconfig/${appId}/${layoutId}`);
|
|
}
|
|
|
|
export async function askToApplySteamLayout(win: BrowserWindow) {
|
|
const appId = getAppId();
|
|
if (!appId) return;
|
|
if (State.store.steamOSLayoutVersion === layoutVersion) return;
|
|
const update = Boolean(State.store.steamOSLayoutVersion);
|
|
|
|
// Touch screen breaks in some menus when native touch mode is enabled on latest SteamOS beta, remove most of the update specific text once that's fixed.
|
|
const { response } = await dialog.showMessageBox(win, {
|
|
message: `${update ? "Update" : "Apply"} Vesktop Steam Input Layout?`,
|
|
detail: `Would you like to ${update ? "Update" : "Apply"} Vesktop's recommended Steam Deck controller settings?
|
|
${update ? "Click yes using the touchpad" : "Tap yes"}, then press the X button or tap Apply Layout to confirm.${
|
|
update ? " Doing so will undo any customizations you have made." : ""
|
|
}
|
|
${update ? "Click" : "Tap"} no to keep your current layout.`,
|
|
buttons: ["Yes", "No"],
|
|
cancelId: MessageBoxChoice.Cancel,
|
|
defaultId: MessageBoxChoice.Default,
|
|
type: "question"
|
|
});
|
|
|
|
if (State.store.steamOSLayoutVersion !== layoutVersion) {
|
|
State.store.steamOSLayoutVersion = layoutVersion;
|
|
}
|
|
|
|
if (response === MessageBoxChoice.Cancel) return;
|
|
|
|
await showLayout(appId);
|
|
}
|