146 lines
4.3 KiB
Python
146 lines
4.3 KiB
Python
#!/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()
|
|
|