From 3f15a0e68689d4bb0999d267b72aafb938c81681 Mon Sep 17 00:00:00 2001 From: Thales Maciel Date: Tue, 24 Feb 2026 11:31:26 -0300 Subject: [PATCH] Simplify daemon tray --- src/leld.py | 73 ++++++++++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 45 deletions(-) diff --git a/src/leld.py b/src/leld.py index 15505e0..f281596 100755 --- a/src/leld.py +++ b/src/leld.py @@ -31,6 +31,12 @@ class State: OUTPUTTING = "outputting" +ASSETS_DIR = Path(__file__).parent / "assets" +RECORD_TIMEOUT_SEC = 300 +STT_LANGUAGE = "en" +TRAY_UPDATE_MS = 250 + + def _compute_type(device: str) -> str: dev = (device or "cpu").lower() if dev == "cuda": @@ -51,7 +57,14 @@ class Daemon: device=cfg.stt.get("device", "cpu"), compute_type=_compute_type(cfg.stt.get("device", "cpu")), ) - self.tray = _Tray(self.get_state, self._quit) + self.icon = Gtk.StatusIcon() + self.icon.set_visible(True) + self.icon.connect("popup-menu", self._on_tray_menu) + self.menu = Gtk.Menu() + quit_item = Gtk.MenuItem(label="Quit") + quit_item.connect("activate", lambda *_: self._quit()) + self.menu.append(quit_item) + self.menu.show_all() def set_state(self, state: str): with self.lock: @@ -67,6 +80,9 @@ class Daemon: def _quit(self): os._exit(0) + def _on_tray_menu(self, _icon, _button, _time): + self.menu.popup(None, None, None, None, 0, _time) + def toggle(self): with self.lock: if self.state == State.IDLE: @@ -90,7 +106,7 @@ class Daemon: logging.info("recording started (%s)", record.wav_path) if self.timer: self.timer.cancel() - self.timer = threading.Timer(300, self._timeout_stop) + self.timer = threading.Timer(RECORD_TIMEOUT_SEC, self._timeout_stop) self.timer.daemon = True self.timer.start() @@ -184,11 +200,7 @@ class Daemon: threading.Thread(target=self._stop_and_process, daemon=True).start() def _transcribe(self, wav_path: str) -> str: - segments, _info = self.model.transcribe( - wav_path, - language=None, - vad_filter=True, - ) + segments, _info = self.model.transcribe(wav_path, language=STT_LANGUAGE, vad_filter=True) parts = [] for seg in segments: text = (seg.text or "").strip() @@ -196,35 +208,14 @@ class Daemon: parts.append(text) return " ".join(parts).strip() - def run_tray(self): - self.tray.run() - - -class _Tray: - def __init__(self, state_getter, on_quit): - self.state_getter = state_getter - self.on_quit = on_quit - self.base = Path(__file__).parent / "assets" - self.icon = Gtk.StatusIcon() - self.icon.set_visible(True) - self.icon.connect("popup-menu", self._on_menu) - self.menu = Gtk.Menu() - quit_item = Gtk.MenuItem(label="Quit") - quit_item.connect("activate", lambda *_: self.on_quit()) - self.menu.append(quit_item) - self.menu.show_all() - - def _on_menu(self, _icon, _button, _time): - self.menu.popup(None, None, None, None, 0, _time) - def _icon_path(self, state: str) -> str: if state == State.RECORDING: - return str(self.base / "recording.png") + return str(ASSETS_DIR / "recording.png") if state == State.STT: - return str(self.base / "transcribing.png") + return str(ASSETS_DIR / "transcribing.png") if state == State.PROCESSING: - return str(self.base / "processing.png") - return str(self.base / "idle.png") + return str(ASSETS_DIR / "processing.png") + return str(ASSETS_DIR / "idle.png") def _title(self, state: str) -> str: if state == State.RECORDING: @@ -235,15 +226,15 @@ class _Tray: return "AI Processing" return "Idle" - def update(self): - state = self.state_getter() + def _update_tray(self): + state = self.get_state() self.icon.set_from_file(self._icon_path(state)) self.icon.set_tooltip_text(self._title(state)) return True - def run(self): - self.update() - GLib.timeout_add(250, self.update) + def run_tray(self): + self._update_tray() + GLib.timeout_add(TRAY_UPDATE_MS, self._update_tray) Gtk.main() @@ -265,7 +256,6 @@ def _lock_single_instance(): def main(): parser = argparse.ArgumentParser() parser.add_argument("--config", default="", help="path to config.json") - parser.add_argument("--no-tray", action="store_true", help="disable tray icon") parser.add_argument("--dry-run", action="store_true", help="log hotkey only") args = parser.parse_args() @@ -289,13 +279,6 @@ def main(): signal.signal(signal.SIGINT, handle_signal) signal.signal(signal.SIGTERM, handle_signal) - if args.no_tray: - listen( - cfg.daemon.get("hotkey", ""), - lambda: logging.info("hotkey pressed (dry-run)") if args.dry_run else daemon.toggle(), - ) - return - threading.Thread( target=lambda: listen( cfg.daemon.get("hotkey", ""),