diff options
Diffstat (limited to 'modules/desktop')
| -rw-r--r-- | modules/desktop/eww/bar/bar.nix | 2 | ||||
| -rw-r--r-- | modules/desktop/eww/bar/bar.yuck | 17 | ||||
| -rw-r--r-- | modules/desktop/eww/bar/system-stats.lua | 86 | ||||
| -rw-r--r-- | modules/desktop/niri/default.nix | 8 |
4 files changed, 106 insertions, 7 deletions
diff --git a/modules/desktop/eww/bar/bar.nix b/modules/desktop/eww/bar/bar.nix index f7ef9cf..0daf7a6 100644 --- a/modules/desktop/eww/bar/bar.nix +++ b/modules/desktop/eww/bar/bar.nix @@ -104,6 +104,7 @@ "@@icon-ram@@" "@@icon-audio@@" "@@icon-calendar@@" + "@@icon-battery@@" ] [ (lib.getExe niri-status) @@ -116,6 +117,7 @@ (toString ../../../../assets/icons/bar/ram.svg) (toString ../../../../assets/icons/bar/audio.svg) (toString ../../../../assets/icons/bar/calendar.svg) + (toString ../../../../assets/icons/bar/battery.svg) ] (builtins.readFile ./bar.yuck); }; diff --git a/modules/desktop/eww/bar/bar.yuck b/modules/desktop/eww/bar/bar.yuck index 2f5046d..f8f48d0 100644 --- a/modules/desktop/eww/bar/bar.yuck +++ b/modules/desktop/eww/bar/bar.yuck @@ -4,17 +4,16 @@ (defpoll full_date :interval "60s" "date '+%A, %d %B %Y'") (deflisten niri_status :initial "{\"workspaces\":[],\"active_windows\":[]}" "@@niri-status-script@@") (deflisten system_stats - :initial "{\"cpu\":{\"percent\":0,\"per_core\":[],\"freq_mhz\":null,\"load_avg\":null,\"tooltip\":\"CPU: 0%\"},\"ram\":{\"percent\":0,\"used\":\"0B\",\"total\":\"0B\",\"available\":\"0B\",\"swap_percent\":0,\"swap_used\":\"0B\",\"swap_total\":\"0B\",\"speed_mhz\":null,\"tooltip\":\"RAM: 0%\"},\"net\":{\"status\":\"down\",\"tooltip\":\"Network Offline\",\"routes\":[]},\"sound\":{\"percent\":0,\"mute\":true,\"sink\":null,\"tooltip\":\"Volume: unknown\"}}" + :initial "{\"cpu\":{\"percent\":0,\"per_core\":[],\"freq_mhz\":null,\"load_avg\":null,\"tooltip\":\"CPU: 0%\"},\"ram\":{\"percent\":0,\"used\":\"0B\",\"total\":\"0B\",\"available\":\"0B\",\"swap_percent\":0,\"swap_used\":\"0B\",\"swap_total\":\"0B\",\"speed_mhz\":null,\"tooltip\":\"RAM: 0%\"},\"net\":{\"status\":\"down\",\"tooltip\":\"Network Offline\",\"routes\":[]},\"sound\":{\"percent\":0,\"mute\":true,\"sink\":null,\"tooltip\":\"Volume: unknown\"},\"battery\":{\"percent\":0,\"present\":false,\"charging\":false,\"status\":\"none\",\"tooltip\":\"No battery\"}}" "@@system-stats-script@@") (defwindow bar :monitor 0 - :geometry (geometry - :x "0px" - :y "0px" - :width "60px" - :height "100%" - :anchor "top right") + :geometry (geometry :x "0px" + :y "0px" + :width "60px" + :height "100%" + :anchor "top right") :stacking "fg" :focusable "none" :reserve (struts :distance "60px" :side "right") @@ -71,6 +70,10 @@ :tooltip "${system_stats.ram.tooltip}" (image :class "system-icon" :path "@@icon-ram@@" :image-width 24 :image-height 24) (label :class "system-label" :text "${system_stats.ram.percent}%")) + (box :orientation "v" :class "system-item" :space-evenly false :spacing 4 + :tooltip "${system_stats.battery.tooltip}" + (image :class "system-icon" :path "@@icon-battery@@" :image-width 24 :image-height 24) + (label :class "system-label" :text "${system_stats.battery.present ? (system_stats.battery.percent + '%') : '-'}")) (eventbox :onclick "pamixer --toggle-mute" :onscroll "bash -c '[ \"{}\" = \"up\" ] && pamixer --increase 5 --unmute || pamixer --decrease 5'" :cursor "pointer" :halign "fill" diff --git a/modules/desktop/eww/bar/system-stats.lua b/modules/desktop/eww/bar/system-stats.lua index c15cbdc..c7ee4fb 100644 --- a/modules/desktop/eww/bar/system-stats.lua +++ b/modules/desktop/eww/bar/system-stats.lua @@ -530,6 +530,84 @@ local function get_sound_state() } end +-- ------------------------------------------------ battery +local function find_battery_path() + local handle = io.popen("ls /sys/class/power_supply/ 2>/dev/null") + if not handle then + return nil + end + local out = handle:read("*a") + handle:close() + for name in out:gmatch("[^\n]+") do + if posix.stat("/sys/class/power_supply/" .. name .. "/capacity") then + return "/sys/class/power_supply/" .. name + end + end + return nil +end + +local function get_battery_state(path) + if not path then + return { percent = 0, present = false, charging = false, tooltip = "No battery", status = "none" } + end + + local function read_file(subpath) + local f = io.open(path .. "/" .. subpath) + if not f then + return nil + end + local s = f:read("*l") + f:close() + return s and s:match("^%s*(.-)%s*$") + end + + local capacity_str = read_file("capacity") + local capacity = capacity_str and tonumber(capacity_str) + if not capacity then + return { percent = 0, present = false, charging = false, tooltip = "No battery", status = "none" } + end + + local status_str = read_file("status") + local charging = (status_str == "Charging" or status_str == "Full") + + local time_to_empty = read_file("time_to_empty_now") + local time_to_full = read_file("time_to_full_now") + local time_str = nil + if not charging and time_to_empty then + local secs = tonumber(time_to_empty) + if secs and secs > 0 then + local h = math.floor(secs / 3600) + local m = math.floor((secs % 3600) / 60) + time_str = string.format("%dh%dm remaining", h, m) + end + elseif charging and time_to_full then + local secs = tonumber(time_to_full) + if secs and secs > 0 then + local h = math.floor(secs / 3600) + local m = math.floor((secs % 3600) / 60) + time_str = string.format("%dh%dm until full", h, m) + end + end + + local lines = { string.format("Battery: %d%%", capacity) } + if status_str then + lines[#lines + 1] = "Status: " .. status_str + end + if time_str then + lines[#lines + 1] = time_str + end + + return { + percent = capacity, + present = true, + charging = charging, + status = nonnull(status_str), + tooltip = table.concat(lines, "\n"), + } +end + +local battery_path = find_battery_path() + -- ------------------------------------------------ state + emit local state = { cpu = { @@ -561,6 +639,13 @@ local state = { sink = NULL, tooltip = "Volume: unknown", }, + battery = { + percent = 0, + present = false, + charging = false, + status = "none", + tooltip = "No battery", + }, } local function emit() @@ -744,6 +829,7 @@ local function main() state.cpu = cpu_state state.ram = ram_state + state.battery = get_battery_state(battery_path) -- Net status is always refreshed here too, so even with inotify -- permanently unavailable we still pick up link changes within -- CPU_INTERVAL seconds. diff --git a/modules/desktop/niri/default.nix b/modules/desktop/niri/default.nix index 5c5d81b..1f1533d 100644 --- a/modules/desktop/niri/default.nix +++ b/modules/desktop/niri/default.nix @@ -84,6 +84,7 @@ default-column-width = { proportion = 1.0; }; + background-color = "transparent"; focus-ring = { width = 1; active-color = config.scheme.withHashtag.base07; @@ -103,5 +104,12 @@ "fill" ]; }; + + wayland.windowManager.niri.extraConfig = '' + layer-rule { + match namespace="^wallpaper$" + place-within-backdrop true + } + ''; }; } |
