mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-24 04:39:06 -05:00
feat: close the first screen when no button comes
RETROBIOS_IDLE_EXIT=SECONDS: with no key on the first screen for that long, before any choice, the interface exits 0 with one line. A mapper that never opens the pad no longer freezes a handheld there.
This commit is contained in:
1 parent
a296bbfdff
commit
a23e9a09b8
4 files changed
+67
-2
No files matched your search
+1
-1
@@ -11,7 +11,7 @@
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
$defaultInstallSha256 = "079fcba3b83003932af8f5ed513e556675832ab20e55bbbbc356581b2daf1a14"
|
||||
$defaultInstallSha256 = "4d0a09cb5df35b5ccac1addbcd31feaf1ae00153694c11c7a1894e73bc063833"
|
||||
$maximumInstallerBytes = 2MB
|
||||
$installerExit = 0
|
||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||
|
||||
+29
@@ -9965,6 +9965,8 @@ class TuiState:
|
||||
self.dry: dict | None = None
|
||||
self.dry_files: list = []
|
||||
self.dry_summary: dict | None = None
|
||||
# Closed by RETROBIOS_IDLE_EXIT, no key ever pressed.
|
||||
self.idle_closed = False
|
||||
# The check run's summary: what it left out and why.
|
||||
self.check_summary: dict | None = None
|
||||
# The confirm screen waits for A even when the plan is unchanged:
|
||||
@@ -10021,6 +10023,24 @@ TUI_PAD_ROUTES = ("gptokeyb", "muxterm", "evmapy", "miyoo")
|
||||
_STEAM_MARKERS = ("SteamGamepadUI", "SteamDeck", "SteamGameId", "GAMESCOPE_WAYLAND_DISPLAY")
|
||||
|
||||
|
||||
# Seconds the first screen waits for a first key before it closes, set by a
|
||||
# launcher whose mapper may never open the pad: the screen would otherwise
|
||||
# hold a handheld that has no other way out.
|
||||
TUI_IDLE_ENV = "RETROBIOS_IDLE_EXIT"
|
||||
TUI_IDLE_WORDS = "No button pressed, closing."
|
||||
|
||||
|
||||
def tui_idle_exit(env: Mapping[str, str] | None = None) -> float | None:
|
||||
"""The seconds RETROBIOS_IDLE_EXIT names, None when unset or not a
|
||||
positive number."""
|
||||
env = os.environ if env is None else env
|
||||
try:
|
||||
seconds = float(env.get(TUI_IDLE_ENV, "").strip())
|
||||
except ValueError:
|
||||
return None
|
||||
return seconds if 0 < seconds < float("inf") else None
|
||||
|
||||
|
||||
def tui_pad_route(os_type: str, env: Mapping[str, str] | None = None) -> str:
|
||||
"""The keys the hints name: a launcher's pad route, "keys" at a desktop,
|
||||
"both" (button and key) where nothing says which one is held."""
|
||||
@@ -12580,6 +12600,8 @@ def tui_farewell(state: TuiState) -> list[str]:
|
||||
|
||||
|
||||
def _farewell_lines(state: TuiState) -> list[str]:
|
||||
if state.idle_closed:
|
||||
return [f"RetroBIOS: {TUI_IDLE_WORDS}"]
|
||||
if state.screen != "result" and state.download is not None:
|
||||
# An install ran: what it wrote is said, whatever ended it.
|
||||
title, lines = tui_outcome(state)
|
||||
@@ -12705,6 +12727,8 @@ def run_tui(args: argparse.Namespace) -> int:
|
||||
number = getattr(signal, name, None)
|
||||
if number is not None:
|
||||
handlers[number] = signal.signal(number, handler)
|
||||
idle = tui_idle_exit()
|
||||
first_screen, opened, pressed = state.screen, time.monotonic(), False
|
||||
sys.stdout = sys.stderr = buffer
|
||||
try:
|
||||
_prune_work_folders(work.parent, time.time())
|
||||
@@ -12735,10 +12759,15 @@ def run_tui(args: argparse.Namespace) -> int:
|
||||
state.now = time.monotonic()
|
||||
terminal.draw(tui_view(state, cols, rows), cols)
|
||||
for key in terminal.keys(TUI_FRAME):
|
||||
pressed = True
|
||||
state.now = time.monotonic()
|
||||
perform(tui_update(state, key))
|
||||
if state.exit_code is not None:
|
||||
break
|
||||
if (idle is not None and not pressed and state.exit_code is None
|
||||
and state.screen == first_screen
|
||||
and time.monotonic() - opened >= idle):
|
||||
state.idle_closed, state.exit_code = True, 0
|
||||
if flags["interrupt"]:
|
||||
flags["interrupt"] = False
|
||||
if time.monotonic() >= ignore_interrupt_until[0]:
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ esac
|
||||
TEMP_INSTALLER=""
|
||||
TEMP_DIRECTORY=""
|
||||
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
DEFAULT_INSTALL_SHA256="079fcba3b83003932af8f5ed513e556675832ab20e55bbbbc356581b2daf1a14"
|
||||
DEFAULT_INSTALL_SHA256="4d0a09cb5df35b5ccac1addbcd31feaf1ae00153694c11c7a1894e73bc063833"
|
||||
MAX_INSTALLER_BYTES=2097152
|
||||
|
||||
cleanup() {
|
||||
|
||||
@@ -2525,6 +2525,22 @@ class AuditRoundThree(unittest.TestCase):
|
||||
sorted(path.name for path in (running, failed, unknown, other)))
|
||||
|
||||
|
||||
class IdleExit(unittest.TestCase):
|
||||
def test_the_variable(self):
|
||||
for value, seconds in (("30", 30.0), (" 2.5 ", 2.5), ("", None), ("0", None),
|
||||
("-4", None), ("soon", None), ("inf", None), ("nan", None)):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(install.tui_idle_exit({install.TUI_IDLE_ENV: value}),
|
||||
seconds)
|
||||
self.assertIsNone(install.tui_idle_exit({}))
|
||||
|
||||
def test_the_farewell(self):
|
||||
state = fresh_state()
|
||||
state.idle_closed, state.exit_code = True, 0
|
||||
self.assertEqual(install.tui_farewell(state),
|
||||
["RetroBIOS: No button pressed, closing."])
|
||||
|
||||
|
||||
class AuditRoundFour(unittest.TestCase):
|
||||
"""tui_audit_3.md, each finding held where it was found."""
|
||||
|
||||
@@ -3044,6 +3060,26 @@ class EndToEnd(unittest.TestCase):
|
||||
self.assertEqual(term.status, 129)
|
||||
self.assertEqual(list(scratch.glob("retrobios-tui-*/error.log")), [])
|
||||
|
||||
def test_no_key_on_the_first_screen_closes_it(self):
|
||||
"""A mapper that never opens the pad left the first screen up for
|
||||
good: a handheld then has no way out but the power button."""
|
||||
self.repo()
|
||||
self.env[install.TUI_IDLE_ENV] = "1"
|
||||
term = self.start()
|
||||
term.wait("Where do you play?")
|
||||
self.assertEqual(term.close(), 0)
|
||||
self.assertIn("No button pressed, closing.", term.after())
|
||||
# A key pressed, the screen stays: the person is there.
|
||||
term = self.start()
|
||||
term.wait("Where do you play?")
|
||||
term.send(DOWN)
|
||||
end = time.monotonic() + 2.5
|
||||
while time.monotonic() < end:
|
||||
term._pump(0.05)
|
||||
self.assertEqual(os.waitpid(term.pid, os.WNOHANG), (0, 0))
|
||||
term.send("q")
|
||||
self.assertEqual(term.close(), 130)
|
||||
|
||||
def test_a_desktop_names_its_keys_and_a_pad_its_buttons(self):
|
||||
self.repo()
|
||||
for env, bar in (({"DISPLAY": ":0"}, "Enter Continue Esc Quit ? Help"),
|
||||
|
||||
Reference in new issue
Block a user