redbear-power: add system load average (1/5/15 min) to System panel

Reads /proc/loadavg every 4th refresh cycle and displays the three
load average values alongside Cores/AvgFreq/MaxTemp/TotalPkg.
This commit is contained in:
2026-07-07 02:12:50 +03:00
parent 2362ea80f1
commit babffee80e
2 changed files with 30 additions and 0 deletions
@@ -145,6 +145,7 @@ pub struct App {
/// `/proc/stat` (Linux). Read every tick — it's a single
/// file read. Fields degrade to `None` when unavailable.
pub sched_stats: crate::sched::SchedStats,
pub load_avg: Option<(f64, f64, f64)>,
/// When true, render the Process tab as a tree (parents above
/// children, prefixed with `├─ ` / `└─ ` connector characters).
/// Toggled by the `T` hotkey. Sort modes are honored within
@@ -443,6 +444,18 @@ impl App {
process_sort: crate::process::SortMode::default(),
process_filter: String::new(),
sched_stats: crate::sched::SchedStats::default(),
load_avg: std::fs::read_to_string("/proc/loadavg").ok().and_then(|s| {
let parts: Vec<&str> = s.split_whitespace().collect();
if parts.len() >= 3 {
Some((
parts[0].parse().ok()?,
parts[1].parse().ok()?,
parts[2].parse().ok()?,
))
} else {
None
}
}),
process_tree: false,
show_full_cmdline: false,
folded: std::collections::BTreeSet::new(),
@@ -557,6 +570,18 @@ impl App {
if self.refresh_counter % 4 == 0 {
self.meminfo = crate::meminfo::read_meminfo();
self.os_info = crate::meminfo::read_os_info();
self.load_avg = std::fs::read_to_string("/proc/loadavg").ok().and_then(|s| {
let parts: Vec<&str> = s.split_whitespace().collect();
if parts.len() >= 3 {
Some((
parts[0].parse().ok()?,
parts[1].parse().ok()?,
parts[2].parse().ok()?,
))
} else {
None
}
});
}
// Battery state changes continuously on a laptop (capacity drops,
@@ -426,6 +426,11 @@ pub fn render_system_panel<'a>(app: &'a App, focused: bool) -> Paragraph<'a> {
max_temp.set_style(theme::VALUE),
" TotalPkg: ".set_style(theme::LABEL),
format!("{total_pkgw:.1} W").set_style(theme::VALUE),
" Load: ".set_style(theme::LABEL),
match app.load_avg {
Some((a, b, c)) => format!("{a:.2} {b:.2} {c:.2}").set_style(theme::VALUE),
None => "n/a".set_style(theme::VALUE_OFF),
},
]));
let any_prochot = app.cpus.iter().any(|c| c.prochot);
let any_critical = app.cpus.iter().any(|c| c.critical);