From 8352ee74e8a437c1f4a4dadb75d63049f45b164b Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Tue, 8 Sep 2026 16:25:11 -0400 Subject: add back workarounds sections, scope out of now playing --- src/components/WorkaroundsSection.tsx | 190 ++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/components/WorkaroundsSection.tsx (limited to 'src/components/WorkaroundsSection.tsx') diff --git a/src/components/WorkaroundsSection.tsx b/src/components/WorkaroundsSection.tsx new file mode 100644 index 0000000..e990784 --- /dev/null +++ b/src/components/WorkaroundsSection.tsx @@ -0,0 +1,190 @@ +import { ButtonItem, Field, PanelSectionRow, SliderField, ToggleField } from "@decky/ui"; +import { useEffect, useState } from "react"; +import { RiArrowDownSFill, RiArrowUpSFill } from "react-icons/ri"; +import { usePerAppWorkarounds } from "../hooks/usePerAppWorkarounds"; +import t from "../i18n/i18n"; +import type { WorkaroundField } from "../utils/steamLaunchOptions"; + +interface WorkaroundsSectionProps { + appId: string; + nonSteam: boolean; +} + +const WORKAROUNDS_COLLAPSED_KEY = "lsfg-workarounds-collapsed"; +type ToggleWorkaroundField = Exclude; + +const TOGGLE_ROWS: readonly { + field: ToggleWorkaroundField; + labelKey: string; + label: string; + descriptionKey: string; + description: string; +}[] = [ + { + field: "disableGamescopeWsi", + labelKey: "CONFIG_DISABLE_GAMESCOPE_WSI", + label: "Disable Gamescope WSI", + descriptionKey: "CONFIG_DISABLE_GAMESCOPE_WSI_DESC", + description: "Adds ENABLE_GAMESCOPE_WSI=0 without changing HDR. Requires game restart to apply.", + }, + { + field: "disableSteamdeckMode", + labelKey: "CONFIG_DISABLE_STEAMDECK_MODE", + label: "Disable Steam Deck Mode", + descriptionKey: "CONFIG_DISABLE_STEAMDECK_MODE_DESC", + description: "Disables a game-specific Steam Deck compatibility switch. Requires game restart to apply.", + }, + { + field: "disableVkbasalt", + labelKey: "CONFIG_DISABLE_VKBASALT", + label: "Disable vkBasalt", + descriptionKey: "CONFIG_DISABLE_VKBASALT_DESC", + description: "Disables vkBasalt layer which can conflict with LSFG (Reshade, some Decky plugins)", + }, + { + field: "enableZink", + labelKey: "CONFIG_ENABLE_ZINK", + label: "Force Zink for OpenGL Games", + descriptionKey: "CONFIG_ENABLE_ZINK_DESC", + description: "Uses Mesa's Zink OpenGL-to-Vulkan driver. May cause crashes or freezes with some games. Requires game restart to apply.", + }, +]; + +function usePersistentCollapsed() { + const [collapsed, setCollapsed] = useState(() => { + try { + const saved = localStorage.getItem(WORKAROUNDS_COLLAPSED_KEY); + return saved !== null ? JSON.parse(saved) === true : true; + } catch { + return true; + } + }); + + useEffect(() => { + try { + localStorage.setItem(WORKAROUNDS_COLLAPSED_KEY, JSON.stringify(collapsed)); + } catch { + // Persisting the view preference is optional. + } + }, [collapsed]); + + return [collapsed, () => setCollapsed((value) => !value)] as const; +} + +export function WorkaroundsSection({ appId, nonSteam }: WorkaroundsSectionProps) { + const [collapsed, toggleCollapsed] = usePersistentCollapsed(); + const { status, snapshot, refresh, update, error } = usePerAppWorkarounds(appId, nonSteam); + const state = snapshot?.parsed.state; + const issues = snapshot?.parsed.issues || []; + const controlsDisabled = status !== "ready" || state === undefined; + const [fpsValue, setFpsValue] = useState(null); + const effectiveFpsValue = fpsValue ?? state?.dxvkFrameRate ?? 0; + const fpsLabel = effectiveFpsValue > 0 + ? `${effectiveFpsValue} FPS` + : t("CONFIG_BASE_FPS_CAP_OFF", "Off"); + + useEffect(() => { + setFpsValue(state?.dxvkFrameRate ?? null); + }, [state?.dxvkFrameRate, status]); + + return ( + <> + + +
+ {t("CONFIG_WORKAROUNDS_TITLE", "Workarounds")} +
+
+ +
+ + {collapsed ? : } + +
+
+ + {!collapsed && ( + <> + {status === "loading" && ( + + + + )} + {status === "error" && ( + <> + + + + + void refresh()}>Retry + + + )} + {status === "ready" && issues.length > 0 && ( + + + + )} + + + { + setFpsValue(value); + void update("dxvkFrameRate", value); + }} + disabled={controlsDisabled} + /> + + {TOGGLE_ROWS.map((row) => ( + + void update(row.field, value)} + disabled={controlsDisabled} + /> + + ))} + + )} + + ); +} -- cgit v1.2.3 From 790132668c4421c68c32bdc8fc9792b0d6028f97 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Tue, 8 Sep 2026 22:18:13 -0400 Subject: I really dont want to but here you go little guy --- src/components/WorkaroundsSection.tsx | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/components/WorkaroundsSection.tsx') diff --git a/src/components/WorkaroundsSection.tsx b/src/components/WorkaroundsSection.tsx index e990784..d783620 100644 --- a/src/components/WorkaroundsSection.tsx +++ b/src/components/WorkaroundsSection.tsx @@ -10,7 +10,7 @@ interface WorkaroundsSectionProps { nonSteam: boolean; } -const WORKAROUNDS_COLLAPSED_KEY = "lsfg-workarounds-collapsed"; +const WORKAROUNDS_COLLAPSED_KEY = "lsfg-workarounds-collapsed-v2"; type ToggleWorkaroundField = Exclude; const TOGGLE_ROWS: readonly { @@ -20,19 +20,26 @@ const TOGGLE_ROWS: readonly { descriptionKey: string; description: string; }[] = [ + { + field: "disableSteamdeckMode", + labelKey: "CONFIG_DISABLE_STEAMDECK_MODE", + label: "Disable Steam Deck Mode", + descriptionKey: "CONFIG_DISABLE_STEAMDECK_MODE_DESC", + description: "Disables a game-specific Steam Deck compatibility switch. Requires game restart to apply.", + }, { field: "disableGamescopeWsi", labelKey: "CONFIG_DISABLE_GAMESCOPE_WSI", label: "Disable Gamescope WSI", descriptionKey: "CONFIG_DISABLE_GAMESCOPE_WSI_DESC", - description: "Adds ENABLE_GAMESCOPE_WSI=0 without changing HDR. Requires game restart to apply.", + description: "Adds ENABLE_GAMESCOPE_WSI=0. Requires game restart to apply.", }, { - field: "disableSteamdeckMode", - labelKey: "CONFIG_DISABLE_STEAMDECK_MODE", - label: "Disable Steam Deck Mode", - descriptionKey: "CONFIG_DISABLE_STEAMDECK_MODE_DESC", - description: "Disables a game-specific Steam Deck compatibility switch. Requires game restart to apply.", + field: "disableHdr", + labelKey: "CONFIG_DISABLE_HDR", + label: "Disable HDR", + descriptionKey: "CONFIG_DISABLE_HDR_DESC", + description: "Prevents DXVK from exposing HDR to the game. Requires game restart to apply.", }, { field: "disableVkbasalt", -- cgit v1.2.3 From 1b932fd69c3dba925e0cbf027e05508b2daf5e8c Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Wed, 9 Sep 2026 01:01:42 -0400 Subject: add back launcher script and correct pathing --- src/components/WorkaroundsSection.tsx | 41 +++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'src/components/WorkaroundsSection.tsx') diff --git a/src/components/WorkaroundsSection.tsx b/src/components/WorkaroundsSection.tsx index d783620..dbdd6a3 100644 --- a/src/components/WorkaroundsSection.tsx +++ b/src/components/WorkaroundsSection.tsx @@ -3,11 +3,12 @@ import { useEffect, useState } from "react"; import { RiArrowDownSFill, RiArrowUpSFill } from "react-icons/ri"; import { usePerAppWorkarounds } from "../hooks/usePerAppWorkarounds"; import t from "../i18n/i18n"; -import type { WorkaroundField } from "../utils/steamLaunchOptions"; +import type { WorkaroundField } from "../hooks/usePerAppWorkarounds"; interface WorkaroundsSectionProps { appId: string; nonSteam: boolean; + onRepair?: () => Promise; } const WORKAROUNDS_COLLAPSED_KEY = "lsfg-workarounds-collapsed-v2"; @@ -78,18 +79,28 @@ function usePersistentCollapsed() { return [collapsed, () => setCollapsed((value) => !value)] as const; } -export function WorkaroundsSection({ appId, nonSteam }: WorkaroundsSectionProps) { +export function WorkaroundsSection({ appId, nonSteam, onRepair }: WorkaroundsSectionProps) { const [collapsed, toggleCollapsed] = usePersistentCollapsed(); const { status, snapshot, refresh, update, error } = usePerAppWorkarounds(appId, nonSteam); - const state = snapshot?.parsed.state; - const issues = snapshot?.parsed.issues || []; - const controlsDisabled = status !== "ready" || state === undefined; + const [repairing, setRepairing] = useState(false); + const state = snapshot?.state; + const controlsDisabled = status !== "ready" || state === undefined || snapshot?.wrapperOwned !== true || snapshot.integrationInstalled !== true; const [fpsValue, setFpsValue] = useState(null); const effectiveFpsValue = fpsValue ?? state?.dxvkFrameRate ?? 0; const fpsLabel = effectiveFpsValue > 0 ? `${effectiveFpsValue} FPS` : t("CONFIG_BASE_FPS_CAP_OFF", "Off"); + const handleRepair = async () => { + if (!onRepair || repairing) return; + setRepairing(true); + try { + if (await onRepair()) await refresh(); + } finally { + setRepairing(false); + } + }; + useEffect(() => { setFpsValue(state?.dxvkFrameRate ?? null); }, [state?.dxvkFrameRate, status]); @@ -155,13 +166,19 @@ export function WorkaroundsSection({ appId, nonSteam }: WorkaroundsSectionProps) )} - {status === "ready" && issues.length > 0 && ( - - - + {status === "ready" && snapshot && (!snapshot.wrapperOwned || !snapshot.integrationInstalled) && ( + <> + + + + {onRepair && ( + + void handleRepair()}> + {repairing ? "Reinstalling..." : "Reinstall wrapper"} + + + )} + )} -- cgit v1.2.3 From cc1e6f47dd9838b066822162a607d2859c043aff Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Wed, 9 Sep 2026 19:16:30 -0400 Subject: refactor: unify flatpak targets with steam profiles --- src/components/WorkaroundsSection.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/components/WorkaroundsSection.tsx') diff --git a/src/components/WorkaroundsSection.tsx b/src/components/WorkaroundsSection.tsx index dbdd6a3..5587392 100644 --- a/src/components/WorkaroundsSection.tsx +++ b/src/components/WorkaroundsSection.tsx @@ -1,6 +1,7 @@ import { ButtonItem, Field, PanelSectionRow, SliderField, ToggleField } from "@decky/ui"; import { useEffect, useState } from "react"; import { RiArrowDownSFill, RiArrowUpSFill } from "react-icons/ri"; +import type { TargetTransport } from "../api/lsfgApi"; import { usePerAppWorkarounds } from "../hooks/usePerAppWorkarounds"; import t from "../i18n/i18n"; import type { WorkaroundField } from "../hooks/usePerAppWorkarounds"; @@ -8,6 +9,7 @@ import type { WorkaroundField } from "../hooks/usePerAppWorkarounds"; interface WorkaroundsSectionProps { appId: string; nonSteam: boolean; + transport: TargetTransport; onRepair?: () => Promise; } @@ -79,9 +81,9 @@ function usePersistentCollapsed() { return [collapsed, () => setCollapsed((value) => !value)] as const; } -export function WorkaroundsSection({ appId, nonSteam, onRepair }: WorkaroundsSectionProps) { +export function WorkaroundsSection({ appId, nonSteam, transport, onRepair }: WorkaroundsSectionProps) { const [collapsed, toggleCollapsed] = usePersistentCollapsed(); - const { status, snapshot, refresh, update, error } = usePerAppWorkarounds(appId, nonSteam); + const { status, snapshot, refresh, update, error } = usePerAppWorkarounds(appId, nonSteam, transport); const [repairing, setRepairing] = useState(false); const state = snapshot?.state; const controlsDisabled = status !== "ready" || state === undefined || snapshot?.wrapperOwned !== true || snapshot.integrationInstalled !== true; -- cgit v1.2.3 From 1ce6d55a1d44eeb0eb04751e124970f2f1f9acbb Mon Sep 17 00:00:00 2001 From: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com> Date: Thu, 10 Sep 2026 15:45:03 -0400 Subject: refactor: decouple workaround controls from flatpak transport --- src/components/WorkaroundsSection.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/components/WorkaroundsSection.tsx') diff --git a/src/components/WorkaroundsSection.tsx b/src/components/WorkaroundsSection.tsx index 5587392..050992c 100644 --- a/src/components/WorkaroundsSection.tsx +++ b/src/components/WorkaroundsSection.tsx @@ -1,7 +1,6 @@ import { ButtonItem, Field, PanelSectionRow, SliderField, ToggleField } from "@decky/ui"; import { useEffect, useState } from "react"; import { RiArrowDownSFill, RiArrowUpSFill } from "react-icons/ri"; -import type { TargetTransport } from "../api/lsfgApi"; import { usePerAppWorkarounds } from "../hooks/usePerAppWorkarounds"; import t from "../i18n/i18n"; import type { WorkaroundField } from "../hooks/usePerAppWorkarounds"; @@ -9,7 +8,7 @@ import type { WorkaroundField } from "../hooks/usePerAppWorkarounds"; interface WorkaroundsSectionProps { appId: string; nonSteam: boolean; - transport: TargetTransport; + directFlatpak?: boolean; onRepair?: () => Promise; } @@ -73,17 +72,15 @@ function usePersistentCollapsed() { useEffect(() => { try { localStorage.setItem(WORKAROUNDS_COLLAPSED_KEY, JSON.stringify(collapsed)); - } catch { - // Persisting the view preference is optional. - } + } catch {} }, [collapsed]); return [collapsed, () => setCollapsed((value) => !value)] as const; } -export function WorkaroundsSection({ appId, nonSteam, transport, onRepair }: WorkaroundsSectionProps) { +export function WorkaroundsSection({ appId, nonSteam, directFlatpak = false, onRepair }: WorkaroundsSectionProps) { const [collapsed, toggleCollapsed] = usePersistentCollapsed(); - const { status, snapshot, refresh, update, error } = usePerAppWorkarounds(appId, nonSteam, transport); + const { status, snapshot, refresh, update, error } = usePerAppWorkarounds(appId, nonSteam, directFlatpak); const [repairing, setRepairing] = useState(false); const state = snapshot?.state; const controlsDisabled = status !== "ready" || state === undefined || snapshot?.wrapperOwned !== true || snapshot.integrationInstalled !== true; -- cgit v1.2.3 From 1de34909f7caa0afc9c5b2745112ce29173eda69 Mon Sep 17 00:00:00 2001 From: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com> Date: Thu, 10 Sep 2026 16:35:25 -0400 Subject: refactor: keep steam workarounds transport agnostic --- src/components/WorkaroundsSection.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/components/WorkaroundsSection.tsx') diff --git a/src/components/WorkaroundsSection.tsx b/src/components/WorkaroundsSection.tsx index 050992c..3de5ec1 100644 --- a/src/components/WorkaroundsSection.tsx +++ b/src/components/WorkaroundsSection.tsx @@ -8,7 +8,6 @@ import type { WorkaroundField } from "../hooks/usePerAppWorkarounds"; interface WorkaroundsSectionProps { appId: string; nonSteam: boolean; - directFlatpak?: boolean; onRepair?: () => Promise; } @@ -78,9 +77,9 @@ function usePersistentCollapsed() { return [collapsed, () => setCollapsed((value) => !value)] as const; } -export function WorkaroundsSection({ appId, nonSteam, directFlatpak = false, onRepair }: WorkaroundsSectionProps) { +export function WorkaroundsSection({ appId, nonSteam, onRepair }: WorkaroundsSectionProps) { const [collapsed, toggleCollapsed] = usePersistentCollapsed(); - const { status, snapshot, refresh, update, error } = usePerAppWorkarounds(appId, nonSteam, directFlatpak); + const { status, snapshot, refresh, update, error } = usePerAppWorkarounds(appId, nonSteam); const [repairing, setRepairing] = useState(false); const state = snapshot?.state; const controlsDisabled = status !== "ready" || state === undefined || snapshot?.wrapperOwned !== true || snapshot.integrationInstalled !== true; -- cgit v1.2.3