Try to create tray with pystray
(self)
| 312 | return False |
| 313 | |
| 314 | def _try_pystray(self) -> bool: |
| 315 | """Try to create tray with pystray""" |
| 316 | try: |
| 317 | import pystray |
| 318 | from PIL import Image, ImageDraw |
| 319 | |
| 320 | # Create a simple icon |
| 321 | size = 64 |
| 322 | image = Image.new("RGBA", (size, size), (0, 0, 0, 0)) |
| 323 | draw = ImageDraw.Draw(image) |
| 324 | draw.ellipse([4, 4, size - 4, size - 4], fill=COLORS["accent"]) |
| 325 | draw.ellipse([16, 16, size - 16, size - 16], fill=COLORS["bg_dark"]) |
| 326 | |
| 327 | # Create menu |
| 328 | menu = pystray.Menu( |
| 329 | pystray.MenuItem("📂 Show Window", self._pystray_show), |
| 330 | pystray.Menu.SEPARATOR, |
| 331 | pystray.MenuItem("▶️ Start", self._pystray_start), |
| 332 | pystray.MenuItem("⏹️ Stop", self._pystray_stop), |
| 333 | pystray.Menu.SEPARATOR, |
| 334 | pystray.MenuItem("🔍 API Test", self._pystray_test), |
| 335 | pystray.Menu.SEPARATOR, |
| 336 | pystray.MenuItem("❌ Exit", self._pystray_quit), |
| 337 | ) |
| 338 | |
| 339 | self.indicator = pystray.Icon( |
| 340 | "AI Studio Proxy", image, "AI Studio Proxy", menu |
| 341 | ) |
| 342 | threading.Thread(target=self.indicator.run, daemon=True).start() |
| 343 | |
| 344 | self.supported = True |
| 345 | self.backend = "pystray" |
| 346 | print("✅ pystray tray started (X11)") |
| 347 | return True |
| 348 | |
| 349 | except Exception as e: |
| 350 | print(f"⚠️ pystray could not be started: {e}") |
| 351 | return False |
| 352 | |
| 353 | def _pystray_show(self, icon=None, item=None): |
| 354 | self.app.root.after(0, self.app._show_window) |