image: Do not require monitor information

Before, monitor information not being available lead to panic.

Closes #77

Part-of: <https://gitlab.gnome.org/Incubator/loupe/-/merge_requests/167>
This commit is contained in:
Sophie Herold 2023-04-10 16:47:01 +02:00 • committed by Marge Bot
parent fad8bb7939
commit 5a93ec71da

View file

@ -654,73 +654,74 @@ mod imp {
if image_width > 0 && image_height > 0 { if image_width > 0 && image_height > 0 {
if let Some(display) = gdk::Display::default() { if let Some(display) = gdk::Display::default() {
if let Some(native) = self.obj().native() { if let Some(native) = self.obj().native() {
let hidpi_scale = self.obj().scale_factor() as f64; if let Some(monitor) = display.monitor_at_surface(&native.surface()) {
let hidpi_scale = self.obj().scale_factor() as f64;
// get monitor information let monitor_geometry = monitor.geometry();
// TODO: Get rid of unwrap // TODO: Per documentation those dimensions should not be physical pixels.
let monitor = display.monitor_at_surface(&native.surface()).unwrap(); // But on Wayland they are physical pixels and on X11 not.
let monitor_geometry = monitor.geometry(); // Taking the version that works on Wayland for now.
// TODO: Per documentation those dimensions should not be physical pixels. // <https://gitlab.gnome.org/GNOME/gtk/-/issues/5391>
// But on Wayland they are physical pixels and on X11 not. let monitor_width = monitor_geometry.width() as f64 - 40.;
// Taking the version that works on Wayland for now. let monitor_height = monitor_geometry.height() as f64 - 60.;
// <https://gitlab.gnome.org/GNOME/gtk/-/issues/5391>
let monitor_width = monitor_geometry.width() as f64 - 40.;
let monitor_height = monitor_geometry.height() as f64 - 60.;
// areas // areas
let monitor_area = monitor_width * monitor_height; let monitor_area = monitor_width * monitor_height;
let image_area = image_width as f64 * image_height as f64; let image_area = image_width as f64 * image_height as f64;
let occupy_area_factor = if monitor_area < 1024. * 768. { let occupy_area_factor = if monitor_area < 1024. * 768. {
// for small monitors occupy 80% of the area // for small monitors occupy 80% of the area
0.8 0.8
} else { } else {
// for large monitors occupy 30% of the area // for large monitors occupy 30% of the area
0.3 0.3
}; };
// factor for width and height that will achieve the desired area occupation // factor for width and height that will achieve the desired area occupation
// derived from: // derived from:
// monitor_area * occupy_area_factor == // monitor_area * occupy_area_factor ==
// (image_width * size_scale) * (image_height * size_scale) // (image_width * size_scale) * (image_height * size_scale)
let size_scale = f64::sqrt(monitor_area / image_area * occupy_area_factor); let size_scale =
// ensure that we never increase image size f64::sqrt(monitor_area / image_area * occupy_area_factor);
let target_scale = f64::min(1.0, size_scale); // ensure that we never increase image size
let mut nat_width = image_width as f64 * target_scale; let target_scale = f64::min(1.0, size_scale);
let mut nat_height = image_height as f64 * target_scale; let mut nat_width = image_width as f64 * target_scale;
let mut nat_height = image_height as f64 * target_scale;
// scale down if targeted occupation does not fit in one direction // scale down if targeted occupation does not fit in one direction
if nat_width > monitor_width { if nat_width > monitor_width {
nat_width = monitor_width; nat_width = monitor_width;
nat_height = nat_height * monitor_width / nat_width; nat_height = nat_height * monitor_width / nat_width;
}
// same for other direction
if nat_height > monitor_height {
nat_height = monitor_height;
nat_width = nat_width * monitor_height / nat_height;
}
let size = match orientation {
gtk::Orientation::Horizontal => (nat_width / hidpi_scale).round(),
gtk::Orientation::Vertical => (nat_height / hidpi_scale).round(),
_ => unreachable!(),
};
return (0, size as i32, -1, -1);
} }
// same for other direction
if nat_height > monitor_height {
nat_height = monitor_height;
nat_width = nat_width * monitor_height / nat_height;
}
let size = match orientation {
gtk::Orientation::Horizontal => (nat_width / hidpi_scale).round(),
gtk::Orientation::Vertical => (nat_height / hidpi_scale).round(),
_ => unreachable!(),
};
return (0, size as i32, -1, -1);
} }
} }
} }
// fallback if monitor size or image size is not known: // fallback if monitor size or image size is not known:
// use original image size and hope for the best // use original image size and hope for the best
// TODO: We could use a small default monitor size estimate instead
let size = match orientation { let size = match orientation {
gtk::Orientation::Horizontal => image_width, gtk::Orientation::Horizontal => image_width,
gtk::Orientation::Vertical => image_height, gtk::Orientation::Vertical => image_height,
_ => unreachable!(), _ => unreachable!(),
}; };
log::warn!("Not enough information available to calculate fitting window size");
(0, size, -1, -1) (0, size, -1, -1)
} }
} }