From 927f6997ee0ab28cf1ec3f654c660ce82e73b17f Mon Sep 17 00:00:00 2001 From: Joshua Yuen Date: Sat, 12 Sep 2026 02:37:02 -0400 Subject: [PATCH] Add AGS battery widget --- modules/home/ags/app/style.scss | 21 +++++++- modules/home/ags/app/widget/Bar.tsx | 4 ++ modules/home/ags/app/widget/Battery.tsx | 69 +++++++++++++++++++++++++ modules/nixos/services.nix | 2 +- 4 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 modules/home/ags/app/widget/Battery.tsx diff --git a/modules/home/ags/app/style.scss b/modules/home/ags/app/style.scss index 8de1907..81d409e 100644 --- a/modules/home/ags/app/style.scss +++ b/modules/home/ags/app/style.scss @@ -44,14 +44,16 @@ .ws:hover, .volume:hover, -.wifi:hover { +.wifi:hover, +.battery:hover { background: transparentize($base05, 0.88); } .volume icon, .mute icon, .wifi icon, -.wifi-header icon { +.wifi-header icon, +.battery icon { font-size: 16px; } @@ -156,3 +158,18 @@ .wifi-row:hover { background: transparentize($base05, 0.88); } + +.battery-percent { + font-size: 1.6em; + font-weight: bold; +} + +.battery-level { + font-size: 0.85em; + margin-left: 3px; +} + +.battery-status { + font-size: 0.85em; + opacity: 0.7; +} diff --git a/modules/home/ags/app/widget/Bar.tsx b/modules/home/ags/app/widget/Bar.tsx index 1ca74d8..8e46760 100644 --- a/modules/home/ags/app/widget/Bar.tsx +++ b/modules/home/ags/app/widget/Bar.tsx @@ -3,19 +3,23 @@ import Workspaces from "./Workspaces" import Clock from "./Clock" import { VolumeWidget } from "./Volume" import { WifiWidget } from "./Wifi" +import { BatteryWidget } from "./Battery" export default function Bar(gdkmonitor: Gdk.Monitor) { const { TOP, LEFT, RIGHT } = Astal.WindowAnchor const volume = VolumeWidget(gdkmonitor) const wifi = WifiWidget(gdkmonitor) + const battery = BatteryWidget(gdkmonitor) const right: Array = [] if (wifi.button) right.push(wifi.button) right.push(volume.button) + if (battery.button) right.push(battery.button) const popups: Array = [] if (wifi.popup) popups.push(wifi.popup) popups.push(volume.popup) + if (battery.popup) popups.push(battery.popup) return [ ( diff --git a/modules/home/ags/app/widget/Battery.tsx b/modules/home/ags/app/widget/Battery.tsx new file mode 100644 index 0000000..51da56e --- /dev/null +++ b/modules/home/ags/app/widget/Battery.tsx @@ -0,0 +1,69 @@ +import AstalBattery from "gi://AstalBattery" +import { Variable, bind } from "astal" +import Dropdown from "./Dropdown" + +const battery = AstalBattery.get_default() + +const CHARGING = 1 +const DISCHARGING = 2 +const FULLY_CHARGED = 4 + +function fmtTime(seconds: number) { + if (!seconds || seconds <= 0) return null + const h = Math.floor(seconds / 3600) + const m = Math.round((seconds % 3600) / 60) + return h > 0 ? `${h}h ${m}m` : `${m}m` +} + +const status = Variable.derive( + [bind(battery, "state"), bind(battery, "time-to-empty"), bind(battery, "time-to-full")], + (state, toEmpty, toFull) => { + if (state === FULLY_CHARGED) return "fully charged" + if (state === CHARGING) { + const t = fmtTime(toFull) + return t ? `charging ยท ${t} to full` : "charging" + } + if (state === DISCHARGING) { + const t = fmtTime(toEmpty) + return t ? `${t} left` : "on battery" + } + return "" + }, +) + +export function BatteryWidget(gdkmonitor: Gdk.Monitor) { + if (!battery.isBattery) return { button: null, popup: null } + + const open = Variable(false) + + const button = ( + + ) + + const popup = ( + + + ) + + return { button, popup } +} \ No newline at end of file diff --git a/modules/nixos/services.nix b/modules/nixos/services.nix index d1395a7..87bc83e 100644 --- a/modules/nixos/services.nix +++ b/modules/nixos/services.nix @@ -3,6 +3,6 @@ }: { services = { - + upower.enable = true; }; }