(defpoll cpu-freq-min :interval "60s" :initial "0" "awk '{print $1/1000}' /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq") (defpoll cpu-freq-max :interval "60s" :initial "1" "awk '{print $1/1000}' /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq") (defpoll cpu-temp :interval "4s" :initial "0" "scripts/sys/cputemp") (defpoll cpu-freq-avg :interval "2s" :initial "0" "awk '{sum+=$1; count++} END {printf \"%.1f\", sum/count/1000000}' /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq") ; The CPU grid is fed by the EWW_CPU magic variable (2 s); jq() reshapes the ; core list into rows of four. ; --- Shared --- (defwidget section-header [title accent] (box :orientation "h" :space-evenly false :valign "center" :class "sys-section-header" (box :class "section-accent ${accent}") (label :class "sys-label" :text title))) ; --- CPU --- (defwidget cpu-core-cell [core] (overlay (circular-progress :width 60 :height 60 :value {core.usage} :start-at 0 :clockwise true :thickness 7 :class "cpu-usage-ring") (circular-progress :value {100 * (core.freq - cpu-freq-min) / (cpu-freq-max - cpu-freq-min)} :start-at 0 :clockwise true :thickness 4 :class "cpu-freq-ring") (box :halign "center" :valign "center" (label :class "cpu-core-label" :text "${core.core}")) ) ) (defwidget cpu-sys-win [] (box :orientation "v" :space-evenly false :class "sys-section" (section-header :title "CPU" :accent "cpu-accent") (box :orientation "v" :space-evenly false :halign "center" (for row in {jq(EWW_CPU.cores, '[.[] | .core |= ltrimstr("cpu")] | [range(0; length; 4) as $i | .[$i:$i + 4]]')} (box :orientation "h" :space-evenly false (for core in {row} (cpu-core-cell :core {core}))))) (box :orientation "h" :space-evenly true :class "gpu-stats-row" (box :orientation "v" :halign "center" :space-evenly false (label :class "gpu-stat-value" :text "${cpu-temp}°C") (label :class "gpu-stat-label" :text "temp")) (box :orientation "v" :halign "center" :space-evenly false (label :class "gpu-stat-value" :text "${cpu-freq-avg}GHz") (label :class "gpu-stat-label" :text "avg clk")) (box :orientation "v" :halign "center" :space-evenly false (label :class "gpu-stat-value" :text "${round(EWW_CPU.avg, 0)}%") (label :class "gpu-stat-label" :text "usage"))) ) ) ; --- GPU --- (defwidget gpu-sys-win [] (box :orientation "v" :space-evenly false :class "sys-section" (section-header :title "GPU" :accent "gpu-accent") (box :orientation "h" :space-evenly true ; GFX - outer: activity%, inner: clock% of range (box :orientation "v" :space-evenly false :halign "center" (overlay (circular-progress :width 68 :height 68 :value {gpu.gfx_pct} :start-at 0 :clockwise true :thickness 7 :class "gpu-ring" :tooltip "GFX ${round(gpu.gfx_pct, 1)}%\nClock ${gpu.sclk} MHz (${round(gpu.sclk_pct, 0)}% of range)") (circular-progress :value {gpu.sclk_pct} :start-at 0 :clockwise true :thickness 4 :class "gpu-freq-ring") (box :halign "center" :valign "center" (label :class "gpu-ring-value" :text "${round(gpu.gfx_pct, 0)}%"))) (label :class "gpu-ring-label" :text "GFX" :halign "center")) ; Memory - outer: activity%, inner: memory clock% of range (box :orientation "v" :space-evenly false :halign "center" (overlay (circular-progress :width 68 :height 68 :value {gpu.mem_pct} :start-at 0 :clockwise true :thickness 7 :class "gpu-ring" :tooltip "Memory ${round(gpu.mem_pct, 1)}%\nClock ${gpu.mclk} MHz (${round(gpu.mclk_pct, 0)}% of range)") (circular-progress :value {gpu.mclk_pct} :start-at 0 :clockwise true :thickness 4 :class "gpu-freq-ring") (box :halign "center" :valign "center" (label :class "gpu-ring-value" :text "${round(gpu.mem_pct, 0)}%"))) (label :class "gpu-ring-label" :text "Mem" :halign "center")) ; Media - outer: activity%, inner: video clock% of GPU clock max (box :orientation "v" :space-evenly false :halign "center" (overlay (circular-progress :width 68 :height 68 :value {gpu.media_pct} :start-at 0 :clockwise true :thickness 7 :class "gpu-ring" :tooltip "Media Engine ${round(gpu.media_pct, 1)}%\nVideo Clock ${gpu.vclk} MHz") (circular-progress :value {gpu.vclk_pct} :start-at 0 :clockwise true :thickness 4 :class "gpu-freq-ring") (box :halign "center" :valign "center" (label :class "gpu-ring-value" :text "${round(gpu.media_pct, 0)}%"))) (label :class "gpu-ring-label" :text "Med" :halign "center"))) (box :orientation "v" :space-evenly false :class "vram-row" (progress :value {100 * gpu.vram_used / gpu.vram_total} :orientation "h" :flipped true :hexpand true :class "vram-bar" :tooltip "VRAM ${round(100 * gpu.vram_used / gpu.vram_total, 1)}%") (box :orientation "h" :space-evenly false (label :class "vram-usage-label" :halign "start" :hexpand true :text "VRAM") (label :class "vram-usage-label" :halign "end" :text "${round(gpu.vram_used / 1024, 1)} / ${round(gpu.vram_total / 1024, 1)} GiB"))) (box :orientation "h" :space-evenly true :class "gpu-stats-row" (box :orientation "v" :halign "center" :space-evenly false (label :class "gpu-stat-value" :text "${gpu.temp}°C") (label :class "gpu-stat-label" :text "temp")) (box :orientation "v" :halign "center" :space-evenly false (label :class "gpu-stat-value" :text "${gpu.power}W") (label :class "gpu-stat-label" :text "power"))) ) ) ; --- RAM --- (defwidget ram-sys-win [] (box :orientation "v" :space-evenly false :class "sys-section" (section-header :title "RAM" :accent "ram-accent") (box :orientation "h" :space-evenly false :halign "center" :spacing 16 :valign "center" (overlay (circular-progress :width 88 :height 88 :value {100*memory.used/memory.total} :start-at 0 :clockwise true :thickness 9 :class "ram-ring" :tooltip "RAM\nUsed ${memory.human.used} / ${memory.human.total}\nCached ${memory.human.cached}") (circular-progress :value {100*memory.cached/memory.total} :start-at {100*memory.used/memory.total} :clockwise true :thickness 9 :class "ram-cached-ring") (box :orientation "v" :valign "center" :halign "center" :space-evenly false (label :class "ram-used-label" :text "${memory.human.used}") (label :class "ram-total-label" :text "${memory.human.total}"))) (box :orientation "v" :space-evenly false :halign "center" :valign "center" (overlay (circular-progress :width 72 :height 72 :value {memory.swap.total > 0 ? 100 * memory.swap.used / memory.swap.total : 0} :start-at 0 :clockwise true :thickness 7 :class "swap-ring" :tooltip "Swap\n${memory.swap.human.used} / ${memory.swap.human.total}") (box :orientation "v" :valign "center" :halign "center" :space-evenly false (label :class "ram-used-label" :text "${memory.swap.human.used}") (label :class "ram-total-label" :text "${memory.swap.human.total}")))) ) ) ) ; --- Battery --- (defwidget bat-stat [value label] (box :orientation "v" :halign "center" :valign "center" :space-evenly false (label :class "bat-stat-value" :text value) (label :class "bat-stat-label" :text label))) ; left: draw while on battery, charge rate while charging; right: time left / to full (defwidget bat-sys-win [] (box :orientation "v" :space-evenly false :class "sys-section" :visible {battery.visible} (section-header :title "Battery" :accent "bat-accent") (box :orientation "h" :space-evenly true :valign "center" (bat-stat :value {battery.state == "charging" ? (battery.rate == "" ? "—" : "${battery.rate} %/h") : (battery.state == "discharging" || battery.state == "low" || battery.state == "critical" ? battery.wattage : "—")} :label {battery.state == "charging" ? "charging" : "draw"}) (overlay (circular-progress :width 72 :height 72 :value {battery.percentage} :start-at 0 :clockwise true :thickness 7 :class "bat-ring bat-${battery.state}" :tooltip "Battery ${round(battery.percentage, 0)}%\n${battery.status} @ ${battery.wattage}") (label :class "bat-ring-label" :text "${round(battery.percentage, 0)}%")) (bat-stat :value {battery.time == "" ? "—" : battery.time} :label {battery.state == "charging" ? "to full" : "left"})) ; 6 h history, one bar per 15 min bucket, coloured like the ring (box :orientation "h" :space-evenly true :class "bat-hist" (for b in {battery.history} (progress :orientation "v" :flipped true :value {b.p < 0 ? 0 : b.p} :class "bat-hist-bar hist-${b.s}" :tooltip {b.p < 0 ? b.t : "${b.t} ${round(b.p, 0)}%"}))) (box :orientation "h" :space-evenly false (label :class "gpu-stat-label" :halign "start" :hexpand true :text "-6h") (label :class "gpu-stat-label" :halign "end" :text "now")) ) ) ; --- Root --- (defwidget sys-win [] (box :class "sys-win" :space-evenly false :orientation "v" (cpu-sys-win) (box :class "section-sep") (gpu-sys-win) (box :class "section-sep") (ram-sys-win) (box :class "section-sep" :visible {battery.visible}) (bat-sys-win) ) )