roundabout,
created on Wednesday, 24 September 2025, 15:24:41 (1758727481),
received on Wednesday, 24 September 2025, 15:24:44 (1758727484)
Author identity: Vlad <vlad.muntoiu@gmail.com>
f5f68d033395fba81a73051c747141673c78cfad
applets/battery/__init__.py
@@ -18,10 +18,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import annotations import threading import panorama_panel import locale from pathlib import Path from pydbus import SystemBusfrom pydbus import SystemBus, SessionBusimport gi gi.require_version("Gtk", "4.0")
@@ -65,6 +67,8 @@ class BatteryMonitor(panorama_panel.Applet):
config = {} self.bus = SystemBus() self.session_bus = SessionBus() self.notification_service = Noneself.upower = self.bus.get("org.freedesktop.UPower") self.button = Gtk.MenuButton()
@@ -72,10 +76,20 @@ class BatteryMonitor(panorama_panel.Applet):
self.button.set_child(self.icon) self.append(self.button) self.low_threshold = config.get("low_threshold", 15/100) self.low_notification = None self.critical_threshold = config.get("critical_threshold", 5/100) self.critical_notification = None self.popover = Gtk.Popover() self.popover_content = Gtk.ListBox() self.update_batteries() GLib.timeout_add_seconds(10, self.update_batteries) def update_batteries(self): self.popover_content.remove_all()total_energy = max_energy = 0 any_charging = False
@@ -91,18 +105,78 @@ class BatteryMonitor(panorama_panel.Applet):
if device.State == 1: any_charging = True if not max_energy: return False print(total_energy, max_energy) self.button.set_tooltip_text(f"{locale.format_string("%d", total_energy / max_energy * 1000)}‰") self.icon.set_from_icon_name(get_battery_icon(total_energy / max_energy, any_charging)) GLib.idle_add(self.do_notifications, total_energy, max_energy) return True def do_notifications(self, total_energy, max_energy): if self.session_bus.get("org.freedesktop.Notifications"): self.notification_service = self.session_bus.get("org.freedesktop.Notifications") else: return # This uses threading to make sure it doesn't hang while waiting to deliver the # notification if total_energy / max_energy < self.low_threshold: if not self.low_notification: def send_notification(): self.low_notification = self.notification_service.Notify( _("Battery"), self.low_notification or self.critical_notification or 0, "battery-low", _("The energy in the battery is low."), "", [], {}, -1 ) threading.Thread(target=send_notification, daemon=True).start() elif self.low_notification: threading.Thread( target=lambda: self.notification_service.CloseNotification(self.low_notification), daemon=True ).start() self.low_notification = None if total_energy / max_energy < self.critical_threshold: if not self.critical_notification: def send_notification(): self.critical_notification = self.notification_service.Notify( _("Battery"), self.low_notification or self.critical_notification or 0, "battery-empty", _("The energy in the battery is very low; the device will shut down soon."), "", [], {}, -1 ) threading.Thread(target=send_notification, daemon=True).start() elif self.critical_notification: threading.Thread( target=lambda: self.notification_service.CloseNotification(self.critical_notification), daemon=True ).start() self.critical_notification = None def get_config(self): return { "icon_size": self.icon.get_pixel_size(), "low_threshold": self.low_threshold, "critical_threshold": self.critical_threshold,} def shutdown(self, app): self.publishing.unpublish()return
config.yaml
@@ -60,6 +60,8 @@ panels:
right: - BatteryMonitor: icon_size: 24 low_threshold: 0.15 critical_threshold: 0.05- Volume: percentage_reveal: 1000 popdown_after_manual: 2000