From 3509fccec7c050c1f4758574ec5a5cdf93774e98 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Tue, 14 Apr 2026 21:44:39 -0400 Subject: [PATCH] [TIZI/TICI] ui: remove per-frame param sync (#1802) * [TIZI/TICI] ui: remove per-frame param sync * fix: prevent params.put skip in OptionControlSP by deferring mutation to set_value The idempotent guard added in the previous commit was being bypassed because _handle_mouse_release mutated self.current_value before calling set_value(), making the check always return early. Now we calculate the new value and pass it to set_value, allowing the guard to work correctly and params to persist. --- .../ui/sunnypilot/layouts/settings/display.py | 17 ++------- .../ui/sunnypilot/widgets/option_control.py | 36 ++++++++++--------- 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/selfdrive/ui/sunnypilot/layouts/settings/display.py b/selfdrive/ui/sunnypilot/layouts/settings/display.py index acd7b52dcc..8ba5663662 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/display.py +++ b/selfdrive/ui/sunnypilot/layouts/settings/display.py @@ -6,12 +6,10 @@ See the LICENSE.md file in the root directory for more details. """ from enum import IntEnum -from openpilot.common.params import Params -from openpilot.system.ui.sunnypilot.widgets.option_control import OptionControlSP from openpilot.system.ui.widgets import Widget from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.widgets.scroller_tici import Scroller -from openpilot.system.ui.sunnypilot.widgets.list_view import option_item_sp, ToggleActionSP +from openpilot.system.ui.sunnypilot.widgets.list_view import option_item_sp from openpilot.sunnypilot.system.params_migration import ONROAD_BRIGHTNESS_TIMER_VALUES @@ -25,7 +23,6 @@ class DisplayLayout(Widget): def __init__(self): super().__init__() - self._params = Params() items = self._initialize_items() self._scroller = Scroller(items, line_separator=True, spacing=0) @@ -87,17 +84,7 @@ class DisplayLayout(Widget): def _update_state(self): super()._update_state() - for _item in self._scroller._items: - if isinstance(_item.action_item, ToggleActionSP) and _item.action_item.toggle.param_key is not None: - _item.action_item.set_state(self._params.get_bool(_item.action_item.toggle.param_key)) - elif isinstance(_item.action_item, OptionControlSP) and _item.action_item.param_key is not None: - raw_value = self._params.get(_item.action_item.param_key, return_default=True) - if _item.action_item.value_map: - reverse_map = {v: k for k, v in _item.action_item.value_map.items()} - raw_value = reverse_map.get(raw_value, _item.action_item.current_value) - _item.action_item.set_value(raw_value) - - brightness_val = self._params.get("OnroadScreenOffBrightness", return_default=True) + brightness_val = self._onroad_brightness.action_item.current_value self._onroad_brightness_timer.action_item.set_enabled(brightness_val not in (OnroadBrightness.AUTO, OnroadBrightness.AUTO_DARK)) def _render(self, rect): diff --git a/system/ui/sunnypilot/widgets/option_control.py b/system/ui/sunnypilot/widgets/option_control.py index 291d8f6ff0..82126417d5 100644 --- a/system/ui/sunnypilot/widgets/option_control.py +++ b/system/ui/sunnypilot/widgets/option_control.py @@ -60,17 +60,19 @@ class OptionControlSP(ItemAction): def set_value(self, value: int): """Set the control to a specific value""" - if self.min_value <= value <= self.max_value: - self.current_value = value - if self.value_map: - self.params.put(self.param_key, self.value_map[value]) - else: - if self.use_float_scaling: - self.params.put(self.param_key, value / 100.0) - else: - self.params.put(self.param_key, value) - if self.on_value_changed: - self.on_value_changed(value) + if not (self.min_value <= value <= self.max_value): + return + if value == self.current_value: + return + self.current_value = value + if self.value_map: + self.params.put(self.param_key, self.value_map[value]) + elif self.use_float_scaling: + self.params.put(self.param_key, value / 100.0) + else: + self.params.put(self.param_key, value) + if self.on_value_changed: + self.on_value_changed(value) def get_displayed_value(self) -> str: """Get the displayed value, handling value mapping if present""" @@ -157,10 +159,10 @@ class OptionControlSP(ItemAction): def _handle_mouse_release(self, mouse_pos: MousePos): if self._minus_enabled and rl.check_collision_point_rec(mouse_pos, self.minus_btn_rect): - self.current_value -= self.value_change_step - self.current_value = max(self.min_value, self.current_value) + new_value = self.current_value - self.value_change_step + new_value = max(self.min_value, new_value) + self.set_value(new_value) elif self._plus_enabled and rl.check_collision_point_rec(mouse_pos, self.plus_btn_rect): - self.current_value += self.value_change_step - self.current_value = min(self.max_value, self.current_value) - - self.set_value(self.current_value) + new_value = self.current_value + self.value_change_step + new_value = min(self.max_value, new_value) + self.set_value(new_value)