#!/usr/bin/env python3 import os import subprocess import sys from PIL import Image import pystray from pystray import MenuItem as item import threading import time # Ruta a los iconos ICON_PATH = "/home/teraflops/Icons/" def get_volume(): """Obtiene el volumen actual usando pamixer.""" try: result = subprocess.check_output(["pamixer", "--get-volume"]) return int(result.strip()) except subprocess.CalledProcessError: return 50 # Valor por defecto si pamixer falla def set_volume(volume): """Establece el volumen usando pamixer.""" subprocess.run(["pamixer", "--set-volume", str(volume)]) def toggle_mute(): """Alterna el mute usando pamixer.""" subprocess.run(["pamixer", "--toggle-mute"]) def get_icon(volume): """Retorna el icono adecuado basado en el volumen.""" if volume == 0: icon_file = "volume-mute.png" elif 1 <= volume <= 33: icon_file = "volume-low.png" elif 34 <= volume <= 66: icon_file = "volume-medium.png" else: icon_file = "volume-high.png" return Image.open(os.path.join(ICON_PATH, icon_file)) def create_menu(icon, volume): """Crea el menú para el icono de la bandeja.""" return ( item('Ajustar Volumen', None), # Este ítem no hace nada item('Salir', on_quit) ) def on_quit(icon, item): """Maneja la opción de salir.""" icon.stop() sys.exit() def update_icon(icon): """Actualiza el icono basado en el volumen actual.""" volume = get_volume() icon.icon = get_icon(volume) def on_click(icon, item): """Maneja el clic izquierdo para mostrar el control de volumen.""" # Aquí puedes implementar una ventana flotante para ajustar el volumen # Por simplicidad, este ejemplo solo alterna el mute toggle_mute() update_icon(icon) def on_scroll(icon, direction): """Ajusta el volumen basado en la dirección del scroll.""" volume = get_volume() if direction == "up": new_volume = min(volume + 5, 100) elif direction == "down": new_volume = max(volume - 5, 0) set_volume(new_volume) update_icon(icon) def run_tray(): """Configura y ejecuta el icono de la bandeja.""" icon = pystray.Icon("volume-applet") icon.icon = get_icon(get_volume()) icon.title = "Control de Volumen" # Definir el menú icon.menu = pystray.Menu( item('Salir', on_quit) ) # Asignar eventos de clic y scroll icon.run_detached = False # Ejecutar en el hilo principal def on_left_click(icon, item): on_click(icon, item) def on_right_click(icon, item): # Los eventos de scroll no están directamente soportados, así que usaremos atajos pass icon.visible = True # Asignar evento de clic izquierdo icon.visible = True icon.update_menu = False icon.run(lambda icon: None) def main(): """Función principal para configurar el tray.""" icon = pystray.Icon("volume-applet") icon.icon = get_icon(get_volume()) icon.title = "Control de Volumen" # Crear menú icon.menu = pystray.Menu( item('Salir', on_quit) ) # Definir acciones icon.visible = True # Asignar eventos de clic icon.run(setup=lambda icon: icon.visible=True) # Manejar clic izquierdo para alternar mute def on_left_click(icon, button, pressed): if button == pystray.Button.LEFT and pressed: on_click(icon, None) # Manejar eventos de scroll (pystray no los soporta directamente, así que usaremos un workaround) # Implementaremos una forma alternativa de detectar scroll usando un hilo def listen_for_scroll(): import pynput.mouse as mouse from pynput.mouse import Listener def on_scroll(x, y, dx, dy): if dy > 0: on_scroll_icon("up") elif dy < 0: on_scroll_icon("down") with Listener(on_scroll=on_scroll) as listener: listener.join() def on_scroll_icon(direction): on_scroll(icon, direction) # Iniciar el hilo para escuchar el scroll scroll_thread = threading.Thread(target=listen_for_scroll, daemon=True) scroll_thread.start() # Iniciar el icono icon.run() if __name__ == "__main__": main()