dotfiles/.local/bin/scratchpadindicator.py_ok
2025-05-28 18:33:04 +02:00

146 lines
4.3 KiB
Python
Executable File

#!/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()