Skip to content

Commit 2dacd44

Browse files
committed
feat: hide legacy GPU slider fix toggle when native steamosctl GPU clock control is available
- Add check_native_gpu_slider_support() utility function to detect steamosctl GPU clock support - Execute steamosctl commands as DECKY_USER to avoid root permission issues - Add supports_native_gpu_slider API endpoint in backend - Integrate native GPU slider detection into BackendData initialization - Auto-disable gpuSliderFix in Settings when native support is detected - Hide GPU slider fix toggle in UI when native GPU clock control is available - Use parallel command execution for faster detection (2s timeout per command)
1 parent 05c66b8 commit 2dacd44

7 files changed

Lines changed: 296 additions & 226 deletions

File tree

main.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,3 +598,11 @@ async def check_file_exist(self, file_path: str) -> bool:
598598
except Exception as e:
599599
logger.error(f"Error checking file exist: {e}", exc_info=True)
600600
return False
601+
602+
async def supports_native_gpu_slider(self) -> bool:
603+
try:
604+
from utils import check_native_gpu_slider_support
605+
return check_native_gpu_slider_support()
606+
except Exception as e:
607+
logger.error(f"Error checking native GPU slider support: {e}", exc_info=True)
608+
return False

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,19 @@
3030
"@decky/ui": "^4.10.6",
3131
"@types/lodash": "^4.17.20",
3232
"@types/markdown-it": "^14.1.2",
33-
"@types/react": "19.1.12",
34-
"@types/react-dom": "19.1.9",
33+
"@types/react": "19.2.2",
34+
"@types/react-dom": "19.2.1",
3535
"@types/webpack": "^5.28.5",
3636
"markdown-it": "^14.1.0",
3737
"merge-anything": "^6.0.6",
38-
"rollup": "^4.52.0",
38+
"rollup": "^4.52.4",
3939
"shx": "^0.4.0",
4040
"tslib": "^2.8.1",
41-
"typescript": "^5.9.2"
41+
"typescript": "^5.9.3"
4242
},
4343
"dependencies": {
4444
"@decky/api": "^1.1.2",
45-
"i18next": "^25.5.2",
45+
"i18next": "^25.5.3",
4646
"lodash": "^4.17.21",
4747
"react-icons": "^5.5.0",
4848
"typescript-json-serializer": "^6.0.1"

pnpm-lock.yaml

Lines changed: 205 additions & 205 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

py_modules/utils/__init__.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
from typing import List
44
import signal
55
from contextlib import contextmanager
6+
import subprocess
67

8+
import decky
79
from config import RYZENADJ_PATH
810

911
from .battery import (
@@ -42,6 +44,7 @@
4244
"get_charge_type",
4345
"version_compare",
4446
"get_ryzenadj_path",
47+
"check_native_gpu_slider_support",
4548
]
4649

4750

@@ -125,7 +128,6 @@ def signal_handler(signum, frame):
125128

126129
def get_bios_settings():
127130
import json
128-
import subprocess
129131
from config import logger
130132

131133
try:
@@ -149,3 +151,54 @@ def get_bios_settings():
149151
except Exception as e:
150152
logger.error(f"Error get_bios_setting {e}")
151153
return {"BiosSettings": []}
154+
155+
156+
def check_native_gpu_slider_support():
157+
"""
158+
Check if steamosctl supports manual GPU clock control by running commands as decky user.
159+
160+
Returns:
161+
bool: True if both get-manual-gpu-clock-max and get-manual-gpu-clock-min commands succeed
162+
"""
163+
from config import logger
164+
165+
try:
166+
logger.debug("Checking native GPU slider support via steamosctl...")
167+
168+
# Define commands to run as decky user
169+
cmd_max = ["sudo", "-u", decky.DECKY_USER, "steamosctl", "get-manual-gpu-clock-max"]
170+
cmd_min = ["sudo", "-u", decky.DECKY_USER, "steamosctl", "get-manual-gpu-clock-min"]
171+
172+
# Start both processes in parallel
173+
process_max = subprocess.Popen(
174+
cmd_max,
175+
stdout=subprocess.PIPE,
176+
stderr=subprocess.PIPE,
177+
env=get_env()
178+
)
179+
process_min = subprocess.Popen(
180+
cmd_min,
181+
stdout=subprocess.PIPE,
182+
stderr=subprocess.PIPE,
183+
env=get_env()
184+
)
185+
186+
# Wait for both processes to complete with timeout
187+
returncode_max = process_max.wait(timeout=2)
188+
returncode_min = process_min.wait(timeout=2)
189+
190+
logger.debug(f"steamosctl get-manual-gpu-clock-max returncode: {returncode_max}")
191+
logger.debug(f"steamosctl get-manual-gpu-clock-min returncode: {returncode_min}")
192+
193+
# Check if both commands succeeded
194+
result = returncode_max == 0 and returncode_min == 0
195+
logger.info(f"Native GPU slider support detected: {result}")
196+
197+
return result
198+
199+
except subprocess.TimeoutExpired:
200+
logger.error("Timeout when checking steamosctl GPU clock support")
201+
return False
202+
except Exception as e:
203+
logger.error(f"Error checking native GPU slider support: {e}")
204+
return False

src/components/gpu.tsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -395,21 +395,23 @@ const GPUModeComponent: FC = () => {
395395

396396
return (
397397
<div>
398-
<PanelSectionRow>
399-
<ToggleField
400-
label={localizationManager.getString(
401-
localizeStrEnum.GPU_NATIVE_SLIDER
402-
)}
403-
description={localizationManager.getString(
404-
localizeStrEnum.GPU_NATIVE_SLIDER_DESC
405-
)}
406-
checked={gpuSliderFix}
407-
onChange={(fix) => {
408-
setGPUSliderFix(fix);
409-
Settings.setGPUSliderFix(fix);
410-
}}
411-
/>
412-
</PanelSectionRow>
398+
{!Backend.data.getSupportsNativeGpuSlider() && (
399+
<PanelSectionRow>
400+
<ToggleField
401+
label={localizationManager.getString(
402+
localizeStrEnum.GPU_NATIVE_SLIDER
403+
)}
404+
description={localizationManager.getString(
405+
localizeStrEnum.GPU_NATIVE_SLIDER_DESC
406+
)}
407+
checked={gpuSliderFix}
408+
onChange={(fix) => {
409+
setGPUSliderFix(fix);
410+
Settings.setGPUSliderFix(fix);
411+
}}
412+
/>
413+
</PanelSectionRow>
414+
)}
413415
{gpuSliderFix && <GPUModeNaviteComponent />}
414416
{!gpuSliderFix && <GPUModeLegacyComponent />}
415417
</div>

src/util/backend.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export const setCpuFreqByCoreType = callable<[Record<string, number>], boolean>(
9191
export const startGpuNotify = callable<[], any>("start_gpu_notify");
9292
export const stopGpuNotify = callable<[], any>("stop_gpu_notify");
9393
export const checkFileExist = callable<[string], boolean>("check_file_exist");
94+
export const supportsNativeGpuSlider = callable<[], boolean>("supports_native_gpu_slider");
9495

9596

9697
const defaultCpuCoreInfo: CPUCoreInfo = {
@@ -164,6 +165,7 @@ export class BackendData {
164165
supportsResetChargeLimit: false as boolean,
165166
supportsSoftwareChargeLimit: false as boolean,
166167
supportsSteamosManager: false as boolean,
168+
supportsNativeGpuSlider: false as boolean,
167169
schedExtSupport: false as boolean,
168170
availableSchedExtSchedulers: [] as string[],
169171
currentSchedExtScheduler: "" as string,
@@ -205,6 +207,7 @@ export class BackendData {
205207
supportsResetChargeLimit: { callable: supportsResetChargeLimit },
206208
supportsSoftwareChargeLimit: { callable: softwareChargeLimit },
207209
supportsSteamosManager: { callable: () => checkFileExist("/usr/bin/steamosctl") },
210+
supportsNativeGpuSlider: { callable: supportsNativeGpuSlider },
208211
cpuCoreInfo: { callable: getCpuCoreInfo },
209212
currentGovernor: { callable: getCpuGovernor },
210213
latestVersion: { callable: getLatestVersion },

src/util/settings.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,10 @@ export class Settings {
853853
}
854854

855855
static appGPUSliderFix(): boolean {
856+
// Check if native GPU slider is supported
857+
if (Backend.data.getSupportsNativeGpuSlider()) {
858+
return false;
859+
}
856860
return Settings.ensureApp().gpuSliderFix!!;
857861
}
858862

0 commit comments

Comments
 (0)