diff --git a/src/frameport/install/installer.py b/src/frameport/install/installer.py index 968f33eb..7bcf73c5 100644 --- a/src/frameport/install/installer.py +++ b/src/frameport/install/installer.py @@ -840,14 +840,21 @@ def update_steam_art(frame: Frame, package: str, reporter: Reporter, title: str return {**(add_to_steam(frame, [package], reporter) or {}), "library": True} +def steam_library_mode() -> str: + """now / later / off. Unset, FramePort running on the Frame itself defaults to later: with now the restart waits + until FramePort closes (it would close Desktop Mode and FramePort too), which looked stuck (GitHub #425).""" + from ..core import library + from ..frame.local import on_frame + + return library.setting("install.steam_library", "later" if on_frame() else "now") + + def add_to_steam(frame: Frame, packages: list[str], reporter: Reporter, wait: float = 120) -> dict: """Add library entries + artwork for installed games; Steam restarts once (a few seconds).""" import time reporter.stage("Add to Steam library") - from ..core import library - - mode = library.setting("install.steam_library", "now") + mode = steam_library_mode() frame.agent("library_mode", mode=mode) submitted = frame.agent("shortcuts", packages=packages, restart=True, mode=mode) if submitted.get("disabled") or submitted.get("state") == "pending": @@ -866,7 +873,8 @@ def add_to_steam(frame: Frame, packages: list[str], reporter: Reporter, wait: fl break if status.get("state") == "waiting": # Steam restarts later: after the game, or back in Gaming Mode reporter.check("Steam library", None, - "added after FramePort on the Frame closes (Steam has to restart for it)" + "added after FramePort on the Frame closes (Steam has to restart for it); to add it " + "now: Settings → Installing → Restart Steam now" if status.get("reason") == "frameport" else "added when you're back in Gaming Mode (Steam has to restart for it)" if status.get("reason") == "desktop" else diff --git a/src/frameport/locales/template.json b/src/frameport/locales/template.json index 48d5b044..b05f0947 100644 --- a/src/frameport/locales/template.json +++ b/src/frameport/locales/template.json @@ -989,6 +989,7 @@ "Last session · ended {ago}": "", "late": "", "Later — next Steam start": "", + "Later — next Steam start (default)": "", "Launch log": "", "Launch log · {title}": "", "Launch options (SteamVR or OpenXR)": "", @@ -1220,8 +1221,9 @@ "Nothing to patch: it runs unchanged.": "", "Nothing to see here.": "", "nothing yet": "", + "Now": "", "Now (default)": "", - "Now waits until Steam can restart safely. Later saves shortcuts for the next Steam start. Off uses FramePort Play without Steam per-game integration; existing shortcuts stay.": "", + "Now waits until Steam can restart safely. Later saves shortcuts for the next Steam start. Off uses FramePort Play without Steam per-game integration; existing shortcuts stay. When FramePort runs on the Frame itself, Later is the default: a restart would close it.": "", "Now waits while a game, Desktop Mode, or local FramePort is open. Later lets you keep installing without restarting Steam. Off uses FramePort Play without Steam per-game integration.": "", "Now {scale:.0%}.": "", "Now {scale:.0%}. Changes apply the next time FramePort starts.": "", diff --git a/src/frameport/targets/frame_lepton.py b/src/frameport/targets/frame_lepton.py index aae219a1..79cc119a 100644 --- a/src/frameport/targets/frame_lepton.py +++ b/src/frameport/targets/frame_lepton.py @@ -71,10 +71,9 @@ class FrameLeptonTarget(Target): return self.connect().frame.agent("collect_diag", timeout=180, package=package) def launch(self, package): - from ..core import library + from ..install.installer import steam_library_mode - return self.connect().frame.agent("launch", package=package, timeout=60, - mode=library.setting("install.steam_library", "now")) + return self.connect().frame.agent("launch", package=package, timeout=60, mode=steam_library_mode()) def set_settings(self, package, settings, *, foveation=None): from ..core import library diff --git a/src/frameport/ui/help.py b/src/frameport/ui/help.py index 8a694cd4..625629a2 100644 --- a/src/frameport/ui/help.py +++ b/src/frameport/ui/help.py @@ -67,7 +67,8 @@ HELP: dict[str, str] = _Translated({ "refine_label_rules": "Checks every box the scanner found against size and place rules (see Labels). Off keeps the " "scanner's own names.", "steam_library":"Now waits until Steam can restart safely. Later saves shortcuts for the next Steam start. " - "Off uses FramePort Play without Steam per-game integration; existing shortcuts stay.", + "Off uses FramePort Play without Steam per-game integration; existing shortcuts stay. " + "When FramePort runs on the Frame itself, Later is the default: a restart would close it.", # ---- game status / library "status": "How well the game runs on the Steam Frame. \"Works\" and \"Works with issues\" were tested on a Frame; " "\"Untested\" is a suggestion nobody has confirmed yet. \"Can't run\" means a known blocker.", diff --git a/src/frameport/ui/views/settings.py b/src/frameport/ui/views/settings.py index 7748f67b..1e4c4dc8 100644 --- a/src/frameport/ui/views/settings.py +++ b/src/frameport/ui/views/settings.py @@ -98,7 +98,8 @@ class SettingsView: def installing(self) -> ft.Control: from ...core import library - from ...install.installer import upload_threads + from ...frame.local import on_frame + from ...install.installer import steam_library_mode, upload_threads def steam_changed(e): mode = e.control.value @@ -123,10 +124,12 @@ class SettingsView: tr("This applies pending library changes and closes Desktop Mode and FramePort on the Frame."), tr("Restart Steam now"), lambda: app.run_bg(work)) + here = on_frame() # FramePort on the Frame itself: Later is the default (GitHub #425) steam = ft.Row([C.dropdown(label=tr("Steam library"), - value=library.setting("install.steam_library", "now"), width=T.px(360), - options=[ft.DropdownOption("now", tr("Now (default)")), - ft.DropdownOption("later", tr("Later — next Steam start")), + value=steam_library_mode(), width=T.px(360), + options=[ft.DropdownOption("now", tr("Now") if here else tr("Now (default)")), + ft.DropdownOption("later", tr("Later — next Steam start (default)") if here + else tr("Later — next Steam start")), ft.DropdownOption("off", tr("Off — launch from FramePort"))], on_select=steam_changed), C.help_icon("steam_library")], spacing=T.S1) def changed(e): diff --git a/tests/test_cli.py b/tests/test_cli.py index 94b670ae..2589f4f9 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -57,3 +57,17 @@ def test_restart_steam_cli_confirmation(monkeypatch): calls.clear() result = CliRunner().invoke(cli.app, ["frame", "restart-steam"], input="y\n") assert result.exit_code == 0 and calls == [{"confirm": False}, {"confirm": True}] + + +def test_steam_library_defaults_to_later_on_the_frame(monkeypatch): + """GitHub #425: with Now, FramePort on the Frame waited for itself to close before Steam could restart.""" + from frameport.core import library + from frameport.install import installer + + monkeypatch.setattr("frameport.frame.local.on_frame", lambda: True) + assert installer.steam_library_mode() == "later" + monkeypatch.setattr("frameport.frame.local.on_frame", lambda: False) + assert installer.steam_library_mode() == "now" + library.set_setting("install.steam_library", "now") + monkeypatch.setattr("frameport.frame.local.on_frame", lambda: True) + assert installer.steam_library_mode() == "now" # a choice the user made wins