Files
StreamCap/app/lifecycle/tray_manager.py

94 lines
2.9 KiB
Python

import os
import threading
import flet as ft
from ..utils.logger import logger
class TrayManager:
def __init__(self, app):
self.app = app
self.icon = None
self.tray_thread = None
self.is_running = False
self.execute_dir = getattr(app, "run_path", os.getcwd())
self.assets_dir = "assets"
def create_image(self):
try:
from PIL import Image
icon_path = os.path.join(self.execute_dir, self.assets_dir, "icons", "tray_icon.ico")
if os.path.exists(icon_path):
return Image.open(icon_path)
except Exception as e:
logger.error(f"Failed to load icon file: {e}")
try:
from PIL import Image
image = Image.new('RGB', (32, 32), color=(255, 255, 255))
return image
except Exception as e:
logger.error("PIL not available, unable to create tray icon")
raise e
def create_tray_icon(self, page: ft.Page):
if self.is_running:
return
try:
import pystray
def on_restore(_icon, _item):
page.window.visible = True
page.window.minimized = False
page.update()
def on_exit(_icon, _item):
self.is_running = False
on_restore(_icon, _item)
if hasattr(self.app, "close_confirm_dialog"):
self.app.close_confirm_dialog.open = True
page.update()
language = self.app.language_manager.language
_ = {}
for key in ("tray_manager", "base"):
_.update(language.get(key, {}))
menu = pystray.Menu(
pystray.MenuItem(_["restore"], on_restore),
pystray.MenuItem(_["exit"], on_exit)
)
self.icon = pystray.Icon("StreamCap", self.create_image(), "StreamCap", menu)
self.is_running = True
self.icon.run()
except ImportError as e:
logger.error(e)
self.is_running = False
page.window.destroy()
raise e
def start(self, page: ft.Page):
if getattr(self.app, "is_web_mode", False):
logger.info("Tray icon not available in web mode")
return False
if self.tray_thread is None or not self.tray_thread.is_alive():
self.tray_thread = threading.Thread(target=self.create_tray_icon, args=(page,), daemon=True)
self.tray_thread.start()
return True
return False
def stop(self):
if self.icon and self.is_running:
self.is_running = False
try:
self.icon.stop()
return True
except Exception as e:
logger.error(f"Error stopping tray icon: {e}")
return False