Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: option to have process tree entries be collapsed by default #1627

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/content/configuration/command-line-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ see information on these options by running `btm -h`, or run `btm --help` to dis
| `-T, --tree` | Makes the process widget use tree mode by default. |
| `-n, --unnormalized_cpu` | Show process CPU% usage without averaging over the number of CPU cores. |
| `-W, --whole_word` | Enables whole-word matching by default while searching. |
| `--tree_collapse` | Collapse process tree by default. |

## Temperature Options

Expand Down
1 change: 1 addition & 0 deletions docs/content/configuration/config-file/flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ each time:
| `memory_legend` | String (one of ["none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right"]) | Where to place the legend for the memory widget. |
| `network_legend` | String (one of ["none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right"]) | Where to place the legend for the network widget. |
| `average_cpu_row` | Boolean | Moves the average CPU usage entry to its own row when using basic mode. |
| `tree_collapse` | Boolean | Collapse process tree by default. |
2 changes: 2 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub struct AppConfigFields {
pub network_use_binary_prefix: bool,
pub retention_ms: u64,
pub dedicated_average_row: bool,
pub tree_collapse: bool,
}

/// For filtering out information
Expand Down Expand Up @@ -530,6 +531,7 @@ impl App {
ProcWidgetMode::Normal => {
proc_widget_state.mode = ProcWidgetMode::Tree {
collapsed_pids: Default::default(),
collapse: self.app_config_fields.tree_collapse,
};
proc_widget_state.force_rerender_and_update();
}
Expand Down
3 changes: 3 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ pub(crate) fn init_app(
let is_default_command = is_flag_enabled!(process_command, args.process, config);
let is_advanced_kill = !(is_flag_enabled!(disable_advanced_kill, args.process, config));
let process_memory_as_value = is_flag_enabled!(process_memory_as_value, args.process, config);
let tree_collapse = is_flag_enabled!(tree_collapse, args.process, config);

// For CPU
let default_cpu_selection = get_default_cpu_selection(args, config);
Expand Down Expand Up @@ -305,6 +306,7 @@ pub(crate) fn init_app(
network_use_binary_prefix,
retention_ms,
dedicated_average_row: get_dedicated_avg_row(config),
tree_collapse,
};

let table_config = ProcTableConfig {
Expand Down Expand Up @@ -384,6 +386,7 @@ pub(crate) fn init_app(
} else if is_default_tree {
ProcWidgetMode::Tree {
collapsed_pids: Default::default(),
collapse: tree_collapse,
}
} else {
ProcWidgetMode::Normal
Expand Down
7 changes: 7 additions & 0 deletions src/options/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,13 @@ pub struct ProcessArgs {
help = "Enables whole-word matching by default while searching."
)]
pub whole_word: bool,

#[arg(
long,
action = ArgAction::SetTrue,
help = "Collapse process tree by default."
)]
pub tree_collapse: bool,
}

/// Temperature arguments/config options.
Expand Down
1 change: 1 addition & 0 deletions src/options/config/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ pub(crate) struct FlagConfig {
pub(crate) enable_cache_memory: Option<bool>,
pub(crate) retention: Option<StringOrNum>,
pub(crate) average_cpu_row: Option<bool>,
pub(crate) tree_collapse: Option<bool>,
}
51 changes: 33 additions & 18 deletions src/widgets/process_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ impl ProcessSearchState {

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ProcWidgetMode {
Tree { collapsed_pids: HashSet<Pid> },
Tree {
collapsed_pids: HashSet<Pid>,
collapse: bool,
},
Grouped,
Normal,
}
Expand Down Expand Up @@ -400,15 +403,16 @@ impl ProcWidgetState {
ProcWidgetMode::Grouped | ProcWidgetMode::Normal => {
self.get_normal_data(&data_collection.process_data.process_harvest)
}
ProcWidgetMode::Tree { collapsed_pids } => {
self.get_tree_data(collapsed_pids, data_collection)
}
ProcWidgetMode::Tree {
collapsed_pids,
collapse,
} => self.get_tree_data(collapsed_pids, data_collection, collapse),
};
self.table.set_data(data);
}

fn get_tree_data(
&self, collapsed_pids: &HashSet<Pid>, data_collection: &DataCollection,
&self, collapsed_pids: &HashSet<Pid>, data_collection: &DataCollection, collapse: &bool,
) -> Vec<ProcWidgetData> {
const BRANCH_END: char = '└';
const BRANCH_SPLIT: char = '├';
Expand Down Expand Up @@ -567,8 +571,18 @@ impl ProcWidgetState {
let disabled = !kept_pids.contains(&process.pid);
let is_last = *siblings_left == 0;

if collapsed_pids.contains(&process.pid) {
if collapsed_pids.contains(&process.pid).eq(&!collapse) {
let mut summed_process = process.clone();
let mut prefix = if prefixes.is_empty() {
String::default()
} else {
format!(
"{}{}{} ",
prefixes.join(""),
if is_last { BRANCH_END } else { BRANCH_SPLIT },
BRANCH_HORIZONTAL
)
};

if let Some(children_pids) = filtered_tree.get(&process.pid) {
let mut sum_queue = children_pids
Expand All @@ -591,19 +605,20 @@ impl ProcWidgetState {
}));
}
}
if !children_pids.is_empty() {
prefix = if prefixes.is_empty() {
"+ ".to_string()
} else {
format!(
"{}{}{} + ",
prefixes.join(""),
if is_last { BRANCH_END } else { BRANCH_SPLIT },
BRANCH_HORIZONTAL
)
};
}
}

let prefix = if prefixes.is_empty() {
"+ ".to_string()
} else {
format!(
"{}{}{} + ",
prefixes.join(""),
if is_last { BRANCH_END } else { BRANCH_SPLIT },
BRANCH_HORIZONTAL
)
};

data.push(summed_process.prefix(Some(prefix)).disabled(disabled));
} else {
let prefix = if prefixes.is_empty() {
Expand Down Expand Up @@ -817,7 +832,7 @@ impl ProcWidgetState {
}

pub fn toggle_current_tree_branch_entry(&mut self) {
if let ProcWidgetMode::Tree { collapsed_pids } = &mut self.mode {
if let ProcWidgetMode::Tree { collapsed_pids, .. } = &mut self.mode {
if let Some(process) = self.table.current_item() {
let pid = process.pid;

Expand Down
Loading