Clamp eframe window size to at most the size of the largest monitor (#2445)
This can hopefully fix some reported bugs where
This commit is contained in:
parent
32677a54e4
commit
4a72abc8ec
4 changed files with 36 additions and 12 deletions
|
@ -255,10 +255,10 @@ pub struct NativeOptions {
|
||||||
/// The initial inner size of the native window in points (logical pixels).
|
/// The initial inner size of the native window in points (logical pixels).
|
||||||
pub initial_window_size: Option<egui::Vec2>,
|
pub initial_window_size: Option<egui::Vec2>,
|
||||||
|
|
||||||
/// The minimum inner window size
|
/// The minimum inner window size in points (logical pixels).
|
||||||
pub min_window_size: Option<egui::Vec2>,
|
pub min_window_size: Option<egui::Vec2>,
|
||||||
|
|
||||||
/// The maximum inner window size
|
/// The maximum inner window size in points (logical pixels).
|
||||||
pub max_window_size: Option<egui::Vec2>,
|
pub max_window_size: Option<egui::Vec2>,
|
||||||
|
|
||||||
/// Should the app window be resizable?
|
/// Should the app window be resizable?
|
||||||
|
|
|
@ -5,6 +5,7 @@ use winit::platform::macos::WindowBuilderExtMacOS as _;
|
||||||
|
|
||||||
#[cfg(feature = "accesskit")]
|
#[cfg(feature = "accesskit")]
|
||||||
use egui::accesskit;
|
use egui::accesskit;
|
||||||
|
use egui::NumExt as _;
|
||||||
#[cfg(feature = "accesskit")]
|
#[cfg(feature = "accesskit")]
|
||||||
use egui_winit::accesskit_winit;
|
use egui_winit::accesskit_winit;
|
||||||
use egui_winit::{native_pixels_per_point, EventResponse, WindowSettings};
|
use egui_winit::{native_pixels_per_point, EventResponse, WindowSettings};
|
||||||
|
@ -48,10 +49,11 @@ pub fn read_window_info(window: &winit::window::Window, pixels_per_point: f32) -
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_builder(
|
pub fn window_builder<E>(
|
||||||
|
event_loop: &EventLoopWindowTarget<E>,
|
||||||
title: &str,
|
title: &str,
|
||||||
native_options: &epi::NativeOptions,
|
native_options: &epi::NativeOptions,
|
||||||
window_settings: &Option<WindowSettings>,
|
window_settings: Option<WindowSettings>,
|
||||||
) -> winit::window::WindowBuilder {
|
) -> winit::window::WindowBuilder {
|
||||||
let epi::NativeOptions {
|
let epi::NativeOptions {
|
||||||
always_on_top,
|
always_on_top,
|
||||||
|
@ -103,7 +105,9 @@ pub fn window_builder(
|
||||||
|
|
||||||
window_builder = window_builder_drag_and_drop(window_builder, *drag_and_drop_support);
|
window_builder = window_builder_drag_and_drop(window_builder, *drag_and_drop_support);
|
||||||
|
|
||||||
if let Some(window_settings) = window_settings {
|
if let Some(mut window_settings) = window_settings {
|
||||||
|
// Restore pos/size from previous session
|
||||||
|
window_settings.clamp_to_sane_values(largest_monitor_point_size(event_loop));
|
||||||
window_builder = window_settings.initialize_window(window_builder);
|
window_builder = window_settings.initialize_window(window_builder);
|
||||||
} else {
|
} else {
|
||||||
if let Some(pos) = *initial_window_pos {
|
if let Some(pos) = *initial_window_pos {
|
||||||
|
@ -112,7 +116,10 @@ pub fn window_builder(
|
||||||
y: pos.y as f64,
|
y: pos.y as f64,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(initial_window_size) = *initial_window_size {
|
if let Some(initial_window_size) = *initial_window_size {
|
||||||
|
let initial_window_size =
|
||||||
|
initial_window_size.at_most(largest_monitor_point_size(event_loop));
|
||||||
window_builder = window_builder.with_inner_size(points_to_size(initial_window_size));
|
window_builder = window_builder.with_inner_size(points_to_size(initial_window_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,6 +127,22 @@ pub fn window_builder(
|
||||||
window_builder
|
window_builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn largest_monitor_point_size<E>(event_loop: &EventLoopWindowTarget<E>) -> egui::Vec2 {
|
||||||
|
let mut max_size = egui::Vec2::ZERO;
|
||||||
|
|
||||||
|
for monitor in event_loop.available_monitors() {
|
||||||
|
let size = monitor.size().to_logical::<f32>(monitor.scale_factor());
|
||||||
|
let size = egui::vec2(size.width, size.height);
|
||||||
|
max_size = max_size.max(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if max_size == egui::Vec2::ZERO {
|
||||||
|
egui::Vec2::splat(16000.0)
|
||||||
|
} else {
|
||||||
|
max_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn load_icon(icon_data: epi::IconData) -> Option<winit::window::Icon> {
|
fn load_icon(icon_data: epi::IconData) -> Option<winit::window::Icon> {
|
||||||
winit::window::Icon::from_rgba(icon_data.rgba, icon_data.width, icon_data.height).ok()
|
winit::window::Icon::from_rgba(icon_data.rgba, icon_data.width, icon_data.height).ok()
|
||||||
}
|
}
|
||||||
|
@ -445,9 +468,7 @@ const STORAGE_WINDOW_KEY: &str = "window";
|
||||||
pub fn load_window_settings(_storage: Option<&dyn epi::Storage>) -> Option<WindowSettings> {
|
pub fn load_window_settings(_storage: Option<&dyn epi::Storage>) -> Option<WindowSettings> {
|
||||||
#[cfg(feature = "persistence")]
|
#[cfg(feature = "persistence")]
|
||||||
{
|
{
|
||||||
let mut settings: WindowSettings = epi::get_value(_storage?, STORAGE_WINDOW_KEY)?;
|
epi::get_value(_storage?, STORAGE_WINDOW_KEY)
|
||||||
settings.clamp_to_sane_values();
|
|
||||||
Some(settings)
|
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "persistence"))]
|
#[cfg(not(feature = "persistence"))]
|
||||||
None
|
None
|
||||||
|
|
|
@ -504,7 +504,7 @@ mod glow_integration {
|
||||||
let window_settings = epi_integration::load_window_settings(storage);
|
let window_settings = epi_integration::load_window_settings(storage);
|
||||||
|
|
||||||
let winit_window =
|
let winit_window =
|
||||||
epi_integration::window_builder(title, native_options, &window_settings)
|
epi_integration::window_builder(event_loop, title, native_options, window_settings)
|
||||||
.build(event_loop)?;
|
.build(event_loop)?;
|
||||||
// a lot of the code below has been lifted from glutin example in their repo.
|
// a lot of the code below has been lifted from glutin example in their repo.
|
||||||
let glutin_window_context =
|
let glutin_window_context =
|
||||||
|
@ -937,7 +937,7 @@ mod wgpu_integration {
|
||||||
) -> Result<winit::window::Window> {
|
) -> Result<winit::window::Window> {
|
||||||
let window_settings = epi_integration::load_window_settings(storage);
|
let window_settings = epi_integration::load_window_settings(storage);
|
||||||
Ok(
|
Ok(
|
||||||
epi_integration::window_builder(title, native_options, &window_settings)
|
epi_integration::window_builder(event_loop, title, native_options, window_settings)
|
||||||
.build(event_loop)?,
|
.build(event_loop)?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,11 +76,14 @@ impl WindowSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clamp_to_sane_values(&mut self) {
|
pub fn clamp_to_sane_values(&mut self, max_size: egui::Vec2) {
|
||||||
|
use egui::NumExt as _;
|
||||||
|
|
||||||
if let Some(size) = &mut self.inner_size_points {
|
if let Some(size) = &mut self.inner_size_points {
|
||||||
// Prevent ridiculously small windows
|
// Prevent ridiculously small windows
|
||||||
let min_size = egui::Vec2::splat(64.0);
|
let min_size = egui::Vec2::splat(64.0);
|
||||||
*size = size.max(min_size);
|
*size = size.at_least(min_size);
|
||||||
|
*size = size.at_most(max_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue