summaryrefslogtreecommitdiff
path: root/src/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'src/hooks')
-rw-r--r--src/hooks/useGameConfiguration.ts39
-rw-r--r--src/hooks/usePerAppWorkarounds.ts35
2 files changed, 46 insertions, 28 deletions
diff --git a/src/hooks/useGameConfiguration.ts b/src/hooks/useGameConfiguration.ts
index c70d589..e120426 100644
--- a/src/hooks/useGameConfiguration.ts
+++ b/src/hooks/useGameConfiguration.ts
@@ -48,11 +48,6 @@ function selectShortcutExecutable(
.map((candidate) => candidate?.trim())
.find((candidate) => candidate && candidate.startsWith("/"));
if (absolute) return absolute;
-
- // Steam's app-details API can report a Flatpak Target as just "flatpak"
- // even when the shortcut's canonical VDF executable is /usr/bin/flatpak.
- // Keep the stored original executable absolute so SetShortcutExe and the
- // generated dispatcher agree on the same direct transport.
if (target.transport.kind === "flatpak") return "/usr/bin/flatpak";
return candidates.map((candidate) => candidate?.trim()).find(Boolean);
}
@@ -158,25 +153,26 @@ export function useGameConfiguration() {
const oldShortcutExe = existing.shortcut_exe || undefined;
const oldCommandTokenAdded = existing.command_token_added === true;
const oldTransport = existing.transport || target.transport;
- if (target.nonSteam && oldState && current.target === wrapperPath && !oldShortcutExe) {
+ const usesShortcutTarget = target.nonSteam && target.transport.kind === "flatpak";
+ if (usesShortcutTarget && oldState && current.target === wrapperPath && !oldShortcutExe) {
throw new Error("Managed shortcut Target has no saved original executable");
}
- if (target.nonSteam && oldState && current.target !== wrapperPath && current.target !== oldShortcutExe) {
+ if (usesShortcutTarget && oldState && current.target !== wrapperPath && current.target !== oldShortcutExe) {
throw new Error("Shortcut Target changed externally; refusing to replace it");
}
- if (target.nonSteam && !oldState && current.target === wrapperPath) {
+ if (usesShortcutTarget && !oldState && current.target === wrapperPath) {
throw new Error("Shortcut Target is already the managed wrapper but its original Target is unknown");
}
const state = oldState || { ...DEFAULT_WORKAROUND_STATE };
- const originalExecutable = target.nonSteam
+ const originalExecutable = usesShortcutTarget
? selectShortcutExecutable(
target,
oldShortcutExe,
- target.transport.kind === "flatpak" ? target.executable : undefined,
+ target.executable,
current.target,
)
: undefined;
- const initialIntegration = target.nonSteam
+ const initialIntegration = usesShortcutTarget
? current.target === wrapperPath
: hasWrapperLaunchIntegration(current.options, wrapperPath);
const initialStateResult = await setWorkaroundState(
@@ -190,16 +186,22 @@ export function useGameConfiguration() {
let integration: Awaited<ReturnType<typeof installWrapperIntegration>> | null = null;
try {
- integration = await installWrapperIntegration(appId, target.nonSteam, wrapperPath, oldCommandTokenAdded);
+ integration = await installWrapperIntegration(
+ appId,
+ target.nonSteam,
+ wrapperPath,
+ oldCommandTokenAdded,
+ target.transport.kind,
+ );
const finalStateResult = await setWorkaroundState(
target.appid,
state,
- target.nonSteam
+ usesShortcutTarget
? (selectShortcutExecutable(
target,
integration.originalExecutable,
originalExecutable,
- target.transport.kind === "flatpak" ? target.executable : undefined,
+ target.executable,
) || null)
: null,
integration.commandTokenAdded,
@@ -215,15 +217,16 @@ export function useGameConfiguration() {
appId,
target.nonSteam,
wrapperPath,
- target.nonSteam
+ usesShortcutTarget
? (selectShortcutExecutable(
target,
integration?.originalExecutable,
originalExecutable,
- target.transport.kind === "flatpak" ? target.executable : undefined,
+ target.executable,
) || undefined)
: undefined,
integration?.commandTokenAdded ?? oldCommandTokenAdded,
+ target.transport.kind,
);
} catch (rollbackError) {
showErrorToast("Workaround rollback failed", asError(rollbackError).message);
@@ -257,6 +260,7 @@ export function useGameConfiguration() {
const existing = await getWorkaroundState(target.appid);
if (!existing.success) throw new Error(existing.error || "Could not read workaround state");
const wrapperPath = existing.wrapper_path || getDefaultWrapperPath();
+ const usesShortcutTarget = target.nonSteam && target.transport.kind === "flatpak";
if (existing.state) {
await removeWrapperIntegration(
appId,
@@ -264,10 +268,11 @@ export function useGameConfiguration() {
wrapperPath,
existing.shortcut_exe || undefined,
existing.command_token_added === true,
+ target.transport.kind,
);
} else {
const current = await readSteamLaunchOptions(appId, target.nonSteam);
- if (target.nonSteam && (current.target === wrapperPath || isLegacyWrapperToken(current.target))) {
+ if (usesShortcutTarget && (current.target === wrapperPath || isLegacyWrapperToken(current.target))) {
throw new Error("Shortcut Target is a frame-generation wrapper but its original Target is unknown");
}
await cleanupLegacySteamLaunchOptions(appId, target.nonSteam, wrapperPath);
diff --git a/src/hooks/usePerAppWorkarounds.ts b/src/hooks/usePerAppWorkarounds.ts
index e9e44e1..ebb12e2 100644
--- a/src/hooks/usePerAppWorkarounds.ts
+++ b/src/hooks/usePerAppWorkarounds.ts
@@ -73,22 +73,31 @@ function selectShortcutExecutable(
return candidates.map((candidate) => candidate?.trim()).find(Boolean);
}
+function usesShortcutTarget(nonSteam: boolean, transport: TargetTransport): boolean {
+ return nonSteam && transport.kind === "flatpak";
+}
+
function integrationIsInstalled(
steam: SteamLaunchOptionsSnapshot,
nonSteam: boolean,
+ transport: TargetTransport,
wrapperPath: string,
): boolean {
- return nonSteam ? steam.target === wrapperPath : hasWrapperLaunchIntegration(steam.options, wrapperPath);
+ return usesShortcutTarget(nonSteam, transport)
+ ? steam.target === wrapperPath
+ : hasWrapperLaunchIntegration(steam.options, wrapperPath);
}
function makeSnapshot(
steam: SteamLaunchOptionsSnapshot,
result: Awaited<ReturnType<typeof getWorkaroundState>>,
nonSteam: boolean,
+ transport: TargetTransport,
): WorkaroundSnapshot {
if (!result.state) throw new Error("Workaround state is not initialized for this profile");
const wrapperPath = result.wrapper_path || getDefaultWrapperPath();
- if (nonSteam && steam.target === wrapperPath && !result.shortcut_exe) {
+ const selectedTransport = result.transport || transport;
+ if (usesShortcutTarget(nonSteam, selectedTransport) && steam.target === wrapperPath && !result.shortcut_exe) {
throw new Error("Managed shortcut Target has no saved original executable");
}
return {
@@ -96,10 +105,10 @@ function makeSnapshot(
state: result.state,
wrapperPath,
wrapperOwned: result.wrapper_owned === true,
- integrationInstalled: integrationIsInstalled(steam, nonSteam, wrapperPath),
+ integrationInstalled: integrationIsInstalled(steam, nonSteam, selectedTransport, wrapperPath),
commandTokenAdded: result.command_token_added === true,
shortcutExe: result.shortcut_exe,
- transport: result.transport || { kind: "host" },
+ transport: selectedTransport,
};
}
@@ -110,10 +119,11 @@ async function adoptWorkaroundState(
steam: SteamLaunchOptionsSnapshot,
wrapperPath: string,
): Promise<WorkaroundSnapshot> {
- if (nonSteam && (!steam.target || steam.target === wrapperPath || isLegacyWrapperToken(steam.target))) {
+ const shortcutTarget = usesShortcutTarget(nonSteam, transport);
+ if (shortcutTarget && (!steam.target || steam.target === wrapperPath || isLegacyWrapperToken(steam.target))) {
throw new Error("Shortcut Target is a wrapper but its original Target is unknown");
}
- const originalExecutable = nonSteam
+ const originalExecutable = shortcutTarget
? selectShortcutExecutable(transport, steam.target)
: null;
const initial = await setWorkaroundState(
@@ -130,18 +140,20 @@ async function adoptWorkaroundState(
Number(appId),
nonSteam,
wrapperPath,
+ false,
+ transport.kind,
);
const finalized = await setWorkaroundState(
appId,
DEFAULT_WORKAROUND_STATE,
- nonSteam
+ shortcutTarget
? (selectShortcutExecutable(transport, integration.originalExecutable, originalExecutable) || null)
: null,
integration.commandTokenAdded,
transport,
);
if (!finalized.success) throw new Error(finalized.error || "Could not finalize workaround state");
- return makeSnapshot(integration.snapshot, finalized, nonSteam);
+ return makeSnapshot(integration.snapshot, finalized, nonSteam, transport);
} catch (error) {
let rollbackSucceeded = true;
if (integration) {
@@ -150,10 +162,11 @@ async function adoptWorkaroundState(
Number(appId),
nonSteam,
wrapperPath,
- nonSteam
+ shortcutTarget
? (selectShortcutExecutable(transport, integration?.originalExecutable, originalExecutable) || undefined)
: undefined,
integration?.commandTokenAdded ?? false,
+ transport.kind,
);
} catch {
// Leave the owned integration in place rather than guessing at cleanup.
@@ -194,7 +207,7 @@ export function usePerAppWorkarounds(
result.wrapper_path || getDefaultWrapperPath(),
);
}
- return makeSnapshot(steam, result, nonSteam);
+ return makeSnapshot(steam, result, nonSteam, transport);
}, [appId, nonSteam, numericAppId, transport]);
const applySnapshot = useCallback((next: WorkaroundSnapshot) => {
@@ -230,7 +243,7 @@ export function usePerAppWorkarounds(
setSnapshot((current) => current ? {
...current,
steam,
- integrationInstalled: integrationIsInstalled(steam, nonSteam, current.wrapperPath),
+ integrationInstalled: integrationIsInstalled(steam, nonSteam, current.transport, current.wrapperPath),
} : current);
},
(subscriptionError) => {