#!/usr/bin/env python3 import time import dbus import dbus.mainloop.glib import os from gi.repository import GLib, Notify import pystray from PIL import Image import threading import queue import subprocess import time start_time = time.time() # Código de inicialización print(f"Tiempo después de la inicialización: { time.time() - start_time} segundos") # Define the paths to the PNG icons ICON_PATHS = { "nvidia": "/home/teraflops/Icons/nvidia.png", "integrated": "/home/teraflops/Icons/amd.png", } # Global variables systray_icon = None update_queue = queue.Queue() # Function to interpret the numerical status into a clearer message def interpret_gpu_status(status): if status == 0: return "nvidia" elif status == 1: return "integrated" else: return None # Ignore "switching mode" and other unknown statuses # Function to update the systray icon def update_systray_icon(status_message): icon_path = ICON_PATHS.get(status_message) if icon_path and os.path.exists(icon_path): try: image = Image.open(icon_path) # Put the update information in the queue update_queue.put((image, f"GPU: {status_message.capitalize()}")) print(f"Queued systray icon update to {status_message}") except Exception as e: print(f"Error preparing systray icon update: {e}") else: print(f"No icon found for status: {status_message}") # Callback for `NotifyGfxStatus` def on_notify_gfx_status(status): print(f"Callback `on_notify_gfx_status` invoked with status: {status}") status_message = interpret_gpu_status(status) # If the status is "nvidia" or "integrated", update the systray icon if status_message: print(f"GPU status changed: {status_message}") update_systray_icon(status_message) # Guardar el estado y el timestamp en /tmp try: with open("/tmp/gpu_mode", "w") as f: f.write(status_message) with open("/tmp/gpu_mode_timestamp", "w") as f: f.write(str(int(time.time()))) print(f"Estado GPU guardado en /tmp/gpu_mode: {status_message}") except Exception as e: print(f"Error al escribir /tmp/gpu_mode o timestamp: {e}") else: print("Intermediate status detected, no action taken.") def set_integrated(icon, item): print("Setting GPU mode to Integrated...") result = subprocess.run( ["/usr/bin/supergfxctl", "-m", "Integrated"], capture_output=True, text=True ) output = result.stdout.strip() error = result.stderr.strip() # Crear y mostrar la notificación if result.returncode == 0: message = output if output else "Modo GPU cambiado a Integrado." notification = Notify.Notification.new("Modo GPU Cambiado", message) else: message = error if error else "Error al cambiar a modo Integrado." notification = Notify.Notification.new( "Error al Cambiar Modo GPU", message) notification.show() print(message) def set_hybrid(icon, item): print("Setting GPU mode to Hybrid...") result = subprocess.run( ["/usr/bin/supergfxctl", "-m", "Hybrid"], capture_output=True, text=True ) output = result.stdout.strip() error = result.stderr.strip() # Crear y mostrar la notificación if result.returncode == 0: message = output if output else "Modo GPU cambiado a Híbrido." notification = Notify.Notification.new("Modo GPU Cambiado", message) else: message = error if error else "Error al cambiar a modo Híbrido." notification = Notify.Notification.new( "Error al Cambiar Modo GPU", message) notification.show() print(message) def set_dedicated(icon, item): print("Setting GPU mode to Dedicated...") result = subprocess.run( ["/usr/bin/supergfxctl", "-m", "AsusMuxDgpu"], capture_output=True, text=True ) output = result.stdout.strip() error = result.stderr.strip() # Crear y mostrar la notificación if result.returncode == 0: message = output if output else "Modo GPU cambiado a Dedicado." notification = Notify.Notification.new("Modo GPU Cambiado", message) else: message = error if error else "Error al cambiar a modo Dedicado." notification = Notify.Notification.new( "Error al Cambiar Modo GPU", message) notification.show() print(message) # Initialize the D-Bus loop and signal handlers def init_dbus_loop(): # Initialize the D-Bus main loop dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) # Connect to the system bus and get the object bus = dbus.SystemBus() proxy = bus.get_object("org.supergfxctl.Daemon", "/org/supergfxctl/Gfx") # Subscribe to the `NotifyGfxStatus` signal bus.add_signal_receiver( on_notify_gfx_status, dbus_interface="org.supergfxctl.Daemon", signal_name="NotifyGfxStatus", ) print("Monitoring GPU signals...") # Start the main loop loop = GLib.MainLoop() loop.run() # Function to create the systray icon def create_systray_icon(): global systray_icon # Use a default icon initially default_status = "integrated" default_icon_path = ICON_PATHS.get(default_status) if default_icon_path and os.path.exists(default_icon_path): image = Image.open(default_icon_path) else: # Create a blank icon if default not found image = Image.new("RGB", (64, 64), color=(255, 0, 0)) # Define the menu menu = pystray.Menu( pystray.MenuItem("Integrated", set_integrated), pystray.MenuItem("Hybrid", set_hybrid), pystray.MenuItem("Dedicated", set_dedicated), pystray.MenuItem("Salir", lambda icon, item: icon.stop()) ) systray_icon = pystray.Icon( "gpu_status", icon=image, title=f"GPU: {default_status.capitalize()}", menu=menu ) # Function to check the queue and update the icon def check_queue(): try: while True: new_image, new_title = update_queue.get_nowait() systray_icon.icon = new_image systray_icon.title = new_title systray_icon.visible = True print(f"Systray icon updated to {new_title}") except queue.Empty: pass # Schedule the next check threading.Timer(1, check_queue).start() # Start checking the queue check_queue() # Start the systray icon systray_icon.run() def main(): # Inicializar Notify Notify.init("GPU Mode Switcher") # Start the D-Bus loop in a separate thread dbus_thread = threading.Thread(target=init_dbus_loop) dbus_thread.daemon = True dbus_thread.start() # Start the systray icon in the main thread create_systray_icon() if __name__ == "__main__": main()