mirror of
https://github.com/ClementTsang/bottom.git
synced 2024-11-03 21:04:38 +03:00
feature: Add appox. total mem as an option for processes and basic mem
Adds a way to display the memory value as a column in the processes widget and the basic memory widget, rather than just the percentage.
This commit is contained in:
parent
59ce90f577
commit
3c373d7129
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -20,6 +20,7 @@
|
||||
"haase",
|
||||
"heim",
|
||||
"hjkl",
|
||||
"libc",
|
||||
"markdownlint",
|
||||
"minwindef",
|
||||
"noheader",
|
||||
@ -32,6 +33,7 @@
|
||||
"softirq",
|
||||
"stime",
|
||||
"subwidget",
|
||||
"sysconf",
|
||||
"sysinfo",
|
||||
"tokei",
|
||||
"twrite",
|
||||
@ -39,6 +41,7 @@
|
||||
"use",
|
||||
"use curr usage",
|
||||
"utime",
|
||||
"virt",
|
||||
"whitespaces",
|
||||
"winapi",
|
||||
"winnt",
|
||||
|
@ -41,8 +41,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Features
|
||||
|
||||
- [#114](https://github.com/ClementTsang/bottom/pull/114): Show process state per process (originally in 0.4.0, moved to later). This only
|
||||
shows if the processes are not merged together; I couldn't think of a nice way to show it when grouped together, unfortunately.
|
||||
- [#114](https://github.com/ClementTsang/bottom/pull/114): Show process state per process (originally in 0.4.0, moved to later). This only shows if the processes are not merged together; I couldn't think of a nice way to show it when grouped together, unfortunately.
|
||||
|
||||
- Add (estimated) memory usage values, toggle this from percent to values for processes with `%`.
|
||||
|
||||
### Changes
|
||||
|
||||
|
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -762,9 +762,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.70"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
|
||||
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
|
@ -38,6 +38,7 @@ backtrace = "0.3"
|
||||
serde = {version = "1.0", features = ["derive"] }
|
||||
unicode-segmentation = "1.6.0"
|
||||
unicode-width = "0.1.7"
|
||||
# libc = "0.2.74"
|
||||
# tui = {version = "0.10.0", features = ["crossterm"], default-features = false, git = "https://github.com/fdehau/tui-rs.git"}
|
||||
tui = {version = "0.9.5", features = ["crossterm"], default-features = false }
|
||||
|
||||
|
@ -225,6 +225,7 @@ Run using `btm`.
|
||||
| `P` | Toggle between showing the full path or just the process name |
|
||||
| `s, F6` | Open process sort widget |
|
||||
| `I` | Invert current sort |
|
||||
| `%` | Toggle between values and percentages for memory usage |
|
||||
|
||||
#### Process search bindings
|
||||
|
||||
@ -260,6 +261,12 @@ Run using `btm`.
|
||||
| `Left, Alt-h` | Go to the next battery |
|
||||
| `Right, Alt-l` | Go to the previous battery |
|
||||
|
||||
#### Basic memory bindings
|
||||
|
||||
| | |
|
||||
| --- | ------------------------------------------------------ |
|
||||
| `%` | Toggle between values and percentages for memory usage |
|
||||
|
||||
### Process searching keywords
|
||||
|
||||
- Note none of the keywords are case sensitive.
|
||||
|
28
src/app.rs
28
src/app.rs
@ -80,6 +80,9 @@ pub struct App {
|
||||
#[builder(default = false, setter(skip))]
|
||||
pub is_force_redraw: bool,
|
||||
|
||||
#[builder(default = false, setter(skip))]
|
||||
pub basic_mode_use_percent: bool,
|
||||
|
||||
pub cpu_state: CpuState,
|
||||
pub mem_state: MemState,
|
||||
pub net_state: NetState,
|
||||
@ -342,6 +345,30 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_percentages(&mut self) {
|
||||
match &self.current_widget.widget_type {
|
||||
BottomWidgetType::BasicMem => {
|
||||
self.basic_mode_use_percent = !self.basic_mode_use_percent; // Oh god this is so lazy.
|
||||
}
|
||||
BottomWidgetType::Proc => {
|
||||
if let Some(proc_widget_state) = self
|
||||
.proc_state
|
||||
.widget_states
|
||||
.get_mut(&self.current_widget.widget_id)
|
||||
{
|
||||
proc_widget_state
|
||||
.columns
|
||||
.toggle(&processes::ProcessSorting::Mem);
|
||||
proc_widget_state
|
||||
.columns
|
||||
.toggle(&processes::ProcessSorting::MemPercent);
|
||||
self.proc_state.force_update = Some(self.current_widget.widget_id);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_ignore_case(&mut self) {
|
||||
let is_in_search_widget = self.is_in_search_widget();
|
||||
if let Some(proc_widget_state) = self
|
||||
@ -1111,6 +1138,7 @@ impl App {
|
||||
'e' => self.expand_widget(),
|
||||
's' => self.toggle_sort(),
|
||||
'I' => self.invert_sort(),
|
||||
'%' => self.toggle_percentages(),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,7 @@ pub struct DataCollector {
|
||||
widgets_to_harvest: UsedWidgets,
|
||||
battery_manager: Option<Manager>,
|
||||
battery_list: Option<Vec<Battery>>,
|
||||
// page_file_size_kb: u64,
|
||||
}
|
||||
|
||||
impl Default for DataCollector {
|
||||
@ -110,6 +111,11 @@ impl Default for DataCollector {
|
||||
widgets_to_harvest: UsedWidgets::default(),
|
||||
battery_manager: None,
|
||||
battery_list: None,
|
||||
// page_file_size_kb: if cfg!(target_os = "linux") {
|
||||
// unsafe { libc::sysconf(libc::_SC_PAGESIZE) as u64 / 1024 }
|
||||
// } else {
|
||||
// 0
|
||||
// },
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -200,6 +206,7 @@ impl DataCollector {
|
||||
current_instant
|
||||
.duration_since(self.last_collection_time)
|
||||
.as_secs(),
|
||||
self.mem_total_kb,
|
||||
)
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
|
@ -53,8 +53,8 @@ pub async fn get_network_data(
|
||||
(0, 0)
|
||||
} else {
|
||||
(
|
||||
((total_rx - *prev_net_rx) as f64 / elapsed_time) as u64,
|
||||
((total_tx - *prev_net_tx) as f64 / elapsed_time) as u64,
|
||||
((total_rx.saturating_sub(*prev_net_rx)) as f64 / elapsed_time) as u64,
|
||||
((total_tx.saturating_sub(*prev_net_tx)) as f64 / elapsed_time) as u64,
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -62,6 +62,9 @@ pub struct ProcessHarvest {
|
||||
pub pid: u32,
|
||||
pub cpu_usage_percent: f64,
|
||||
pub mem_usage_percent: f64,
|
||||
pub mem_usage_kb: u64,
|
||||
// pub rss_kb: u64,
|
||||
// pub virt_kb: u64,
|
||||
pub name: String,
|
||||
pub path: String,
|
||||
pub read_bytes_per_sec: u64,
|
||||
@ -224,12 +227,13 @@ fn get_linux_cpu_usage(
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn convert_ps<S: core::hash::BuildHasher>(
|
||||
process: &str, cpu_usage: f64, cpu_fraction: f64,
|
||||
prev_pid_stats: &mut HashMap<u32, PrevProcDetails, S>,
|
||||
new_pid_stats: &mut HashMap<u32, PrevProcDetails, S>, use_current_cpu_total: bool,
|
||||
time_difference_in_secs: u64,
|
||||
time_difference_in_secs: u64, mem_total_kb: u64,
|
||||
) -> std::io::Result<ProcessHarvest> {
|
||||
let pid = (&process[..10])
|
||||
.trim()
|
||||
@ -313,6 +317,7 @@ fn convert_ps<S: core::hash::BuildHasher>(
|
||||
name,
|
||||
path,
|
||||
mem_usage_percent,
|
||||
mem_usage_kb: (mem_usage_percent * mem_total_kb as f64 / 100.0) as u64,
|
||||
cpu_usage_percent,
|
||||
total_read_bytes,
|
||||
total_write_bytes,
|
||||
@ -327,7 +332,7 @@ fn convert_ps<S: core::hash::BuildHasher>(
|
||||
pub fn linux_get_processes_list(
|
||||
prev_idle: &mut f64, prev_non_idle: &mut f64,
|
||||
prev_pid_stats: &mut HashMap<u32, PrevProcDetails, RandomState>, use_current_cpu_total: bool,
|
||||
time_difference_in_secs: u64,
|
||||
time_difference_in_secs: u64, mem_total_kb: u64,
|
||||
) -> crate::utils::error::Result<Vec<ProcessHarvest>> {
|
||||
let ps_result = Command::new("ps")
|
||||
.args(&["-axo", "pid:10,comm:100,%mem:5,args:100", "--noheader"])
|
||||
@ -336,7 +341,6 @@ pub fn linux_get_processes_list(
|
||||
let split_string = ps_stdout.split('\n');
|
||||
if let Ok((cpu_usage, cpu_fraction)) = cpu_usage_calculation(prev_idle, prev_non_idle) {
|
||||
let process_list = split_string.collect::<Vec<&str>>();
|
||||
|
||||
let mut new_pid_stats = HashMap::new();
|
||||
|
||||
let process_vector: Vec<ProcessHarvest> = process_list
|
||||
@ -352,6 +356,7 @@ pub fn linux_get_processes_list(
|
||||
&mut new_pid_stats,
|
||||
use_current_cpu_total,
|
||||
time_difference_in_secs,
|
||||
mem_total_kb,
|
||||
) {
|
||||
if !process_object.name.is_empty() {
|
||||
Some(process_object)
|
||||
@ -431,6 +436,7 @@ pub fn windows_macos_get_processes_list(
|
||||
} else {
|
||||
0.0
|
||||
},
|
||||
mem_usage_kb: process_val.memory(),
|
||||
cpu_usage_percent: process_cpu_usage,
|
||||
read_bytes_per_sec: disk_usage.read_bytes,
|
||||
write_bytes_per_sec: disk_usage.written_bytes,
|
||||
|
@ -671,12 +671,12 @@ impl Prefix {
|
||||
match prefix_type {
|
||||
PrefixType::Cpu => matches_condition(
|
||||
&numerical_query.condition,
|
||||
process.cpu_usage,
|
||||
process.cpu_percent_usage,
|
||||
numerical_query.value,
|
||||
),
|
||||
PrefixType::Mem => matches_condition(
|
||||
&numerical_query.condition,
|
||||
process.mem_usage,
|
||||
process.mem_percent_usage,
|
||||
numerical_query.value,
|
||||
),
|
||||
PrefixType::Rps => matches_condition(
|
||||
|
@ -165,6 +165,7 @@ impl Default for ProcColumn {
|
||||
ProcessName,
|
||||
Command,
|
||||
CpuPercent,
|
||||
Mem,
|
||||
MemPercent,
|
||||
ReadPerSecond,
|
||||
WritePerSecond,
|
||||
@ -187,7 +188,7 @@ impl Default for ProcColumn {
|
||||
},
|
||||
);
|
||||
}
|
||||
MemPercent | Mem => {
|
||||
MemPercent => {
|
||||
column_mapping.insert(
|
||||
column,
|
||||
ColumnInfo {
|
||||
@ -196,6 +197,15 @@ impl Default for ProcColumn {
|
||||
},
|
||||
);
|
||||
}
|
||||
Mem => {
|
||||
column_mapping.insert(
|
||||
column,
|
||||
ColumnInfo {
|
||||
enabled: false,
|
||||
shortcut: Some("m"),
|
||||
},
|
||||
);
|
||||
}
|
||||
ProcessName => {
|
||||
column_mapping.insert(
|
||||
column,
|
||||
@ -250,6 +260,20 @@ impl Default for ProcColumn {
|
||||
}
|
||||
|
||||
impl ProcColumn {
|
||||
pub fn toggle(&mut self, column: &ProcessSorting) {
|
||||
if let Some(mapping) = self.column_mapping.get_mut(column) {
|
||||
mapping.enabled = !(mapping.enabled);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_enabled(&self, column: &ProcessSorting) -> bool {
|
||||
if let Some(mapping) = self.column_mapping.get(column) {
|
||||
mapping.enabled
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_enabled_columns_len(&self) -> usize {
|
||||
self.ordered_columns
|
||||
.iter()
|
||||
|
@ -42,8 +42,10 @@ pub struct DisplayableData {
|
||||
pub process_data: Vec<ConvertedProcessData>,
|
||||
// What's actually displayed
|
||||
pub finalized_process_data_map: HashMap<u64, Vec<ConvertedProcessData>>,
|
||||
pub mem_label: String,
|
||||
pub swap_label: String,
|
||||
pub mem_label_percent: String,
|
||||
pub swap_label_percent: String,
|
||||
pub mem_label_frac: String,
|
||||
pub swap_label_frac: String,
|
||||
pub mem_data: Vec<(f64, f64)>,
|
||||
pub swap_data: Vec<(f64, f64)>,
|
||||
pub cpu_data: Vec<ConvertedCpuData>,
|
||||
|
@ -76,7 +76,7 @@ impl HelpDialog for Painter {
|
||||
|
||||
app_state.help_dialog_state.scroll_state.max_scroll_index =
|
||||
(self.styled_help_text.len() as u16
|
||||
+ (constants::HELP_TEXT.len() as u16 - 4)
|
||||
+ (constants::HELP_TEXT.len() as u16 - 5)
|
||||
+ overflow_buffer)
|
||||
.saturating_sub(draw_loc.height);
|
||||
|
||||
|
@ -67,6 +67,7 @@ impl DiskTableWidget for Painter {
|
||||
get_variable_intrinsic_widths(width as u16, &width_ratios, &DISK_HEADERS_LENS);
|
||||
let intrinsic_widths = &variable_intrinsic_results.0[0..variable_intrinsic_results.1];
|
||||
|
||||
// TODO: This seems to be bugged? The selected text style gets "stuck"? I think this gets fixed with tui 0.10?
|
||||
let (border_and_title_style, highlight_style) = if is_on_widget {
|
||||
(
|
||||
self.colours.highlighted_border_style,
|
||||
|
@ -38,8 +38,6 @@ impl MemBasicWidget for Painter {
|
||||
);
|
||||
}
|
||||
|
||||
// +9 due to 3 + 4 + 2 + 2 columns for the name & space + percentage + bar bounds + margin spacing
|
||||
let bar_length = usize::from(draw_loc.width.saturating_sub(11));
|
||||
let ram_use_percentage = if let Some(mem) = mem_data.last() {
|
||||
mem.1
|
||||
} else {
|
||||
@ -50,21 +48,64 @@ impl MemBasicWidget for Painter {
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let num_bars_ram = calculate_basic_use_bars(ram_use_percentage, bar_length);
|
||||
let num_bars_swap = calculate_basic_use_bars(swap_use_percentage, bar_length);
|
||||
let mem_label = format!(
|
||||
"RAM[{}{}{:3.0}%]\n",
|
||||
"|".repeat(num_bars_ram),
|
||||
" ".repeat(bar_length - num_bars_ram),
|
||||
ram_use_percentage.round(),
|
||||
|
||||
// +7 due to 3 + 2 + 2 columns for the name & space + bar bounds + margin spacing
|
||||
// Then + length of fraction
|
||||
let ram_bar_length = usize::from(
|
||||
draw_loc
|
||||
.width
|
||||
.saturating_sub(7)
|
||||
.saturating_sub(app_state.canvas_data.mem_label_frac.trim().len() as u16),
|
||||
);
|
||||
let swap_label = format!(
|
||||
"SWP[{}{}{:3.0}%]",
|
||||
"|".repeat(num_bars_swap),
|
||||
" ".repeat(bar_length - num_bars_swap),
|
||||
swap_use_percentage.round(),
|
||||
let swap_bar_length = usize::from(
|
||||
draw_loc
|
||||
.width
|
||||
.saturating_sub(7)
|
||||
.saturating_sub(app_state.canvas_data.swap_label_frac.trim().len() as u16),
|
||||
);
|
||||
|
||||
let num_bars_ram = calculate_basic_use_bars(ram_use_percentage, ram_bar_length);
|
||||
let num_bars_swap = calculate_basic_use_bars(swap_use_percentage, swap_bar_length);
|
||||
// TODO: Use different styling for the frac.
|
||||
let mem_label = if app_state.basic_mode_use_percent {
|
||||
format!(
|
||||
"RAM[{}{}{:3.0}%]\n",
|
||||
"|".repeat(num_bars_ram),
|
||||
" ".repeat(
|
||||
ram_bar_length - num_bars_ram
|
||||
+ app_state.canvas_data.mem_label_frac.trim().len()
|
||||
- 4
|
||||
),
|
||||
ram_use_percentage.round()
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"RAM[{}{}{}]\n",
|
||||
"|".repeat(num_bars_ram),
|
||||
" ".repeat(ram_bar_length - num_bars_ram),
|
||||
&app_state.canvas_data.mem_label_frac.trim()
|
||||
)
|
||||
};
|
||||
let swap_label = if app_state.basic_mode_use_percent {
|
||||
format!(
|
||||
"SWP[{}{}{:3.0}%]",
|
||||
"|".repeat(num_bars_swap),
|
||||
" ".repeat(
|
||||
swap_bar_length - num_bars_swap
|
||||
+ app_state.canvas_data.swap_label_frac.trim().len()
|
||||
- 4
|
||||
),
|
||||
swap_use_percentage.round()
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"SWP[{}{}{}]",
|
||||
"|".repeat(num_bars_swap),
|
||||
" ".repeat(swap_bar_length - num_bars_swap),
|
||||
&app_state.canvas_data.swap_label_frac.trim()
|
||||
)
|
||||
};
|
||||
|
||||
let mem_text = [
|
||||
Text::styled(mem_label, self.colours.ram_style),
|
||||
Text::styled(swap_label, self.colours.swap_style),
|
||||
|
@ -62,10 +62,13 @@ impl MemGraphWidget for Painter {
|
||||
.labels_style(self.colours.graph_style);
|
||||
|
||||
let mut mem_canvas_vec: Vec<Dataset<'_>> = vec![];
|
||||
|
||||
let mem_label = format!(
|
||||
"RAM:{}{}",
|
||||
app_state.canvas_data.mem_label_percent, app_state.canvas_data.mem_label_frac
|
||||
);
|
||||
mem_canvas_vec.push(
|
||||
Dataset::default()
|
||||
.name(&app_state.canvas_data.mem_label)
|
||||
.name(&mem_label)
|
||||
.marker(if app_state.app_config_fields.use_dot {
|
||||
Marker::Dot
|
||||
} else {
|
||||
@ -76,9 +79,13 @@ impl MemGraphWidget for Painter {
|
||||
.graph_type(tui::widgets::GraphType::Line),
|
||||
);
|
||||
|
||||
let swap_label = format!(
|
||||
"SWP:{}{}",
|
||||
app_state.canvas_data.swap_label_percent, app_state.canvas_data.swap_label_frac
|
||||
);
|
||||
mem_canvas_vec.push(
|
||||
Dataset::default()
|
||||
.name(&app_state.canvas_data.swap_label)
|
||||
.name(&swap_label)
|
||||
.marker(if app_state.app_config_fields.use_dot {
|
||||
Marker::Dot
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
app::App,
|
||||
app::{data_harvester::processes::ProcessSorting, App},
|
||||
canvas::{
|
||||
drawing_utils::{
|
||||
get_search_start_position, get_start_position, get_variable_intrinsic_widths,
|
||||
@ -152,6 +152,7 @@ impl ProcessTableWidget for Painter {
|
||||
|
||||
// Draw!
|
||||
let is_proc_widget_grouped = proc_widget_state.is_grouped;
|
||||
let mem_enabled = proc_widget_state.columns.is_enabled(&ProcessSorting::Mem);
|
||||
let process_rows = sliced_vec.iter().map(|process| {
|
||||
Row::Data(
|
||||
vec![
|
||||
@ -161,8 +162,12 @@ impl ProcessTableWidget for Painter {
|
||||
process.pid.to_string()
|
||||
},
|
||||
process.name.clone(),
|
||||
format!("{:.1}%", process.cpu_usage),
|
||||
format!("{:.1}%", process.mem_usage),
|
||||
format!("{:.1}%", process.cpu_percent_usage),
|
||||
if mem_enabled {
|
||||
format!("{:.0}{}", process.mem_usage_str.0, process.mem_usage_str.1)
|
||||
} else {
|
||||
format!("{:.1}%", process.mem_percent_usage)
|
||||
},
|
||||
process.read_per_sec.to_string(),
|
||||
process.write_per_sec.to_string(),
|
||||
process.total_read.to_string(),
|
||||
|
@ -42,14 +42,15 @@ lazy_static! {
|
||||
}
|
||||
|
||||
// Help text
|
||||
pub const HELP_CONTENTS_TEXT: [&str; 7] = [
|
||||
pub const HELP_CONTENTS_TEXT: [&str; 8] = [
|
||||
"Press the corresponding numbers to jump to the section, or scroll:\n",
|
||||
"1 - General\n",
|
||||
"2 - CPU widget\n",
|
||||
"3 - Process widget\n",
|
||||
"4 - Process search widget\n",
|
||||
"5 - Process sort widget\n",
|
||||
"6 - Battery widget",
|
||||
"6 - Battery widget\n",
|
||||
"7 - Basic memory widget",
|
||||
];
|
||||
|
||||
pub const GENERAL_HELP_TEXT: [&str; 29] = [
|
||||
@ -91,7 +92,7 @@ pub const CPU_HELP_TEXT: [&str; 2] = [
|
||||
|
||||
// TODO [Help]: Search in help?
|
||||
// TODO [Help]: Move to using tables for easier formatting?
|
||||
pub const PROCESS_HELP_TEXT: [&str; 11] = [
|
||||
pub const PROCESS_HELP_TEXT: [&str; 12] = [
|
||||
"3 - Process widget\n",
|
||||
"dd Kill the selected process\n",
|
||||
"c Sort by CPU usage, press again to reverse sorting order\n",
|
||||
@ -102,7 +103,8 @@ pub const PROCESS_HELP_TEXT: [&str; 11] = [
|
||||
"Ctrl-f, / Open process search widget\n",
|
||||
"P Toggle between showing the full path or just the process name\n",
|
||||
"s, F6 Open process sort widget\n",
|
||||
"I Invert current sort",
|
||||
"I Invert current sort\n",
|
||||
"% Toggle between values and percentages for memory usage",
|
||||
];
|
||||
|
||||
pub const SEARCH_HELP_TEXT: [&str; 43] = [
|
||||
@ -166,6 +168,11 @@ pub const BATTERY_HELP_TEXT: [&str; 3] = [
|
||||
"Right Go to next battery",
|
||||
];
|
||||
|
||||
pub const BASIC_MEM_HELP_TEXT: [&str; 2] = [
|
||||
"7 - Basic memory widget\n",
|
||||
"% Toggle between values and percentages for memory usage",
|
||||
];
|
||||
|
||||
lazy_static! {
|
||||
pub static ref HELP_TEXT: Vec<Vec<&'static str>> = vec![
|
||||
HELP_CONTENTS_TEXT.to_vec(),
|
||||
@ -175,6 +182,7 @@ lazy_static! {
|
||||
SEARCH_HELP_TEXT.to_vec(),
|
||||
SORT_HELP_TEXT.to_vec(),
|
||||
BATTERY_HELP_TEXT.to_vec(),
|
||||
BASIC_MEM_HELP_TEXT.to_vec(),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,10 @@ pub struct ConvertedNetworkData {
|
||||
pub struct ConvertedProcessData {
|
||||
pub pid: u32,
|
||||
pub name: String,
|
||||
pub cpu_usage: f64,
|
||||
pub mem_usage: f64,
|
||||
pub cpu_percent_usage: f64,
|
||||
pub mem_percent_usage: f64,
|
||||
pub mem_usage_kb: u64,
|
||||
pub mem_usage_str: (f64, String),
|
||||
pub group_pids: Vec<u32>,
|
||||
pub read_per_sec: String,
|
||||
pub write_per_sec: String,
|
||||
@ -51,8 +53,9 @@ pub struct ConvertedProcessData {
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct SingleProcessData {
|
||||
pub pid: u32,
|
||||
pub cpu_usage: f64,
|
||||
pub mem_usage: f64,
|
||||
pub cpu_percent_usage: f64,
|
||||
pub mem_percent_usage: f64,
|
||||
pub mem_usage_kb: u64,
|
||||
pub group_pids: Vec<u32>,
|
||||
pub read_per_sec: u64,
|
||||
pub write_per_sec: u64,
|
||||
@ -231,9 +234,11 @@ pub fn convert_swap_data_points(
|
||||
result
|
||||
}
|
||||
|
||||
pub fn convert_mem_labels(current_data: &data_farmer::DataCollection) -> (String, String) {
|
||||
let mem_label = "RAM:".to_string()
|
||||
+ &format!(
|
||||
pub fn convert_mem_labels(
|
||||
current_data: &data_farmer::DataCollection,
|
||||
) -> (String, String, String, String) {
|
||||
(
|
||||
format!(
|
||||
"{:3.0}%",
|
||||
match current_data.memory_harvest.mem_total_in_mb {
|
||||
0 => 0.0,
|
||||
@ -241,15 +246,13 @@ pub fn convert_mem_labels(current_data: &data_farmer::DataCollection) -> (String
|
||||
current_data.memory_harvest.mem_used_in_mb as f64 * 100.0
|
||||
/ current_data.memory_harvest.mem_total_in_mb as f64,
|
||||
}
|
||||
)
|
||||
+ &format!(
|
||||
),
|
||||
format!(
|
||||
" {:.1}GB/{:.1}GB",
|
||||
current_data.memory_harvest.mem_used_in_mb as f64 / 1024.0,
|
||||
(current_data.memory_harvest.mem_total_in_mb as f64 / 1024.0)
|
||||
);
|
||||
|
||||
let swap_label = "SWP:".to_string()
|
||||
+ &format!(
|
||||
),
|
||||
format!(
|
||||
"{:3.0}%",
|
||||
match current_data.swap_harvest.mem_total_in_mb {
|
||||
0 => 0.0,
|
||||
@ -257,14 +260,13 @@ pub fn convert_mem_labels(current_data: &data_farmer::DataCollection) -> (String
|
||||
current_data.swap_harvest.mem_used_in_mb as f64 * 100.0
|
||||
/ current_data.swap_harvest.mem_total_in_mb as f64,
|
||||
}
|
||||
)
|
||||
+ &format!(
|
||||
),
|
||||
format!(
|
||||
" {:.1}GB/{:.1}GB",
|
||||
current_data.swap_harvest.mem_used_in_mb as f64 / 1024.0,
|
||||
(current_data.swap_harvest.mem_total_in_mb as f64 / 1024.0)
|
||||
);
|
||||
|
||||
(mem_label, swap_label)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_rx_tx_data_points(
|
||||
@ -398,8 +400,10 @@ pub fn convert_process_data(
|
||||
ProcessNamingType::Name => process.name.to_string(),
|
||||
ProcessNamingType::Path => process.path.to_string(),
|
||||
},
|
||||
cpu_usage: process.cpu_usage_percent,
|
||||
mem_usage: process.mem_usage_percent,
|
||||
cpu_percent_usage: process.cpu_usage_percent,
|
||||
mem_percent_usage: process.mem_usage_percent,
|
||||
mem_usage_kb: process.mem_usage_kb,
|
||||
mem_usage_str: get_exact_byte_values(process.mem_usage_kb * 1024, false),
|
||||
group_pids: vec![process.pid],
|
||||
read_per_sec,
|
||||
write_per_sec,
|
||||
@ -428,8 +432,9 @@ pub fn convert_process_data(
|
||||
..SingleProcessData::default()
|
||||
});
|
||||
|
||||
(*entry).cpu_usage += process.cpu_usage_percent;
|
||||
(*entry).mem_usage += process.mem_usage_percent;
|
||||
(*entry).cpu_percent_usage += process.cpu_usage_percent;
|
||||
(*entry).mem_percent_usage += process.mem_usage_percent;
|
||||
(*entry).mem_usage_kb += process.mem_usage_kb;
|
||||
(*entry).group_pids.push(process.pid);
|
||||
(*entry).read_per_sec += process.read_bytes_per_sec;
|
||||
(*entry).write_per_sec += process.write_bytes_per_sec;
|
||||
@ -458,8 +463,10 @@ pub fn convert_process_data(
|
||||
ConvertedProcessData {
|
||||
pid: p.pid,
|
||||
name: identifier.to_string(),
|
||||
cpu_usage: p.cpu_usage,
|
||||
mem_usage: p.mem_usage,
|
||||
cpu_percent_usage: p.cpu_percent_usage,
|
||||
mem_percent_usage: p.mem_percent_usage,
|
||||
mem_usage_kb: p.mem_usage_kb,
|
||||
mem_usage_str: get_exact_byte_values(p.mem_usage_kb * 1024, false),
|
||||
group_pids: p.group_pids,
|
||||
read_per_sec,
|
||||
write_per_sec,
|
||||
|
22
src/main.rs
22
src/main.rs
@ -213,8 +213,10 @@ fn main() -> error::Result<()> {
|
||||
app.canvas_data.swap_data =
|
||||
convert_swap_data_points(&app.data_collection, false);
|
||||
let memory_and_swap_labels = convert_mem_labels(&app.data_collection);
|
||||
app.canvas_data.mem_label = memory_and_swap_labels.0;
|
||||
app.canvas_data.swap_label = memory_and_swap_labels.1;
|
||||
app.canvas_data.mem_label_percent = memory_and_swap_labels.0;
|
||||
app.canvas_data.mem_label_frac = memory_and_swap_labels.1;
|
||||
app.canvas_data.swap_label_percent = memory_and_swap_labels.2;
|
||||
app.canvas_data.swap_label_frac = memory_and_swap_labels.3;
|
||||
}
|
||||
|
||||
if app.used_widgets.use_cpu {
|
||||
@ -668,20 +670,26 @@ fn sort_process_data(
|
||||
ProcessSorting::CpuPercent => {
|
||||
to_sort_vec.sort_by(|a, b| {
|
||||
utils::gen_util::get_ordering(
|
||||
a.cpu_usage,
|
||||
b.cpu_usage,
|
||||
a.cpu_percent_usage,
|
||||
b.cpu_percent_usage,
|
||||
proc_widget_state.process_sorting_reverse,
|
||||
)
|
||||
});
|
||||
}
|
||||
ProcessSorting::Mem => {
|
||||
// TODO: Do when I do mem values in processes
|
||||
to_sort_vec.sort_by(|a, b| {
|
||||
utils::gen_util::get_ordering(
|
||||
a.mem_usage_kb,
|
||||
b.mem_usage_kb,
|
||||
proc_widget_state.process_sorting_reverse,
|
||||
)
|
||||
});
|
||||
}
|
||||
ProcessSorting::MemPercent => {
|
||||
to_sort_vec.sort_by(|a, b| {
|
||||
utils::gen_util::get_ordering(
|
||||
a.mem_usage,
|
||||
b.mem_usage,
|
||||
a.mem_percent_usage,
|
||||
b.mem_percent_usage,
|
||||
proc_widget_state.process_sorting_reverse,
|
||||
)
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user