From 859f2c8a22484ef424d95ac8648dc63ed38302c3 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sat, 24 Oct 2026 01:03:36 +0200 Subject: [PATCH] fix: match the idle line and keep the found folder The handheld launcher compared the idle close's line without install.py's RetroBIOS: prefix, and its test fake printed it the same way, so the device still waited 300 s: a test now ties both to TUI_IDLE_WORDS. The interface offered the built-in default folder when the folder found here could not be opened, a folder RetroArch does not read. --- install.ps1 | 2 +- install.py | 11 ++++++++--- install.sh | 2 +- ports/shared/tui.txt | 2 +- tests/test_handheld_launchers.py | 11 ++++++++++- tests/test_install_tui.py | 4 ++++ 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/install.ps1 b/install.ps1 index 0cd73eaa..aadf7a7c 100644 --- a/install.ps1 +++ b/install.ps1 @@ -11,7 +11,7 @@ $ErrorActionPreference = "Stop" $defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" - $defaultInstallSha256 = "dcf0c308a5a3176b66360e196d10b2ac678bda7f9245b22bc0cf43b0459a7d4d" + $defaultInstallSha256 = "bf5fd291aeffd7759153f2cfc168ef153a8806e20d708b00e5287fdd63036b20" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index 27c1b40f..24789925 100644 --- a/install.py +++ b/install.py @@ -9217,7 +9217,10 @@ def _install(args: argparse.Namespace, real_stdout: TextIO) -> None: # A system_directory under /root read from retroarch.cfg, run without # sudo: the case probe raised PermissionError before any line. for _name, path in platforms: - _refuse_closed(path, "detected here") + if closed_folder(path) is not None and len(platforms) > 1: + print(" Nothing was installed. Name one platform with --platform " + "to install it alone.", file=sys.stderr) + _refuse_closed(path, "detected here (name another with --dest)") total_downloaded = 0 total_up_to_date = 0 @@ -10791,8 +10794,10 @@ def _choose(state: TuiState, plat: str, dest: Path) -> list[tuple]: state.platform, state.status = plat, _closed_status(state, closed) if state.stack and state.screen in ("folder", "browse", "path"): return [] - state.folder_default = (None if plat in CARD_PLATFORMS - else _default_dest(state.os_type, plat)) + # The folder found here is the one the frontend reads: the built-in + # default beside it is one it does not, offered as "reads its BIOS + # files from" and filled with Enter. + state.folder_default = None return _push(state, "folder") card = card_system(dest) if card and card[0] == plat and card[1] != dest: diff --git a/install.sh b/install.sh index c901cd7a..732c351a 100755 --- a/install.sh +++ b/install.sh @@ -18,7 +18,7 @@ esac TEMP_INSTALLER="" TEMP_DIRECTORY="" DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" -DEFAULT_INSTALL_SHA256="dcf0c308a5a3176b66360e196d10b2ac678bda7f9245b22bc0cf43b0459a7d4d" +DEFAULT_INSTALL_SHA256="bf5fd291aeffd7759153f2cfc168ef153a8806e20d708b00e5287fdd63036b20" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/ports/shared/tui.txt b/ports/shared/tui.txt index e7f2a4bb..f01e3cc5 100644 --- a/ports/shared/tui.txt +++ b/ports/shared/tui.txt @@ -876,7 +876,7 @@ rb_here() { # Ended by Start + Select or a signal: the player asked to leave, and no # button may be left to close a message. : - elif [ "$status" != "0" ] && [ "$(head -n 1 "$RB_STATE/tui.err" 2>/dev/null)" = "No button pressed, closing." ]; then + elif [ "$status" != "0" ] && [ "$(head -n 1 "$RB_STATE/tui.err" 2>/dev/null)" = "RetroBIOS: No button pressed, closing." ]; then # Closed for want of a button: the mapper never opened the pad, so no A # is coming. The error it closed is the next line, shown for # RB_DEAD_WAIT seconds. diff --git a/tests/test_handheld_launchers.py b/tests/test_handheld_launchers.py index 3eef936d..75705624 100644 --- a/tests/test_handheld_launchers.py +++ b/tests/test_handheld_launchers.py @@ -486,7 +486,7 @@ if os.environ.get("FAKE_HOLD"): sys.exit(0) if os.environ.get("FAKE_IDLE_ERROR"): # RETROBIOS_IDLE_EXIT on an error screen: the idle line, then the error. - print("No button pressed, closing.", file=sys.stderr) + print("RetroBIOS: No button pressed, closing.", file=sys.stderr) print("Error: " + os.environ["FAKE_IDLE_ERROR"], file=sys.stderr) if os.environ.get("FAKE_ERROR"): print("Error: " + os.environ["FAKE_ERROR"], file=sys.stderr) @@ -1214,6 +1214,15 @@ class ThePortMasterPort(unittest.TestCase): self.assertNotIn("No button pressed", device.screen) device.assert_console_restored() + def test_the_idle_line_is_the_one_install_py_writes(self): + """The launcher keyed on the words without install.py's prefix, and + its fake printed them the same way: the test passed, the device + still waited 300 s.""" + line = f"RetroBIOS: {install.TUI_IDLE_WORDS}" + tui = (REPO_ROOT / "ports" / "shared" / "tui.txt").read_text(encoding="utf-8") + self.assertIn(f'= "{line}" ]', tui) + self.assertIn(f'print("{line}", file=sys.stderr)', FAKE_INSTALL) + def test_start_select_before_the_interface_handles_signals(self): """A SIGTERM before run_tui installs its handlers ends Python on the default action, status 143.""" diff --git a/tests/test_install_tui.py b/tests/test_install_tui.py index f1c2c6c4..2a496a29 100644 --- a/tests/test_install_tui.py +++ b/tests/test_install_tui.py @@ -2923,6 +2923,10 @@ class AFolderThisUserCannotOpen(unittest.TestCase): state.stack = ["setup"] self.assertEqual(install.tui_update(state, Key("enter")), []) self.assertEqual(state.screen, "folder") + # The folder found is the one RetroArch reads: its built-in default + # is not, and was offered with Enter on "Use this folder". + self.assertIsNone(state.folder_default) + self.assertNotIn("reads its BIOS files from", self.said(state)) self.assertIn(f"This user cannot open {install._short_path(self.lock, state.home)} " "(Permission denied)", self.said(state))