From 403220580045aa7c272f1a06ff2a0194d18f88b3 Mon Sep 17 00:00:00 2001 From: vikingowl Date: Sat, 28 Mar 2026 08:51:33 +0100 Subject: [PATCH] perf(ui): defer initial query to after window.present() update_results('') was called inside MainWindow::new(), blocking the window from appearing until the daemon responded. Move it to a glib::idle_add_local_once callback scheduled after present() so the window renders immediately. --- crates/owlry/src/app.rs | 3 ++ crates/owlry/src/ui/main_window.rs | 49 +++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/crates/owlry/src/app.rs b/crates/owlry/src/app.rs index 9244ade..3433e56 100644 --- a/crates/owlry/src/app.rs +++ b/crates/owlry/src/app.rs @@ -135,6 +135,9 @@ impl OwlryApp { Self::load_css(&config.borrow()); window.present(); + + // Populate results AFTER present() so the window appears immediately + window.schedule_initial_results(); } /// Create a local backend as fallback when daemon is unavailable. diff --git a/crates/owlry/src/ui/main_window.rs b/crates/owlry/src/ui/main_window.rs index 35dab67..b0bd759 100644 --- a/crates/owlry/src/ui/main_window.rs +++ b/crates/owlry/src/ui/main_window.rs @@ -224,7 +224,6 @@ impl MainWindow { main_window.setup_signals(); main_window.setup_lazy_loading(); - main_window.update_results(""); // Ensure search entry has focus when window is shown main_window.search_entry.grab_focus(); @@ -1181,6 +1180,54 @@ impl MainWindow { entry.emit_by_name::<()>("changed", &[]); } + /// Schedule initial results population via idle callback. + /// Call this AFTER `window.present()` so the window appears immediately. + pub fn schedule_initial_results(&self) { + let backend = self.backend.clone(); + let results_list = self.results_list.clone(); + let config = self.config.clone(); + let filter = self.filter.clone(); + let current_results = self.current_results.clone(); + let lazy_state = self.lazy_state.clone(); + + gtk4::glib::idle_add_local_once(move || { + let cfg = config.borrow(); + let max_results = cfg.general.max_results; + drop(cfg); + + let results = backend.borrow_mut().search( + "", + max_results, + &filter.borrow(), + &config.borrow(), + ); + + // Clear existing results + while let Some(child) = results_list.first_child() { + results_list.remove(&child); + } + + let initial_count = INITIAL_RESULTS.min(results.len()); + { + let mut lazy = lazy_state.borrow_mut(); + lazy.all_results = results.clone(); + lazy.displayed_count = initial_count; + } + + for item in results.iter().take(initial_count) { + let row = ResultRow::new(item); + results_list.append(&row); + } + + if let Some(first_row) = results_list.row_at_index(0) { + results_list.select_row(Some(&first_row)); + } + + *current_results.borrow_mut() = + results.into_iter().take(initial_count).collect(); + }); + } + fn update_results(&self, query: &str) { let cfg = self.config.borrow(); let max_results = cfg.general.max_results;