diff --git a/tui/src/birdcage_tui/app.py b/tui/src/birdcage_tui/app.py index 1349e63..c7990d1 100644 --- a/tui/src/birdcage_tui/app.py +++ b/tui/src/birdcage_tui/app.py @@ -129,6 +129,17 @@ class BirdcageApp(App): if hasattr(screen, "on_show"): screen.on_show() + def on_unmount(self) -> None: + """Stop all polling threads and disconnect the device on shutdown.""" + for mode_key in MODES: + screen = self.query_one(f"#{mode_key}") + if hasattr(screen, "_polling"): + screen._polling = False + if hasattr(screen, "_monitoring"): + screen._monitoring = False + if self.device and hasattr(self.device, "disconnect"): + self.device.disconnect() + def action_toggle_dark(self) -> None: self.dark = not self.dark diff --git a/tui/src/birdcage_tui/screens/position.py b/tui/src/birdcage_tui/screens/position.py index da348c2..388b3c6 100644 --- a/tui/src/birdcage_tui/screens/position.py +++ b/tui/src/birdcage_tui/screens/position.py @@ -87,6 +87,10 @@ class PositionScreen(Container): self._polling = True self._poll_worker = self._do_position_poll() + def on_unmount(self) -> None: + """Stop polling thread on teardown.""" + self._polling = False + # ------------------------------------------------------------------ # Position poll worker # ------------------------------------------------------------------ diff --git a/tui/src/birdcage_tui/screens/signal.py b/tui/src/birdcage_tui/screens/signal.py index 0903c0a..9b7c7e9 100644 --- a/tui/src/birdcage_tui/screens/signal.py +++ b/tui/src/birdcage_tui/screens/signal.py @@ -71,6 +71,10 @@ class SignalScreen(Container): """Called when this screen becomes visible.""" pass # Monitoring is explicit via Start/Stop buttons. + def on_unmount(self) -> None: + """Stop monitoring thread on teardown.""" + self._monitoring = False + # ------------------------------------------------------------------ # Signal poll worker # ------------------------------------------------------------------