diff --git a/Cargo.toml b/Cargo.toml index 56531927..3fd5637e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,10 @@ edition = "2021" opt-level = 1 [profile.release] -opt-level = 3 -strip = true +codegen-units = 1 lto = true +strip = true +opt-level = 3 [dependencies] adw = { version = "0.7.0", features = ["v1_5"], package = "libadwaita" } diff --git a/src/application.rs b/src/application.rs index fdc399b3..82b0867a 100644 --- a/src/application.rs +++ b/src/application.rs @@ -292,7 +292,7 @@ impl Application { ); } - ApplicationExtManual::run(self); + ApplicationExtManual::run_with_args::<&str>(self, &[]); } } diff --git a/src/bin/resources-adjust.rs b/src/bin/resources-adjust.rs index b905cb5e..ffcee624 100644 --- a/src/bin/resources-adjust.rs +++ b/src/bin/resources-adjust.rs @@ -21,12 +21,10 @@ fn main() { // find tasks that belong to this process let tasks_path = PathBuf::from("/proc/").join(pid.to_string()).join("task"); - for entry in std::fs::read_dir(tasks_path).unwrap() { - if let Ok(entry) = entry { - let thread_id = entry.file_name().to_string_lossy().parse().unwrap(); + for entry in std::fs::read_dir(tasks_path).unwrap().flatten() { + let thread_id = entry.file_name().to_string_lossy().parse().unwrap(); - adjust(thread_id, nice, &cpu_set); - } + adjust(thread_id, nice, &cpu_set); } std::process::exit(0) @@ -49,5 +47,5 @@ fn adjust(id: i32, nice: i32, cpu_set: &CpuSet) { std::process::exit(error) } - let _ = sched_setaffinity(Pid::from_raw(id), &cpu_set); + let _ = sched_setaffinity(Pid::from_raw(id), cpu_set); } diff --git a/src/gui.rs b/src/gui.rs index 638f648e..9ab9f786 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1,4 +1,5 @@ use std::ffi::OsString; +use std::sync::LazyLock; use crate::application; #[rustfmt::skip] @@ -6,13 +7,58 @@ use crate::config; use crate::utils::app::DATA_DIRS; use crate::utils::IS_FLATPAK; +use clap::{command, Parser}; use gettextrs::{gettext, LocaleCategory}; use gtk::{gio, glib}; use self::application::Application; use self::config::{GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE}; +pub static ARGS: LazyLock = LazyLock::new(Args::parse); + +#[derive(Parser, Debug)] +#[command(version, about)] +pub struct Args { + /// Disable GPU monitoring + #[arg(short = 'g', long, default_value_t = false)] + pub disable_gpu_monitoring: bool, + + /// Disable network interface monitoring + #[arg(short = 'n', long, default_value_t = false)] + pub disable_network_interface_monitoring: bool, + + /// Disable drive monitoring + #[arg(short = 'd', long, default_value_t = false)] + pub disable_drive_monitoring: bool, + + /// Disable battery monitoring + #[arg(short = 'b', long, default_value_t = false)] + pub disable_battery_monitoring: bool, + + /// Disable CPU monitoring + #[arg(short = 'c', long, default_value_t = false)] + pub disable_cpu_monitoring: bool, + + /// Disable memory monitoring + #[arg(short = 'm', long, default_value_t = false)] + pub disable_memory_monitoring: bool, + + /// Disable process monitoring + #[arg(short = 'p', long, default_value_t = false)] + pub disable_process_monitoring: bool, + + /// Open tab specified by ID. + /// Valid IDs are: "applications", "processes", "cpu", "memory", "gpu-$PCI_SLOT$", + /// "drive-$MODEL_NAME_OR_DEVICE_NAME$", "network-$INTERFACE_NAME$", + /// "battery-$MANUFACTURER$-$MODEL_NAME$-$DEVICE_NAME$" + #[arg(short = 't', long)] + pub open_tab_id: Option, +} + pub fn main() { + // Force args parsing here so we don't start printing logs before printing the help page + std::hint::black_box(ARGS.disable_battery_monitoring); + // Initialize logger pretty_env_logger::init(); diff --git a/src/ui/pages/applications/mod.rs b/src/ui/pages/applications/mod.rs index 830244c6..5253bc1a 100644 --- a/src/ui/pages/applications/mod.rs +++ b/src/ui/pages/applications/mod.rs @@ -69,7 +69,8 @@ mod imp { pub filter_model: RefCell, pub sort_model: RefCell, pub column_view: RefCell, - pub open_dialog: RefCell, ResAppDialog)>>, + pub open_info_dialog: RefCell, ResAppDialog)>>, + pub info_dialog_closed: Cell, pub sender: OnceLock>, @@ -154,7 +155,8 @@ mod imp { filter_model: Default::default(), sort_model: Default::default(), column_view: Default::default(), - open_dialog: Default::default(), + open_info_dialog: Default::default(), + info_dialog_closed: Default::default(), sender: Default::default(), applications_scrolled_window: Default::default(), end_application_button: Default::default(), @@ -239,7 +241,7 @@ mod imp { if let Some(application_entry) = res_applications.imp().popped_over_app.borrow().as_ref() { - res_applications.open_information_dialog(application_entry); + res_applications.open_info_dialog(application_entry); } }, ); @@ -515,7 +517,7 @@ impl ResApplications { .selected_item() .map(|object| object.downcast::().unwrap()); if let Some(selection) = selection_option { - this.open_information_dialog(&selection); + this.open_info_dialog(&selection); } } )); @@ -564,14 +566,32 @@ impl ResApplications { } } - pub fn open_information_dialog(&self, app: &ApplicationEntry) { + pub fn open_info_dialog(&self, app: &ApplicationEntry) { let imp = self.imp(); - let app_dialog = ResAppDialog::new(); - app_dialog.init(app); - app_dialog.present(Some(&MainWindow::default())); - *imp.open_dialog.borrow_mut() = Some(( + + if imp.open_info_dialog.borrow().is_some() { + return; + } + + imp.info_dialog_closed.set(false); + + let dialog = ResAppDialog::new(); + + dialog.init(app); + + dialog.present(Some(&MainWindow::default())); + + dialog.connect_closed(clone!( + #[weak(rename_to = this)] + self, + move |_| { + this.imp().info_dialog_closed.set(true); + } + )); + + *imp.open_info_dialog.borrow_mut() = Some(( app.id().as_ref().map(std::string::ToString::to_string), - app_dialog, + dialog, )); } @@ -602,8 +622,13 @@ impl ResApplications { pub fn refresh_apps_list(&self, apps_context: &AppsContext) { let imp = self.imp(); + if imp.info_dialog_closed.get() { + let _ = imp.open_info_dialog.take(); + imp.info_dialog_closed.set(false); + } + let store = imp.store.borrow_mut(); - let mut dialog_opt = &*imp.open_dialog.borrow_mut(); + let mut dialog_opt = &*imp.open_info_dialog.borrow_mut(); let mut ids_to_remove = HashSet::new(); let mut already_existing_ids = HashSet::new(); @@ -671,7 +696,10 @@ impl ResApplications { // -1 because we don't want to count System Processes self.set_property( "tab_usage_string", - i18n_f("Running Apps: {}", &[&(store.n_items() - 1).to_string()]), + i18n_f( + "Running Apps: {}", + &[&(store.n_items().saturating_sub(1)).to_string()], + ), ); } @@ -789,8 +817,8 @@ impl ResApplications { )); name_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<&ResApplicationNameCell>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<&ResApplicationNameCell>); }); let name_col_sorter = StringSorter::builder() @@ -841,8 +869,8 @@ impl ResApplications { )); memory_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let memory_col_sorter = NumericSorter::builder() @@ -904,8 +932,8 @@ impl ResApplications { )); cpu_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let cpu_col_sorter = NumericSorter::builder() @@ -968,8 +996,8 @@ impl ResApplications { )); read_speed_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let read_speed_col_sorter = NumericSorter::builder() @@ -1028,8 +1056,8 @@ impl ResApplications { )); read_total_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let read_total_col_sorter = NumericSorter::builder() @@ -1092,8 +1120,8 @@ impl ResApplications { )); write_speed_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let write_speed_col_sorter = NumericSorter::builder() @@ -1154,8 +1182,8 @@ impl ResApplications { )); write_total_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let write_total_col_sorter = NumericSorter::builder() @@ -1213,8 +1241,8 @@ impl ResApplications { )); gpu_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let gpu_col_sorter = NumericSorter::builder() @@ -1273,8 +1301,8 @@ impl ResApplications { )); encoder_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let encoder_col_sorter = NumericSorter::builder() @@ -1333,8 +1361,8 @@ impl ResApplications { )); decoder_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let decoder_col_sorter = NumericSorter::builder() @@ -1390,8 +1418,8 @@ impl ResApplications { )); gpu_mem_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let gpu_mem_col_sorter = NumericSorter::builder() diff --git a/src/ui/pages/battery.rs b/src/ui/pages/battery.rs index 33f45b79..c588234c 100644 --- a/src/ui/pages/battery.rs +++ b/src/ui/pages/battery.rs @@ -6,6 +6,8 @@ use crate::i18n::i18n; use crate::utils::battery::BatteryData; use crate::utils::units::{convert_energy, convert_power}; +pub const TAB_ID_PREFIX: &str = "battery"; + mod imp { use std::cell::{Cell, RefCell}; @@ -206,7 +208,6 @@ impl Default for ResBattery { } impl ResBattery { - const ID_PREFIX: &'static str = "battery"; const MAIN_GRAPH_COLOR: [u8; 3] = [0x33, 0xd1, 0x7a]; pub fn new() -> Self { @@ -224,7 +225,7 @@ impl ResBattery { let tab_id = format!( "{}-{}-{}-{}", - Self::ID_PREFIX, + TAB_ID_PREFIX, battery.manufacturer.as_deref().unwrap_or_default(), battery.model_name.as_deref().unwrap_or_default(), battery.sysfs_path.file_name().unwrap().to_string_lossy(), diff --git a/src/ui/pages/cpu.rs b/src/ui/pages/cpu.rs index 6f9d19e9..d5be3aad 100644 --- a/src/ui/pages/cpu.rs +++ b/src/ui/pages/cpu.rs @@ -10,6 +10,8 @@ use crate::utils::settings::SETTINGS; use crate::utils::units::{convert_frequency, convert_temperature}; use crate::utils::{cpu, FiniteOr, NUM_CPUS}; +pub const TAB_ID: &str = "cpu"; + mod imp { use std::cell::{Cell, RefCell}; @@ -155,7 +157,7 @@ mod imp { tab_name: Cell::new(glib::GString::from(i18n("Processor"))), tab_detail_string: Cell::new(glib::GString::new()), tab_usage_string: Cell::new(glib::GString::new()), - tab_id: Cell::new(glib::GString::from("cpu")), + tab_id: Cell::new(glib::GString::from(TAB_ID)), old_total_usage: Cell::default(), old_thread_usages: RefCell::default(), logical_cpus_amount: Cell::default(), diff --git a/src/ui/pages/drive.rs b/src/ui/pages/drive.rs index f64fe6bf..d46b5902 100644 --- a/src/ui/pages/drive.rs +++ b/src/ui/pages/drive.rs @@ -8,6 +8,8 @@ use crate::i18n::{i18n, i18n_f}; use crate::utils::drive::{Drive, DriveData}; use crate::utils::units::{convert_speed, convert_storage}; +pub const TAB_ID_PREFIX: &str = "drive"; + mod imp { use std::{ cell::{Cell, RefCell}, @@ -233,7 +235,6 @@ impl Default for ResDrive { } impl ResDrive { - const ID_PREFIX: &'static str = "drive"; const MAIN_GRAPH_COLOR: [u8; 3] = [0xff, 0x78, 0x00]; const SECTOR_SIZE: usize = 512; @@ -252,7 +253,7 @@ impl ResDrive { let tab_id = format!( "{}-{}", - Self::ID_PREFIX, + TAB_ID_PREFIX, drive .model .as_deref() diff --git a/src/ui/pages/gpu.rs b/src/ui/pages/gpu.rs index afb4e595..db6777df 100644 --- a/src/ui/pages/gpu.rs +++ b/src/ui/pages/gpu.rs @@ -7,6 +7,8 @@ use crate::utils::gpu::{Gpu, GpuData}; use crate::utils::units::{convert_frequency, convert_power, convert_storage, convert_temperature}; use crate::utils::{pci, FiniteOr}; +pub const TAB_ID_PREFIX: &str = "gpu"; + mod imp { use std::cell::{Cell, RefCell}; @@ -219,7 +221,6 @@ impl Default for ResGPU { } impl ResGPU { - const ID_PREFIX: &'static str = "gpu"; const MAIN_GRAPH_COLOR: [u8; 3] = [0xe0, 0x1b, 0x24]; pub fn new() -> Self { @@ -234,7 +235,7 @@ impl ResGPU { pub fn setup_widgets(&self, gpu: &Gpu) { let imp = self.imp(); - let tab_id = format!("{}-{}", Self::ID_PREFIX, &gpu.pci_slot().to_string()); + let tab_id = format!("{}-{}", TAB_ID_PREFIX, &gpu.pci_slot().to_string()); imp.set_tab_id(&tab_id); imp.gpu_usage.set_title_label(&i18n("Total Usage")); diff --git a/src/ui/pages/memory.rs b/src/ui/pages/memory.rs index 0749a186..6dd45a4c 100644 --- a/src/ui/pages/memory.rs +++ b/src/ui/pages/memory.rs @@ -7,6 +7,8 @@ use crate::utils::memory::{self, MemoryData, MemoryDevice}; use crate::utils::units::convert_storage; use crate::utils::FiniteOr; +pub const TAB_ID: &str = "memory"; + mod imp { use std::cell::{Cell, RefCell}; @@ -138,7 +140,7 @@ mod imp { tab_name: Cell::new(glib::GString::from(i18n("Memory"))), tab_detail_string: Cell::new(glib::GString::new()), tab_usage_string: Cell::new(glib::GString::new()), - tab_id: Cell::new(glib::GString::from("memory")), + tab_id: Cell::new(glib::GString::from(TAB_ID)), graph_locked_max_y: Cell::new(true), primary_ord: Cell::new(MEMORY_PRIMARY_ORD), secondary_ord: Default::default(), diff --git a/src/ui/pages/network.rs b/src/ui/pages/network.rs index db11fffe..24369589 100644 --- a/src/ui/pages/network.rs +++ b/src/ui/pages/network.rs @@ -8,6 +8,8 @@ use crate::i18n::{i18n, i18n_f}; use crate::utils::network::{NetworkData, NetworkInterface}; use crate::utils::units::{convert_speed, convert_storage}; +pub const TAB_ID_PREFIX: &str = "network"; + mod imp { use std::cell::{Cell, RefCell}; @@ -226,7 +228,6 @@ impl Default for ResNetwork { } impl ResNetwork { - const ID_PREFIX: &'static str = "network"; // TODO: this is the color for receiving, but it is also used in sidebar, // which graphs the sum of send+recv. // This does not make much sense, but we probably can't do something @@ -248,7 +249,7 @@ impl ResNetwork { let tab_id = format!( "{}-{}", - Self::ID_PREFIX, + TAB_ID_PREFIX, network_interface.interface_name.to_str().unwrap() ); imp.set_tab_id(&tab_id); diff --git a/src/ui/pages/processes/mod.rs b/src/ui/pages/processes/mod.rs index 588d9a34..eabea16a 100644 --- a/src/ui/pages/processes/mod.rs +++ b/src/ui/pages/processes/mod.rs @@ -98,9 +98,13 @@ mod imp { pub filter_model: RefCell, pub sort_model: RefCell, pub column_view: RefCell, + pub open_info_dialog: RefCell>, pub open_options_dialog: RefCell>, + pub info_dialog_closed: Cell, + pub options_dialog_closed: Cell, + pub sender: OnceLock>, pub popped_over_process: RefCell>, @@ -165,6 +169,8 @@ mod imp { column_view: Default::default(), open_info_dialog: Default::default(), open_options_dialog: Default::default(), + info_dialog_closed: Default::default(), + options_dialog_closed: Default::default(), sender: Default::default(), uses_progress_bar: Cell::new(false), icon: RefCell::new(ThemedIcon::new("generic-process-symbolic").into()), @@ -602,6 +608,13 @@ impl ResProcesses { pub fn open_options_dialog(&self, process: &ProcessEntry) { let imp = self.imp(); + + if imp.open_info_dialog.borrow().is_some() || imp.open_options_dialog.borrow().is_some() { + return; + } + + imp.options_dialog_closed.set(false); + let dialog = ResProcessOptionsDialog::new(); dialog.init( @@ -610,6 +623,14 @@ impl ResProcesses { &imp.toast_overlay, ); + dialog.connect_closed(clone!( + #[weak(rename_to = this)] + self, + move |_| { + this.imp().options_dialog_closed.set(true); + } + )); + dialog.present(Some(&MainWindow::default())); *imp.open_options_dialog.borrow_mut() = Some((process.pid(), dialog)); @@ -617,10 +638,28 @@ impl ResProcesses { pub fn open_info_dialog(&self, process: &ProcessEntry) { let imp = self.imp(); - let process_dialog = ResProcessDialog::new(); - process_dialog.init(process, process.user()); - process_dialog.present(Some(&MainWindow::default())); - *imp.open_info_dialog.borrow_mut() = Some((process.pid(), process_dialog)); + + if imp.open_info_dialog.borrow().is_some() || imp.open_options_dialog.borrow().is_some() { + return; + } + + imp.options_dialog_closed.set(false); + + let dialog = ResProcessDialog::new(); + + dialog.init(process, process.user()); + + dialog.connect_closed(clone!( + #[weak(rename_to = this)] + self, + move |_| { + this.imp().info_dialog_closed.set(true); + } + )); + + dialog.present(Some(&MainWindow::default())); + + *imp.open_info_dialog.borrow_mut() = Some((process.pid(), dialog)); } fn search_filter(&self, obj: &Object) -> bool { @@ -643,6 +682,16 @@ impl ResProcesses { pub fn refresh_processes_list(&self, apps_context: &AppsContext) { let imp = self.imp(); + if imp.info_dialog_closed.get() { + let _ = imp.open_info_dialog.take(); + imp.info_dialog_closed.set(false); + } + + if imp.options_dialog_closed.get() { + let _ = imp.open_options_dialog.take(); + imp.options_dialog_closed.set(false); + } + let store = imp.store.borrow_mut(); let mut info_dialog_opt = imp.open_info_dialog.borrow_mut(); let mut options_dialog_opt = imp.open_options_dialog.borrow_mut(); @@ -830,8 +879,8 @@ impl ResProcesses { )); name_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<&ResProcessNameCell>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<&ResProcessNameCell>); }); let name_col_sorter = StringSorter::builder() @@ -876,8 +925,8 @@ impl ResProcesses { )); pid_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let pid_col_sorter = NumericSorter::builder() @@ -930,8 +979,8 @@ impl ResProcesses { )); user_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let user_col_sorter = StringSorter::builder() @@ -988,8 +1037,8 @@ impl ResProcesses { )); memory_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let memory_col_sorter = NumericSorter::builder() @@ -1051,8 +1100,8 @@ impl ResProcesses { )); cpu_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let cpu_col_sorter = NumericSorter::builder() @@ -1115,8 +1164,8 @@ impl ResProcesses { )); read_speed_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let read_speed_col_sorter = NumericSorter::builder() @@ -1181,8 +1230,8 @@ impl ResProcesses { )); read_total_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let read_total_col_sorter = NumericSorter::builder() @@ -1247,8 +1296,8 @@ impl ResProcesses { )); write_speed_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let write_speed_col_sorter = NumericSorter::builder() @@ -1313,8 +1362,8 @@ impl ResProcesses { )); write_total_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let write_total_col_sorter = NumericSorter::builder() @@ -1372,8 +1421,8 @@ impl ResProcesses { )); gpu_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let gpu_col_sorter = NumericSorter::builder() @@ -1432,8 +1481,8 @@ impl ResProcesses { )); encoder_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let encoder_col_sorter = NumericSorter::builder() @@ -1492,8 +1541,8 @@ impl ResProcesses { )); decoder_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let decoder_col_sorter = NumericSorter::builder() @@ -1551,8 +1600,8 @@ impl ResProcesses { )); gpu_mem_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let gpu_mem_col_sorter = NumericSorter::builder() @@ -1610,8 +1659,8 @@ impl ResProcesses { )); total_cpu_time_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let total_cpu_time_col_sorter = NumericSorter::builder() @@ -1669,8 +1718,8 @@ impl ResProcesses { )); user_cpu_time_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let user_cpu_time_col_sorter = NumericSorter::builder() @@ -1728,8 +1777,8 @@ impl ResProcesses { )); system_cpu_time_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let system_cpu_time_col_sorter = NumericSorter::builder() @@ -1795,8 +1844,8 @@ impl ResProcesses { )); priority_col_factory.connect_teardown(move |_factory, item| { - let item = item.downcast_ref::(); - item.unwrap().set_child(None::<>k::Inscription>); + let item = item.downcast_ref::().unwrap(); + item.set_child(None::<>k::Inscription>); }); let priority_col_sorter = NumericSorter::builder() diff --git a/src/ui/window.rs b/src/ui/window.rs index c3593b8f..b60449d3 100644 --- a/src/ui/window.rs +++ b/src/ui/window.rs @@ -11,6 +11,7 @@ use log::{info, warn}; use crate::application::Application; use crate::config::PROFILE; +use crate::gui::ARGS; use crate::i18n::{i18n, i18n_f, ni18n_f}; use crate::ui::pages::applications::ResApplications; use crate::ui::pages::battery::ResBattery; @@ -185,8 +186,8 @@ glib::wrapper! { } struct RefreshData { - cpu_data: CpuData, - mem_data: Result, + cpu_data: Option, + mem_data: Option>, gpu_data: Vec, drive_paths: Vec, drive_data: Vec, @@ -266,7 +267,7 @@ impl MainWindow { if selected_page.is::() { if let Some(app_item) = imp.applications.get_selected_app_entry() { - imp.applications.open_information_dialog(&app_item); + imp.applications.open_info_dialog(&app_item); } } else if selected_page.is::() { if let Some(process_item) = imp.processes.get_selected_process_entry() { @@ -324,10 +325,6 @@ impl MainWindow { imp.resources_sidebar.set_stack(&imp.content_stack); - imp.applications.init(imp.sender.clone()); - imp.processes.init(imp.sender.clone()); - imp.memory.init(); - if SETTINGS.show_search_on_start() { // we want the search bar to show up for both but also let the last viewed page grab the focus, so order is // important here @@ -340,16 +337,35 @@ impl MainWindow { } } - *self.imp().apps_context.borrow_mut() = AppsContext::new(); + if ARGS.disable_process_monitoring { + self.remove_page(imp.applications_page.child().downcast_ref().unwrap()); + self.remove_page(imp.processes_page.child().downcast_ref().unwrap()); + } else { + *imp.apps_context.borrow_mut() = AppsContext::new(); + imp.applications.init(imp.sender.clone()); + imp.processes.init(imp.sender.clone()) + } + + if ARGS.disable_cpu_monitoring { + self.remove_page(imp.cpu_page.child().downcast_ref().unwrap()); + } else { + let cpu_info = cpu::cpu_info().context("unable to get CPUInfo").unwrap(); + if let Some(model_name) = cpu_info.model_name.as_deref() { + imp.processor_window_title.set_title(model_name); + imp.processor_window_title.set_subtitle(&i18n("Processor")); + } + imp.cpu.init(cpu_info); + } - let cpu_info = cpu::cpu_info().context("unable to get CPUInfo").unwrap(); - if let Some(model_name) = cpu_info.model_name.as_deref() { - imp.processor_window_title.set_title(model_name); - imp.processor_window_title.set_subtitle(&i18n("Processor")); + if ARGS.disable_memory_monitoring { + self.remove_page(imp.memory_page.child().downcast_ref().unwrap()); + } else { + imp.memory.init(); } - self.imp().cpu.init(cpu_info); - self.init_gpu_pages(); + if !ARGS.disable_gpu_monitoring { + self.init_gpu_pages(); + } let main_context = MainContext::default(); @@ -363,9 +379,17 @@ impl MainWindow { } fn gather_refresh_data(logical_cpus: usize, gpus: &[Gpu]) -> RefreshData { - let cpu_data = CpuData::new(logical_cpus); + let cpu_data = if ARGS.disable_cpu_monitoring { + None + } else { + Some(CpuData::new(logical_cpus)) + }; - let mem_data = MemoryData::new(); + let mem_data = if ARGS.disable_memory_monitoring { + None + } else { + Some(MemoryData::new()) + }; let mut gpu_data = Vec::with_capacity(gpus.len()); for gpu in gpus { @@ -374,32 +398,48 @@ impl MainWindow { gpu_data.push(data); } - let drive_paths = Drive::get_sysfs_paths().unwrap_or_default(); + let drive_paths = if ARGS.disable_drive_monitoring { + Vec::new() + } else { + Drive::get_sysfs_paths().unwrap_or_default() + }; let mut drive_data = Vec::with_capacity(drive_paths.len()); for path in &drive_paths { drive_data.push(DriveData::new(path)); } - let network_paths = NetworkInterface::get_sysfs_paths().unwrap_or_default(); + let network_paths = if ARGS.disable_network_interface_monitoring { + Vec::new() + } else { + NetworkInterface::get_sysfs_paths().unwrap_or_default() + }; let mut network_data = Vec::with_capacity(network_paths.len()); for path in &network_paths { network_data.push(NetworkData::new(path)); } - let battery_paths = Battery::get_sysfs_paths().unwrap_or_default(); + let battery_paths = if ARGS.disable_battery_monitoring { + Vec::new() + } else { + Battery::get_sysfs_paths().unwrap_or_default() + }; let mut battery_data = Vec::with_capacity(battery_paths.len()); for path in &battery_paths { battery_data.push(BatteryData::new(path)); } - let process_data = Process::all_data() - .inspect_err(|e| { - warn!( - "Unable to update process and app data!\n{e}\n{}", - e.backtrace() - ); - }) - .unwrap_or_default(); + let process_data = if ARGS.disable_process_monitoring { + Vec::new() + } else { + Process::all_data() + .inspect_err(|e| { + warn!( + "Unable to update process and app data!\n{e}\n{}", + e.backtrace() + ); + }) + .unwrap_or_default() + }; RefreshData { cpu_data, @@ -471,15 +511,19 @@ impl MainWindow { /* * Cpu */ - imp.cpu.refresh_page(&cpu_data); + if let Some(cpu_data) = cpu_data { + imp.cpu.refresh_page(&cpu_data); + } /* * Memory */ - if let Ok(mem_data) = mem_data { - imp.memory.refresh_page(mem_data); - } else if let Err(error) = mem_data { - warn!("Unable to update memory data, reason: {error}"); + if let Some(mem_data_result) = mem_data { + if let Ok(mem_data) = mem_data_result { + imp.memory.refresh_page(mem_data); + } else if let Err(error) = mem_data_result { + warn!("Unable to update memory data, reason: {error}"); + } } /* @@ -539,13 +583,16 @@ impl MainWindow { pub async fn periodic_refresh_all(&self) { let imp = self.imp(); - let gpus = imp - .gpu_pages - .borrow() - .values() - .map(|(gpu, _)| gpu) - .cloned() - .collect::>(); + let gpus = if ARGS.disable_gpu_monitoring { + Vec::new() + } else { + imp.gpu_pages + .borrow() + .values() + .map(|(gpu, _)| gpu) + .cloned() + .collect::>() + }; let logical_cpus = imp.cpu.imp().logical_cpus_amount.get(); @@ -571,9 +618,13 @@ impl MainWindow { self.refresh_ui(refresh_data); - // if this is our first refresh, we want to set the opening view to what it was when the last session was ended + // if this is our first refresh, we want to set the opening view to what it was when the last session was + // ended or whatever the user has supplied via CLI arg if first_refresh { - let saved_page = SETTINGS.last_viewed_page(); + let page_to_open = ARGS + .open_tab_id + .clone() + .unwrap_or_else(|| SETTINGS.last_viewed_page()); // yes, this is bad and O(n). for page in imp.content_stack.pages().iter::().flatten() { @@ -581,7 +632,7 @@ impl MainWindow { let child_id = toolbar.content().unwrap().property::("tab_id"); - if child_id == saved_page { + if child_id == page_to_open { imp.content_stack.set_visible_child(&toolbar); imp.resources_sidebar .set_selected_list_item_by_tab_id(&child_id); @@ -664,7 +715,7 @@ impl MainWindow { // Add new drive pages for path in paths { - if !drive_pages.contains_key(&path) { + drive_pages.entry(path.clone()).or_insert_with(|| { // A drive has been added info!( "A drive has been added (or turned visible): {}", @@ -683,14 +734,12 @@ impl MainWindow { let page = ResDrive::new(); page.init(drive, highest_secondary_ord); - let toolbar = if let Some(model) = &drive.inner.model { + if let Some(model) = &drive.inner.model { self.add_page(&page, model, &display_name) } else { self.add_page(&page, &drive.inner.block_device, &display_name) - }; - - drive_pages.insert(path, toolbar); - } + } + }); } } @@ -739,7 +788,7 @@ impl MainWindow { // Add new network pages for path in paths { - if !network_pages.contains_key(&path) { + network_pages.entry(path.clone()).or_insert_with(|| { // A network interface has been added info!( "A network interface has been added (or turned visible): {}", @@ -757,14 +806,12 @@ impl MainWindow { let page = ResNetwork::new(); page.init(network_interface, highest_secondary_ord); - let toolbar = self.add_page( + self.add_page( &page, &network_interface.inner.display_name(), &network_interface.inner.interface_type.to_string(), - ); - - network_pages.insert(path.clone(), toolbar); - } + ) + }); } } @@ -799,7 +846,7 @@ impl MainWindow { // Add new network pages for path in paths { - if !battery_pages.contains_key(&path) { + battery_pages.entry(path.clone()).or_insert_with(|| { // A battery has been added info!("A battery has been added: {}", path.display()); @@ -814,7 +861,7 @@ impl MainWindow { let page = ResBattery::new(); page.init(battery, highest_secondary_ord); - let toolbar = self.add_page( + self.add_page( &page, &battery .inner @@ -823,10 +870,8 @@ impl MainWindow { .unwrap() .to_string_lossy(), &battery.inner.display_name(), - ); - - battery_pages.insert(path.clone(), toolbar); - } + ) + }); } } diff --git a/src/utils/process.rs b/src/utils/process.rs index 28a8e589..75638109 100644 --- a/src/utils/process.rs +++ b/src/utils/process.rs @@ -257,6 +257,7 @@ impl Process { if let Ok(return_code) = result { if return_code == 0 { + info!("Successfully adjusted {}", self.data.pid); Ok(()) } else { bail!("non-zero return code: {return_code}")