Files
whisper-local/whisper_local/tray/_tray.py
T

71 lines
2.0 KiB
Python
Raw Normal View History

2026-04-11 21:09:39 +02:00
"""Tray-App und App-Zustände für whisper-local."""
import enum
import threading
from typing import Callable
class AppState(enum.Enum):
WAITING = "waiting"
RECORDING = "recording"
TRANSCRIBING = "transcribing"
2026-04-11 21:09:39 +02:00
class PystrayApp:
"""Tray-Icon via pystray — cross-platform (Windows + Linux)."""
def __init__(self, on_settings: Callable[[], None], on_quit: Callable[[], None]):
self._on_settings = on_settings
self._on_quit = on_quit
self._icon = None
def start(self) -> None:
"""Startet pystray in einem Daemon-Thread."""
import pystray
from whisper_local.tray._icon import create_icon
menu = pystray.Menu(
pystray.MenuItem("Einstellungen", self._menu_settings),
pystray.MenuItem("Beenden", self._menu_quit),
)
self._icon = pystray.Icon(
"whisper-local",
create_icon(AppState.WAITING),
"whisper-local",
menu,
)
thread = threading.Thread(target=self._icon.run, daemon=True)
thread.start()
def set_state(self, state: AppState) -> None:
"""Tauscht das Icon aus (thread-sicher)."""
if self._icon is not None:
from whisper_local.tray._icon import create_icon
self._icon.icon = create_icon(state)
def set_warning(self, msg: str | None) -> None:
"""Setzt Tray-Titel auf Warnung oder zurück auf normal (thread-sicher)."""
if self._icon is not None:
self._icon.title = "whisper-local" if msg is None else f"whisper-local ⚠ {msg}"
def _menu_settings(self, icon, item) -> None:
self._on_settings()
def _menu_quit(self, icon, item) -> None:
if self._icon is not None:
self._icon.stop()
self._on_quit()
class NoOpTray:
"""Platzhalter-Implementierung für nicht-Windows-Plattformen."""
def start(self) -> None:
pass
def set_state(self, state: AppState) -> None:
pass
def set_warning(self, msg: str | None) -> None:
pass