fix(ui): HomeScreen::poll() re-fired shutdown() every tick after the first

_shutdown_init (set true once KEY_ENTER is pressed on the Shutdown home
page) was never cleared, so this branch kept calling _task->shutdown()
on every single poll() tick indefinitely once triggered.

Invisible on real hardware: _board->powerOff() halts the MCU in the
non-restart path, so there's no next tick to matter. But
SimMainBoard::powerOff() is a deliberate no-op (no real hardware to
power off), so a sim instance keeps running after "shutdown" -- and each
repeated shutdown() call re-fires _display->turnOff(), which blacks out
its <canvas> (keyed by simInstanceTag) again on every frame.

This is what made meshcore-solo-site's RESET button unusable after a
device had been shut down: the still-running old instance kept
re-blacking the very canvas a freshly reset instance (same tag, same
canvas element) was trying to render its own boot splash onto -- visible
as a black screen, with the new instance's splash winning a single frame
every so often before being painted over again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018iubftDmKNWmkNnhJRz8UH
This commit is contained in:
Jakub
2026-09-03 22:20:55 +02:00
co-authored by Claude Sonnet 5
parent 718dbdbe74
commit 5fbfd7c5f9
@@ -534,6 +534,16 @@ public:
void poll() override { void poll() override {
if (_shutdown_init && !_task->isButtonPressed()) { // must wait for USR button to be released if (_shutdown_init && !_task->isButtonPressed()) { // must wait for USR button to be released
// _shutdown_init is never cleared elsewhere -- on real hardware
// that's harmless because _board->powerOff() halts the MCU, so
// there is no next poll() tick to matter. In the sim, powerOff()
// is a deliberate no-op (no real hardware to power off, see
// SimMainBoard.h), so without this the instance keeps running and
// this branch re-fires shutdown() -> _display->turnOff() on every
// single tick forever, repeatedly blacking out its canvas -- which
// fights with a freshly reset instance's own boot splash trying to
// render onto that same (simInstanceTag-keyed) canvas element.
_shutdown_init = false;
_task->shutdown(); _task->shutdown();
} }
} }