feature: allow left to collapse trees and right to expand them (#1306)

Allow using the left arrow to collapse a tree branch in the process widget, or a right arrow to expand it.

---------

Co-authored-by: Clement Tsang <34804052+ClementTsang@users.noreply.github.com>
This commit is contained in:
Yuri Astrakhan 2025-04-21 02:59:51 -04:00 committed by ClementTsang
parent 86b7ef331e
commit 729f714bf9
No known key found for this signature in database
GPG Key ID: DC3B7867D8D97095
5 changed files with 49 additions and 4 deletions

View File

@ -28,6 +28,7 @@ That said, these are more guidelines rather than hardset rules, though the proje
- [#1641](https://github.com/ClementTsang/bottom/pull/1641): Support AMD GPU data collection on Linux.
- [#1642](https://github.com/ClementTsang/bottom/pull/1642): Support changing the widget borders.
- [#1717](https://github.com/ClementTsang/bottom/pull/1717): Support delete key (fn + delete on macOS) to kill processes.
- [#1306](https://github.com/ClementTsang/bottom/pull/1306): Support using left/right key to collapse/expand process trees respectively.
### Bug Fixes

View File

@ -99,7 +99,9 @@ Pressing ++t++ or ++f5++ in the table toggles tree mode in the process widget, d
<img src="../../../assets/screenshots/process/process_tree.webp" alt="A picture of tree mode in a process widget."/>
</figure>
A process in tree mode can also be "collapsed", hiding its children and any descendants, using either the ++minus++ or ++plus++ keys, or double-clicking on an entry.
A process in tree mode can also be "collapsed", hiding its children and any descendants, using the either the ++minus++,
++plus++, or ++left++ keys, or clicking on an entry. It can be expanded by using the ++minus++, ++plus++, or ++right++
keys, or by clicking on the entry again.
!!! info

View File

@ -687,6 +687,15 @@ impl App {
pub fn on_left_key(&mut self) {
if !self.is_in_dialog() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => {
if let Some(proc_widget_state) = self
.states
.proc_state
.get_mut_widget_state(self.current_widget.widget_id)
{
proc_widget_state.collapse_current_tree_branch_entry();
}
}
BottomWidgetType::ProcSearch => {
let is_in_search_widget = self.is_in_search_widget();
if let Some(proc_widget_state) = self
@ -749,6 +758,15 @@ impl App {
pub fn on_right_key(&mut self) {
if !self.is_in_dialog() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => {
if let Some(proc_widget_state) = self
.states
.proc_state
.get_mut_widget_state(self.current_widget.widget_id)
{
proc_widget_state.expand_current_tree_branch_entry();
}
}
BottomWidgetType::ProcSearch => {
let is_in_search_widget = self.is_in_search_widget();
if let Some(proc_widget_state) = self

View File

@ -77,9 +77,9 @@ const CPU_HELP_TEXT: [&str; 2] = [
"Mouse scroll Scrolling over an CPU core/average shows only that entry on the chart",
];
const PROCESS_HELP_TEXT: [&str; 17] = [
const PROCESS_HELP_TEXT: [&str; 19] = [
"3 - Process widget",
"dd, F9 Kill the selected process",
"dd, F9, Delete Kill the selected process",
"c Sort by CPU usage, press again to reverse",
"m Sort by memory usage, press again to reverse",
"p Sort by PID name, press again to reverse",
@ -91,7 +91,9 @@ const PROCESS_HELP_TEXT: [&str; 17] = [
"I Invert current sort",
"% Toggle between values and percentages for memory usage",
"t, F5 Toggle tree mode",
"+, -, click Collapse/expand a branch while in tree mode",
"Right Collapse a branch while in tree mode",
"Left Expand a branch while in tree mode",
"+, -, click Toggle whether a branch is expanded or collapsed in tree mode",
"click on header Sorts the entries by that column, click again to invert the sort",
"C Sort by GPU usage, press again to reverse",
"M Sort by GPU memory usage, press again to reverse",

View File

@ -817,6 +817,28 @@ impl ProcWidgetState {
}
}
pub fn collapse_current_tree_branch_entry(&mut self) {
if let ProcWidgetMode::Tree { collapsed_pids } = &mut self.mode {
if let Some(process) = self.table.current_item() {
let pid = process.pid;
collapsed_pids.insert(pid);
self.force_data_update();
}
}
}
pub fn expand_current_tree_branch_entry(&mut self) {
if let ProcWidgetMode::Tree { collapsed_pids } = &mut self.mode {
if let Some(process) = self.table.current_item() {
let pid = process.pid;
collapsed_pids.remove(&pid);
self.force_data_update();
}
}
}
pub fn toggle_current_tree_branch_entry(&mut self) {
if let ProcWidgetMode::Tree { collapsed_pids } = &mut self.mode {
if let Some(process) = self.table.current_item() {