mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 04:04:09 +02:00
ft-steam: open Steam's menu through Steam's own UI
steam/ft-steam menu opens the SteamVR dashboard on Steam's menu, or closes the dashboard if it's up, without pointer mode: it asks Steam's UI over its debugging port to show its dashboard overlay (ShowVROverlay, what Steam calls itself) and focus the Steam frame's left menu (MenuStore.OpenMainMenu). ft-steam check says whether those calls still exist, and update-check.py runs it, since a Steam client update can rename them. The CDP client moves from display-settings/steam_settings.py to steam/steamui.py, so both use it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4479fbfcc1
commit
2487351556
4 files changed
+210
-102
No files matched your search
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
"""ft-steam: Steam's menu and checks, through Steam's own UI (steamui.py).
|
||||
|
||||
ft-steam menu open the SteamVR dashboard on Steam's menu, or close the dashboard if it's
|
||||
open (the Steam button's job, as a shortcut: the input relay's steam_menu)
|
||||
ft-steam check do Steam's UI calls that the above needs still exist (update-check.py)
|
||||
|
||||
No pointer mode needed: it asks Steam to show its dashboard overlay (window.ShowVROverlay, what
|
||||
Steam itself calls) and to focus the Steam frame's left menu (MenuStore.OpenMainMenu, which in
|
||||
VR invokes the frame's focus_left_frame_menu_action). SteamClient.OpenVR.VROverlay says
|
||||
whether the dashboard is up and hides it. These are Steam's UI internals, not an API, so a
|
||||
Steam client update can rename them: `ft-steam check` says so.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
||||
from steamui import SteamUnreachable, evaluate # noqa: E402
|
||||
|
||||
WINDOW = "SteamUIStore.WindowStore.VRGamepadUIMainWindowInstance"
|
||||
|
||||
MENU = f"""(async () => {{
|
||||
const vr = SteamClient.OpenVR.VROverlay;
|
||||
if (await vr.IsDashboardVisible()) {{ vr.HideDashboard(); return "closed"; }}
|
||||
const w = {WINDOW};
|
||||
if (!w) throw new Error("Steam's VR dashboard window isn't open");
|
||||
ShowVROverlay(w.GetVROverlayKey());
|
||||
// The frame's menu takes focus only once the dashboard is up.
|
||||
for (let i = 0; i < 40 && !(await vr.IsDashboardVisible()); i++) await new Promise(r => setTimeout(r, 25));
|
||||
w.MenuStore.OpenMainMenu();
|
||||
return "opened";
|
||||
}})()"""
|
||||
|
||||
CHECK = f"""(() => {{
|
||||
const missing = [];
|
||||
const vr = SteamClient.OpenVR && SteamClient.OpenVR.VROverlay;
|
||||
for (const f of ["IsDashboardVisible", "HideDashboard"]) if (!vr || typeof vr[f] !== "function") missing.push("SteamClient.OpenVR.VROverlay." + f);
|
||||
if (typeof window.ShowVROverlay !== "function") missing.push("ShowVROverlay");
|
||||
const w = {WINDOW};
|
||||
if (!w) missing.push("{WINDOW}");
|
||||
else {{
|
||||
if (typeof w.GetVROverlayKey !== "function") missing.push("GetVROverlayKey");
|
||||
if (!w.MenuStore || typeof w.MenuStore.OpenMainMenu !== "function") missing.push("MenuStore.OpenMainMenu");
|
||||
}}
|
||||
return missing;
|
||||
}})()"""
|
||||
|
||||
|
||||
def main():
|
||||
cmd = sys.argv[1] if len(sys.argv) == 2 else ""
|
||||
if cmd not in ("menu", "check"):
|
||||
sys.exit(__doc__)
|
||||
try:
|
||||
result = evaluate(MENU if cmd == "menu" else CHECK)
|
||||
except SteamUnreachable as e:
|
||||
sys.exit(f"ft-steam: {e}")
|
||||
if cmd == "check":
|
||||
if result:
|
||||
sys.exit("Steam's UI lacks " + ", ".join(result))
|
||||
print("ok")
|
||||
else:
|
||||
print(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user