summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxXJSONDeruloXx <danielhimebauch@gmail.com>2026-09-11 09:09:29 -0400
committerxXJSONDeruloXx <danielhimebauch@gmail.com>2026-09-11 09:09:29 -0400
commit18af8d1de5c7d12af674018ce819cc91480cf51a (patch)
treee36fdc2bf5c8584999e92d326ec507d4b1c0259a
parentd2bfdafa92f3d31cc5392bf8a5a1f1df5c2358ce (diff)
downloaddecky-lsfg-vk-18af8d1de5c7d12af674018ce819cc91480cf51a.tar.gz
decky-lsfg-vk-18af8d1de5c7d12af674018ce819cc91480cf51a.zip
fix tab change jutter
-rw-r--r--src/components/ConfigurationTab.tsx1
-rw-r--r--src/components/Content.tsx30
-rw-r--r--src/styles.ts13
3 files changed, 24 insertions, 20 deletions
diff --git a/src/components/ConfigurationTab.tsx b/src/components/ConfigurationTab.tsx
index a6d4c2a..12f36a5 100644
--- a/src/components/ConfigurationTab.tsx
+++ b/src/components/ConfigurationTab.tsx
@@ -88,7 +88,6 @@ export function ConfigurationTab({
<PanelSectionRow>
<ToggleField
label="Show debug tab"
- description="Show the raw configuration and generated files tab for troubleshooting."
checked={showDebugTab}
onChange={onShowDebugTabChange}
/>
diff --git a/src/components/Content.tsx b/src/components/Content.tsx
index 0d49f89..dc8c54f 100644
--- a/src/components/Content.tsx
+++ b/src/components/Content.tsx
@@ -1,5 +1,5 @@
-import { Field, PanelSection, PanelSectionRow, Tabs } from "@decky/ui";
-import { useEffect, useRef, useState } from "react";
+import { Tabs } from "@decky/ui";
+import { useEffect, useRef, useState, type FocusEvent } from "react";
import { FaCube, FaFileAlt, FaGamepad, FaList, FaTools } from "react-icons/fa";
import { ConfigurationData } from "../config/configSchema";
import { useFlatpakConfiguration } from "../hooks/useFlatpakConfiguration";
@@ -79,6 +79,7 @@ export function Content() {
const flatpak = useFlatpakConfiguration(setupComplete);
const [tab, setTab] = useState("Setup");
const [showDebugTab, setShowDebugTab] = usePersistentBoolean(DEBUG_TAB_VISIBILITY_KEY, true);
+ const [contentFocused, setContentFocused] = useState(false);
const previousRunningWorkload = useRef<string | null>(null);
const runningFlatpak = flatpak.runningApp;
const nowPlayingTarget = resolveNowPlayingTarget(runningGame, runningFlatpak);
@@ -154,13 +155,11 @@ export function Content() {
launcher={nowPlayingTarget.launcher}
onConfigChange={flatpak.updateConfig}
/>
- ) : (
- <NowPlayingTabPlaceholder />
- );
+ ) : null;
const tabs = setupComplete
? [
- { id: "NowPlaying", title: tabIcons.nowPlaying, content: nowPlaying },
+ ...(nowPlaying ? [{ id: "NowPlaying", title: tabIcons.nowPlaying, content: nowPlaying }] : []),
{
id: "Games",
title: tabIcons.games,
@@ -205,11 +204,16 @@ export function Content() {
const availableTabIds = new Set(tabs.map(({ id }) => id));
const activeTab = availableTabIds.has(tab) ? tab : setupComplete ? "Games" : "Setup";
+ const handleFocusCapture = (event: FocusEvent<HTMLDivElement>) => {
+ const focusedElement = event.target as HTMLElement | null;
+ setContentFocused(!focusedElement?.closest?.('[role="tab"]'));
+ };
return (
<div
- className="lsfg-vk-tabs"
+ className={`lsfg-vk-tabs${contentFocused ? " lsfg-vk-tabs--content-focused" : ""}`}
style={{ height: "95%", width: "300px", position: "fixed", marginTop: "-12px", overflow: "hidden" }}
+ onFocusCapture={handleFocusCapture}
>
<style>{tabStyles}</style>
<Tabs
@@ -222,15 +226,3 @@ export function Content() {
</div>
);
}
-
-function NowPlayingTabPlaceholder() {
- return (
- <div>
- <PanelSection title="Now Playing">
- <PanelSectionRow>
- <Field label="Nothing running" description="Start an enabled Steam, non-Steam, or Flatpak target to configure it here." />
- </PanelSectionRow>
- </PanelSection>
- </div>
- );
-}
diff --git a/src/styles.ts b/src/styles.ts
index 1bc089b..d197451 100644
--- a/src/styles.ts
+++ b/src/styles.ts
@@ -31,4 +31,17 @@ export const tabStyles = `
display: block;
margin: 0;
}
+
+ .lsfg-vk-tabs--content-focused [role="tablist"][aria-orientation="horizontal"],
+ .lsfg-vk-tabs--content-focused [role="tablist"][aria-orientation="horizontal"] > div,
+ .lsfg-vk-tabs--content-focused [role="tablist"][aria-orientation="horizontal"] > div > div,
+ .lsfg-vk-tabs--content-focused [role="tablist"][aria-orientation="horizontal"] [role="tab"] {
+ animation: none !important;
+ transition: none !important;
+ }
+
+ .lsfg-vk-tabs--content-focused [role="tablist"][aria-orientation="horizontal"] > div > div {
+ scroll-behavior: auto !important;
+ scroll-snap-type: none !important;
+ }
`;