From 3fbd928b98ea8e63556d59cd3b14074f7d146afc Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 17 Dec 2025 01:53:17 -0800 Subject: [PATCH] Revert "ui: generic hold gesture (#36893)" This reverts commit 9768109ec11416648076163af230d82563666628. --- selfdrive/ui/mici/layouts/home.py | 33 +++++++++++++++++++++++-------- system/ui/widgets/__init__.py | 30 ++-------------------------- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/selfdrive/ui/mici/layouts/home.py b/selfdrive/ui/mici/layouts/home.py index af97de92f4..9152bdc7fa 100644 --- a/selfdrive/ui/mici/layouts/home.py +++ b/selfdrive/ui/mici/layouts/home.py @@ -1,3 +1,5 @@ +import time + from cereal import log import pyray as rl from collections.abc import Callable @@ -81,6 +83,9 @@ class MiciHomeLayout(Widget): self._on_settings_click: Callable | None = None self._last_refresh = 0 + self._mouse_down_t: None | float = None + self._did_long_press = False + self._is_pressed_prev = False self._version_text = None self._experimental_mode = False @@ -119,13 +124,23 @@ class MiciHomeLayout(Widget): def _update_params(self): self._experimental_mode = ui_state.params.get_bool("ExperimentalMode") - def _handle_long_press(self, _): - # long gating for experimental mode - only allow toggle if longitudinal control is available - if ui_state.has_longitudinal_control: - self._experimental_mode = not self._experimental_mode - ui_state.params.put("ExperimentalMode", self._experimental_mode) - def _update_state(self): + if self.is_pressed and not self._is_pressed_prev: + self._mouse_down_t = time.monotonic() + elif not self.is_pressed and self._is_pressed_prev: + self._mouse_down_t = None + self._did_long_press = False + self._is_pressed_prev = self.is_pressed + + if self._mouse_down_t is not None: + if time.monotonic() - self._mouse_down_t > 0.5: + # long gating for experimental mode - only allow toggle if longitudinal control is available + if ui_state.has_longitudinal_control: + self._experimental_mode = not self._experimental_mode + ui_state.params.put("ExperimentalMode", self._experimental_mode) + self._mouse_down_t = None + self._did_long_press = True + if rl.get_time() - self._last_refresh > 5.0: device_state = ui_state.sm['deviceState'] self._update_network_status(device_state) @@ -144,8 +159,10 @@ class MiciHomeLayout(Widget): self._on_settings_click = on_settings def _handle_mouse_release(self, mouse_pos: MousePos): - if self._on_settings_click: - self._on_settings_click() + if not self._did_long_press: + if self._on_settings_click: + self._on_settings_click() + self._did_long_press = False def _get_version_text(self) -> tuple[str, str, str, str] | None: description = ui_state.params.get("UpdaterCurrentDescription") diff --git a/system/ui/widgets/__init__.py b/system/ui/widgets/__init__.py index 5b3b4a691c..a3fed6d962 100644 --- a/system/ui/widgets/__init__.py +++ b/system/ui/widgets/__init__.py @@ -20,8 +20,6 @@ class DialogResult(IntEnum): class Widget(abc.ABC): - LONG_PRESS_TIME = 0.5 - def __init__(self): self._rect: rl.Rectangle = rl.Rectangle(0, 0, 0, 0) self._parent_rect: rl.Rectangle | None = None @@ -35,10 +33,6 @@ class Widget(abc.ABC): self._multi_touch = False self.__was_awake = True - # Long press state (single touch only, slot 0) - self._long_press_start_t: float | None = None - self._long_press_fired: bool = False - @property def rect(self) -> rl.Rectangle: return self._rect @@ -133,28 +127,19 @@ class Widget(abc.ABC): self._handle_mouse_press(mouse_event.pos) self.__is_pressed[mouse_event.slot] = True self.__tracking_is_pressed[mouse_event.slot] = True - if mouse_event.slot == 0: - self._long_press_start_t = rl.get_time() - self._long_press_fired = False self._handle_mouse_event(mouse_event) # Callback such as scroll panel signifies user is scrolling elif not touch_valid: self.__is_pressed[mouse_event.slot] = False self.__tracking_is_pressed[mouse_event.slot] = False - if mouse_event.slot == 0: - self._long_press_start_t = None - self._long_press_fired = False elif mouse_event.left_released: self._handle_mouse_event(mouse_event) - if self.__is_pressed[mouse_event.slot] and mouse_in_rect and not (mouse_event.slot == 0 and self._long_press_fired): + if self.__is_pressed[mouse_event.slot] and mouse_in_rect: self._handle_mouse_release(mouse_event.pos) self.__is_pressed[mouse_event.slot] = False self.__tracking_is_pressed[mouse_event.slot] = False - if mouse_event.slot == 0: - self._long_press_start_t = None - self._long_press_fired = False # Mouse/touch is still within our rect elif mouse_in_rect: @@ -165,17 +150,8 @@ class Widget(abc.ABC): # Mouse/touch left our rect but may come back into focus later elif not mouse_in_rect: self.__is_pressed[mouse_event.slot] = False - if mouse_event.slot == 0: - self._long_press_start_t = None - self._long_press_fired = False self._handle_mouse_event(mouse_event) - # Long press detection - if self._long_press_start_t is not None and not self._long_press_fired: - if (rl.get_time() - self._long_press_start_t) >= self.LONG_PRESS_TIME: - self._long_press_fired = True - self._handle_long_press(gui_app.last_mouse_event.pos) - def _layout(self) -> None: """Optionally lay out child widgets separately. This is called before rendering.""" @@ -199,11 +175,9 @@ class Widget(abc.ABC): self._click_callback() return False - def _handle_long_press(self, mouse_pos: MousePos) -> None: - """Optionally handle a long-press gesture.""" - def _handle_mouse_event(self, mouse_event: MouseEvent) -> None: """Optionally handle mouse events. This is called before rendering.""" + # Default implementation does nothing, can be overridden by subclasses def show_event(self): """Optionally handle show event. Parent must manually call this"""