feature: Allow toggling advanced kill menu (#408)

Allows toggling the advanced kill menu via --advanced_kill or advanced_kill=true.
This commit is contained in:
Clement Tsang 2021-02-15 22:23:22 -05:00 committed by GitHub
parent fb7b1226fd
commit e437b14922
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 398 additions and 356 deletions

15
.vscode/settings.json vendored
View File

@ -1,6 +1,9 @@
{
"cSpell.words": [
"ABRT",
"ALRM",
"Artem",
"CHLD",
"COPR",
"Condvar",
"DWORD",
@ -8,10 +11,12 @@
"EINVAL",
"EPERM",
"ESRCH",
"Erlend",
"Fini",
"GIBI",
"GIBIBYTE",
"GIGA",
"Hamberg",
"KIBI",
"Lukas",
"MEBI",
@ -25,15 +30,25 @@
"PKGBUILDs",
"Polishchuk",
"Qudsi",
"RTMAX",
"RTMIN",
"Rysavy",
"SEGV",
"SIGTERM",
"STKFLT",
"TEBI",
"TERA",
"TSTP",
"TTIN",
"TTOU",
"Tebibytes",
"Toolset",
"Ungrouped",
"VTALRM",
"WASD",
"Wojnarowski",
"XCPU",
"XFSZ",
"aarch",
"andys",
"armhf",

View File

@ -247,37 +247,38 @@ Run using `btm`.
Use `btm --help` for more information.
```
--advanced_kill Shows more options when killing a process on Unix-like systems.
--autohide_time Temporarily shows the time scale in graphs.
-b, --basic Hides graphs and uses a more basic look.
-b, --basic Hides graphs and uses a more basic look.
--battery Shows the battery widget.
-S, --case_sensitive Enables case sensitivity by default.
-c, --celsius Sets the temperature type to Celsius.
-S, --case_sensitive Enables case sensitivity by default.
-c, --celsius Sets the temperature type to Celsius.
--color <COLOR SCHEME> Use a color scheme, use --help for supported values.
--process_command Show processes as their commands by default.
-C, --config <CONFIG PATH> Sets the location of the config file.
-u, --current_usage Sets process CPU% to be based on current CPU%.
-t, --default_time_value <MS> Default time value for graphs in ms.
-C, --config <CONFIG PATH> Sets the location of the config file.
-u, --current_usage Sets process CPU% to be based on current CPU%.
-t, --default_time_value <MS> Default time value for graphs in ms.
--default_widget_count <INT> Sets the n'th selected widget type as the default.
--default_widget_type <WIDGET TYPE> Sets which widget type to use as the default widget.
--default_widget_type <WIDGET TYPE> Sets the default widget type, use --help for more info.
--disable_click Disables mouse clicks.
-m, --dot_marker Uses a dot marker for graphs.
-f, --fahrenheit Sets the temperature type to Fahrenheit.
-g, --group Groups processes with the same name by default.
-h, --help Prints help information. Use --help for more info.
-a, --hide_avg_cpu Hides the average CPU usage.
-m, --dot_marker Uses a dot marker for graphs.
-f, --fahrenheit Sets the temperature type to Fahrenheit.
-g, --group Groups processes with the same name by default.
-h, --help Prints help information. Use --help for more info.
-a, --hide_avg_cpu Hides the average CPU usage.
--hide_table_gap Hides the spacing between table headers and entries.
--hide_time Completely hides the time scaling.
-k, --kelvin Sets the temperature type to Kelvin.
-l, --left_legend Puts the CPU chart legend to the left side.
-k, --kelvin Sets the temperature type to Kelvin.
-l, --left_legend Puts the CPU chart legend to the left side.
--mem_as_value Defaults to showing process memory usage by value.
-r, --rate <MS> Sets a refresh rate in ms.
-R, --regex Enables regex by default.
--show_table_scroll_position Shows the scroll position tracker in table widgets
-d, --time_delta <MS> The amount in ms changed upon zooming.
-T, --tree Defaults to showing the process widget in tree mode.
--process_command Show processes as their commands by default.
-r, --rate <MS> Sets a refresh rate in ms.
-R, --regex Enables regex by default.
--show_table_scroll_position Shows the scroll position tracker in table widgets.
-d, --time_delta <MS> The amount in ms changed upon zooming.
-T, --tree Defaults to showing the process widget in tree mode.
--use_old_network_legend DEPRECATED - uses the older network legend.
-V, --version Prints version information.
-W, --whole_word Enables whole-word matching by default.
-V, --version Prints version information.
-W, --whole_word Enables whole-word matching by default.
```
### Keybindings
@ -564,7 +565,7 @@ The following options can be set under `[flags]` to achieve the same effect as p
These are the following supported flag config values, which correspond to the flag of the same name described in [Flags](#flags):
| Field | Type | Functionality |
| ---------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| ---------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `hide_avg_cpu` | Boolean | Hides the average CPU usage. |
| `dot_marker` | Boolean | Uses a dot marker for graphs. |
| `left_legend` | Boolean | Puts the CPU chart legend to the left side. |
@ -588,6 +589,7 @@ These are the following supported flag config values, which correspond to the fl
| `tree` | Boolean | Defaults to showing the process widget in tree mode. |
| `show_table_scroll_position` | Boolean | Shows the scroll position tracker in table widgets. |
| `process_command` | Boolean | Show processes as their commands by default. |
| `advanced_kill` | Boolean | Shows more options when killing a process on Unix-like systems. |
#### Theming

View File

@ -54,6 +54,7 @@ pub struct AppConfigFields {
pub disable_click: bool,
pub no_write: bool,
pub show_table_scroll_position: bool,
pub is_advanced_kill: bool,
}
/// For filtering out information
@ -858,7 +859,13 @@ impl App {
#[cfg(target_os = "windows")]
self.on_right_key();
#[cfg(target_family = "unix")]
{
if self.app_config_fields.is_advanced_kill {
self.on_left_key();
} else {
self.on_right_key();
}
}
return;
}
self.reset_multi_tap_keys();
@ -874,7 +881,13 @@ impl App {
#[cfg(target_os = "windows")]
self.on_left_key();
#[cfg(target_family = "unix")]
{
if self.app_config_fields.is_advanced_kill {
self.on_right_key();
} else {
self.on_left_key();
}
}
return;
}
self.reset_multi_tap_keys();
@ -884,20 +897,6 @@ impl App {
if self.is_config_open {
} else if !self.is_in_dialog() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => {
// if let Some(proc_widget_state) = self
// .proc_state
// .get_mut_widget_state(self.current_widget.widget_id)
// {
// proc_widget_state.current_column_index =
// proc_widget_state.current_column_index.saturating_sub(1);
// debug!(
// "Current column index <: {}",
// proc_widget_state.current_column_index
// );
// }
}
BottomWidgetType::ProcSearch => {
let is_in_search_widget = self.is_in_search_widget();
if let Some(proc_widget_state) = self
@ -943,6 +942,7 @@ impl App {
} else if self.delete_dialog_state.is_showing_dd {
#[cfg(target_family = "unix")]
{
if self.app_config_fields.is_advanced_kill {
match self.delete_dialog_state.selected_signal {
KillSignal::KILL(prev_signal) => {
self.delete_dialog_state.selected_signal = match prev_signal - 1 {
@ -952,8 +952,11 @@ impl App {
signal => KillSignal::KILL(signal),
};
}
KillSignal::CANCEL => (),
KillSignal::CANCEL => {}
};
} else {
self.delete_dialog_state.selected_signal = KillSignal::default();
}
}
#[cfg(target_os = "windows")]
{
@ -966,22 +969,6 @@ impl App {
if self.is_config_open {
} else if !self.is_in_dialog() {
match self.current_widget.widget_type {
BottomWidgetType::Proc => {
// if let Some(proc_widget_state) = self
// .proc_state
// .get_mut_widget_state(self.current_widget.widget_id)
// {
// if proc_widget_state.current_column_index
// < proc_widget_state.columns.get_enabled_columns()
// {
// proc_widget_state.current_column_index += 1;
// }
// debug!(
// "Current column index >: {}",
// proc_widget_state.current_column_index
// );
// }
}
BottomWidgetType::ProcSearch => {
let is_in_search_widget = self.is_in_search_widget();
if let Some(proc_widget_state) = self
@ -1031,6 +1018,7 @@ impl App {
} else if self.delete_dialog_state.is_showing_dd {
#[cfg(target_family = "unix")]
{
if self.app_config_fields.is_advanced_kill {
let new_signal = match self.delete_dialog_state.selected_signal {
KillSignal::CANCEL => 1,
// 32+33 are skipped
@ -1042,6 +1030,9 @@ impl App {
KillSignal::KILL(signal) => signal + 1,
};
self.delete_dialog_state.selected_signal = KillSignal::KILL(new_signal);
} else {
self.delete_dialog_state.selected_signal = KillSignal::CANCEL;
}
}
#[cfg(target_os = "windows")]
{

View File

@ -381,15 +381,15 @@ impl Painter {
} else {
terminal_width * 50 / 100
};
let text_height;
#[cfg(target_family = "unix")]
let text_height = if cfg!(target_os = "windows")
|| !app_state.app_config_fields.is_advanced_kill
{
text_height = 22;
}
#[cfg(target_os = "windows")]
{
text_height = 7;
}
7
} else {
22
};
// let (text_width, text_height) = if let Some(dd_text) = &dd_text {
// let width = if current_width < 100 {
// current_width * 90 / 100

View File

@ -67,10 +67,10 @@ impl KillDialog for Painter {
None
}
#[cfg(target_os = "windows")]
fn draw_dd_confirm_buttons<B: Backend>(
&self, f: &mut Frame<'_, B>, button_draw_loc: &Rect, app_state: &mut App,
) {
if cfg!(target_os = "windows") || !app_state.app_config_fields.is_advanced_kill {
let (yes_button, no_button) = match app_state.delete_dialog_state.selected_signal {
KillSignal::KILL(_) => (
Span::styled("Yes", self.colours.currently_selected_text_style),
@ -125,12 +125,9 @@ impl KillDialog for Painter {
),
];
}
}
} else {
#[cfg(target_family = "unix")]
fn draw_dd_confirm_buttons<B: Backend>(
&self, f: &mut Frame<'_, B>, button_draw_loc: &Rect, app_state: &mut App,
) {
{
let signal_text;
#[cfg(target_os = "linux")]
{
@ -277,8 +274,8 @@ impl KillDialog for Painter {
};
let scroll_offset: usize = app_state.delete_dialog_state.scroll_pos;
let mut buttons = signal_text
[scroll_offset + 1..min((layout.len() as usize) + scroll_offset, signal_text.len())]
let mut buttons = signal_text[scroll_offset + 1
..min((layout.len() as usize) + scroll_offset, signal_text.len())]
.iter()
.map(|text| Span::raw(*text))
.collect::<Vec<Span<'_>>>();
@ -306,6 +303,8 @@ impl KillDialog for Painter {
f.render_widget(Paragraph::new(btn).alignment(Alignment::Left), pos);
}
}
}
}
fn draw_dd_dialog<B: Backend>(
&self, f: &mut Frame<'_, B>, dd_text: Option<Text<'_>>, app_state: &mut App, draw_loc: Rect,
@ -356,15 +355,13 @@ impl KillDialog for Painter {
draw_loc,
);
let btn_height;
#[cfg(target_family = "unix")]
{
btn_height = 20;
}
#[cfg(target_os = "windows")]
{
btn_height = 3;
}
let btn_height =
if cfg!(target_os = "windows") || !app_state.app_config_fields.is_advanced_kill {
3
} else {
20
};
// Now draw buttons if needed...
let split_draw_loc = Layout::default()
.direction(Direction::Vertical)

View File

@ -106,6 +106,7 @@ rather than total CPU usage.\n\n",
"\
Disables mouse clicks from interacting with the program.\n\n",
);
let dot_marker = Arg::with_name("dot_marker")
.short("m")
.long("dot_marker")
@ -115,6 +116,7 @@ Disables mouse clicks from interacting with the program.\n\n",
Uses a dot marker for graphs as opposed to the default braille
marker.\n\n",
);
let group = Arg::with_name("group") // FIXME: Rename this to something like "group_process", would be "breaking" though.
.short("g")
.long("group")
@ -123,6 +125,7 @@ marker.\n\n",
"\
Groups processes with the same name by default.\n\n",
);
let hide_avg_cpu = Arg::with_name("hide_avg_cpu")
.short("a")
.long("hide_avg_cpu")
@ -131,6 +134,7 @@ Groups processes with the same name by default.\n\n",
"\
Hides the average CPU usage from being shown.\n\n",
);
let hide_table_gap = Arg::with_name("hide_table_gap")
.long("hide_table_gap")
.help("Hides the spacing between table headers and entries.")
@ -138,6 +142,7 @@ Hides the average CPU usage from being shown.\n\n",
"\
Hides the spacing between table headers and entries.\n\n",
);
let hide_time = Arg::with_name("hide_time")
.long("hide_time")
.help("Completely hides the time scaling.")
@ -145,6 +150,7 @@ Hides the spacing between table headers and entries.\n\n",
"\
Completely hides the time scaling from being shown.\n\n",
);
let process_command = Arg::with_name("process_command")
.long("process_command")
.help("Show processes as their commands by default.")
@ -153,6 +159,7 @@ Completely hides the time scaling from being shown.\n\n",
Show processes as their commands by default in the process widget.
",
);
let left_legend = Arg::with_name("left_legend")
.short("l")
.long("left_legend")
@ -161,6 +168,7 @@ Completely hides the time scaling from being shown.\n\n",
"\
Puts the CPU chart legend to the left side rather than the right side.\n\n",
);
// let no_write = Arg::with_name("no_write")
// .long("no_write")
// .help("Disables writing to the config file.")
@ -168,6 +176,7 @@ Puts the CPU chart legend to the left side rather than the right side.\n\n",
// "\
// Disables config changes in-app from writing to the config file.",
// );
let regex = Arg::with_name("regex")
.short("R")
.long("regex")
@ -176,6 +185,15 @@ Puts the CPU chart legend to the left side rather than the right side.\n\n",
"\
When searching for a process, enables regex by default.\n\n",
);
let advanced_kill = Arg::with_name("advanced_kill")
.long("advanced_kill")
.help("Shows more options when killing a process on Unix-like systems.")
.long_help(
"\
Shows more options when killing a process on Unix-like systems.\n\n",
);
let show_table_scroll_position = Arg::with_name("show_table_scroll_position")
.long("show_table_scroll_position")
.help("Shows the scroll position tracker in table widgets.")
@ -183,6 +201,7 @@ When searching for a process, enables regex by default.\n\n",
"\
Shows the list scroll position tracker in the widget title for table widgets.\n\n",
);
let use_old_network_legend = Arg::with_name("use_old_network_legend")
.long("use_old_network_legend")
.help("DEPRECATED - uses the older network legend.")
@ -191,6 +210,7 @@ When searching for a process, enables regex by default.\n\n",
DEPRECATED - uses the older (pre-0.4) network widget legend.
This display is not tested anymore and could be broken.\n\n\n",
);
let whole_word = Arg::with_name("whole_word")
.short("W")
.long("whole_word")
@ -396,6 +416,7 @@ Defaults to showing the process widget in tree mode.\n\n",
.arg(hide_time)
.arg(show_table_scroll_position)
.arg(left_legend)
.arg(advanced_kill)
// .arg(no_write)
.arg(rate)
.arg(regex)

View File

@ -154,6 +154,9 @@ pub struct ConfigFlags {
#[builder(default, setter(strip_option))]
pub process_command: Option<bool>,
#[builder(default, setter(strip_option))]
pub advanced_kill: Option<bool>,
}
#[derive(Clone, Default, Debug, Deserialize, Serialize)]
@ -260,6 +263,7 @@ pub fn build_app(
let show_memory_as_values = get_mem_as_value(matches, config);
let is_default_tree = get_is_default_tree(matches, config);
let is_default_command = get_is_default_process_command(matches, config);
let is_advanced_kill = get_is_using_advanced_kill(matches, config);
for row in &widget_layout.rows {
for col in &row.children {
@ -399,6 +403,7 @@ pub fn build_app(
// no_write: get_no_write(matches, config),
no_write: false,
show_table_scroll_position: get_show_table_scroll_position(matches, config),
is_advanced_kill,
};
let used_widgets = UsedWidgets {
@ -1015,3 +1020,14 @@ fn get_is_default_process_command(matches: &clap::ArgMatches<'static>, config: &
}
false
}
fn get_is_using_advanced_kill(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
if matches.is_present("advanced_kill") {
return true;
} else if let Some(flags) = &config.flags {
if let Some(advanced_kill) = flags.advanced_kill {
return advanced_kill;
}
}
false
}