167 lines
4.2 KiB
Python
Executable File
167 lines
4.2 KiB
Python
Executable File
#!/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()
|
|
|