From f9ace4a9568ee22ff52091e448aba40b2b8c305a Mon Sep 17 00:00:00 2001 From: vasilito Date: Tue, 7 Jul 2026 01:30:47 +0300 Subject: [PATCH] redbear-power: CPU% color grading + context-sensitive keybar - Process rows: CPU% now color-graded (green <10%, yellow 10-50%, red 50-90%, bright red >90%) using styled spans instead of monolithic format string - Keybar shows context-aware hints: process-specific keys (k/N/l/o/i/F/y) on Process tab, power-specific keys (p/P/m/M/t) on other tabs - [EXPANDED] indicator added to keybar alongside [FROZEN] --- .../system/redbear-power/source/src/render.rs | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/local/recipes/system/redbear-power/source/src/render.rs b/local/recipes/system/redbear-power/source/src/render.rs index 87048a6fe8..d375d337a8 100644 --- a/local/recipes/system/redbear-power/source/src/render.rs +++ b/local/recipes/system/redbear-power/source/src/render.rs @@ -20,7 +20,7 @@ use ratatui::backend::TestBackend; use ratatui::layout::{Constraint, Layout}; #[allow(unused_imports)] use ratatui::style::{Style, Styled, Stylize}; -use ratatui::text::Line; +use ratatui::text::{Line, Span}; use ratatui::widgets::{Block, Borders, Cell, Paragraph, Row, Table, Tabs, Wrap}; use ratatui::{Frame, Terminal}; @@ -1281,16 +1281,22 @@ pub fn render_process_panel<'a>(app: &'a App, focused: bool) -> Paragraph<'a> { } else { theme::VALUE }; - lines.push(Line::from(format!( - " {}{:<7} {} {:<5} {:<4} {:<3} {:<3} {:<6} {:<11} {:<11} {:<11} {:<11} {:<11} {:<12} {:<6} {:<5} {:<3} {}", - prefix, - p.pid, - p.state, - p.sched_policy, - p.priority, - p.nice, - p.num_threads, - format!("{:.1}", p.cpu_pct), + let cpu_str = format!("{:<6}", format!("{:.1}", p.cpu_pct)); + let cpu_style = if p.cpu_pct >= 90.0 { + theme::VALUE_HOT_LIGHT + } else if p.cpu_pct >= 50.0 { + theme::VALUE_HOT + } else if p.cpu_pct >= 10.0 { + theme::VALUE_WARM + } else { + theme::VALUE + }; + let pre = format!( + " {}{:<7} {} {:<5} {:<4} {:<3} {:<3} ", + prefix, p.pid, p.state, p.sched_policy, p.priority, p.nice, p.num_threads, + ); + let post = format!( + " {:<11} {:<11} {:<11} {:<11} {:<11} {:<12} {:<6} {:<5} {:<3} {}", io_str, rate_str, thread_io_total_str, @@ -1301,7 +1307,15 @@ pub fn render_process_panel<'a>(app: &'a App, focused: bool) -> Paragraph<'a> { rss_spark, affinity_indicator, comm_truncated, - ).set_style(row_style))); + ); + let mut spans = vec![Span::styled(pre, row_style)]; + if is_cursor { + spans.push(Span::styled(cpu_str, app.theme.cursor_highlight)); + } else { + spans.push(Span::styled(cpu_str, cpu_style)); + } + spans.push(Span::styled(post, row_style)); + lines.push(Line::from(spans)); } Paragraph::new(lines) .block(panel_border(focused, " Process ", &app.theme)) @@ -1925,14 +1939,23 @@ pub fn render_cpu_table<'a>( } pub fn render_keybar<'a>(app: &'a App) -> Paragraph<'a> { + let gov = format!(" g:{}", app.cpufreq.active.as_str()); + let tab_hints: &str = if app.current_tab == crate::app::TabId::Process { + " ↑↓:sel k:kill N:nice l:files o:sort i:invert F:filter y:tree Enter:detail" + } else { + " ↑↓:cpu p/P:±pstate m/M:min/max t:throttle r:refresh" + }; let mut parts = vec![ - format!(" g:{}", app.cpufreq.active.as_str()), - " ↑↓:cpu p/P:±pstate m/M:min/max t:throttle r:refresh".to_string(), - " T:tab ?:help e:expand f:freeze k:kill q:quit".to_string(), + gov, + tab_hints.to_string(), + " T:tab ?:help e:expand f:freeze q:quit".to_string(), ]; if app.frozen { parts.push(" [FROZEN]".to_string()); } + if app.expanded { + parts.push(" [EXPANDED]".to_string()); + } let line = parts.join(""); Paragraph::new(line) .style(theme::VALUE_OFF)