Allow users to create viewports larger than monitor on Windows & macOS (#4337)
Added clamp_size_to_monitor_size field on ViewportBuilder, which means whether clamp the window's size to monitor's size. (default to `true`) * Closes https://github.com/emilk/egui/issues/3389 ### simple example ```rust pub struct MyApp {} impl MyApp { pub fn new() -> MyApp { MyApp {} } } impl eframe::App for MyApp { fn update(&mut self, ctx: &Context, frame: &mut eframe::Frame) { egui::CentralPanel::default() .frame(Frame::none().fill(Color32::DARK_GRAY)) .show(ctx, |ui| { if ctx.input(|i| i.key_pressed(Key::Escape)) { ctx.send_viewport_cmd(ViewportCommand::Close); } }); } } pub fn main() { let option = eframe::NativeOptions { viewport: ViewportBuilder::default() .with_position([10.0, 10.0]) .with_inner_size([3000.0, 2000.0]) .with_clamp_size_to_monitor_size(false), ..Default::default() }; eframe::run_native( "a large window app", option, Box::new(|ctx| Box::new(MyApp::new())), ).unwrap(); } ``` It works on my windows (with 3 monitors), but I don't have a test environment for macos --------- Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
parent
436c671331
commit
ff8cfc2aa0
|
|
@ -20,14 +20,23 @@ pub fn viewport_builder<E>(
|
||||||
|
|
||||||
let mut viewport_builder = native_options.viewport.clone();
|
let mut viewport_builder = native_options.viewport.clone();
|
||||||
|
|
||||||
|
let clamp_size_to_monitor_size = viewport_builder.clamp_size_to_monitor_size.unwrap_or(
|
||||||
|
// On some Linux systems, a window size larger than the monitor causes crashes
|
||||||
|
cfg!(target_os = "linux"),
|
||||||
|
);
|
||||||
|
|
||||||
// Always use the default window size / position on iOS. Trying to restore the previous position
|
// Always use the default window size / position on iOS. Trying to restore the previous position
|
||||||
// causes the window to be shown too small.
|
// causes the window to be shown too small.
|
||||||
#[cfg(not(target_os = "ios"))]
|
#[cfg(not(target_os = "ios"))]
|
||||||
let inner_size_points = if let Some(mut window_settings) = window_settings {
|
let inner_size_points = if let Some(mut window_settings) = window_settings {
|
||||||
// Restore pos/size from previous session
|
// Restore pos/size from previous session
|
||||||
|
|
||||||
window_settings
|
if clamp_size_to_monitor_size {
|
||||||
.clamp_size_to_sane_values(largest_monitor_point_size(egui_zoom_factor, event_loop));
|
window_settings.clamp_size_to_sane_values(largest_monitor_point_size(
|
||||||
|
egui_zoom_factor,
|
||||||
|
event_loop,
|
||||||
|
));
|
||||||
|
}
|
||||||
window_settings.clamp_position_to_monitors(egui_zoom_factor, event_loop);
|
window_settings.clamp_position_to_monitors(egui_zoom_factor, event_loop);
|
||||||
|
|
||||||
viewport_builder = window_settings.initialize_viewport_builder(viewport_builder);
|
viewport_builder = window_settings.initialize_viewport_builder(viewport_builder);
|
||||||
|
|
@ -37,10 +46,12 @@ pub fn viewport_builder<E>(
|
||||||
viewport_builder = viewport_builder.with_position(pos);
|
viewport_builder = viewport_builder.with_position(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(initial_window_size) = viewport_builder.inner_size {
|
if clamp_size_to_monitor_size {
|
||||||
let initial_window_size = initial_window_size
|
if let Some(initial_window_size) = viewport_builder.inner_size {
|
||||||
.at_most(largest_monitor_point_size(egui_zoom_factor, event_loop));
|
let initial_window_size = initial_window_size
|
||||||
viewport_builder = viewport_builder.with_inner_size(initial_window_size);
|
.at_most(largest_monitor_point_size(egui_zoom_factor, event_loop));
|
||||||
|
viewport_builder = viewport_builder.with_inner_size(initial_window_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewport_builder.inner_size
|
viewport_builder.inner_size
|
||||||
|
|
|
||||||
|
|
@ -1598,6 +1598,7 @@ pub fn create_winit_window_builder<T>(
|
||||||
window_type: _window_type,
|
window_type: _window_type,
|
||||||
|
|
||||||
mouse_passthrough: _, // handled in `apply_viewport_builder_to_window`
|
mouse_passthrough: _, // handled in `apply_viewport_builder_to_window`
|
||||||
|
clamp_size_to_monitor_size: _, // Handled in `viewport_builder` in `epi_integration.rs`
|
||||||
} = viewport_builder;
|
} = viewport_builder;
|
||||||
|
|
||||||
let mut window_builder = winit::window::WindowBuilder::new()
|
let mut window_builder = winit::window::WindowBuilder::new()
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,11 @@ pub struct ViewportBuilder {
|
||||||
pub min_inner_size: Option<Vec2>,
|
pub min_inner_size: Option<Vec2>,
|
||||||
pub max_inner_size: Option<Vec2>,
|
pub max_inner_size: Option<Vec2>,
|
||||||
|
|
||||||
|
/// Whether clamp the window's size to monitor's size. The default is `true` on linux, otherwise it is `false`.
|
||||||
|
///
|
||||||
|
/// Note: On some Linux systems, a window size larger than the monitor causes crashes
|
||||||
|
pub clamp_size_to_monitor_size: Option<bool>,
|
||||||
|
|
||||||
pub fullscreen: Option<bool>,
|
pub fullscreen: Option<bool>,
|
||||||
pub maximized: Option<bool>,
|
pub maximized: Option<bool>,
|
||||||
pub resizable: Option<bool>,
|
pub resizable: Option<bool>,
|
||||||
|
|
@ -493,6 +498,15 @@ impl ViewportBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets whether clamp the window's size to monitor's size. The default is `true` on linux, otherwise it is `false`.
|
||||||
|
///
|
||||||
|
/// Note: On some Linux systems, a window size larger than the monitor causes crashes
|
||||||
|
#[inline]
|
||||||
|
pub fn with_clamp_size_to_monitor_size(mut self, value: bool) -> Self {
|
||||||
|
self.clamp_size_to_monitor_size = Some(value);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Does not work on X11.
|
/// Does not work on X11.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_close_button(mut self, value: bool) -> Self {
|
pub fn with_close_button(mut self, value: bool) -> Self {
|
||||||
|
|
@ -606,6 +620,7 @@ impl ViewportBuilder {
|
||||||
inner_size: new_inner_size,
|
inner_size: new_inner_size,
|
||||||
min_inner_size: new_min_inner_size,
|
min_inner_size: new_min_inner_size,
|
||||||
max_inner_size: new_max_inner_size,
|
max_inner_size: new_max_inner_size,
|
||||||
|
clamp_size_to_monitor_size: new_clamp_size_to_monitor_size,
|
||||||
fullscreen: new_fullscreen,
|
fullscreen: new_fullscreen,
|
||||||
maximized: new_maximized,
|
maximized: new_maximized,
|
||||||
resizable: new_resizable,
|
resizable: new_resizable,
|
||||||
|
|
@ -740,6 +755,13 @@ impl ViewportBuilder {
|
||||||
|
|
||||||
let mut recreate_window = false;
|
let mut recreate_window = false;
|
||||||
|
|
||||||
|
if new_clamp_size_to_monitor_size.is_some()
|
||||||
|
&& self.clamp_size_to_monitor_size != new_clamp_size_to_monitor_size
|
||||||
|
{
|
||||||
|
self.clamp_size_to_monitor_size = new_clamp_size_to_monitor_size;
|
||||||
|
recreate_window = true;
|
||||||
|
}
|
||||||
|
|
||||||
if new_active.is_some() && self.active != new_active {
|
if new_active.is_some() && self.active != new_active {
|
||||||
self.active = new_active;
|
self.active = new_active;
|
||||||
recreate_window = true;
|
recreate_window = true;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue