util/root: Add window_inspect() to avoid unwraps

This commit is contained in:
Sophie Herold 2025-12-09 21:55:07 +01:00
parent 7b45009eed
commit cfd33fa2dd
3 changed files with 41 additions and 18 deletions

View file

@ -35,6 +35,7 @@ pub trait ParentWindow: WidgetExt {
result.unwrap()
}
#[track_caller]
fn try_window(&self) -> Option<LpWindow> {
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();

View file

@ -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::<gtk::Label>() {
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);

View file

@ -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());
});
}
}