# main.py import os import queue import sys import threading def _setup_error_log(): """Last-resort error log for crashes before tray appears (frozen mode).""" if not getattr(sys, "frozen", False): return import traceback if os.name == "nt": log_dir = os.path.join(os.environ.get("LOCALAPPDATA", ""), "WhisperDictation") else: log_dir = os.path.join(os.path.expanduser("~"), ".local", "share", "WhisperDictation") os.makedirs(log_dir, exist_ok=True) log_path = os.path.join(log_dir, "error.log") sys.excepthook = lambda *args: open(log_path, "a").write( "".join(traceback.format_exception(*args)) + "\n" ) def main(): _setup_error_log() from whisper_app import app, config, audio, transcriber, hotkey from whisper_app import overlay, tray, log_window, settings_window, vocab_window import tkinter as tk config.load_config() config.load_vocab() # Tkinter root (hidden) root = tk.Tk() root.withdraw() app.overlay_tk = root # Log queue — connect before model load so early messages appear log_q: queue.Queue = queue.Queue() app.set_log_queue(log_q) # Windows overlay.create(root) log_win = log_window.create( root, log_q, on_settings=lambda: settings_window.open(root, _reload), on_vocab=lambda: vocab_window.open(root), ) # Load model in background so the tray appears immediately threading.Thread(target=transcriber.load_model, daemon=True).start() # Audio stream stream = audio.get_audio_stream() stream.start() # Hotkey def _on_release(): threading.Thread(target=transcriber.stop_and_transcribe, daemon=True).start() app.hotkey_listener = hotkey.HotkeyListener( config.config["hotkey"], on_press=_start_recording, on_release=_on_release, ) # Tray icon = tray.create( on_settings=lambda: settings_window.open(root, _reload), on_vocab=lambda: vocab_window.open(root), on_show_log=lambda: root.after(0, log_window.show), on_quit=lambda: _quit(stream, icon), ) threading.Thread(target=icon.run, daemon=True).start() app.log(f"Bereit. Hotkey: {config.config['hotkey']}") root.mainloop() stream.stop() def _start_recording(): from whisper_app import app, transcriber app.audio_chunks = [] transcriber.set_state(app.AppState.RECORDING) app.log("Recording...") def _reload(): from whisper_app import app, config, transcriber, hotkey if app.hotkey_listener: app.hotkey_listener.stop() threading.Thread(target=transcriber.load_model, daemon=True).start() app.hotkey_listener = hotkey.HotkeyListener( config.config["hotkey"], on_press=_start_recording, on_release=lambda: threading.Thread( target=transcriber.stop_and_transcribe, daemon=True).start(), ) app.log(f"Hotkey aktualisiert: {config.config['hotkey']}") def _quit(stream, icon): stream.stop() icon.stop() from whisper_app import app if app.overlay_tk: app.overlay_tk.after(0, app.overlay_tk.quit) if __name__ == "__main__": import multiprocessing multiprocessing.freeze_support() main()