From d638775f4393d2fed3f2acc6d9842b96986b0642 Mon Sep 17 00:00:00 2001 From: Srija Vuppala Date: Thu, 25 Jun 2026 00:47:08 -0400 Subject: [PATCH] ui: remove interactive timeout callback when driver camera dialog closes Device.add_interactive_timeout_callback() had no corresponding remove method, so every time the driver camera dialog was opened a new gui_app.pop_widget callback was appended and never cleaned up. Opening the dialog repeatedly grew the callback list unbounded. Add Device.remove_interactive_timeout_callback() and call it from hide_event() on both the tici and mici DriverCameraDialog so the callback is removed when the dialog closes. --- openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py | 5 ++++- openpilot/selfdrive/ui/onroad/driver_camera_dialog.py | 2 +- openpilot/selfdrive/ui/ui_state.py | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py b/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py index d880189412886f..66941d384edb52 100644 --- a/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py +++ b/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py @@ -232,9 +232,12 @@ def _draw_eyes(self, rect: rl.Rectangle, driver_data): class DriverCameraDialog(NavWidget, BaseDriverCameraDialog): def __init__(self): super().__init__() - # TODO: this can grow unbounded, should be given some thought device.add_interactive_timeout_callback(gui_app.pop_widget) + def hide_event(self): + super().hide_event() + device.remove_interactive_timeout_callback(gui_app.pop_widget) + if __name__ == "__main__": gui_app.init_window("Driver Camera View (mici)") diff --git a/openpilot/selfdrive/ui/onroad/driver_camera_dialog.py b/openpilot/selfdrive/ui/onroad/driver_camera_dialog.py index 7e07e44210ba22..413f3768579445 100644 --- a/openpilot/selfdrive/ui/onroad/driver_camera_dialog.py +++ b/openpilot/selfdrive/ui/onroad/driver_camera_dialog.py @@ -13,12 +13,12 @@ class DriverCameraDialog(CameraView): def __init__(self): super().__init__("camerad", VisionStreamType.VISION_STREAM_DRIVER) self.driver_state_renderer = DriverStateRenderer() - # TODO: this can grow unbounded, should be given some thought device.add_interactive_timeout_callback(gui_app.pop_widget) ui_state.params.put_bool("IsDriverViewEnabled", True, block=True) def hide_event(self): super().hide_event() + device.remove_interactive_timeout_callback(gui_app.pop_widget) ui_state.params.put_bool("IsDriverViewEnabled", False, block=True) self.close() diff --git a/openpilot/selfdrive/ui/ui_state.py b/openpilot/selfdrive/ui/ui_state.py index 78388593c8945b..b59550a6099700 100644 --- a/openpilot/selfdrive/ui/ui_state.py +++ b/openpilot/selfdrive/ui/ui_state.py @@ -246,6 +246,9 @@ def _reset_interactive_timeout(self) -> None: def add_interactive_timeout_callback(self, callback: Callable): self._interactive_timeout_callbacks.append(callback) + def remove_interactive_timeout_callback(self, callback: Callable): + self._interactive_timeout_callbacks.remove(callback) + def update(self): self._start_brightness_thread() # start thread after manager forks ui