diff --git a/cpu_monitor_gui.py b/cpu_monitor_gui.py index a333cd9..ed4227c 100755 --- a/cpu_monitor_gui.py +++ b/cpu_monitor_gui.py @@ -3,10 +3,24 @@ import tkinter as tk from tkinter import ttk +import subprocess +import tempfile +import os import time +import sys +import gi import psutil +gi.require_version('Gtk', '3.0') +gi.require_version('AyatanaAppIndicator3', '0.1') +from gi.repository import AyatanaAppIndicator3, GLib, Gtk + + +MAX_POINTS = 60 +UPDATE_INTERVAL = 1000 # ms + + try: from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure @@ -15,10 +29,6 @@ except ImportError: HAVE_MPL = False -MAX_POINTS = 60 -UPDATE_INTERVAL = 1000 # ms - - class Tracker: def __init__(self): self.cpu_data = [] @@ -29,6 +39,99 @@ class Tracker: return psutil.cpu_percent(interval=None) +class SysTrayIndicator: + def __init__(self, monitor): + self.indicator = AyatanaAppIndicator3.Indicator.new( + "cpu-monitor", + "utilities-system-monitor", + AyatanaAppIndicator3.IndicatorCategory.SYSTEM_SERVICES + ) + self.indicator.set_status(AyatanaAppIndicator3.IndicatorStatus.ACTIVE) + self.indicator.set_menu(self._create_menu()) + self.monitor = monitor + self._update_icon() + + def _create_menu(self): + menu = Gtk.Menu() + cpu = psutil.cpu_percent(interval=None) + ram = psutil.virtual_memory().percent + disk = psutil.disk_usage('/').percent + + item1 = Gtk.MenuItem(label=f"CPU: {cpu:.1f}%") + item1.show() + menu.append(item1) + + item2 = Gtk.MenuItem(label=f"RAM: {ram:.1f}%") + item2.show() + menu.append(item2) + + item3 = Gtk.MenuItem(label=f"Disk: {disk:.1f}%") + item3.show() + menu.append(item3) + + sep = Gtk.SeparatorMenuItem() + sep.show() + menu.append(sep) + + hide = Gtk.MenuItem(label="Hide Window") + hide.connect("activate", lambda w: self.monitor.root.withdraw()) + hide.show() + menu.append(hide) + + show = Gtk.MenuItem(label="Show Window") + show.connect("activate", lambda w: self.monitor.root.deiconify()) + show.show() + menu.append(show) + + sep2 = Gtk.SeparatorMenuItem() + sep2.show() + menu.append(sep2) + + quit_item = Gtk.MenuItem(label="Quit") + quit_item.connect("activate", lambda w: self._quit()) + quit_item.show() + menu.append(quit_item) + + menu.show() + return menu + + def _quit(self): + GLib.idle_add(Gtk.main_quit) + sys.exit(0) + + def _update_icon(self): + try: + import cairo + except ImportError: + GLib.timeout_add_seconds(1, self._update_icon) + return + + cpu = psutil.cpu_percent() + if cpu > 80: + color = (0.93, 0.33, 0.31) + elif cpu > 50: + color = (1.0, 0.55, 0.0) + else: + color = (0.40, 0.76, 0.97) + + size = 24 + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, size, size) + cr = cairo.Context(surface) + cr.set_source_rgba(*color, 1.0) + cr.paint() + + tmp = tempfile.NamedTemporaryFile(suffix='.png', delete=False, dir='/tmp') + tmp.close() + surface.write_to_png(tmp.name) + + try: + self.indicator.set_icon_full(tmp.name, "CPU Monitor") + except Exception: + pass + + GLib.timeout_add_seconds(2, self._update_icon) + + class App: cpu_data = [] ram_data = [] @@ -184,12 +287,15 @@ class App: def _stop(self): self._running = False self.status_label.config(text="Stopped.") - self.root.destroy() + self.root.withdraw() def main(): root = tk.Tk() app = App(root) + + _tray = SysTrayIndicator(app) + root.mainloop() diff --git a/debian/changelog b/debian/changelog old mode 100644 new mode 100755 index 32bc293..acf84b7 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ -cpu-monitor (1.2) noble; urgency=low +cpu-monitor (1.4) noble; urgency=low - * Removed AppIndicator (Wayland incompatible) - * Simpler, more reliable autostart + * v1.4: Add working AppIndicator systray with GTK3 + * v1.4: System tray icon with CPU/RAM/Disk status menu + * v1.4: Hide/Show window from systray menu -- tmzf5455 Sun, 10 May 2026 00:00:00 +0000 diff --git a/debian/control b/debian/control old mode 100644 new mode 100755 index 7408072..3c48dd8 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Rules-Requires-Root: no Package: cpu-monitor Architecture: all -Depends: python3, python3-psutil, python3-matplotlib, python3-tk, ${misc:Depends} +Depends: python3, python3-psutil, python3-matplotlib, python3-tk, gir1.2-ayatanaappindicator3-0.1, gir1.2-gtk-3.0, ${misc:Depends} Description: CPU/RAM/Disk/Network monitor GUI A system monitor tool with real-time matplotlib charts and a tkinter GUI, showing CPU, RAM, disk and network usage. diff --git a/debian/source/format b/debian/source/format old mode 100644 new mode 100755