other: bump min version to 1.95.0 (#2052)

Bumps the minimum version set to 1.95.0. This should give us a couple of neat new features to work with.
This commit is contained in:
Clement Tsang authored and GitHub committed 2026-06-20 06:16:51 +00:00
1 parent 79d33f22c2
commit 382dfdb80c
31 files changed
+1328 -1453

No files matched your search

+1 -1
View File
@@ -40,7 +40,7 @@ exclude = [
]
edition = "2024"
# The oldest version I've tested that should still build - note this is not an official MSRV!
rust-version = "1.85"
rust-version = "1.95.0"
[lib]
test = true
+668 -760
View File
File diff suppressed because it is too large. Load diff
+29 -29
View File
@@ -92,11 +92,11 @@ impl StoredData {
// We must adjust all the network values to their selected type (defaults to
// bits).
if matches!(settings.network_unit_type, DataUnit::Byte) {
if let Some(network) = &mut data.network {
network.rx /= 8;
network.tx /= 8;
}
if matches!(settings.network_unit_type, DataUnit::Byte)
&& let Some(network) = &mut data.network
{
network.rx /= 8;
network.tx /= 8;
}
if !settings.use_basic_mode {
@@ -150,17 +150,17 @@ impl StoredData {
})
.unwrap_or_default();
if let Some(disks) = data.disks {
if let Some(io) = data.io {
self.eat_disks(disks, io, harvested_time);
if let Some(disks) = data.disks
&& let Some(io) = data.io
{
self.eat_disks(disks, io, harvested_time);
if used_widgets.use_disk_io_graph {
self.time_series_data.update_disk_io(
&self.disk_harvest,
&filters.disk_io_graph_filter,
settings.disk_io_graph_show_unmounted,
);
}
if used_widgets.use_disk_io_graph {
self.time_series_data.update_disk_io(
&self.disk_harvest,
&filters.disk_io_graph_filter,
settings.disk_io_graph_show_unmounted,
);
}
}
@@ -252,22 +252,22 @@ impl StoredData {
};
let (mut io_read_rate_bytes, mut io_write_rate_bytes) = (None, None);
if let Some(Some(io_device)) = io_device {
if let Some(prev_io) = self.prev_io.get_mut(itx) {
io_read_rate_bytes = Some(
((io_device.read_bytes.saturating_sub(prev_io.0)) as f64
/ time_since_last_harvest)
.round() as u64,
);
if let Some(Some(io_device)) = io_device
&& let Some(prev_io) = self.prev_io.get_mut(itx)
{
io_read_rate_bytes = Some(
((io_device.read_bytes.saturating_sub(prev_io.0)) as f64
/ time_since_last_harvest)
.round() as u64,
);
io_write_rate_bytes = Some(
((io_device.write_bytes.saturating_sub(prev_io.1)) as f64
/ time_since_last_harvest)
.round() as u64,
);
io_write_rate_bytes = Some(
((io_device.write_bytes.saturating_sub(prev_io.1)) as f64
/ time_since_last_harvest)
.round() as u64,
);
*prev_io = (io_device.read_bytes, io_device.write_bytes);
}
*prev_io = (io_device.read_bytes, io_device.write_bytes);
}
let summed_total_bytes = match (device.used_space, device.free_space) {
+81 -86
View File
@@ -179,129 +179,124 @@ impl BottomLayout {
if let Some(current_col) = current_row
.1
.get(&(col_width_percentage_start, col_width_percentage_end))
{
if let Some(current_col_row) = current_col.1.get(&(
&& let Some(current_col_row) = current_col.1.get(&(
col_row_height_percentage_start,
col_row_height_percentage_end,
)) {
if let Some(to_left_widget) = current_col_row
.1
.range(
..(
widget_width_percentage_start,
widget_width_percentage_start,
),
)
.next_back()
{
widget.left_neighbour = Some(*to_left_widget.1);
}
))
{
if let Some(to_left_widget) = current_col_row
.1
.range(
..(
widget_width_percentage_start,
widget_width_percentage_start,
),
)
.next_back()
{
widget.left_neighbour = Some(*to_left_widget.1);
}
// Right
if let Some(to_right_neighbour) = current_col_row
.1
.range(
(
widget_width_percentage_end,
widget_width_percentage_end,
)..,
)
.next()
{
widget.right_neighbour = Some(*to_right_neighbour.1);
}
// Right
if let Some(to_right_neighbour) = current_col_row
.1
.range(
(
widget_width_percentage_end,
widget_width_percentage_end,
)..,
)
.next()
{
widget.right_neighbour = Some(*to_right_neighbour.1);
}
}
if widget.left_neighbour.is_none() {
if let Some(to_left_col) = current_row
if widget.left_neighbour.is_none()
&& let Some(to_left_col) = current_row
.1
.range(
..(col_width_percentage_start, col_width_percentage_start),
)
.next_back()
{
// Check left in same row
let mut current_best_distance = 0;
let mut current_best_widget_id = widget.widget_id;
{
// Check left in same row
let mut current_best_distance = 0;
let mut current_best_widget_id = widget.widget_id;
for widget_position in &(to_left_col.1).1 {
let candidate_start = (widget_position.0).0;
let candidate_end = (widget_position.0).1;
for widget_position in &(to_left_col.1).1 {
let candidate_start = (widget_position.0).0;
let candidate_end = (widget_position.0).1;
if is_intersecting(
if is_intersecting(
(
col_row_height_percentage_start,
col_row_height_percentage_end,
),
(candidate_start, candidate_end),
) {
let candidate_distance = get_distance(
(
col_row_height_percentage_start,
col_row_height_percentage_end,
),
(candidate_start, candidate_end),
) {
let candidate_distance = get_distance(
(
col_row_height_percentage_start,
col_row_height_percentage_end,
),
(candidate_start, candidate_end),
);
);
if current_best_distance < candidate_distance {
if let Some(new_best_widget) =
(widget_position.1).1.iter().next_back()
{
current_best_distance = candidate_distance + 1;
current_best_widget_id = *(new_best_widget.1);
}
}
if current_best_distance < candidate_distance
&& let Some(new_best_widget) =
(widget_position.1).1.iter().next_back()
{
current_best_distance = candidate_distance + 1;
current_best_widget_id = *(new_best_widget.1);
}
}
if current_best_distance > 0 {
widget.left_neighbour = Some(current_best_widget_id);
}
}
if current_best_distance > 0 {
widget.left_neighbour = Some(current_best_widget_id);
}
}
if widget.right_neighbour.is_none() {
if let Some(to_right_col) = current_row
if widget.right_neighbour.is_none()
&& let Some(to_right_col) = current_row
.1
.range((col_width_percentage_end, col_width_percentage_end)..)
.next()
{
// Check right in same row
let mut current_best_distance = 0;
let mut current_best_widget_id = widget.widget_id;
{
// Check right in same row
let mut current_best_distance = 0;
let mut current_best_widget_id = widget.widget_id;
for widget_position in &(to_right_col.1).1 {
let candidate_start = (widget_position.0).0;
let candidate_end = (widget_position.0).1;
for widget_position in &(to_right_col.1).1 {
let candidate_start = (widget_position.0).0;
let candidate_end = (widget_position.0).1;
if is_intersecting(
if is_intersecting(
(
col_row_height_percentage_start,
col_row_height_percentage_end,
),
(candidate_start, candidate_end),
) {
let candidate_distance = get_distance(
(
col_row_height_percentage_start,
col_row_height_percentage_end,
),
(candidate_start, candidate_end),
) {
let candidate_distance = get_distance(
(
col_row_height_percentage_start,
col_row_height_percentage_end,
),
(candidate_start, candidate_end),
);
);
if current_best_distance < candidate_distance {
if let Some(new_best_widget) =
(widget_position.1).1.iter().next()
{
current_best_distance = candidate_distance + 1;
current_best_widget_id = *(new_best_widget.1);
}
}
if current_best_distance < candidate_distance
&& let Some(new_best_widget) =
(widget_position.1).1.iter().next()
{
current_best_distance = candidate_distance + 1;
current_best_widget_id = *(new_best_widget.1);
}
}
if current_best_distance > 0 {
widget.right_neighbour = Some(current_best_widget_id);
}
}
if current_best_distance > 0 {
widget.right_neighbour = Some(current_best_widget_id);
}
}
+2 -2
View File
@@ -303,11 +303,11 @@ impl Painter {
// bars...
let cpu_height = {
let c = (actual_cpu_data_len / 4) as u16
+ u16::from(actual_cpu_data_len % 4 != 0)
+ u16::from(!actual_cpu_data_len.is_multiple_of(4))
+ u16::from(
app_state.app_config_fields.show_average_cpu
&& app_state.app_config_fields.dedicated_average_row
&& actual_cpu_data_len.saturating_sub(1) % 4 != 0,
&& !actual_cpu_data_len.saturating_sub(1).is_multiple_of(4),
);
if c <= 1 { 1 } else { c }
+5 -5
View File
@@ -80,11 +80,11 @@ pub fn render_search_input(
input_vec.extend(query_spans);
if let Some(hint) = state.hint {
if state.input_field_state.current_query().is_empty() {
input_vec.push(Span::styled(" ", styles.text_style));
input_vec.push(Span::styled(hint, styles.hint_style));
}
if let Some(hint) = state.hint
&& state.input_field_state.current_query().is_empty()
{
input_vec.push(Span::styled(" ", styles.text_style));
input_vec.push(Span::styled(hint, styles.hint_style));
}
let input_line = Line::from(input_vec);
+40 -41
View File
@@ -838,13 +838,12 @@ impl<F: Copy + Default + Into<f64>> Widget for TimeChart<'_, F> {
}
}
if let Some(y) = layout.axis_x {
if let Some(x) = layout.axis_y {
if let Some(cell) = buf.cell_mut((x, y)) {
cell.set_symbol(symbols::line::BOTTOM_LEFT)
.set_style(self.x_axis.style);
}
}
if let Some(y) = layout.axis_x
&& let Some(x) = layout.axis_y
&& let Some(cell) = buf.cell_mut((x, y))
{
cell.set_symbol(symbols::line::BOTTOM_LEFT)
.set_style(self.x_axis.style);
}
let x_bounds = self.x_axis.bounds.get_bounds();
@@ -860,42 +859,42 @@ impl<F: Copy + Default + Into<f64>> Widget for TimeChart<'_, F> {
})
.render(graph_area, buf);
if let Some((x, y)) = layout.title_x {
if let Some(title) = self.x_axis.title.as_ref() {
let width = graph_area
.right()
.saturating_sub(x)
.min(title.width() as u16);
buf.set_style(
Rect {
x,
y,
width,
height: 1,
},
original_style,
);
buf.set_line(x, y, title, width);
}
if let Some((x, y)) = layout.title_x
&& let Some(title) = self.x_axis.title.as_ref()
{
let width = graph_area
.right()
.saturating_sub(x)
.min(title.width() as u16);
buf.set_style(
Rect {
x,
y,
width,
height: 1,
},
original_style,
);
buf.set_line(x, y, title, width);
}
if let Some((x, y)) = layout.title_y {
if let Some(title) = self.y_axis.title.as_ref() {
let width = graph_area
.right()
.saturating_sub(x)
.min(title.width() as u16);
buf.set_style(
Rect {
x,
y,
width,
height: 1,
},
original_style,
);
buf.set_line(x, y, title, width);
}
if let Some((x, y)) = layout.title_y
&& let Some(title) = self.y_axis.title.as_ref()
{
let width = graph_area
.right()
.saturating_sub(x)
.min(title.width() as u16);
buf.set_style(
Rect {
x,
y,
width,
height: 1,
},
original_style,
);
buf.set_line(x, y, title, width);
}
if let Some(legend_area) = layout.legend_area {
+42 -46
View File
@@ -242,28 +242,25 @@ impl ProcessKillDialog {
ButtonState::Signals { state, .. } => {
use crate::utils::process_killer;
if let Some(selected) = state.selected() {
if selected != 0 {
// On Linux, we need to skip 32 and 33.
let signal = if cfg!(target_os = "linux")
&& (selected == 32 || selected == 33)
{
if let Some(selected) = state.selected()
&& selected != 0
{
// On Linux, we need to skip 32 and 33.
let signal =
if cfg!(target_os = "linux") && (selected == 32 || selected == 33) {
selected + 2
} else {
selected
};
for pid in pids {
if let Err(err) =
process_killer::kill_process_given_pid(pid, signal)
{
self.state = ProcessKillDialogState::Error {
process_name,
pid: Some(pid),
err: err.to_string(),
};
return;
}
for pid in pids {
if let Err(err) = process_killer::kill_process_given_pid(pid, signal) {
self.state = ProcessKillDialogState::Error {
process_name,
pid: Some(pid),
err: err.to_string(),
};
return;
}
}
}
@@ -315,52 +312,51 @@ impl ProcessKillDialog {
'l' => self.on_right_key(),
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => {
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))]
if let Some(value) = c.to_digit(10) {
if let ProcessKillDialogState::Selecting(ProcessKillSelectingInner {
if let Some(value) = c.to_digit(10)
&& let ProcessKillDialogState::Selecting(ProcessKillSelectingInner {
button_state: ButtonState::Signals { state, .. },
..
}) = &mut self.state
{
if let Some((prev, last_press)) = self.last_char {
if prev.is_ascii_digit() && last_press.elapsed() <= MAX_KEY_TIMEOUT {
let current = state.selected().unwrap_or(0);
let new = {
let new = current * 10 + value as usize;
{
if let Some((prev, last_press)) = self.last_char {
if prev.is_ascii_digit() && last_press.elapsed() <= MAX_KEY_TIMEOUT {
let current = state.selected().unwrap_or(0);
let new = {
let new = current * 10 + value as usize;
// Note that 32 and 33 are skipped on linux.
if cfg!(target_os = "linux") {
if new == 32 || new == 33 {
value as usize
} else if new >= 34 {
new - 2
} else {
new
}
// Note that 32 and 33 are skipped on linux.
if cfg!(target_os = "linux") {
if new == 32 || new == 33 {
value as usize
} else if new >= 34 {
new - 2
} else {
new
}
};
if new >= SIGNAL_TEXT.len() {
// If the new value is too large, then just assume we instead
// want the value itself.
state.select(Some(value as usize));
self.last_char = Some((c, Instant::now()));
} else {
state.select(Some(new));
self.last_char = None;
new
}
} else {
};
if new >= SIGNAL_TEXT.len() {
// If the new value is too large, then just assume we instead
// want the value itself.
state.select(Some(value as usize));
self.last_char = Some((c, Instant::now()));
} else {
state.select(Some(new));
self.last_char = None;
}
} else {
state.select(Some(value as usize));
self.last_char = Some((c, Instant::now()));
}
return; // Needed to avoid accidentally clearing last_char.
} else {
state.select(Some(value as usize));
self.last_char = Some((c, Instant::now()));
}
return; // Needed to avoid accidentally clearing last_char.
}
}
'g' => {
+23 -24
View File
@@ -50,33 +50,31 @@ impl Painter {
let show_decimal = app_state.app_config_fields.show_cpu_decimal;
if app_state.app_config_fields.dedicated_average_row
&& app_state.app_config_fields.show_average_cpu
{
if let Some((index, avg)) = cpu_data
&& let Some((index, avg)) = cpu_data
.iter()
.find_position(|&datum| matches!(datum.data_type, CpuDataType::Avg))
{
let (outer, inner, ratio, style) = self.cpu_info(avg, show_decimal);
let [cores_loc, mut avg_loc] =
Layout::vertical([Constraint::Min(0), Constraint::Length(1)]).areas(draw_loc);
{
let (outer, inner, ratio, style) = self.cpu_info(avg, show_decimal);
let [cores_loc, mut avg_loc] =
Layout::vertical([Constraint::Min(0), Constraint::Length(1)]).areas(draw_loc);
// The cores section all have horizontal margin, so to line up with the cores we
// need to add some margin ourselves.
avg_loc.x += 1;
avg_loc.width -= 2;
// The cores section all have horizontal margin, so to line up with the cores we
// need to add some margin ourselves.
avg_loc.x += 1;
avg_loc.width -= 2;
f.render_widget(
PipeGauge::default()
.gauge_style(style)
.label_style(style)
.inner_label(inner)
.start_label(outer)
.ratio(ratio.into()),
avg_loc,
);
avg_row_count += 1;
avg_index = index;
draw_loc = cores_loc;
}
f.render_widget(
PipeGauge::default()
.gauge_style(style)
.label_style(style)
.inner_label(inner)
.start_label(outer)
.ratio(ratio.into()),
avg_loc,
);
avg_row_count += 1;
avg_index = index;
draw_loc = cores_loc;
}
if draw_loc.height > 0 {
@@ -119,7 +117,8 @@ impl Painter {
let to_divide = REQUIRED_COLUMNS - itx;
let num_taken = min(
remaining_height,
(row_counter / to_divide) + usize::from(row_counter % to_divide != 0),
(row_counter / to_divide)
+ usize::from(!row_counter.is_multiple_of(to_divide)),
);
row_counter -= num_taken;
let chunk = (&mut gauge_info).take(num_taken);
+6 -6
View File
@@ -42,12 +42,12 @@ impl Painter {
}
// Update draw loc in widget map
if app_state.should_get_widget_bounds() {
if let Some(bottom_widget) = app_state.widget_map.get_mut(&widget_id) {
bottom_widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
bottom_widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
if app_state.should_get_widget_bounds()
&& let Some(bottom_widget) = app_state.widget_map.get_mut(&widget_id)
{
bottom_widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
bottom_widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
} else {
let graph_width = draw_loc.width - legend_width;
+10 -14
View File
@@ -93,15 +93,11 @@ impl Painter {
// Compute y_max across all visible series.
let mut visible_sources: Vec<&_> = Vec::new();
for name in &device_names {
if show_read {
if let Some(data) = read_data.get(*name) {
visible_sources.push(data);
}
if show_read && let Some(data) = read_data.get(*name) {
visible_sources.push(data);
}
if show_write {
if let Some(data) = write_data.get(*name) {
visible_sources.push(data);
}
if show_write && let Some(data) = write_data.get(*name) {
visible_sources.push(data);
}
}
let y_max = widget_state.graph.y_max(visible_sources.into_iter(), times);
@@ -230,12 +226,12 @@ impl Painter {
);
}
if app_state.should_get_widget_bounds() {
if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
if app_state.should_get_widget_bounds()
&& let Some(widget) = app_state.widget_map.get_mut(&widget_id)
{
widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
}
}
+6 -6
View File
@@ -179,12 +179,12 @@ impl Painter {
});
// Update draw loc in widget map
if app_state.should_get_widget_bounds() {
if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
if app_state.should_get_widget_bounds()
&& let Some(widget) = app_state.widget_map.get_mut(&widget_id)
{
widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
}
}
+6 -6
View File
@@ -278,12 +278,12 @@ impl Painter {
}
// Update draw loc in widget map
if app_state.should_get_widget_bounds() {
if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
if app_state.should_get_widget_bounds()
&& let Some(widget) = app_state.widget_map.get_mut(&widget_id)
{
widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
}
}
+6 -6
View File
@@ -98,12 +98,12 @@ impl Painter {
}
// Update draw loc in widget map.
if app_state.should_get_widget_bounds() {
if let Some(temperature_graph_widget) = app_state.widget_map.get_mut(&widget_id) {
temperature_graph_widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
temperature_graph_widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
if app_state.should_get_widget_bounds()
&& let Some(temperature_graph_widget) = app_state.widget_map.get_mut(&widget_id)
{
temperature_graph_widget.top_left_corner = Some((draw_loc.x, draw_loc.y));
temperature_graph_widget.bottom_right_corner =
Some((draw_loc.x + draw_loc.width, draw_loc.y + draw_loc.height));
}
}
}
+8 -8
View File
@@ -472,14 +472,14 @@ impl DataCollector {
#[inline]
fn update_processes(&mut self) {
if self.widgets_to_harvest.use_proc {
if let Ok(mut process_list) = self.get_processes() {
// NB: To avoid duplicate sorts on rerenders/events, we sort the processes by
// PID here. We also want to avoid re-sorting *again* later on
// if we're sorting by PID, since we already did it here!
process_list.sort_unstable_by_key(|p| p.pid);
self.data.list_of_processes = Some(process_list);
}
if self.widgets_to_harvest.use_proc
&& let Ok(mut process_list) = self.get_processes()
{
// NB: To avoid duplicate sorts on rerenders/events, we sort the processes by
// PID here. We also want to avoid re-sorting *again* later on
// if we're sorting by PID, since we already did it here!
process_list.sort_unstable_by_key(|p| p.pid);
self.data.list_of_processes = Some(process_list);
}
}
+57 -57
View File
@@ -348,75 +348,75 @@ pub fn get_amd_vecs(widgets_to_harvest: &UsedWidgets, prev_time: Instant) -> Opt
.unwrap_or(amd_gpu_marketing::AMDGPU_DEFAULT_NAME.to_string());
if let Some(mem) = get_amd_vram(&device_path) {
if widgets_to_harvest.use_mem {
if let Some(total_bytes) = NonZeroU64::new(mem.total) {
mem_vec.push((
device_name.clone(),
MemData {
total_bytes,
used_bytes: mem.used,
},
));
}
if widgets_to_harvest.use_mem
&& let Some(total_bytes) = NonZeroU64::new(mem.total)
{
mem_vec.push((
device_name.clone(),
MemData {
total_bytes,
used_bytes: mem.used,
},
));
}
total_mem += mem.total
}
if widgets_to_harvest.use_proc {
if let Some(procs) = get_amd_fdinfo(&device_path) {
PREV_PROC_DATA.with_borrow_mut(|prev_proc_data| {
let prev_fdinfo = prev_proc_data.entry(device_path).or_default();
let mut seen_pids = IntHashSet::default();
if widgets_to_harvest.use_proc
&& let Some(procs) = get_amd_fdinfo(&device_path)
{
PREV_PROC_DATA.with_borrow_mut(|prev_proc_data| {
let prev_fdinfo = prev_proc_data.entry(device_path).or_default();
let mut seen_pids = IntHashSet::default();
let mut procs_map = IntHashMap::default();
for (proc_pid, proc_usage) in procs {
seen_pids.insert(proc_pid);
if let Some(prev_usage) = prev_fdinfo.get_mut(&proc_pid) {
// calculate deltas
let gfx_usage =
diff_usage(prev_usage.gfx_usage, proc_usage.gfx_usage, &interval);
let dma_usage =
diff_usage(prev_usage.dma_usage, proc_usage.dma_usage, &interval);
let enc_usage =
diff_usage(prev_usage.enc_usage, proc_usage.enc_usage, &interval);
let dec_usage =
diff_usage(prev_usage.dec_usage, proc_usage.dec_usage, &interval);
let uvd_usage =
diff_usage(prev_usage.uvd_usage, proc_usage.uvd_usage, &interval);
let vcn_usage =
diff_usage(prev_usage.vcn_usage, proc_usage.vcn_usage, &interval);
let vpe_usage =
diff_usage(prev_usage.vpe_usage, proc_usage.vpe_usage, &interval);
let mut procs_map = IntHashMap::default();
for (proc_pid, proc_usage) in procs {
seen_pids.insert(proc_pid);
if let Some(prev_usage) = prev_fdinfo.get_mut(&proc_pid) {
// calculate deltas
let gfx_usage =
diff_usage(prev_usage.gfx_usage, proc_usage.gfx_usage, &interval);
let dma_usage =
diff_usage(prev_usage.dma_usage, proc_usage.dma_usage, &interval);
let enc_usage =
diff_usage(prev_usage.enc_usage, proc_usage.enc_usage, &interval);
let dec_usage =
diff_usage(prev_usage.dec_usage, proc_usage.dec_usage, &interval);
let uvd_usage =
diff_usage(prev_usage.uvd_usage, proc_usage.uvd_usage, &interval);
let vcn_usage =
diff_usage(prev_usage.vcn_usage, proc_usage.vcn_usage, &interval);
let vpe_usage =
diff_usage(prev_usage.vpe_usage, proc_usage.vpe_usage, &interval);
// combined usage
let gpu_util_wide = gfx_usage
+ dma_usage
+ enc_usage
+ dec_usage
+ uvd_usage
+ vcn_usage
+ vpe_usage;
// combined usage
let gpu_util_wide = gfx_usage
+ dma_usage
+ enc_usage
+ dec_usage
+ uvd_usage
+ vcn_usage
+ vpe_usage;
let gpu_util: u32 = gpu_util_wide.try_into().unwrap_or(0);
let gpu_util: u32 = gpu_util_wide.try_into().unwrap_or(0);
if gpu_util > 0 || proc_usage.vram_usage > 0 {
procs_map.insert(proc_pid, (proc_usage.vram_usage, gpu_util));
}
*prev_usage = proc_usage;
} else {
prev_fdinfo.insert(proc_pid, proc_usage);
if gpu_util > 0 || proc_usage.vram_usage > 0 {
procs_map.insert(proc_pid, (proc_usage.vram_usage, gpu_util));
}
}
prev_fdinfo.retain(|k, _| seen_pids.contains(k));
if !procs_map.is_empty() {
proc_vec.push(procs_map);
*prev_usage = proc_usage;
} else {
prev_fdinfo.insert(proc_pid, proc_usage);
}
});
}
}
prev_fdinfo.retain(|k, _| seen_pids.contains(k));
if !procs_map.is_empty() {
proc_vec.push(procs_map);
}
});
}
}
+4 -4
View File
@@ -41,10 +41,10 @@ pub fn get_disk_usage(collector: &DataCollector) -> anyhow::Result<Vec<DiskHarve
let mount_point = partition.mount_point().to_string_lossy().to_string();
#[cfg(target_os = "linux")]
if collector.include_unmounted_disks {
if let Some(base) = name.rsplit('/').next() {
mounted_names.insert(base.to_string());
}
if collector.include_unmounted_disks
&& let Some(base) = name.rsplit('/').next()
{
mounted_names.insert(base.to_string());
}
// Precedence ordering in the case where name and mount filters disagree,
+4 -4
View File
@@ -191,10 +191,10 @@ pub(crate) fn physical_partitions() -> anyhow::Result<Vec<Partition>> {
// `lines()`.
while let Ok(bytes) = reader.read_line(&mut line) {
if bytes > 0 {
if let Ok(partition) = Partition::from_str(&line) {
if partition.fs_type().is_physical() {
results.push(partition);
}
if let Ok(partition) = Partition::from_str(&line)
&& partition.fs_type().is_physical()
{
results.push(partition);
}
line.clear();
+10 -11
View File
@@ -43,20 +43,19 @@ fn parse_unmounted_disks<R: BufRead>(mut reader: R, mounted: &HashSet<String>) -
let blocks = parts.nth(2).and_then(|b| b.parse::<u64>().ok());
let name = parts.next();
if let (Some(blocks), Some(name)) = (blocks, name) {
if !(mounted.contains(name)
if let (Some(blocks), Some(name)) = (blocks, name)
&& !(mounted.contains(name)
|| name.starts_with("loop")
|| name.starts_with("ram")
|| name.starts_with("zram"))
{
disks.push(DiskHarvest {
name: format!("/dev/{name}"),
mount_point: String::new(),
free_space: None,
used_space: None,
total_space: Some(blocks * PARTITION_BLOCK_SIZE),
});
}
{
disks.push(DiskHarvest {
name: format!("/dev/{name}"),
mount_point: String::new(),
free_space: None,
used_space: None,
total_space: Some(blocks * PARTITION_BLOCK_SIZE),
});
}
line.clear();
+4 -6
View File
@@ -108,19 +108,17 @@ pub fn zfs_io_stats() -> anyhow::Result<Vec<IoCounters>> {
"nwritten" => {
if let Some((_type, val)) =
value.trim_start().rsplit_once(' ')
&& let Ok(number) = val.parse::<u64>()
{
if let Ok(number) = val.parse::<u64>() {
write = number;
}
write = number;
}
}
"nread" => {
if let Some((_type, val)) =
value.trim_start().rsplit_once(' ')
&& let Ok(number) = val.parse::<u64>()
{
if let Ok(number) = val.parse::<u64>() {
read = number;
}
read = number;
}
}
_ => {}
+4 -4
View File
@@ -13,10 +13,10 @@ fn read_stat_key(path: &str, key: &str) -> Option<u64> {
// TODO: Maybe check if this is worth it for the files we read.
let file = fs::File::open(path).ok()?;
for line in std::io::BufReader::new(file).lines().map_while(Result::ok) {
if let Some(rest) = line.strip_prefix(key) {
if let Some(val) = rest.strip_prefix(' ') {
return val.trim().parse().ok();
}
if let Some(rest) = line.strip_prefix(key)
&& let Some(val) = rest.strip_prefix(' ')
{
return val.trim().parse().ok();
}
}
+11 -12
View File
@@ -57,18 +57,17 @@ pub fn get_nvidia_vecs(
for i in 0..num_gpu {
if let Ok(device) = nvml.device_by_index(i) {
if let Ok(name) = device.name() {
if widgets_to_harvest.use_mem {
if let Ok(mem) = device.memory_info() {
if let Some(total_bytes) = NonZeroU64::new(mem.total) {
mem_vec.push((
name.clone(),
MemData {
total_bytes,
used_bytes: mem.used,
},
));
}
}
if widgets_to_harvest.use_mem
&& let Ok(mem) = device.memory_info()
&& let Some(total_bytes) = NonZeroU64::new(mem.total)
{
mem_vec.push((
name.clone(),
MemData {
total_bytes,
used_bytes: mem.used,
},
));
}
if (widgets_to_harvest.use_temp || widgets_to_harvest.use_temp_graph)
+23 -24
View File
@@ -62,24 +62,24 @@ fn get_hwmon_candidates() -> (HashSet<PathBuf>, usize) {
if let Ok(read_dir) = Path::new("/sys/devices/platform").read_dir() {
for entry in read_dir.flatten() {
if entry.file_name().to_string_lossy().starts_with("coretemp.") {
if let Ok(read_dir) = entry.path().join("hwmon").read_dir() {
for entry in read_dir.flatten() {
let path = entry.path();
if entry.file_name().to_string_lossy().starts_with("coretemp.")
&& let Ok(read_dir) = entry.path().join("hwmon").read_dir()
{
for entry in read_dir.flatten() {
let path = entry.path();
if path.join("temp1_input").exists() {
// It's possible that there are dupes (represented by symlinks) - the
// easy way is to just substitute the parent
// directory and check if the hwmon
// variant exists already in a set.
//
// For more info, see https://github.com/giampaolo/psutil/pull/1822/files
if let Some(child) = path.file_name() {
let to_check_path = Path::new("/sys/class/hwmon").join(child);
if path.join("temp1_input").exists() {
// It's possible that there are dupes (represented by symlinks) - the
// easy way is to just substitute the parent
// directory and check if the hwmon
// variant exists already in a set.
//
// For more info, see https://github.com/giampaolo/psutil/pull/1822/files
if let Some(child) = path.file_name() {
let to_check_path = Path::new("/sys/class/hwmon").join(child);
if !dirs.contains(&to_check_path) {
dirs.insert(path);
}
if !dirs.contains(&to_check_path) {
dirs.insert(path);
}
}
}
@@ -326,15 +326,14 @@ fn hwmon_temperatures(filter: &Option<Filter>, graph_filter: &Option<Filter>) ->
// TODO: It's possible we may want to move the filter check further up to avoid
// probing hwmon if not needed?
if Filter::optional_should_keep(filter, &name)
|| Filter::optional_should_keep(graph_filter, &name)
if (Filter::optional_should_keep(filter, &name)
|| Filter::optional_should_keep(graph_filter, &name))
&& let Ok(temp_celsius) = parse_temp(&temp_path)
{
if let Ok(temp_celsius) = parse_temp(&temp_path) {
temperatures.push(TempSensorData {
name,
temperature: Some(temp_celsius),
});
}
temperatures.push(TempSensorData {
name,
temperature: Some(temp_celsius),
});
}
}
}
+56 -60
View File
@@ -158,63 +158,59 @@ fn create_input_thread(
loop {
// We don't block.
if let Some(is_terminated) = cancellation_token.try_check() {
if is_terminated {
break;
}
if let Some(is_terminated) = cancellation_token.try_check()
&& is_terminated
{
break;
}
if let Ok(poll) = poll(Duration::from_millis(20)) {
if poll {
if let Ok(event) = read() {
match event {
Event::Resize(_, _) => {
// TODO: Might want to debounce this in the future, or take into
// account the actual resize values.
// Maybe we want to keep the current implementation in case the
// resize event might not fire...
// not sure.
if let Ok(poll) = poll(Duration::from_millis(20))
&& poll
&& let Ok(event) = read()
{
match event {
Event::Resize(_, _) => {
// TODO: Might want to debounce this in the future, or take into
// account the actual resize values.
// Maybe we want to keep the current implementation in case the
// resize event might not fire...
// not sure.
if sender.send(BottomEvent::Resize).is_err() {
break;
}
}
Event::Paste(paste) => {
if sender.send(BottomEvent::PasteEvent(paste)).is_err() {
break;
}
}
Event::Key(key)
if !keys_disabled && key.kind == KeyEventKind::Press =>
{
// For now, we only care about key down events. This may change in
// the future.
if sender.send(BottomEvent::KeyInput(key)).is_err() {
break;
}
}
Event::Mouse(mouse) => match mouse.kind {
MouseEventKind::Moved | MouseEventKind::Drag(..) => {}
MouseEventKind::ScrollDown | MouseEventKind::ScrollUp => {
if Instant::now().duration_since(mouse_timer).as_millis() >= 20
{
if sender.send(BottomEvent::MouseInput(mouse)).is_err() {
break;
}
mouse_timer = Instant::now();
}
}
_ => {
if sender.send(BottomEvent::MouseInput(mouse)).is_err() {
break;
}
}
},
Event::Key(_) => {}
Event::FocusGained => {}
Event::FocusLost => {}
if sender.send(BottomEvent::Resize).is_err() {
break;
}
}
Event::Paste(paste) => {
if sender.send(BottomEvent::PasteEvent(paste)).is_err() {
break;
}
}
Event::Key(key) if !keys_disabled && key.kind == KeyEventKind::Press => {
// For now, we only care about key down events. This may change in
// the future.
if sender.send(BottomEvent::KeyInput(key)).is_err() {
break;
}
}
Event::Mouse(mouse) => match mouse.kind {
MouseEventKind::Moved | MouseEventKind::Drag(..) => {}
MouseEventKind::ScrollDown | MouseEventKind::ScrollUp => {
if Instant::now().duration_since(mouse_timer).as_millis() >= 20 {
if sender.send(BottomEvent::MouseInput(mouse)).is_err() {
break;
}
mouse_timer = Instant::now();
}
}
_ => {
if sender.send(BottomEvent::MouseInput(mouse)).is_err() {
break;
}
}
},
Event::Key(_) => {}
Event::FocusGained => {}
Event::FocusLost => {}
}
}
}
@@ -258,10 +254,10 @@ fn create_collection_thread(
loop {
// Check once at the very top... don't block though.
if let Some(is_terminated) = cancellation_token.try_check() {
if is_terminated {
break;
}
if let Some(is_terminated) = cancellation_token.try_check()
&& is_terminated
{
break;
}
if let Ok(message) = control_receiver.try_recv() {
@@ -276,10 +272,10 @@ fn create_collection_thread(
data_collector.update_data();
// Yet another check to bail if needed... do not block!
if let Some(is_terminated) = cancellation_token.try_check() {
if is_terminated {
break;
}
if let Some(is_terminated) = cancellation_token.try_check()
&& is_terminated
{
break;
}
let event = BottomEvent::Update(Box::from(data_collector.data));
+79 -82
View File
@@ -142,13 +142,13 @@ fn get_config_path(override_config_path: Option<&Path>) -> Option<PathBuf> {
let mut old_home_path = home_path;
old_home_path.push(".config/");
old_home_path.push(DEFAULT_CONFIG_FILE_LOCATION);
if let Ok(res) = old_home_path.try_exists() {
if res {
// We used to create it at `<HOME>/DEFAULT_CONFIG_FILE_PATH`, but changed it
// to be more correct later. However, for legacy reasons, if it already exists,
// use the old one.
return Some(old_home_path);
}
if let Ok(res) = old_home_path.try_exists()
&& res
{
// We used to create it at `<HOME>/DEFAULT_CONFIG_FILE_PATH`, but changed it
// to be more correct later. However, for legacy reasons, if it already exists,
// use the old one.
return Some(old_home_path);
}
}
@@ -157,28 +157,26 @@ fn get_config_path(override_config_path: Option<&Path>) -> Option<PathBuf> {
path
});
if cfg!(target_os = "macos") {
if let Ok(xdg_config_path) = std::env::var("XDG_CONFIG_HOME") {
if !xdg_config_path.is_empty() {
// If XDG_CONFIG_HOME exists and is non-empty, _but_ we previously used the
// Library-based path for a config and it exists, then use that
// instead for backwards-compatibility.
if let Some(old_macos_path) = &config_path {
if let Ok(res) = old_macos_path.try_exists() {
if res {
return config_path;
}
}
}
// Otherwise, try and use the XDG_CONFIG_HOME-based path.
let mut cfg_path = PathBuf::new();
cfg_path.push(xdg_config_path);
cfg_path.push(DEFAULT_CONFIG_FILE_LOCATION);
return Some(cfg_path);
}
if cfg!(target_os = "macos")
&& let Ok(xdg_config_path) = std::env::var("XDG_CONFIG_HOME")
&& !xdg_config_path.is_empty()
{
// If XDG_CONFIG_HOME exists and is non-empty, _but_ we previously used the
// Library-based path for a config and it exists, then use that
// instead for backwards-compatibility.
if let Some(old_macos_path) = &config_path
&& let Ok(res) = old_macos_path.try_exists()
&& res
{
return config_path;
}
// Otherwise, try and use the XDG_CONFIG_HOME-based path.
let mut cfg_path = PathBuf::new();
cfg_path.push(xdg_config_path);
cfg_path.push(DEFAULT_CONFIG_FILE_LOCATION);
return Some(cfg_path);
}
config_path
@@ -530,32 +528,32 @@ pub(crate) fn init_app(args: BottomArgs, config: Config) -> Result<(App, BottomL
for col_row in &col.children {
for widget in &col_row.children {
widget_map.insert(widget.widget_id, widget.clone());
if let Some(default_widget_type) = &default_widget_type_option {
if !is_custom_layout || use_basic_mode {
match widget.widget_type {
BasicCpu => {
if let Cpu = *default_widget_type {
initial_widget_id = widget.widget_id;
initial_widget_type = Cpu;
}
if let Some(default_widget_type) = &default_widget_type_option
&& (!is_custom_layout || use_basic_mode)
{
match widget.widget_type {
BasicCpu => {
if let Cpu = *default_widget_type {
initial_widget_id = widget.widget_id;
initial_widget_type = Cpu;
}
BasicMem => {
if let Mem = *default_widget_type {
initial_widget_id = widget.widget_id;
initial_widget_type = Cpu;
}
}
BasicMem => {
if let Mem = *default_widget_type {
initial_widget_id = widget.widget_id;
initial_widget_type = Cpu;
}
BasicNet => {
if let Net = *default_widget_type {
initial_widget_id = widget.widget_id;
initial_widget_type = Cpu;
}
}
BasicNet => {
if let Net = *default_widget_type {
initial_widget_id = widget.widget_id;
initial_widget_type = Cpu;
}
_ => {
if *default_widget_type == widget.widget_type {
initial_widget_id = widget.widget_id;
initial_widget_type = widget.widget_type.clone();
}
}
_ => {
if *default_widget_type == widget.widget_type {
initial_widget_id = widget.widget_id;
initial_widget_type = widget.widget_type.clone();
}
}
}
@@ -977,10 +975,10 @@ fn get_temperature(args: &BottomArgs, config: &Config) -> OptionResult<Temperatu
return Ok(TemperatureType::Kelvin);
} else if args.temperature.celsius {
return Ok(TemperatureType::Celsius);
} else if let Some(flags) = &config.flags {
if let Some(temp_type) = &flags.temperature_type {
return parse_config_value!(TemperatureType::from_str(temp_type), "temperature_type");
}
} else if let Some(flags) = &config.flags
&& let Some(temp_type) = &flags.temperature_type
{
return parse_config_value!(TemperatureType::from_str(temp_type), "temperature_type");
}
Ok(TemperatureType::Celsius)
}
@@ -991,11 +989,11 @@ fn get_show_average_cpu(args: &BottomArgs, config: &Config) -> bool {
return false;
} else if let Some(cpu) = &config.cpu {
return !cpu.hide_avg_cpu.unwrap_or(false);
} else if let Some(flags) = &config.flags {
if let Some(hide) = flags.hide_avg_cpu {
deprecated_warning("hide_avg_cpu", "cpu.hide_avg_cpu");
return !hide;
}
} else if let Some(flags) = &config.flags
&& let Some(hide) = flags.hide_avg_cpu
{
deprecated_warning("hide_avg_cpu", "cpu.hide_avg_cpu");
return !hide;
}
true
@@ -1102,20 +1100,19 @@ fn get_default_widget_and_count(
fn get_use_battery(args: &BottomArgs, config: &Config) -> bool {
// TODO: Move this so it's dynamic in the app itself and automatically hide if
// there are no batteries?
if let Ok(battery_manager) = Manager::new() {
if let Ok(batteries) = battery_manager.batteries() {
if batteries.count() == 0 {
return false;
}
}
if let Ok(battery_manager) = Manager::new()
&& let Ok(batteries) = battery_manager.batteries()
&& batteries.count() == 0
{
return false;
}
if args.battery.battery {
return true;
} else if let Some(flags) = &config.flags {
if let Some(battery) = flags.battery {
return battery;
}
} else if let Some(flags) = &config.flags
&& let Some(battery) = flags.battery
{
return battery;
}
false
@@ -1220,13 +1217,13 @@ fn get_network_unit_type(args: &BottomArgs, config: &Config) -> DataUnit {
if use_bytes {
return DataUnit::Byte;
}
} else if let Some(flags) = &config.flags {
if let Some(network_use_bytes) = flags.network_use_bytes {
deprecated_warning("network_use_bytes", "network_graph.use_bytes");
} else if let Some(flags) = &config.flags
&& let Some(network_use_bytes) = flags.network_use_bytes
{
deprecated_warning("network_use_bytes", "network_graph.use_bytes");
if network_use_bytes {
return DataUnit::Byte;
}
if network_use_bytes {
return DataUnit::Byte;
}
}
@@ -1240,13 +1237,13 @@ fn get_network_scale_type(args: &BottomArgs, config: &Config) -> AxisScaling {
if use_log {
return AxisScaling::Log;
}
} else if let Some(flags) = &config.flags {
if let Some(network_use_log) = flags.network_use_log {
deprecated_warning("network_use_log", "network_graph.use_log");
} else if let Some(flags) = &config.flags
&& let Some(network_use_log) = flags.network_use_log
{
deprecated_warning("network_use_log", "network_graph.use_log");
if network_use_log {
return AxisScaling::Log;
}
if network_use_log {
return AxisScaling::Log;
}
}
+8 -8
View File
@@ -86,10 +86,10 @@ impl Row {
}
} else {
// Check default flag
if let Some(default_widget_flag) = widget.default {
if default_widget_flag {
*default_widget_id = *iter_id;
}
if let Some(default_widget_flag) = widget.default
&& default_widget_flag
{
*default_widget_id = *iter_id;
}
}
@@ -144,10 +144,10 @@ impl Row {
}
} else {
// Check default flag
if let Some(default_widget_flag) = widget.default {
if default_widget_flag {
*default_widget_id = *iter_id;
}
if let Some(default_widget_flag) = widget.default
&& default_widget_flag
{
*default_widget_id = *iter_id;
}
}
+1 -4
View File
@@ -8,11 +8,8 @@ use crate::widgets::ProcColumn;
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct ProcessesConfig {
/// A list of process widget columns.
///
// TODO: make this more composable(?) in the future, we might need to
// rethink how it's done for custom widgets
#[serde(default)]
pub columns: Vec<ProcColumn>,
pub columns: Vec<ProcColumn>, // TODO: make this more composable(?) in the future, we might need to rethink how it's done for custom widgets
/// The default sort column.
#[serde(default)]
+4 -4
View File
@@ -261,10 +261,10 @@ impl Styles {
selected_border_colour
);
if let Some(widgets) = &config.widgets {
if let Some(widget_borders) = widgets.widget_border_type {
self.border_type = widget_borders.into();
}
if let Some(widgets) = &config.widgets
&& let Some(widget_borders) = widgets.widget_border_type
{
self.border_type = widget_borders.into();
}
Ok(())
+10 -10
View File
@@ -113,11 +113,11 @@ impl InputFieldState {
let mut index = 0;
for i in 0..(cursor_index + 1) {
if let Some(r) = self.size_mappings.get(&i) {
if r.start + available_width >= cursor_range.end {
index = i;
break;
}
if let Some(r) = self.size_mappings.get(&i)
&& r.start + available_width >= cursor_range.end
{
index = i;
break;
}
}
@@ -130,11 +130,11 @@ impl InputFieldState {
if cursor_range.start < start_range.end {
let mut index = 0;
for i in cursor_index..(self.current_query.len()) {
if let Some(r) = self.size_mappings.get(&i) {
if r.start + available_width >= cursor_range.end {
index = i;
break;
}
if let Some(r) = self.size_mappings.get(&i)
&& r.start + available_width >= cursor_range.end
{
index = i;
break;
}
}
index
+95 -98
View File
@@ -881,38 +881,38 @@ impl ProcWidgetState {
}
pub fn toggle_mem_percentage(&mut self) {
if let Some(index) = self.column_mapping.get_index_of(&ProcWidgetColumn::Mem) {
if let Some(mem) = self.get_mut_proc_col(index) {
match mem {
ProcColumn::MemValue => {
*mem = ProcColumn::MemPercent;
}
ProcColumn::MemPercent => {
*mem = ProcColumn::MemValue;
}
_ => unreachable!(),
if let Some(index) = self.column_mapping.get_index_of(&ProcWidgetColumn::Mem)
&& let Some(mem) = self.get_mut_proc_col(index)
{
match mem {
ProcColumn::MemValue => {
*mem = ProcColumn::MemPercent;
}
self.sort_table.set_data(self.column_text());
self.force_data_update();
ProcColumn::MemPercent => {
*mem = ProcColumn::MemValue;
}
_ => unreachable!(),
}
self.sort_table.set_data(self.column_text());
self.force_data_update();
}
#[cfg(feature = "gpu")]
if let Some(index) = self.column_mapping.get_index_of(&ProcWidgetColumn::GpuMem) {
if let Some(mem) = self.get_mut_proc_col(index) {
match mem {
ProcColumn::GpuMemValue => {
*mem = ProcColumn::GpuMemPercent;
}
ProcColumn::GpuMemPercent => {
*mem = ProcColumn::GpuMemValue;
}
_ => unreachable!(),
if let Some(index) = self.column_mapping.get_index_of(&ProcWidgetColumn::GpuMem)
&& let Some(mem) = self.get_mut_proc_col(index)
{
match mem {
ProcColumn::GpuMemValue => {
*mem = ProcColumn::GpuMemPercent;
}
self.sort_table.set_data(self.column_text());
self.force_data_update();
ProcColumn::GpuMemPercent => {
*mem = ProcColumn::GpuMemValue;
}
_ => unreachable!(),
}
self.sort_table.set_data(self.column_text());
self.force_data_update();
}
}
@@ -938,24 +938,24 @@ impl ProcWidgetState {
/// Marks the selected column as hidden, and automatically resets the
/// selected column to the default sort index and order.
fn hide_column(&mut self, column: ProcWidgetColumn) {
if let Some(index) = self.column_mapping.get_index_of(&column) {
if let Some(col) = self.table.columns.get_mut(index) {
col.set_hidden(true);
if let Some(index) = self.column_mapping.get_index_of(&column)
&& let Some(col) = self.table.columns.get_mut(index)
{
col.set_hidden(true);
if self.table.sort_index() == index {
self.table.set_sort_index(self.default_sort_index);
self.table.set_order(self.default_sort_order);
}
if self.table.sort_index() == index {
self.table.set_sort_index(self.default_sort_index);
self.table.set_order(self.default_sort_order);
}
}
}
/// Marks the selected column as shown.
fn show_column(&mut self, column: ProcWidgetColumn) {
if let Some(index) = self.column_mapping.get_index_of(&column) {
if let Some(col) = self.table.columns.get_mut(index) {
col.set_hidden(false);
}
if let Some(index) = self.column_mapping.get_index_of(&column)
&& let Some(col) = self.table.columns.get_mut(index)
{
col.set_hidden(false);
}
}
@@ -969,29 +969,29 @@ impl ProcWidgetState {
}
pub fn collapse_current_tree_branch_entry(&mut self) {
if let ProcWidgetMode::Tree(collapsed) = &mut self.mode {
if let Some(process) = self.table.current_item() {
collapsed.collapse(process.pid);
self.force_data_update();
}
if let ProcWidgetMode::Tree(collapsed) = &mut self.mode
&& let Some(process) = self.table.current_item()
{
collapsed.collapse(process.pid);
self.force_data_update();
}
}
pub fn expand_current_tree_branch_entry(&mut self) {
if let ProcWidgetMode::Tree(collapsed) = &mut self.mode {
if let Some(process) = self.table.current_item() {
collapsed.expand(process.pid);
self.force_data_update();
}
if let ProcWidgetMode::Tree(collapsed) = &mut self.mode
&& let Some(process) = self.table.current_item()
{
collapsed.expand(process.pid);
self.force_data_update();
}
}
pub fn toggle_current_tree_branch_entry(&mut self) {
if let ProcWidgetMode::Tree(collapsed) = &mut self.mode {
if let Some(process) = self.table.current_item() {
collapsed.toggle(process.pid);
self.force_data_update();
}
if let ProcWidgetMode::Tree(collapsed) = &mut self.mode
&& let Some(process) = self.table.current_item()
{
collapsed.toggle(process.pid);
self.force_data_update();
}
}
@@ -999,30 +999,29 @@ impl ProcWidgetState {
if let Some(index) = self
.column_mapping
.get_index_of(&ProcWidgetColumn::ProcNameOrCommand)
&& let Some(col) = self.table.columns.get_mut(index)
{
if let Some(col) = self.table.columns.get_mut(index) {
let inner = col.inner_mut();
match inner {
ProcColumn::Name => {
*inner = ProcColumn::Command;
if let ColumnWidthBounds::Soft { max_percentage, .. } = col.bounds_mut() {
*max_percentage = Some(0.5);
}
let inner = col.inner_mut();
match inner {
ProcColumn::Name => {
*inner = ProcColumn::Command;
if let ColumnWidthBounds::Soft { max_percentage, .. } = col.bounds_mut() {
*max_percentage = Some(0.5);
}
ProcColumn::Command => {
*inner = ProcColumn::Name;
if let ColumnWidthBounds::Soft { max_percentage, .. } = col.bounds_mut() {
*max_percentage = match self.mode {
ProcWidgetMode::Tree { .. } => Some(0.5),
ProcWidgetMode::Grouped | ProcWidgetMode::Normal => Some(0.3),
};
}
}
_ => unreachable!(),
}
self.sort_table.set_data(self.column_text());
self.force_rerender_and_update();
ProcColumn::Command => {
*inner = ProcColumn::Name;
if let ColumnWidthBounds::Soft { max_percentage, .. } = col.bounds_mut() {
*max_percentage = match self.mode {
ProcWidgetMode::Tree { .. } => Some(0.5),
ProcWidgetMode::Grouped | ProcWidgetMode::Normal => Some(0.3),
};
}
}
_ => unreachable!(),
}
self.sort_table.set_data(self.column_text());
self.force_rerender_and_update();
}
}
@@ -1038,37 +1037,35 @@ impl ProcWidgetState {
/// State columns should be re-enabled, and the mode switched to
/// [`ProcWidgetMode::Normal`].
pub fn toggle_tab(&mut self) {
if !matches!(self.mode, ProcWidgetMode::Tree { .. }) {
if let Some(index) = self
if !matches!(self.mode, ProcWidgetMode::Tree { .. })
&& let Some(index) = self
.column_mapping
.get_index_of(&ProcWidgetColumn::PidOrCount)
{
if let Some(sort_col) = self.table.columns.get_mut(index) {
let col = sort_col.inner_mut();
match col {
ProcColumn::Pid => {
*col = ProcColumn::Count;
sort_col.default_order = SortOrder::Descending;
&& let Some(sort_col) = self.table.columns.get_mut(index)
{
let col = sort_col.inner_mut();
match col {
ProcColumn::Pid => {
*col = ProcColumn::Count;
sort_col.default_order = SortOrder::Descending;
self.hide_column(ProcWidgetColumn::User);
self.hide_column(ProcWidgetColumn::State);
self.mode = ProcWidgetMode::Grouped;
}
ProcColumn::Count => {
*col = ProcColumn::Pid;
sort_col.default_order = SortOrder::Ascending;
self.show_column(ProcWidgetColumn::User);
self.show_column(ProcWidgetColumn::State);
self.mode = ProcWidgetMode::Normal;
}
_ => unreachable!(),
}
self.sort_table.set_data(self.column_text());
self.force_rerender_and_update();
self.hide_column(ProcWidgetColumn::User);
self.hide_column(ProcWidgetColumn::State);
self.mode = ProcWidgetMode::Grouped;
}
ProcColumn::Count => {
*col = ProcColumn::Pid;
sort_col.default_order = SortOrder::Ascending;
self.show_column(ProcWidgetColumn::User);
self.show_column(ProcWidgetColumn::State);
self.mode = ProcWidgetMode::Normal;
}
_ => unreachable!(),
}
self.sort_table.set_data(self.column_text());
self.force_rerender_and_update();
}
}
+25 -25
View File
@@ -392,36 +392,36 @@ impl QueryProcessor for Prefix {
}
}
if let Some(condition) = condition {
if let Some(read_value) = value {
// Note that the values *might* have a unit or need to be parsed
// differently based on the
// prefix type!
if let Some(condition) = condition
&& let Some(read_value) = value
{
// Note that the values *might* have a unit or need to be parsed
// differently based on the
// prefix type!
// TODO: Support this without spaces?
// TODO: Support this without spaces?
let mut value = read_value;
let mut value = read_value;
match prefix_type {
PrefixType::MemBytes
| PrefixType::ReadPerSecond
| PrefixType::WritePerSecond
| PrefixType::TotalRead
| PrefixType::TotalWrite => {
process_prefix_units(query, &mut value);
}
#[cfg(feature = "gpu")]
PrefixType::GpuMemoryBytes => {
process_prefix_units(query, &mut value);
}
_ => {}
match prefix_type {
PrefixType::MemBytes
| PrefixType::ReadPerSecond
| PrefixType::WritePerSecond
| PrefixType::TotalRead
| PrefixType::TotalWrite => {
process_prefix_units(query, &mut value);
}
return Ok(Prefix::Attribute(new_numerical_attribute(
prefix_type,
NumericalQuery { condition, value },
)?));
#[cfg(feature = "gpu")]
PrefixType::GpuMemoryBytes => {
process_prefix_units(query, &mut value);
}
_ => {}
}
return Ok(Prefix::Attribute(new_numerical_attribute(
prefix_type,
NumericalQuery { condition, value },
)?));
}
}
}