From 5fbfd7c5f90fec2f43994d09c76524976c34a7cc Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Thu, 3 Sep 2026 22:20:55 +0200 Subject: [PATCH] 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 (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 Claude-Session: https://claude.ai/code/session_018iubftDmKNWmkNnhJRz8UH --- examples/companion_radio/ui-new/UITask.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index d3866959..547eb07d 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -534,6 +534,16 @@ public: void poll() override { 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(); } }