diff --git a/services/tray/chobit_tray.py b/services/tray/chobit_tray.py index 622132f..766b5fc 100644 --- a/services/tray/chobit_tray.py +++ b/services/tray/chobit_tray.py @@ -134,6 +134,7 @@ class ChobitTray(TrayApp): menu: list[TrayMenuItem] = [ TrayMenuItem.action("Settings", self._open_board), + TrayMenuItem.action("Camera Settings", self._open_camera_settings), TrayMenuItem.separator(), TrayMenuItem.action("Toggle Snap", self._toggle_snap), ] @@ -193,12 +194,6 @@ class ChobitTray(TrayApp): self._select_camera(index) elif cmd == "list_cameras": self._send_camera_list() - elif cmd == "open_camera_preview": - try: - from gi.repository import GLib - GLib.idle_add(self._open_camera_panel) - except ImportError: - pass def _send_camera_list(self) -> None: """Send enumerated camera list to Godot via UDP.""" @@ -206,6 +201,7 @@ class ChobitTray(TrayApp): {"index": c["index"], "name": c["name"], "path": c.get("path", "")} for c in self._cameras ] + fr.record("tray.camera_list", "Camera list sent to Godot", {"count": len(cameras)}) msg = {"cmd": "camera_list", "cameras": cameras} sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: @@ -332,6 +328,7 @@ class ChobitTray(TrayApp): ): return if not VISION_SCRIPT.exists(): + fr.record("tray.vision.error", "Vision script not found", {"path": str(VISION_SCRIPT)}) return LOG_DIR.mkdir(parents=True, exist_ok=True) log_file = VISION_LOG.open("a") @@ -341,19 +338,23 @@ class ChobitTray(TrayApp): str(VISION_SCRIPT), "--camera", str(self._active_camera), + "--preview-port", + "19703", ], stdout=log_file, stderr=log_file, ) + fr.record("tray.vision.start", "Vision sidecar started", {"camera": self._active_camera}) def _stop_vision(self) -> None: """Stop the vision sidecar subprocess.""" if self._vision_process is not None: + fr.record("tray.vision.stop", "Vision sidecar stopped", {"camera": self._active_camera}) self._terminate(self._vision_process) self._vision_process = None def _cleanup(self) -> None: - """Stop managed subprocesses.""" + fr.record("tray.quit", "Tray exiting — stopping Godot and vision") _send_command("quit") self._stop_vision() @@ -398,6 +399,10 @@ class ChobitTray(TrayApp): fr.record("tray.open_settings", "Settings panel opened") _send_command("open_settings") + def _open_camera_settings(self) -> None: + fr.record("tray.open_camera_settings", "Camera settings panel opened") + _send_command("open_settings_page", page="camera") + def create_app(dev_mode: bool = False) -> ChobitTray: """Create and return a ChobitTray instance (without running the main loop).""" diff --git a/services/tray/dev_trays.py b/services/tray/dev_trays.py index 65d289b..d6c8ee2 100644 --- a/services/tray/dev_trays.py +++ b/services/tray/dev_trays.py @@ -213,8 +213,10 @@ class FaceDevTray(DevServiceTray): def __init__(self, main_tray: ChobitTray) -> None: self._main_tray = main_tray menu = [ - TrayMenuItem.action("Toggle Camera", self._toggle_camera), + TrayMenuItem.action("Camera Settings", self._open_camera_settings), + TrayMenuItem.separator(), TrayMenuItem.action("Toggle Face", self._toggle_face), + TrayMenuItem.action("Toggle Gaze", self._toggle_gaze), TrayMenuItem.action("Toggle Halo", self._toggle_gaze_halo), TrayMenuItem.quit("Quit Face:dev"), ] @@ -261,12 +263,22 @@ class FaceDevTray(DevServiceTray): labels["Halo"] = "—" return ("warning" if redis_ok else "stopped"), labels - def _toggle_camera(self) -> None: + def _open_camera_settings(self) -> None: + fr.record("tray.open_camera_settings", "Camera settings panel opened") + _send_command("open_settings_page", page="camera") + + def _toggle_face(self) -> None: + fr.record("tray.toggle_face", "Vision sidecar toggled via Face:dev") self._main_tray.toggle_camera() self.set_status_labels(self.get_status_labels()) - def _toggle_face(self) -> None: - fr.record("tray.toggle_face", "Face/gaze mode toggled") + def _toggle_gaze(self) -> None: + fr.record("tray.toggle_gaze", "Gaze mode toggled via Face:dev") + _send_command("toggle_gaze") + self.set_status_labels(self.get_status_labels()) + + def _toggle_gaze(self) -> None: + fr.record("tray.toggle_gaze", "Godot gaze mode toggled") _send_command("toggle_gaze") self.set_status_labels(self.get_status_labels())