From cfd33fa2ddf9794cf2c59f8c162284115b9b657a Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Tue, 9 Dec 2025 21:55:07 +0100 Subject: [PATCH] util/root: Add window_inspect() to avoid unwraps --- src/util/root.rs | 8 ++++++ src/widgets/image_window.rs | 40 +++++++++++++++++++---------- src/widgets/image_window/actions.rs | 11 ++++---- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/util/root.rs b/src/util/root.rs index 51db078..a5774b1 100644 --- a/src/util/root.rs +++ b/src/util/root.rs @@ -35,6 +35,7 @@ pub trait ParentWindow: WidgetExt { result.unwrap() } + #[track_caller] fn try_window(&self) -> Option { let result = self.root().and_downcast(); @@ -49,18 +50,25 @@ pub trait ParentWindow: WidgetExt { result } + #[track_caller] fn window_show_toast(&self, text: &str, priority: adw::ToastPriority) { if let Some(window) = self.try_window() { window.show_toast(text, priority); } } + #[track_caller] fn window_add_toast(&self, toast: adw::Toast) { if let Some(window) = self.try_window() { window.add_toast(toast); } } + #[track_caller] + fn window_inspect(&self, f: impl FnOnce(&LpWindow)) { + self.try_window().inspect(f); + } + fn edit_window(&self) -> LpEditWindow { let parent = self.parent().unwrap(); diff --git a/src/widgets/image_window.rs b/src/widgets/image_window.rs index d14db04..047ff2d 100644 --- a/src/widgets/image_window.rs +++ b/src/widgets/image_window.rs @@ -438,7 +438,7 @@ mod imp { // Maybe one day this will actually work log::debug!("Trying to focus window after drag and drop"); - obj.window().present(); + obj.window_inspect(|w| w.present()); true } @@ -539,7 +539,10 @@ impl LpImageWindow { .as_ref(), ); - if let Ok(selected) = chooser.open_multiple_future(Some(&self.window())).await { + if let Ok(selected) = chooser + .open_multiple_future(self.try_window().as_ref()) + .await + { let images: Vec<_> = selected .into_iter() .filter_map(|files| { @@ -560,7 +563,7 @@ impl LpImageWindow { if let Some(ref file) = imp.image_view.current_file() { let launcher = gtk::FileLauncher::new(Some(file)); launcher.set_always_ask(true); - if let Err(e) = launcher.launch_future(Some(&self.window())).await { + if let Err(e) = launcher.launch_future(self.try_window().as_ref()).await { if !e.matches(gtk::DialogError::Dismissed) { log::error!("Could not open image in external program: {}", e); } @@ -592,7 +595,11 @@ impl LpImageWindow { /// Returns true if some text in metadata is currently selected fn has_metadata_selected(&self) -> bool { - if let Some(focus_widget) = GtkWindowExt::focus(&self.window()) { + let Some(window) = self.try_window() else { + return false; + }; + + if let Some(focus_widget) = GtkWindowExt::focus(&window) { if focus_widget.is_ancestor(&*self.imp().properties_view) { if let Ok(label) = focus_widget.downcast::() { return label.selection_bounds().is_some(); @@ -848,7 +855,7 @@ impl LpImageWindow { imp.stack.set_visible_child(&*imp.status_page); imp.status_page.grab_focus(); // Leave fullscreen since status page has no controls to leave it - self.window().set_fullscreened(false); + self.window_inspect(|w| w.set_fullscreened(false)); } imp.properties_button.set_sensitive(has_image); @@ -878,7 +885,7 @@ impl LpImageWindow { .and_then(|x| x.metadata().file_name()) .unwrap_or_else(|| gettext("Image Viewer")); - self.window().set_title(Some(&title)); + self.window_inspect(|x| x.set_title(Some(&title))); } pub fn image_size_available(&self) { @@ -910,12 +917,14 @@ impl LpImageWindow { if current_page.is_some_and(|page| page.image().error().is_some()) { log::debug!("Showing window because loading image failed"); - self.window().present(); + self.window_inspect(|w| w.present()); } } fn on_fullscreen_changed(&self) { - let icon = if self.window().is_fullscreen() { + let is_fullscreen = self.try_window().map_or(false, |w| w.is_fullscreen()); + + let icon = if is_fullscreen { "view-restore-symbolic" } else { "view-fullscreen-symbolic" @@ -924,7 +933,7 @@ impl LpImageWindow { self.update_headerbar_style(); - if !self.window().is_fullscreen() { + if !is_fullscreen { self.set_cursor(None); self.show_controls(); } @@ -939,18 +948,23 @@ impl LpImageWindow { } fn is_content_extended_to_top(&self) -> bool { - self.window().is_fullscreen() && !self.imp().properties_button.is_active() + self.try_window().map_or(false, |w| w.is_fullscreen()) + && !self.imp().properties_button.is_active() } fn update_accel_status(&self) { - let Some(application) = self.window().application() else { + let Some(window) = self.try_window() else { + return; + }; + + let Some(application) = window.application() else { log::error!("No application for window found"); return; }; // Only change status if active window - if self.window().is_active() { - if self.window().visible_dialog().is_some() || !self.is_mapped() { + if window.is_active() { + if window.visible_dialog().is_some() || !self.is_mapped() { // If AdwDialog is visible, remove global accels that are for the main window // Same for this not being visible, so potentially editing view is open ActionPartGlobal::remove_accels(&application); diff --git a/src/widgets/image_window/actions.rs b/src/widgets/image_window/actions.rs index 51c46fd..80d89ef 100644 --- a/src/widgets/image_window/actions.rs +++ b/src/widgets/image_window/actions.rs @@ -239,14 +239,13 @@ impl Action { Action::ToggleFullscreen => { klass.install_action(&action, None, move |obj, _, _| { - let win = obj.window(); - win.toggle_fullscreen(!win.is_fullscreen()); + obj.window_inspect(|w| w.toggle_fullscreen(!w.is_fullscreen())); }); } Action::LeaveFullscreen => { klass.install_action(&action, None, move |obj, _, _| { - obj.window().toggle_fullscreen(false); + obj.window_inspect(|w| w.toggle_fullscreen(false)); }); } @@ -272,7 +271,9 @@ impl Action { Action::About => { klass.install_action_async(&action, None, |obj, _, _| async move { - obj.window().show_about().await + if let Some(window) = obj.try_window() { + window.show_about().await + } }); } @@ -288,7 +289,7 @@ impl Action { Action::Edit => { klass.install_action_async(&action, None, move |obj, _, _| async move { - obj.window().show_edit(); + obj.window_inspect(|w| w.show_edit()); }); } }