Merge branch 'dev'
This commit is contained in:
commit
6eb4b9e249
4 changed files with 657 additions and 243 deletions
20
README.md
20
README.md
|
@ -14,7 +14,7 @@ You will need that installed for this plugin to work.
|
||||||
- Set some GPU power parameters (fastPPT & slowPPT)
|
- Set some GPU power parameters (fastPPT & slowPPT)
|
||||||
- Set the fan RPM (unsupported on SteamOS beta)
|
- Set the fan RPM (unsupported on SteamOS beta)
|
||||||
- Display supplementary battery info
|
- Display supplementary battery info
|
||||||
- Keep settings between restarts (stored in `~/.config/powertools.json`)
|
- Keep settings between restarts (stored in `~/.config/powertools/<appid>.json`)
|
||||||
|
|
||||||
## Cool, but that's too much work
|
## Cool, but that's too much work
|
||||||
|
|
||||||
|
@ -79,6 +79,24 @@ This is how I figured out how the fan stuff works.
|
||||||
I've only scratched the surface of what this code allows, I'm sure it has more useful information.
|
I've only scratched the surface of what this code allows, I'm sure it has more useful information.
|
||||||
https://lkml.org/lkml/2022/2/5/391
|
https://lkml.org/lkml/2022/2/5/391
|
||||||
|
|
||||||
|
### Game launch detection
|
||||||
|
|
||||||
|
The biggest limitation right now is it can't detect a game closing -- only opening -- and only after PowerTools is looked at at least once (per SteamOS restart).
|
||||||
|
|
||||||
|
From a plugin, this can be accomplished by running some front-end Javascript.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
await execute_in_tab("SP", false,
|
||||||
|
`SteamClient.Apps.RegisterForGameActionStart((actionType, data) => {
|
||||||
|
console.log("start game", appStore.GetAppOverviewByGameID(data));
|
||||||
|
});`
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
In PowerTools, the callback (the part surrounded by `{` and `}`, containing `console.log(...)`) sends a message to a local HTTP server to notify the PowerTools back-end that a game has been launched.
|
||||||
|
|
||||||
|
If you go to `http://127.0.0.1:5030` on your Steam Deck with PowerTools >=0.6.0, you can see some info about the last game you launched.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This is licensed under GNU GPLv3.
|
This is licensed under GNU GPLv3.
|
||||||
|
|
178
main.py
178
main.py
|
@ -2,11 +2,14 @@ import time
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import pathlib
|
||||||
|
import subprocess
|
||||||
|
|
||||||
VERSION = "0.5.0"
|
VERSION = "0.6.0"
|
||||||
SETTINGS_LOCATION = "~/.config/powertools.json"
|
HOME_DIR = str(pathlib.Path(os.getcwd()).parent.parent.resolve())
|
||||||
|
DEFAULT_SETTINGS_LOCATION = HOME_DIR + "/.config/powertools/default_settings.json"
|
||||||
LOG_LOCATION = "/tmp/powertools.log"
|
LOG_LOCATION = "/tmp/powertools.log"
|
||||||
FANTASTIC_INSTALL_DIR = "~/homebrew/plugins/Fantastic"
|
FANTASTIC_INSTALL_DIR = HOME_DIR + "/homebrew/plugins/Fantastic"
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -17,8 +20,15 @@ logging.basicConfig(
|
||||||
force = True)
|
force = True)
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.DEBUG)
|
||||||
logging.info(f"PowerTools v{VERSION} https://github.com/NGnius/PowerTools")
|
logging.info(f"PowerTools v{VERSION} https://github.com/NGnius/PowerTools")
|
||||||
|
logging.debug(f"CWD: {os.getcwd()} HOME:{HOME_DIR}")
|
||||||
|
|
||||||
|
import sys
|
||||||
|
#import pathlib
|
||||||
|
sys.path.append(str(pathlib.Path(__file__).parent.resolve()))
|
||||||
|
import server as pt_server
|
||||||
|
|
||||||
startup_time = time.time()
|
startup_time = time.time()
|
||||||
|
|
||||||
class CPU:
|
class CPU:
|
||||||
|
@ -120,6 +130,7 @@ class Plugin:
|
||||||
auto_fan = True
|
auto_fan = True
|
||||||
persistent = True
|
persistent = True
|
||||||
modified_settings = False
|
modified_settings = False
|
||||||
|
current_gameid = None
|
||||||
|
|
||||||
async def get_version(self) -> str:
|
async def get_version(self) -> str:
|
||||||
return VERSION
|
return VERSION
|
||||||
|
@ -198,16 +209,16 @@ class Plugin:
|
||||||
self.modified_settings = True
|
self.modified_settings = True
|
||||||
if tick >= len(self.FAN_SPEEDS):
|
if tick >= len(self.FAN_SPEEDS):
|
||||||
# automatic mode
|
# automatic mode
|
||||||
|
self.enable_jupiter_fan_control(self)
|
||||||
self.auto_fan = True
|
self.auto_fan = True
|
||||||
write_to_sys("/sys/class/hwmon/hwmon5/recalculate", 0)
|
write_to_sys("/sys/class/hwmon/hwmon5/recalculate", 0)
|
||||||
write_to_sys("/sys/class/hwmon/hwmon5/fan1_target", 4099) # 4099 is default
|
write_to_sys("/sys/class/hwmon/hwmon5/fan1_target", 4099) # 4099 is default
|
||||||
#subprocess.Popen("systemctl start jupiter-fan-control.service", stdout=subprocess.PIPE, shell=True).wait()
|
|
||||||
else:
|
else:
|
||||||
# manual voltage
|
# manual voltage
|
||||||
|
self.disable_jupiter_fan_control(self)
|
||||||
self.auto_fan = False
|
self.auto_fan = False
|
||||||
write_to_sys("/sys/class/hwmon/hwmon5/recalculate", 1)
|
write_to_sys("/sys/class/hwmon/hwmon5/recalculate", 1)
|
||||||
write_to_sys("/sys/class/hwmon/hwmon5/fan1_target", self.FAN_SPEEDS[tick])
|
write_to_sys("/sys/class/hwmon/hwmon5/fan1_target", self.FAN_SPEEDS[tick])
|
||||||
#subprocess.Popen("systemctl stop jupiter-fan-control.service", stdout=subprocess.PIPE, shell=True).wait()
|
|
||||||
|
|
||||||
async def get_fan_tick(self) -> int:
|
async def get_fan_tick(self) -> int:
|
||||||
fan_target = read_fan_target()
|
fan_target = read_fan_target()
|
||||||
|
@ -231,6 +242,27 @@ class Plugin:
|
||||||
async def fantastic_installed(self) -> bool:
|
async def fantastic_installed(self) -> bool:
|
||||||
return os.path.exists(FANTASTIC_INSTALL_DIR)
|
return os.path.exists(FANTASTIC_INSTALL_DIR)
|
||||||
|
|
||||||
|
def disable_jupiter_fan_control(self):
|
||||||
|
active = subprocess.Popen(["systemctl", "is-active", "jupiter-fan-control.service"]).wait() == 0
|
||||||
|
if active:
|
||||||
|
logging.info("Stopping jupiter-fan-control.service so it doesn't interfere")
|
||||||
|
# only disable if currently active
|
||||||
|
self.jupiter_fan_control_was_disabled = True
|
||||||
|
stop_p = subprocess.Popen(["systemctl", "stop", "jupiter-fan-control.service"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
stop_p.wait()
|
||||||
|
logging.debug("systemctl stop jupiter-fan-control.service stdout:\n" + stop_p.stdout.read().decode())
|
||||||
|
logging.debug("systemctl stop jupiter-fan-control.service stderr:\n" + stop_p.stderr.read().decode())
|
||||||
|
|
||||||
|
def enable_jupiter_fan_control(self):
|
||||||
|
if self.jupiter_fan_control_was_disabled:
|
||||||
|
logging.info("Starting jupiter-fan-control.service so it doesn't interfere")
|
||||||
|
# only re-enable if I disabled it
|
||||||
|
self.jupiter_fan_control_was_disabled = False
|
||||||
|
start_p = subprocess.Popen(["systemctl", "start", "jupiter-fan-control.service"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
start_p.wait()
|
||||||
|
logging.debug("systemctl start jupiter-fan-control.service stdout:\n" + start_p.stdout.read().decode())
|
||||||
|
logging.debug("systemctl start jupiter-fan-control.service stderr:\n" + start_p.stderr.read().decode())
|
||||||
|
|
||||||
# Battery stuff
|
# Battery stuff
|
||||||
|
|
||||||
async def get_charge_now(self) -> int:
|
async def get_charge_now(self) -> int:
|
||||||
|
@ -245,55 +277,56 @@ class Plugin:
|
||||||
# Asyncio-compatible long-running code, executed in a task when the plugin is loaded
|
# Asyncio-compatible long-running code, executed in a task when the plugin is loaded
|
||||||
async def _main(self):
|
async def _main(self):
|
||||||
# startup: load & apply settings
|
# startup: load & apply settings
|
||||||
if os.path.exists(SETTINGS_LOCATION):
|
self.jupiter_fan_control_was_disabled = False
|
||||||
settings = read_json(SETTINGS_LOCATION)
|
if os.path.exists(DEFAULT_SETTINGS_LOCATION):
|
||||||
logging.debug(f"Loaded settings from {SETTINGS_LOCATION}: {settings}")
|
settings = read_json(DEFAULT_SETTINGS_LOCATION)
|
||||||
|
logging.debug(f"Loaded settings from {DEFAULT_SETTINGS_LOCATION}: {settings}")
|
||||||
else:
|
else:
|
||||||
settings = None
|
settings = None
|
||||||
logging.debug(f"Settings {SETTINGS_LOCATION} does not exist, skipped")
|
logging.debug(f"Settings {DEFAULT_SETTINGS_LOCATION} does not exist, skipped")
|
||||||
if settings is None or settings["persistent"] == False:
|
if settings is None or settings["persistent"] == False:
|
||||||
logging.debug("Ignoring settings from file")
|
logging.debug("Ignoring settings from file")
|
||||||
self.persistent = False
|
self.persistent = False
|
||||||
self.cpus = []
|
self.guess_settings(self)
|
||||||
|
self.modified_settings = True
|
||||||
for cpu_number in range(0, Plugin.CPU_COUNT):
|
|
||||||
self.cpus.append(CPU(cpu_number))
|
|
||||||
|
|
||||||
# If any core has two threads, smt is True
|
|
||||||
self.smt = self.cpus[1].status()
|
|
||||||
if(not self.smt):
|
|
||||||
for cpu_number in range(2, len(self.cpus), 2):
|
|
||||||
if(self.cpus[cpu_number].status()):
|
|
||||||
self.smt = True
|
|
||||||
break
|
|
||||||
logging.info(f"SMT state is guessed to be {self.smt}")
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# apply settings
|
# apply settings
|
||||||
logging.debug("Restoring settings from file")
|
logging.debug("Restoring settings from file")
|
||||||
self.persistent = True
|
self.persistent = True
|
||||||
# CPU
|
self.apply_settings(self, settings)
|
||||||
self.cpus = []
|
# self.modified_settings = False
|
||||||
|
|
||||||
for cpu_number in range(0, Plugin.CPU_COUNT):
|
|
||||||
self.cpus.append(CPU(cpu_number, settings=settings["cpu"]["threads"][cpu_number]))
|
|
||||||
self.smt = settings["cpu"]["smt"]
|
|
||||||
write_cpu_boost(settings["cpu"]["boost"])
|
|
||||||
# GPU
|
|
||||||
write_gpu_ppt(1, settings["gpu"]["slowppt"])
|
|
||||||
write_gpu_ppt(2, settings["gpu"]["fastppt"])
|
|
||||||
# Fan
|
|
||||||
if not (os.path.exists(FANTASTIC_INSTALL_DIR) or settings["fan"]["auto"]):
|
|
||||||
write_to_sys("/sys/class/hwmon/hwmon5/recalculate", 1)
|
|
||||||
write_to_sys("/sys/class/hwmon/hwmon5/fan1_target", settings["fan"]["target"])
|
|
||||||
self.dirty = False
|
|
||||||
logging.info("Handled saved settings, back-end startup complete")
|
logging.info("Handled saved settings, back-end startup complete")
|
||||||
|
# server setup
|
||||||
|
await pt_server.start(VERSION)
|
||||||
# work loop
|
# work loop
|
||||||
while True:
|
while True:
|
||||||
|
# persistence
|
||||||
if self.modified_settings and self.persistent:
|
if self.modified_settings and self.persistent:
|
||||||
self.save_settings(self)
|
self.save_settings(self)
|
||||||
self.modified_settings = False
|
self.modified_settings = False
|
||||||
|
if self.persistent:
|
||||||
|
# per-game profiles
|
||||||
|
current_game = pt_server.http_server.game()
|
||||||
|
old_gameid = self.current_gameid
|
||||||
|
if current_game is not None and current_game.has_settings():
|
||||||
|
self.current_gameid = current_game.gameid
|
||||||
|
if old_gameid != self.current_gameid:
|
||||||
|
logging.info(f"Applying custom settings for {current_game.name()} {current_game.appid()}")
|
||||||
|
# new game; apply settings
|
||||||
|
settings = current_game.load_settings()
|
||||||
|
if settings is not None:
|
||||||
|
self.apply_settings(self, settings)
|
||||||
|
else:
|
||||||
|
self.current_gameid = None
|
||||||
|
if old_gameid != self.current_gameid:
|
||||||
|
logging.info("Reapplying default settings; game without custom settings found")
|
||||||
|
# game without custom settings; apply defaults
|
||||||
|
settings = read_json(DEFAULT_SETTINGS_LOCATION)
|
||||||
|
self.apply_settings(self, settings)
|
||||||
|
logging.debug(f"gameid update: {old_gameid} -> {self.current_gameid}")
|
||||||
|
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
await pt_server.shutdown()
|
||||||
|
|
||||||
# called from main_view::onViewReady
|
# called from main_view::onViewReady
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
|
@ -342,8 +375,71 @@ class Plugin:
|
||||||
|
|
||||||
def save_settings(self):
|
def save_settings(self):
|
||||||
settings = self.current_settings(self)
|
settings = self.current_settings(self)
|
||||||
logging.info(f"Saving settings to file: {settings}")
|
logging.debug(f"Saving settings to file: {settings}")
|
||||||
write_json(SETTINGS_LOCATION, settings)
|
current_game = pt_server.http_server.game()
|
||||||
|
if current_game is not None and self.current_gameid is not None:
|
||||||
|
save_location = current_game.settings_path()
|
||||||
|
else:
|
||||||
|
save_location = DEFAULT_SETTINGS_LOCATION
|
||||||
|
write_json(save_location, settings)
|
||||||
|
logging.info(f"Saved settings to {save_location}")
|
||||||
|
|
||||||
|
def apply_settings(self, settings: dict):
|
||||||
|
# CPU
|
||||||
|
self.cpus = []
|
||||||
|
|
||||||
|
for cpu_number in range(0, Plugin.CPU_COUNT):
|
||||||
|
self.cpus.append(CPU(cpu_number, settings=settings["cpu"]["threads"][cpu_number]))
|
||||||
|
self.smt = settings["cpu"]["smt"]
|
||||||
|
write_cpu_boost(settings["cpu"]["boost"])
|
||||||
|
# GPU
|
||||||
|
write_gpu_ppt(1, settings["gpu"]["slowppt"])
|
||||||
|
write_gpu_ppt(2, settings["gpu"]["fastppt"])
|
||||||
|
# Fan
|
||||||
|
if not (os.path.exists(FANTASTIC_INSTALL_DIR) or settings["fan"]["auto"]):
|
||||||
|
self.disable_jupiter_fan_control(self)
|
||||||
|
write_to_sys("/sys/class/hwmon/hwmon5/recalculate", 1)
|
||||||
|
write_to_sys("/sys/class/hwmon/hwmon5/fan1_target", settings["fan"]["target"])
|
||||||
|
elif settings["fan"]["auto"] and not os.path.exists(FANTASTIC_INSTALL_DIR):
|
||||||
|
self.enable_jupiter_fan_control(self)
|
||||||
|
|
||||||
|
|
||||||
|
def guess_settings(self):
|
||||||
|
self.cpus = []
|
||||||
|
for cpu_number in range(0, Plugin.CPU_COUNT):
|
||||||
|
self.cpus.append(CPU(cpu_number))
|
||||||
|
|
||||||
|
# If any core has two threads, smt is True
|
||||||
|
self.smt = self.cpus[1].status()
|
||||||
|
if(not self.smt):
|
||||||
|
for cpu_number in range(2, len(self.cpus), 2):
|
||||||
|
if(self.cpus[cpu_number].status()):
|
||||||
|
self.smt = True
|
||||||
|
break
|
||||||
|
logging.info(f"SMT state is guessed to be {self.smt}")
|
||||||
|
|
||||||
|
# per-game profiles
|
||||||
|
|
||||||
|
async def get_current_game(self) -> str:
|
||||||
|
current_game = pt_server.http_server.game()
|
||||||
|
if current_game is None:
|
||||||
|
return "Menu (default)"
|
||||||
|
else:
|
||||||
|
return f"{current_game.name()} ({current_game.appid()})"
|
||||||
|
|
||||||
|
async def set_per_game_profile(self, enabled: bool):
|
||||||
|
current_game = pt_server.http_server.game()
|
||||||
|
if enabled and self.persistent and current_game is not None:
|
||||||
|
self.current_gameid = current_game.gameid
|
||||||
|
self.modified_settings = True
|
||||||
|
else:
|
||||||
|
if not enabled and current_game is not None and current_game.has_settings():
|
||||||
|
# delete settings; disable settings loading
|
||||||
|
os.remove(current_game.settings_path())
|
||||||
|
self.current_gameid = None
|
||||||
|
|
||||||
|
async def get_per_game_profile(self) -> bool:
|
||||||
|
return self.current_gameid is not None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
562
main_view.html
562
main_view.html
|
@ -81,12 +81,73 @@
|
||||||
function getPersistent() {
|
function getPersistent() {
|
||||||
return call_plugin_method("get_persistent", {});
|
return call_plugin_method("get_persistent", {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setPerGameProfile(value) {
|
||||||
|
return call_plugin_method("set_per_game_profile", {"enabled": value});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPerGameProfile() {
|
||||||
|
return call_plugin_method("get_per_game_profile", {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentGame() {
|
||||||
|
return call_plugin_method("get_current_game", {});
|
||||||
|
}
|
||||||
|
|
||||||
// other logic
|
// other logic
|
||||||
|
|
||||||
async function onReady() {
|
async function onReady() {
|
||||||
await onViewReady();
|
await onViewReady();
|
||||||
|
|
||||||
|
// detect game starts and exits
|
||||||
|
console.log("Injecting game detection code into main window (SP)");
|
||||||
|
await execute_in_tab("SP", false,
|
||||||
|
`console.log("Hey PowerTools is over here now too!");
|
||||||
|
SteamClient.Apps.RegisterForGameActionStart((actionType, data) => {
|
||||||
|
console.log("start game", appStore.GetAppOverviewByGameID(data));
|
||||||
|
fetch("http://127.0.0.1:5030/on_game_start/" + data.toString(), {method: "POST", body: JSON.stringify(appStore.GetAppOverviewByGameID(data))}).then((_) => {});
|
||||||
|
});
|
||||||
|
// this seems to not run when I thought (runs right after ^^^, not when game exits)
|
||||||
|
/*SteamClient.Apps.RegisterForGameActionEnd((actionType, data) => {
|
||||||
|
if (data != null && data != undefined) {
|
||||||
|
console.log("stop game", appStore.GetAppOverviewByGameID(data));
|
||||||
|
fetch("http://127.0.0.1:5030/on_game_exit/" + data.toString(), {method: "POST", body: JSON.stringify(appStore.GetAppOverviewByGameID(data))}).then((_) => {});
|
||||||
|
} else {
|
||||||
|
console.log("stop game null");
|
||||||
|
fetch("http://127.0.0.1:5030/on_game_exit_null", {method: "POST", body:data}).then((_) => {});
|
||||||
|
}
|
||||||
|
});*/`
|
||||||
|
);
|
||||||
|
|
||||||
|
await updateCurrentGame();
|
||||||
|
/*let boostToggle = document.getElementById("boostToggle");
|
||||||
|
setToggleState(boostToggle, await getCPUBoost());
|
||||||
|
setToggleState(document.getElementById("smtToggle"), await getSMT());
|
||||||
|
selectNotch("cpuThreadsNotch", await getCPUs() - 1, 8);
|
||||||
|
selectNotch("frequencyNotch", await getMaxBoost(), 3);
|
||||||
|
await onReadyGPU();
|
||||||
|
let isFantasticInstalled = await getFantastic();
|
||||||
|
if (isFantasticInstalled) {
|
||||||
|
// Don't fight with Fantastic
|
||||||
|
let fanRoot = document.getElementById("fanRoot");
|
||||||
|
fanRoot.style.visibility = "hidden";
|
||||||
|
fanRoot.style.height = "0px";
|
||||||
|
} else {
|
||||||
|
selectNotch("fanNotch", await getFanTick(), 8);
|
||||||
|
}
|
||||||
|
await updateBatteryStats();
|
||||||
|
setToggleState(document.getElementById("persistToggle"), await getPersistent());
|
||||||
|
setToggleState(document.getElementById("gameProfileToggle"), await getPerGameProfile());
|
||||||
|
await updateCurrentGame();*/
|
||||||
|
// this is unimportant; always do it last
|
||||||
|
await updateVersion();
|
||||||
|
window.setInterval(function() {
|
||||||
|
updateBatteryStats().then(_ => {});
|
||||||
|
updateCurrentGame().then(_ => {});
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function reloadSettings() {
|
||||||
let boostToggle = document.getElementById("boostToggle");
|
let boostToggle = document.getElementById("boostToggle");
|
||||||
setToggleState(boostToggle, await getCPUBoost());
|
setToggleState(boostToggle, await getCPUBoost());
|
||||||
setToggleState(document.getElementById("smtToggle"), await getSMT());
|
setToggleState(document.getElementById("smtToggle"), await getSMT());
|
||||||
|
@ -104,9 +165,7 @@
|
||||||
}
|
}
|
||||||
await updateBatteryStats();
|
await updateBatteryStats();
|
||||||
setToggleState(document.getElementById("persistToggle"), await getPersistent());
|
setToggleState(document.getElementById("persistToggle"), await getPersistent());
|
||||||
// this is unimportant; always do it last
|
setToggleState(document.getElementById("gameProfileToggle"), await getPerGameProfile());
|
||||||
await updateVersion();
|
|
||||||
window.setInterval(function() {updateBatteryStats().then(_ => {})}, 5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setCPUNotch(index) {
|
async function setCPUNotch(index) {
|
||||||
|
@ -115,6 +174,12 @@
|
||||||
selectNotch(ROOT_ID, await getCPUs() - 1, 8);
|
selectNotch(ROOT_ID, await getCPUs() - 1, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onSlideCPUNotch(e) {
|
||||||
|
const ROOT_ID = "cpuThreadsNotch";
|
||||||
|
let closest = closestNotch(e, ROOT_ID, 8);
|
||||||
|
await setCPUNotch(closest);
|
||||||
|
}
|
||||||
|
|
||||||
const TOGGLE_ON_CLASS = "gamepaddialog_On_3ld7T";
|
const TOGGLE_ON_CLASS = "gamepaddialog_On_3ld7T";
|
||||||
|
|
||||||
function setToggleState(toggle, state) {
|
function setToggleState(toggle, state) {
|
||||||
|
@ -159,12 +224,24 @@
|
||||||
selectNotch(ROOT_ID, await getMaxBoost(), 3);
|
selectNotch(ROOT_ID, await getMaxBoost(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onSlideBoostNotch(e) {
|
||||||
|
const ROOT_ID = "frequencyNotch";
|
||||||
|
let closest = closestNotch(e, ROOT_ID, 3);
|
||||||
|
await setBoostNotch(closest);
|
||||||
|
}
|
||||||
|
|
||||||
async function onSetFanNotch(index) {
|
async function onSetFanNotch(index) {
|
||||||
const ROOT_ID = "fanNotch";
|
const ROOT_ID = "fanNotch";
|
||||||
await setFanTick(index);
|
await setFanTick(index);
|
||||||
selectNotch(ROOT_ID, index, 8);
|
selectNotch(ROOT_ID, index, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onSlideFanNotch(e) {
|
||||||
|
const ROOT_ID = "fanNotch";
|
||||||
|
let closest = closestNotch(e, ROOT_ID, 8);
|
||||||
|
await onSetFanNotch(closest);
|
||||||
|
}
|
||||||
|
|
||||||
async function onReadyGPU() {
|
async function onReadyGPU() {
|
||||||
let power1_cap = await getGPUPower(1);
|
let power1_cap = await getGPUPower(1);
|
||||||
let power2_cap = await getGPUPower(2);
|
let power2_cap = await getGPUPower(2);
|
||||||
|
@ -202,6 +279,12 @@
|
||||||
selectNotch(ROOT_ID, index, 3);
|
selectNotch(ROOT_ID, index, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onSlideSlowPPTNotch(e) {
|
||||||
|
const ROOT_ID = "slowPPTNotch";
|
||||||
|
let closest = closestNotch(e, ROOT_ID, 3);
|
||||||
|
onSetSlowPPTNotch(closest);
|
||||||
|
}
|
||||||
|
|
||||||
async function onSetFastPPTNotch(index) {
|
async function onSetFastPPTNotch(index) {
|
||||||
const ROOT_ID = "fastPPTNotch";
|
const ROOT_ID = "fastPPTNotch";
|
||||||
document.getElementById("fastPPTAutoDefault").innerText = "Default";
|
document.getElementById("fastPPTAutoDefault").innerText = "Default";
|
||||||
|
@ -215,6 +298,12 @@
|
||||||
selectNotch(ROOT_ID, index, 3);
|
selectNotch(ROOT_ID, index, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onSlideFastPPTNotch(e) {
|
||||||
|
const ROOT_ID = "fastPPTNotch";
|
||||||
|
let closest = closestNotch(e, ROOT_ID, 3);
|
||||||
|
await onSetFastPPTNotch(closest);
|
||||||
|
}
|
||||||
|
|
||||||
function selectNotch(rootId, index, elements) {
|
function selectNotch(rootId, index, elements) {
|
||||||
// WARNING: this yeets any style in div of slider
|
// WARNING: this yeets any style in div of slider
|
||||||
const ENABLED_CLASS = "gamepadslider_TickActive_1gnUV";
|
const ENABLED_CLASS = "gamepadslider_TickActive_1gnUV";
|
||||||
|
@ -231,6 +320,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closestNotch(e, rootId, elements) {
|
||||||
|
let root = document.getElementById(rootId);
|
||||||
|
let val = e.x / root.scrollWidth;
|
||||||
|
let closest_notch = Math.round(val * elements);
|
||||||
|
if (closest_notch > elements) {
|
||||||
|
closest_notch = elements;
|
||||||
|
} else if (closest_notch < 0) {
|
||||||
|
closest_notch = 0;
|
||||||
|
}
|
||||||
|
return closest_notch
|
||||||
|
//selectNotch(closest_notch);
|
||||||
|
}
|
||||||
|
|
||||||
async function updateBatteryStats() {
|
async function updateBatteryStats() {
|
||||||
//console.log("Updating battery stats");
|
//console.log("Updating battery stats");
|
||||||
let batCapacityNow = document.getElementById("batCapacityNow");
|
let batCapacityNow = document.getElementById("batCapacityNow");
|
||||||
|
@ -238,8 +340,8 @@
|
||||||
let chargeNow = await getChargeNow();
|
let chargeNow = await getChargeNow();
|
||||||
let chargeFull = await getChargeFull();
|
let chargeFull = await getChargeFull();
|
||||||
let chargeDesign = await getChargeDesign();
|
let chargeDesign = await getChargeDesign();
|
||||||
batCapacityNow.innerText = (7.7 * chargeNow / 1000000).toFixed(2).toString() + " Wh (" + (100 * chargeNow / chargeFull).toFixed(0).toString() + "%)";
|
batCapacityNow.innerText = (7.7 * chargeNow / 1000000).toFixed(1).toString() + " Wh (" + (100 * chargeNow / chargeFull).toFixed(1).toString() + "%)";
|
||||||
batCapacityFull.innerText = (7.7 * chargeFull / 1000000).toFixed(2).toString() + " Wh (" + (100 * chargeFull / chargeDesign).toFixed(0).toString() + "%)";
|
batCapacityFull.innerText = (7.7 * chargeFull / 1000000).toFixed(1).toString() + " Wh (" + (100 * chargeFull / chargeDesign).toFixed(1).toString() + "%)";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function togglePersist() {
|
async function togglePersist() {
|
||||||
|
@ -249,6 +351,26 @@
|
||||||
setToggleState(toggle, !isActive);
|
setToggleState(toggle, !isActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function toggleGameProfile() {
|
||||||
|
let toggle = document.getElementById("gameProfileToggle");
|
||||||
|
let isActive = getToggleState(toggle);
|
||||||
|
await setPerGameProfile(!isActive);
|
||||||
|
setToggleState(toggle, await getPerGameProfile());
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastGameName = "";
|
||||||
|
|
||||||
|
async function updateCurrentGame() {
|
||||||
|
let gameNow = document.getElementById("gameNow");
|
||||||
|
let gameNameNow = await getCurrentGame();
|
||||||
|
if (lastGameName != gameNameNow) {
|
||||||
|
setToggleState(document.getElementById("gameProfileToggle"), await getPerGameProfile());
|
||||||
|
await reloadSettings();
|
||||||
|
}
|
||||||
|
lastGameName = gameNameNow
|
||||||
|
gameNow.innerText = gameNameNow;
|
||||||
|
}
|
||||||
|
|
||||||
let versionCount = -1;
|
let versionCount = -1;
|
||||||
async function updateVersion() {
|
async function updateVersion() {
|
||||||
let version = await getVersion();
|
let version = await getVersion();
|
||||||
|
@ -266,94 +388,100 @@
|
||||||
<style type="text/css" media="screen"></style>
|
<style type="text/css" media="screen"></style>
|
||||||
</head>
|
</head>
|
||||||
<body onload="onReady()" style="/*margin:0px;padding:0px;*/overflow-x:hidden;margin:0px;">
|
<body onload="onReady()" style="/*margin:0px;padding:0px;*/overflow-x:hidden;margin:0px;">
|
||||||
|
<!-- Spacer (moves top out of shadow above it) -->
|
||||||
|
<div class="quickaccessmenu_TabGroupPanel_1QO7b">
|
||||||
|
<div class="quickaccesscontrols_PanelSection_2C0g0" style="margin-bottom:6px;">
|
||||||
|
<!--<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
|
</div>-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- CPU -->
|
<!-- CPU -->
|
||||||
|
|
||||||
<!-- SMT toggle switch, roughly copied from https://github.com/SteamDeckHomebrew/ExtraSettingsPlugin/blob/main/main_view.html -->
|
<!-- SMT toggle switch, roughly copied from https://github.com/SteamDeckHomebrew/ExtraSettingsPlugin/blob/main/main_view.html -->
|
||||||
<!-- Due to a bug in MangoHud, this has a warning for now -->
|
<!-- Due to a bug in MangoHud, this has a warning for now -->
|
||||||
<div class="quickaccessmenu_TabGroupPanel_1QO7b Panel Focusable">
|
<div class="quickaccessmenu_TabGroupPanel_1QO7b Panel Focusable">
|
||||||
<div class="quickaccesscontrols_PanelSection_2C0g0" style="padding:0px 4px;">
|
<div class="quickaccesscontrols_PanelSection_2C0g0" style="">
|
||||||
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_WithDescription_3bMIS gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_WithDescription_3bMIS gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;" onclick="toggleCPUSMT()">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">
|
<div class="gamepaddialog_FieldLabel_3b0U-">
|
||||||
CPU SMT
|
CPU SMT
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
<div id="smtToggle" tabindex="0" class="gamepaddialog_Toggle_24G4g Focusable" onclick="toggleCPUSMT()">
|
<div id="smtToggle" tabindex="0" class="gamepaddialog_Toggle_24G4g Focusable" >
|
||||||
<div class="gamepaddialog_ToggleRail_2JtC3"></div>
|
<div class="gamepaddialog_ToggleRail_2JtC3"></div>
|
||||||
<div class="gamepaddialog_ToggleSwitch_3__OD"></div>
|
<div class="gamepaddialog_ToggleSwitch_3__OD"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepaddialog_FieldDescription_2OJfk">Enables odd-numbered CPUs</div>
|
<div class="gamepaddialog_FieldDescription_2OJfk">Enables odd-numbered CPUs</div>
|
||||||
<div style="font-size:x-small;">
|
</div>
|
||||||
WARNING: Disabling crashes the performance overlay.
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- CPUs selector -->
|
||||||
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparatorStandard_3s1Rk gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable">
|
||||||
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
|
<div class="gamepaddialog_FieldLabel_3b0U-">Threads</div>
|
||||||
|
</div>
|
||||||
|
<div id="cpuThreadsNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.5;" onmousemove="onSlideCPUNotch(event)">
|
||||||
|
<div class="gamepadslider_SliderControl_3o137">
|
||||||
|
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
||||||
|
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
||||||
|
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="cpuThreadsNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(1)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">1</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="cpuThreadsNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(2)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">2</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="cpuThreadsNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(3)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">3</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="cpuThreadsNotch3" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(4)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">4</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="cpuThreadsNotch4" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(5)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">5</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="cpuThreadsNotch5" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(6)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">6</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="cpuThreadsNotch6" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(7)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">7</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="cpuThreadsNotch7" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(8)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">8</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- CPUs selector -->
|
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparator_1lUZx gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable">
|
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">Threads</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="cpuThreadsNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.5;">
|
|
||||||
<div class="gamepadslider_SliderControl_3o137">
|
|
||||||
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
|
||||||
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
|
||||||
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="cpuThreadsNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(1)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">1</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="cpuThreadsNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(2)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">2</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="cpuThreadsNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(3)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">3</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="cpuThreadsNotch3" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(4)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">4</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="cpuThreadsNotch4" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(5)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">5</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="cpuThreadsNotch5" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(6)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">6</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="cpuThreadsNotch6" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(7)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">7</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="cpuThreadsNotch7" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setCPUNotch(8)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">8</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CPU Boost toggle switch, roughly copied from https://github.com/SteamDeckHomebrew/ExtraSettingsPlugin/blob/main/main_view.html -->
|
<!-- CPU Boost toggle switch, roughly copied from https://github.com/SteamDeckHomebrew/ExtraSettingsPlugin/blob/main/main_view.html -->
|
||||||
<div class="quickaccesscontrols_PanelSection_2C0g0" style="padding:0px 4px;">
|
<div class="quickaccesscontrols_PanelSection_2C0g0" style="">
|
||||||
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_WithDescription_3bMIS gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_WithDescription_3bMIS gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;" onclick="toggleCPUBoost()">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">
|
<div class="gamepaddialog_FieldLabel_3b0U-">
|
||||||
CPU Boost
|
CPU Boost
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
<div id="boostToggle" tabindex="0" class="gamepaddialog_Toggle_24G4g Focusable" onclick="toggleCPUBoost()">
|
<div id="boostToggle" tabindex="0" class="gamepaddialog_Toggle_24G4g Focusable">
|
||||||
<div class="gamepaddialog_ToggleRail_2JtC3"></div>
|
<div class="gamepaddialog_ToggleRail_2JtC3"></div>
|
||||||
<div class="gamepaddialog_ToggleSwitch_3__OD"></div>
|
<div class="gamepaddialog_ToggleSwitch_3__OD"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -364,173 +492,182 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Frequency selector -->
|
<!-- Frequency selector -->
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparator_1lUZx gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparatorStandard_3s1Rk gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable">
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">Max Frequency</div>
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
</div>
|
<div class="gamepaddialog_FieldLabel_3b0U-">Max Frequency</div>
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
|
||||||
<div id="frequencyNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.5;">
|
|
||||||
<div class="gamepadslider_SliderControl_3o137">
|
|
||||||
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
|
||||||
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
|
||||||
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
<div id="frequencyNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.5;" onmousemove="onSlideBoostNotch(event)">
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
<div class="gamepadslider_SliderControl_3o137">
|
||||||
<div id="frequencyNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='setBoostNotch(0)'></div>
|
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1" style="margin-left:2em;">1.7GHz</div>
|
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
||||||
|
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="frequencyNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='setBoostNotch(0)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1" style="margin-left:2em;">1.7GHz</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="frequencyNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='setBoostNotch(1)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">2.4GHz</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="frequencyNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setBoostNotch(2)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1" style="margin-right:2em;">2.8GHz</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="frequencyNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='setBoostNotch(1)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">2.4GHz</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
<div style="font-size:x-small;">
|
||||||
<div id="frequencyNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht" onclick='setBoostNotch(2)'></div>
|
WARNING: This will change the CPU governor.
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1" style="margin-right:2em;">2.8GHz</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div style="font-size:x-small;">
|
|
||||||
WARNING: This will change the CPU governor.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- GPU -->
|
<!-- GPU -->
|
||||||
|
|
||||||
<div class="quickaccesscontrols_PanelSection_2C0g0" style="padding:0px 4px;">
|
<div class="quickaccesscontrols_PanelSection_2C0g0" style="">
|
||||||
|
|
||||||
<!-- SlowPPT power limit (number 1) -->
|
<!-- SlowPPT power limit (number 1) -->
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable">
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">GPU SlowPPT Power</div>
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
</div>
|
<div class="gamepaddialog_FieldLabel_3b0U-">GPU SlowPPT Power</div>
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
|
||||||
<div id="slowPPTNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.33;">
|
|
||||||
<div class="gamepadslider_SliderControl_3o137">
|
|
||||||
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
|
||||||
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
|
||||||
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
<div id="slowPPTNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.33;" onmousemove="onSlideSlowPPTNotch(event)">
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
<div class="gamepadslider_SliderControl_3o137">
|
||||||
<div id="slowPPTNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetSlowPPTNotch(0)'></div>
|
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">0</div>
|
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
||||||
|
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="slowPPTNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetSlowPPTNotch(0)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">0</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="slowPPTNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetSlowPPTNotch(1)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1" id="slowPPTAutoDefault">Auto</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="slowPPTNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetSlowPPTNotch(2)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">Max</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="slowPPTNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetSlowPPTNotch(1)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1" id="slowPPTAutoDefault">Auto</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="slowPPTNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetSlowPPTNotch(2)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">Max</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- FastPPT power limit (number 2) -->
|
<!-- FastPPT power limit (number 2) -->
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparator_1lUZx gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparatorStandard_3s1Rk gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable">
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">GPU FastPPT Power</div>
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
</div>
|
<div class="gamepaddialog_FieldLabel_3b0U-">GPU FastPPT Power</div>
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
|
||||||
<div id="fastPPTNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.33;">
|
|
||||||
<div class="gamepadslider_SliderControl_3o137">
|
|
||||||
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
|
||||||
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
|
||||||
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
<div id="fastPPTNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.33;" onmousemove="onSlideFastPPTNotch(event)">
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
<div class="gamepadslider_SliderControl_3o137">
|
||||||
<div id="fastPPTNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFastPPTNotch(0)'></div>
|
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">0</div>
|
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
||||||
|
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fastPPTNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFastPPTNotch(0)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">0</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fastPPTNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFastPPTNotch(1)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1" id="fastPPTAutoDefault">Auto</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fastPPTNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFastPPTNotch(2)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">Max</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fastPPTNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFastPPTNotch(1)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1" id="fastPPTAutoDefault">Auto</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fastPPTNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFastPPTNotch(2)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">Max</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Fan RPM selector -->
|
<!-- Fan RPM selector -->
|
||||||
<!-- TODO: Make this non-notched slider when PluginLoader PR#41 is merged -->
|
<div class="quickaccesscontrols_PanelSection_2C0g0" style="" id="fanRoot">
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparator_1lUZx gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" id="fanRoot">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<!-- TODO: Make this non-notched slider when PluginLoader PR#41 is merged -->
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">Fan RPM</div>
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_WithChildrenBelow_1u5FT gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparatorStandard_3s1Rk gamepaddialog_ChildrenWidthFixed_1ugIU gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable">
|
||||||
</div>
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
<div class="gamepaddialog_FieldLabel_3b0U-">Fan RPM</div>
|
||||||
<div id="fanNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.33;">
|
</div>
|
||||||
<div class="gamepadslider_SliderControl_3o137">
|
<div class="gamepaddialog_FieldDescription_2OJfk" style="display:none;">Requires disabling updated fan control</div>
|
||||||
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
<div id="fanNotch" class="gamepadslider_SliderControlAndNotches_1Cccx Focusable" tabindex="0" style="--normalized-slider-value:0.33;" onmousemove="onSlideFanNotch(event)">
|
||||||
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
<div class="gamepadslider_SliderControl_3o137">
|
||||||
|
<div class="gamepadslider_SliderTrack_Mq25N gamepadslider_SliderHasNotches_2XiAy "></div>
|
||||||
|
<div class="gamepadslider_SliderHandleContainer_1pQZi">
|
||||||
|
<div class="gamepadslider_SliderHandle_2yVKj"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fanNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(0)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">0</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fanNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(1)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">1K</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fanNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(2)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">2K</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fanNotch3" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(3)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">3K</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fanNotch4" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(4)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">4K</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fanNotch5" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(5)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">5K</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fanNotch6" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(6)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">6K</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_3x6ve">
|
||||||
|
<div id="fanNotch7" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(7)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_u_sH1">Auto</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="font-size:x-small;">
|
||||||
|
WARNING: This can cause component overheating.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepadslider_SliderNotchContainer_2N-a5 Panel Focusable">
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fanNotch0" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(0)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">0</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fanNotch1" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(1)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">1K</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fanNotch2" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(2)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">2K</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fanNotch3" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(3)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">3K</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fanNotch4" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(4)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">4K</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fanNotch5" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(5)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">5K</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fanNotch6" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(6)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">6K</div>
|
|
||||||
</div>
|
|
||||||
<div class="gamepadslider_SliderNotch_3x6ve">
|
|
||||||
<div id="fanNotch7" class="gamepadslider_SliderNotchTick_Fv1Ht gamepadslider_TickActive_j418S" onclick='onSetFanNotch(7)'></div>
|
|
||||||
<div class="gamepadslider_SliderNotchLabel_u_sH1">Auto</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style="font-size:x-small;">
|
|
||||||
WARNING: This can cause component overheating.
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Battery Info -->
|
<!-- Battery Info -->
|
||||||
<div class="quickaccesscontrols_PanelSection_2C0g0" style="padding:0px 4px;" onclick="updateBatteryStats()" style="margin-bottom:0px;">
|
<div class="quickaccesscontrols_PanelSection_2C0g0" style="" onclick="updateBatteryStats()" style="margin-bottom:0px;">
|
||||||
<div class="quickaccesscontrols_PanelSectionTitle_2iFf9">
|
<div class="quickaccesscontrols_PanelSectionTitle_2iFf9">
|
||||||
<div class="quickaccesscontrols_Text_1hJkB">Battery</div>
|
<div class="quickaccesscontrols_Text_1hJkB">Battery</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="Panel Focusable" tabindex="0">
|
<div class="Panel Focusable" tabindex="0">
|
||||||
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparator_1lUZx gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparatorStandard_3s1Rk gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">Now (Charge)</div>
|
<div class="gamepaddialog_FieldLabel_3b0U-">Now (Charge)</div>
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
|
@ -540,7 +677,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparator_1lUZx gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparatorStandard_3s1Rk gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">Max (Design)</div>
|
<div class="gamepaddialog_FieldLabel_3b0U-">Max (Design)</div>
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
|
@ -551,26 +688,50 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="quickaccesscontrols_PanelSection_2C0g0" style="padding:0px 4px;">
|
<div class="quickaccesscontrols_PanelSection_2C0g0" style="">
|
||||||
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_WithDescription_3bMIS gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_WithDescription_3bMIS gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;" onclick="togglePersist()">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">
|
<div class="gamepaddialog_FieldLabel_3b0U-">
|
||||||
Persistent
|
Persistent
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
<div id="persistToggle" tabindex="0" class="gamepaddialog_Toggle_24G4g Focusable" onclick="togglePersist()">
|
<div id="persistToggle" tabindex="0" class="gamepaddialog_Toggle_24G4g Focusable">
|
||||||
<div class="gamepaddialog_ToggleRail_2JtC3"></div>
|
<div class="gamepaddialog_ToggleRail_2JtC3"></div>
|
||||||
<div class="gamepaddialog_ToggleSwitch_3__OD"></div>
|
<div class="gamepaddialog_ToggleSwitch_3__OD"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gamepaddialog_FieldDescription_2OJfk">Restores settings after a reboot</div>
|
<div class="gamepaddialog_FieldDescription_2OJfk">Restores settings after an app or OS restart</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_WithDescription_3bMIS gamepaddialog_ExtraPaddingOnChildrenBelow_5UO-_ gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;" onclick="toggleGameProfile()">
|
||||||
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
|
<div class="gamepaddialog_FieldLabel_3b0U-">
|
||||||
|
Use per-game profile
|
||||||
|
</div>
|
||||||
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
|
<div id="gameProfileToggle" tabindex="0" class="gamepaddialog_Toggle_24G4g Focusable">
|
||||||
|
<div class="gamepaddialog_ToggleRail_2JtC3"></div>
|
||||||
|
<div class="gamepaddialog_ToggleSwitch_3__OD"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88">
|
||||||
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparatorStandard_3s1Rk gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
||||||
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
|
<div class="gamepaddialog_FieldLabel_3b0U-">Now Playing</div>
|
||||||
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
|
<div class="gamepaddialog_LabelFieldValue_5Mylh" id="gameNow"> the bongos </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="quickaccesscontrols_PanelSection_2C0g0" style="padding:0px 4px;">
|
|
||||||
<div class="quickaccesscontrols_PanelSectionRow_2VQ88" onclick="updateVersion()">
|
<div class="quickaccesscontrols_PanelSectionRow_2VQ88" onclick="updateVersion()">
|
||||||
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparator_1lUZx gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
<div class="gamepaddialog_Field_S-_La gamepaddialog_WithFirstRow_qFXi6 gamepaddialog_VerticalAlignCenter_3XNvA gamepaddialog_InlineWrapShiftsChildrenBelow_pHUb6 gamepaddialog_WithBottomSeparatorStandard_3s1Rk gamepaddialog_StandardPadding_XRBFu gamepaddialog_HighlightOnFocus_wE4V6 Panel Focusable" style="--indent-level:0;">
|
||||||
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
<div class="gamepaddialog_FieldLabelRow_H9WOq">
|
||||||
<div class="gamepaddialog_FieldLabel_3b0U-">PowerTools</div>
|
<div class="gamepaddialog_FieldLabel_3b0U-">PowerTools</div>
|
||||||
<div class="gamepaddialog_FieldChildren_14_HB">
|
<div class="gamepaddialog_FieldChildren_14_HB">
|
||||||
|
@ -581,6 +742,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
140
server.py
Normal file
140
server.py
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
import logging
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
# import asyncio
|
||||||
|
from aiohttp import web
|
||||||
|
import aiohttp
|
||||||
|
|
||||||
|
HOME_DIR = str(pathlib.Path(os.getcwd()).parent.parent.resolve())
|
||||||
|
SETTINGS_DIR = HOME_DIR + "/.config/powertools"
|
||||||
|
|
||||||
|
if not os.path.exists(SETTINGS_DIR):
|
||||||
|
os.mkdir(SETTINGS_DIR)
|
||||||
|
|
||||||
|
http_runner = None
|
||||||
|
http_server = None
|
||||||
|
http_site = None
|
||||||
|
|
||||||
|
class GameInfo:
|
||||||
|
def __init__(self, gameid: int, game_info: dict):
|
||||||
|
self.gameid = gameid
|
||||||
|
self.game_info = game_info
|
||||||
|
|
||||||
|
def appid(self):
|
||||||
|
return self.game_info["appid"]
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
return self.game_info["display_name"]
|
||||||
|
|
||||||
|
def settings_path(self) -> str:
|
||||||
|
return SETTINGS_DIR + os.path.sep + str(self.appid()) + ".json"
|
||||||
|
|
||||||
|
def load_settings(self) -> dict:
|
||||||
|
settings_path = self.settings_path()
|
||||||
|
if os.path.exists(settings_path):
|
||||||
|
with open(settings_path, mode="r") as f:
|
||||||
|
return json.load(f)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def has_settings(self) -> bool:
|
||||||
|
return os.path.exists(self.settings_path())
|
||||||
|
|
||||||
|
|
||||||
|
class Server(web.Application):
|
||||||
|
|
||||||
|
def __init__(self, version):
|
||||||
|
super().__init__()
|
||||||
|
self.version = version
|
||||||
|
self.current_game = None
|
||||||
|
self.add_routes([
|
||||||
|
web.get("/", lambda req: self.index(req)),
|
||||||
|
web.post("/on_game_start/{game_id}", lambda req: self.on_game_start(req)),
|
||||||
|
web.post("/on_game_exit/{game_id}", lambda req: self.on_game_exit(req)),
|
||||||
|
web.post("/on_game_exit_null", lambda req: self.on_game_exit_null(req)),
|
||||||
|
web.get("/self_destruct", lambda req: self.self_destruct(req))
|
||||||
|
])
|
||||||
|
logging.debug("Server init complete")
|
||||||
|
|
||||||
|
def game(self) -> GameInfo:
|
||||||
|
return self.current_game
|
||||||
|
|
||||||
|
async def index(self, request):
|
||||||
|
logging.debug("Debug index page accessed")
|
||||||
|
current_game = None if self.current_game is None else self.current_game.gameid
|
||||||
|
game_info = None if self.current_game is None else self.current_game.game_info
|
||||||
|
settings_info = None if self.current_game is None else self.current_game.load_settings()
|
||||||
|
return web.json_response({
|
||||||
|
"name": "PowerTools",
|
||||||
|
"version": self.version,
|
||||||
|
"latest_game_id": current_game,
|
||||||
|
"game_info": game_info,
|
||||||
|
"settings": settings_info
|
||||||
|
}, headers={"Access-Control-Allow-Origin": "*"})
|
||||||
|
|
||||||
|
async def on_game_start(self, request):
|
||||||
|
game_id = request.match_info["game_id"]
|
||||||
|
data = await request.text()
|
||||||
|
logging.debug(f"on_game_start {game_id} body:\n{data}")
|
||||||
|
try:
|
||||||
|
game_id = int(game_id)
|
||||||
|
data = json.loads(data)
|
||||||
|
except:
|
||||||
|
return web.Response(text="WTF", status=400)
|
||||||
|
self.current_game = GameInfo(game_id, data)
|
||||||
|
if self.current_game.has_settings():
|
||||||
|
self.last_recognised_game = self.current_game
|
||||||
|
return web.Response(status=204, headers={"Access-Control-Allow-Origin": "*"})
|
||||||
|
|
||||||
|
async def on_game_exit(self, request):
|
||||||
|
# ignored for now
|
||||||
|
game_id = request.match_info["game_id"]
|
||||||
|
data = await request.text()
|
||||||
|
logging.debug(f"on_game_exit {game_id}")
|
||||||
|
try:
|
||||||
|
game_id = int(game_id)
|
||||||
|
except ValueError:
|
||||||
|
return web.Response(text="WTF", status=400)
|
||||||
|
if self.current_game.gameid == game_id:
|
||||||
|
pass
|
||||||
|
#self.current_game = None
|
||||||
|
# TODO change settings to default
|
||||||
|
return web.Response(status=204, headers={"Access-Control-Allow-Origin": "*"})
|
||||||
|
|
||||||
|
async def on_game_exit_null(self, request):
|
||||||
|
# ignored for now
|
||||||
|
logging.info(f"on_game_exit_null")
|
||||||
|
#self.current_game = None
|
||||||
|
# TODO change settings to default
|
||||||
|
return web.Response(status=204, headers={"Access-Control-Allow-Origin": "*"})
|
||||||
|
|
||||||
|
async def self_destruct(self, request):
|
||||||
|
logging.warning("Geodude self-destructed")
|
||||||
|
await shutdown()
|
||||||
|
# unreachable \/ \/ \/
|
||||||
|
return web.Response(status=204, headers={"Access-Control-Allow-Origin": "*"})
|
||||||
|
|
||||||
|
async def start(version):
|
||||||
|
global http_runner, http_server, http_site
|
||||||
|
# make sure old server has shutdown
|
||||||
|
try:
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get('http://127.0.0.1:5030/self_destruct') as response:
|
||||||
|
await response.text()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
http_server = Server(version)
|
||||||
|
http_runner = web.AppRunner(http_server)
|
||||||
|
await http_runner.setup()
|
||||||
|
site = web.TCPSite(http_runner, '127.0.0.1', 5030)
|
||||||
|
await site.start()
|
||||||
|
|
||||||
|
async def shutdown(): # never really called
|
||||||
|
global http_runner, http_server, http_site
|
||||||
|
if http_runner is not None:
|
||||||
|
await http_runner.cleanup()
|
||||||
|
http_runner = None
|
||||||
|
http_site.stop()
|
||||||
|
http_site = None
|
||||||
|
http_server = None
|
Loading…
Reference in a new issue