#!/usr/bin/env python3 import subprocess import json import threading import queue from PIL import Image, ImageDraw, ImageFont import pystray update_queue = queue.Queue() icon = None ICON_PATH = "/home/teraflops/Imágenes/clipboard_16641980.png" UNICODE_GLYPH = "󱣽" FONT_PATH = "/usr/share/fonts/TTF/MesloLGS-NF-Regular.ttf" # Usa la ruta de tu fuente Nerd Font aquí FONT_SIZE = 90 def generate_glyph_icon(glyph=UNICODE_GLYPH, color=(255, 255, 255, 255)): size = 64 image = Image.new("RGBA", (size, size), (0, 0, 0, 0)) # Fondo transparente draw = ImageDraw.Draw(image) try: font = ImageFont.truetype(FONT_PATH, FONT_SIZE) except Exception as e: print(f"Error cargando fuente: {e}") font = ImageFont.load_default() bbox = draw.textbbox((0, 0), glyph, font=font) w = bbox[2] - bbox[0] h = bbox[3] - bbox[1] x = (size - w) / 2 - bbox[0] y = (size - h) / 2 - bbox[1] + 2 # bajamos un poco el glifo draw.text((x, y), glyph, font=font, fill=color) return image def get_scratchpad_clients(): try: result = subprocess.run(["hyprctl", "clients", "-j"], capture_output=True, text=True) clients = json.loads(result.stdout) scratchpad = [ {"title": c.get("title", "No Title"), "address": c.get("address")} for c in clients if c.get("workspace", {}).get("name") == "special:scratchpad" ] return scratchpad except Exception as e: print(f"Error getting clients: {e}") return [] def refresh_icon(): clients = get_scratchpad_clients() count = len(clients) try: if count == 0: image = generate_glyph_icon(color=(128, 128, 128, 180)) # Gris semitransparente tooltip = "Scratchpad vacío" elif count == 1: image = generate_glyph_icon(color=(255, 255, 255, 255)) # Blanco tooltip = f"Scratchpad: 1 ventana" elif count < 4: image = generate_glyph_icon(color=(255, 255, 0, 255)) # Amarillo tooltip = f"Scratchpad: {count} ventanas" else: image = generate_glyph_icon(color=(255, 0, 0, 255)) # Rojo tooltip = f"Scratchpad lleno: {count} ventanas" update_queue.put((image, tooltip)) except Exception as e: print(f"Error actualizando icono: {e}") def show_window_list(icon, item): clients = get_scratchpad_clients() if not clients: return menu_input = "\n".join([c["title"] for c in clients]) try: selection = subprocess.run( ["wofi", "--dmenu", "--prompt", "Scratchpad"], input=menu_input, text=True, capture_output=True ).stdout.strip() if selection: for c in clients: if c["title"] == selection: address = c["address"] subprocess.run(["hyprctl", "dispatch", "togglespecialworkspace", "scratchpad"]) subprocess.run(["hyprctl", "dispatch", "focuswindow", address]) break except Exception as e: print(f"Error mostrando menú: {e}") def toggle_scratchpad(icon, item): subprocess.run(["hyprctl", "dispatch", "togglespecialworkspace", "scratchpad"]) def quit_app(icon, item): icon.stop() def check_updates(): try: while True: new_image, new_title = update_queue.get_nowait() icon.icon = new_image icon.title = new_title except queue.Empty: pass threading.Timer(5, refresh_icon).start() threading.Timer(1, check_updates).start() def create_icon(): global icon # Generar icono inicial con glifo try: default_image = generate_glyph_icon() except Exception as e: print(f"Error generando ícono con glifo: {e}") default_image = Image.new("RGB", (64, 64), color="gray") menu = pystray.Menu( pystray.MenuItem("Mostrar ventanas", lambda icon, item: subprocess.Popen(["/home/teraflops/.local/bin/scratchpad_panel.py"])), pystray.MenuItem("Toggle Scratchpad", toggle_scratchpad), pystray.MenuItem("Salir", quit_app), ) icon = pystray.Icon("scratchpad", icon=default_image, title="Scratchpad", menu=menu) refresh_icon() check_updates() icon.run() if __name__ == "__main__": create_icon()