diff --git a/data/net.nokyan.Resources.gschema.xml.in b/data/net.nokyan.Resources.gschema.xml.in index 2abc5f30..730bcb34 100644 --- a/data/net.nokyan.Resources.gschema.xml.in +++ b/data/net.nokyan.Resources.gschema.xml.in @@ -25,10 +25,6 @@ "Normal" Refresh Speed - - false - Show search field for Processes and Applications on launch - false Show virtual block devices such as LVM containers diff --git a/data/resources/ui/dialogs/settings_dialog.ui b/data/resources/ui/dialogs/settings_dialog.ui index e5582399..b2b939b5 100644 --- a/data/resources/ui/dialogs/settings_dialog.ui +++ b/data/resources/ui/dialogs/settings_dialog.ui @@ -81,11 +81,6 @@ - - - Show Search Fields on Launch - - Show Usage Details in Sidebar diff --git a/data/resources/ui/pages/applications.ui b/data/resources/ui/pages/applications.ui index af1959fc..786eebce 100644 --- a/data/resources/ui/pages/applications.ui +++ b/data/resources/ui/pages/applications.ui @@ -49,6 +49,17 @@ + + + + + + Search applications + + + + + @@ -62,78 +73,34 @@ - vertical + 16 + 16 + 16 + 16 + true + 16 + end - - slide-up - - - 16 - 0 - 16 - 16 - 300 - 400 - - - - Search applications - - - - - + + info-symbolic + false + Show App Information + + Show App Information + + - - 16 - 16 - 16 - 16 - 16 - - - search-symbolic - Search - - Toggle search field - - - - - - - true - 16 - end - - - info-symbolic - false - Show App Information - - Show App Information - - - - - - - End App - end_app_menu - false - - - - - + + End App + end_app_menu + false + diff --git a/data/resources/ui/pages/processes.ui b/data/resources/ui/pages/processes.ui index 44aa8786..1a2aeb52 100644 --- a/data/resources/ui/pages/processes.ui +++ b/data/resources/ui/pages/processes.ui @@ -95,6 +95,17 @@ + + + + + + Search processes + + + + + @@ -108,91 +119,47 @@ - vertical + 16 + 16 + 16 + 16 + true + 16 + end + + + options-symbolic + false + Show Process Options + + Show Process Options + + + + - - slide-up - - - 16 - 0 - 16 - 16 - 300 - 400 - - - - Search processes - - - - - + + info-symbolic + false + Show Process Information + + Show Process Information + + - - 16 - 16 - 16 - 16 - 16 - - - search-symbolic - Search - - Toggle search field - - - - - - - true - 16 - end - - - options-symbolic - false - Show Process Options - - Show Process Options - - - - - - - info-symbolic - false - Show Process Information - - Show Process Information - - - - - - - End Process - end_process_menu - false - - - - - + + End Process + end_process_menu + false + diff --git a/data/resources/ui/window.ui b/data/resources/ui/window.ui index 5ed59b4a..51de568d 100644 --- a/data/resources/ui/window.ui +++ b/data/resources/ui/window.ui @@ -61,7 +61,7 @@ True False - + Apps @@ -82,10 +82,19 @@ + + + search-symbolic + Search + + Toggle search field + + + - + @@ -113,6 +122,15 @@ + + + search-symbolic + Search + + Toggle search field + + + diff --git a/src/ui/dialogs/settings_dialog.rs b/src/ui/dialogs/settings_dialog.rs index bb180e5f..86aaee0b 100644 --- a/src/ui/dialogs/settings_dialog.rs +++ b/src/ui/dialogs/settings_dialog.rs @@ -30,8 +30,6 @@ mod imp { #[template_child] pub graph_data_points_row: TemplateChild, #[template_child] - pub show_search_on_start_row: TemplateChild, - #[template_child] pub sidebar_details_row: TemplateChild, #[template_child] pub sidebar_description_row: TemplateChild, @@ -188,8 +186,6 @@ impl ResSettingsDialog { .set_active(SETTINGS.sidebar_description()); imp.sidebar_meter_type_row .set_selected((SETTINGS.sidebar_meter_type() as u8) as u32); - imp.show_search_on_start_row - .set_active(SETTINGS.show_search_on_start()); imp.normalize_cpu_usage_row .set_active(SETTINGS.normalize_cpu_usage()); @@ -313,11 +309,6 @@ impl ResSettingsDialog { } }); - imp.show_search_on_start_row - .connect_active_notify(|switch_row| { - let _ = SETTINGS.set_show_search_on_start(switch_row.is_active()); - }); - imp.normalize_cpu_usage_row .connect_active_notify(|switch_row| { let _ = SETTINGS.set_normalize_cpu_usage(switch_row.is_active()); diff --git a/src/ui/pages/applications/mod.rs b/src/ui/pages/applications/mod.rs index 863c8b69..b8eaccf2 100644 --- a/src/ui/pages/applications/mod.rs +++ b/src/ui/pages/applications/mod.rs @@ -52,14 +52,12 @@ mod imp { #[template_child] pub popover_menu: TemplateChild, #[template_child] - pub search_revealer: TemplateChild, + pub search_bar: TemplateChild, #[template_child] pub search_entry: TemplateChild, #[template_child] pub applications_scrolled_window: TemplateChild, #[template_child] - pub search_button: TemplateChild, - #[template_child] pub information_button: TemplateChild, #[template_child] pub end_application_button: TemplateChild, @@ -115,9 +113,8 @@ mod imp { Self { toast_overlay: Default::default(), popover_menu: Default::default(), - search_revealer: Default::default(), + search_bar: Default::default(), search_entry: Default::default(), - search_button: Default::default(), information_button: Default::default(), store: gio::ListStore::new::().into(), selection_model: Default::default(), @@ -300,12 +297,13 @@ impl ResApplications { pub fn toggle_search(&self) { let imp = self.imp(); - imp.search_button.set_active(!imp.search_button.is_active()); + imp.search_bar + .set_search_mode(!imp.search_bar.is_search_mode()); } pub fn close_search(&self) { let imp = self.imp(); - imp.search_button.set_active(false); + imp.search_bar.set_search_mode(false); } pub fn init(&self, sender: Sender) { @@ -438,20 +436,8 @@ impl ResApplications { } )); - imp.search_button.connect_toggled(clone!( - #[weak(rename_to = this)] - self, - move |button| { - let imp = this.imp(); - imp.search_revealer.set_reveal_child(button.is_active()); - if let Some(filter) = imp.filter_model.borrow().filter() { - filter.changed(FilterChange::Different); - } - if button.is_active() { - imp.search_entry.grab_focus(); - } - } - )); + imp.search_bar + .set_key_capture_widget(self.parent().as_ref()); imp.search_entry.connect_search_changed(clone!( #[strong(rename_to = this)] @@ -474,7 +460,7 @@ impl ResApplications { } } )); - imp.search_entry.add_controller(event_controller); + imp.search_bar.add_controller(event_controller); imp.information_button.connect_clicked(clone!( #[weak(rename_to = this)] @@ -536,6 +522,10 @@ impl ResApplications { } } + pub fn search_bar(&self) -> >k::SearchBar { + &self.imp().search_bar + } + pub fn open_info_dialog(&self, app: &ApplicationEntry) { let imp = self.imp(); @@ -569,7 +559,7 @@ impl ResApplications { let imp = self.imp(); let item = obj.downcast_ref::().unwrap(); let search_string = imp.search_entry.text().to_string().to_lowercase(); - !imp.search_revealer.reveals_child() + !imp.search_bar.is_search_mode() || item.name().to_lowercase().contains(&search_string) || item .id() diff --git a/src/ui/pages/processes/mod.rs b/src/ui/pages/processes/mod.rs index 710cfc51..fb2ff61a 100644 --- a/src/ui/pages/processes/mod.rs +++ b/src/ui/pages/processes/mod.rs @@ -81,14 +81,12 @@ mod imp { #[template_child] pub popover_menu_multiple: TemplateChild, #[template_child] - pub search_revealer: TemplateChild, + pub search_bar: TemplateChild, #[template_child] pub search_entry: TemplateChild, #[template_child] pub processes_scrolled_window: TemplateChild, #[template_child] - pub search_button: TemplateChild, - #[template_child] pub options_button: TemplateChild, #[template_child] pub information_button: TemplateChild, @@ -154,10 +152,9 @@ mod imp { toast_overlay: Default::default(), popover_menu: Default::default(), popover_menu_multiple: Default::default(), - search_revealer: Default::default(), + search_bar: Default::default(), search_entry: Default::default(), processes_scrolled_window: Default::default(), - search_button: Default::default(), options_button: Default::default(), information_button: Default::default(), end_process_button: Default::default(), @@ -374,12 +371,13 @@ impl ResProcesses { pub fn toggle_search(&self) { let imp = self.imp(); - imp.search_button.set_active(!imp.search_button.is_active()); + imp.search_bar + .set_search_mode(!imp.search_bar.is_search_mode()); } pub fn close_search(&self) { let imp = self.imp(); - imp.search_button.set_active(false); + imp.search_bar.set_search_mode(false); } pub fn init(&self, sender: Sender) { @@ -531,20 +529,8 @@ impl ResProcesses { } )); - imp.search_button.connect_toggled(clone!( - #[weak(rename_to = this)] - self, - move |button| { - let imp = this.imp(); - imp.search_revealer.set_reveal_child(button.is_active()); - if let Some(filter) = imp.filter_model.borrow().filter() { - filter.changed(FilterChange::Different); - } - if button.is_active() { - imp.search_entry.grab_focus(); - } - } - )); + imp.search_bar + .set_key_capture_widget(self.parent().as_ref()); imp.search_entry.connect_search_changed(clone!( #[strong(rename_to = this)] @@ -648,6 +634,10 @@ impl ResProcesses { } } + pub fn search_bar(&self) -> >k::SearchBar { + &self.imp().search_bar + } + pub fn open_options_dialog(&self, process: &ProcessEntry) { let imp = self.imp(); @@ -708,7 +698,7 @@ impl ResProcesses { let imp = self.imp(); let item = obj.downcast_ref::().unwrap(); let search_string = imp.search_entry.text().to_string().to_lowercase(); - !imp.search_revealer.reveals_child() + !imp.search_bar.is_search_mode() || item.name().to_lowercase().contains(&search_string) || item.commandline().to_lowercase().contains(&search_string) } diff --git a/src/ui/widgets/stack_sidebar.rs b/src/ui/widgets/stack_sidebar.rs index 47f92133..c204e951 100644 --- a/src/ui/widgets/stack_sidebar.rs +++ b/src/ui/widgets/stack_sidebar.rs @@ -246,6 +246,8 @@ impl ResStackSidebar { imp.list_box.append(&row); + row.set_focus_on_click(false); + if let Some(visible_page) = imp.stack.borrow().visible_child() { if visible_page == page.child() { imp.list_box.select_row(Some(&row)); @@ -314,8 +316,7 @@ impl ResStackSidebar { imp.stack.borrow().set_visible_child(&child); if let Some(page) = child - .downcast::() - .ok() + .downcast_ref::() .and_then(|toolbar| toolbar.content()) { let _ = SETTINGS diff --git a/src/ui/window.rs b/src/ui/window.rs index 081fe166..1bf98b70 100644 --- a/src/ui/window.rs +++ b/src/ui/window.rs @@ -28,10 +28,10 @@ use crate::utils::npu::{Npu, NpuData}; use crate::utils::process::{Process, ProcessAction}; use crate::utils::settings::SETTINGS; +use super::pages::applications; use super::pages::gpu::ResGPU; use super::pages::network::ResNetwork; use super::pages::npu::ResNPU; -use super::pages::{applications, processes}; #[derive(Debug, Clone)] pub enum Action { @@ -78,14 +78,18 @@ mod imp { #[template_child] pub cpu_page: TemplateChild, #[template_child] - pub applications: TemplateChild, + pub apps: TemplateChild, #[template_child] - pub applications_page: TemplateChild, + pub apps_page: TemplateChild, + #[template_child] + pub apps_search_button: TemplateChild, #[template_child] pub processes: TemplateChild, #[template_child] pub processes_page: TemplateChild, #[template_child] + pub processes_search_button: TemplateChild, + #[template_child] pub memory: TemplateChild, #[template_child] pub memory_page: TemplateChild, @@ -118,10 +122,12 @@ mod imp { split_view: TemplateChild::default(), resources_sidebar: TemplateChild::default(), content_stack: TemplateChild::default(), - applications: TemplateChild::default(), - applications_page: TemplateChild::default(), + apps: TemplateChild::default(), + apps_page: TemplateChild::default(), + apps_search_button: TemplateChild::default(), processes: TemplateChild::default(), processes_page: TemplateChild::default(), + processes_search_button: TemplateChild::default(), cpu: TemplateChild::default(), cpu_page: TemplateChild::default(), memory: TemplateChild::default(), @@ -233,10 +239,110 @@ impl MainWindow { } )); } + window.setup_widgets(); + window.setup_signals(); + window } + fn setup_widgets(&self) { + trace!("Setting up Application widgets…"); + let imp = self.imp(); + + let gpus = Gpu::get_gpus().unwrap_or_default(); + + if !ARGS.disable_gpu_monitoring { + self.init_gpu_pages(&gpus); + } + + imp.resources_sidebar.set_stack(&imp.content_stack); + + if ARGS.disable_process_monitoring { + self.remove_page(imp.apps_page.child().downcast_ref().unwrap()); + self.remove_page(imp.processes_page.child().downcast_ref().unwrap()); + } else { + *imp.apps_context.borrow_mut() = AppsContext::new( + gpus.iter() + .filter(|gpu| gpu.combined_media_engine().unwrap_or_default()) + .map(Gpu::gpu_identifier) + .collect(), + ); + imp.apps.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::CpuInfo::get() + .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); + } + + if ARGS.disable_memory_monitoring { + self.remove_page(imp.memory_page.child().downcast_ref().unwrap()); + } else { + imp.memory.init(); + } + + if !ARGS.disable_npu_monitoring { + self.init_npu_pages(); + } + + let main_context = MainContext::default(); + + main_context.spawn_local(clone!( + #[weak(rename_to = this)] + self, + async move { + this.periodic_refresh_all().await; + } + )); + } + + fn setup_signals(&self) { + let imp = self.imp(); + + imp.apps + .search_bar() + .bind_property( + "search-mode-enabled", + &imp.apps_search_button.get(), + "active", + ) + .sync_create() + .bidirectional() + .build(); + + imp.processes + .search_bar() + .bind_property( + "search-mode-enabled", + &imp.processes_search_button.get(), + "active", + ) + .sync_create() + .bidirectional() + .build(); + + imp.content_stack.connect_visible_child_notify(clone!( + #[weak] + imp, + move |_| { + // close the split view if we're in "mobile layout" and the user has clicked on an element + if imp.split_view.is_collapsed() { + imp.split_view.set_show_sidebar(false); + } + } + )); + } + fn get_selected_page(&self) -> Option { self.imp() .content_stack @@ -251,7 +357,7 @@ impl MainWindow { let selected_page = self.get_selected_page().unwrap(); if selected_page.is::() { - imp.applications.toggle_search(); + imp.apps.toggle_search(); } else if selected_page.is::() { imp.processes.toggle_search(); } @@ -263,9 +369,8 @@ impl MainWindow { let selected_page = self.get_selected_page().unwrap(); if selected_page.is::() { - if let Some(app_item) = imp.applications.get_selected_app_entry() { - imp.applications - .open_app_action_dialog(&app_item, process_action); + if let Some(app_item) = imp.apps.get_selected_app_entry() { + imp.apps.open_app_action_dialog(&app_item, process_action); } } else if selected_page.is::() { let selected = imp.processes.get_selected_process_entries(); @@ -282,8 +387,8 @@ impl MainWindow { let selected_page = self.get_selected_page().unwrap(); if selected_page.is::() { - if let Some(app_item) = imp.applications.get_selected_app_entry() { - imp.applications.open_info_dialog(&app_item); + if let Some(app_item) = imp.apps.get_selected_app_entry() { + imp.apps.open_info_dialog(&app_item); } } else if selected_page.is::() { let selected = imp.processes.get_selected_process_entries(); @@ -366,78 +471,6 @@ impl MainWindow { npus } - fn setup_widgets(&self) { - trace!("Setting up Application widgets…"); - let imp = self.imp(); - - let gpus = Gpu::get_gpus().unwrap_or_default(); - - if !ARGS.disable_gpu_monitoring { - self.init_gpu_pages(&gpus); - } - - imp.resources_sidebar.set_stack(&imp.content_stack); - - 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 - if SETTINGS.last_viewed_page() == applications::TAB_ID { - imp.processes.toggle_search(); - imp.applications.toggle_search(); - } else if SETTINGS.last_viewed_page() == processes::TAB_ID { - imp.applications.toggle_search(); - imp.processes.toggle_search(); - } - } - - 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( - gpus.iter() - .filter(|gpu| gpu.combined_media_engine().unwrap_or_default()) - .map(Gpu::gpu_identifier) - .collect(), - ); - 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::CpuInfo::get() - .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); - } - - if ARGS.disable_memory_monitoring { - self.remove_page(imp.memory_page.child().downcast_ref().unwrap()); - } else { - imp.memory.init(); - } - - if !ARGS.disable_npu_monitoring { - self.init_npu_pages(); - } - - let main_context = MainContext::default(); - - main_context.spawn_local(clone!( - #[weak(rename_to = this)] - self, - async move { - this.periodic_refresh_all().await; - } - )); - } - fn gather_refresh_data(logical_cpus: usize, gpus: &[Gpu], npus: &[Npu]) -> RefreshData { let start = Instant::now(); @@ -559,7 +592,7 @@ impl MainWindow { let mut apps_context = imp.apps_context.borrow_mut(); apps_context.refresh(process_data); - imp.applications.refresh_apps_list(&apps_context); + imp.apps.refresh_apps_list(&apps_context); imp.processes.refresh_processes_list(&apps_context); /* diff --git a/src/utils/settings.rs b/src/utils/settings.rs index a3e41faa..d130affc 100644 --- a/src/utils/settings.rs +++ b/src/utils/settings.rs @@ -342,7 +342,6 @@ impl Settings { uint_settings!(graph_data_points, apps_sort_by, processes_sort_by); bool_settings!( - show_search_on_start, show_virtual_drives, show_virtual_network_interfaces, sidebar_details,