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:
parent
fad8bb7939
commit
5a93ec71da
1 changed files with 50 additions and 49 deletions
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue