diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index a8208a147ca..827b9ec249c 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -38,7 +38,11 @@ pub fn viewport_builder( } 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( + egui_zoom_factor, + event_loop, + viewport_builder, + ); window_settings.inner_size_points() } else { if let Some(pos) = viewport_builder.position { diff --git a/crates/egui-winit/src/window_settings.rs b/crates/egui-winit/src/window_settings.rs index c59a0f451ce..ec633d3df0a 100644 --- a/crates/egui-winit/src/window_settings.rs +++ b/crates/egui-winit/src/window_settings.rs @@ -50,8 +50,10 @@ impl WindowSettings { self.inner_size_points } - pub fn initialize_viewport_builder( + pub fn initialize_viewport_builder( &self, + egui_zoom_factor: f32, + event_loop: &winit::event_loop::EventLoopWindowTarget, mut viewport_builder: ViewportBuilder, ) -> ViewportBuilder { crate::profile_function!(); @@ -64,7 +66,15 @@ impl WindowSettings { self.outer_position_pixels }; if let Some(pos) = pos_px { - viewport_builder = viewport_builder.with_position(pos); + let monitor_scale_factor = if let Some(inner_size_points) = self.inner_size_points { + find_active_monitor(egui_zoom_factor, event_loop, inner_size_points, &pos) + .map_or(1.0, |monitor| monitor.scale_factor() as f32) + } else { + 1.0 + }; + + let scaled_pos = pos / (egui_zoom_factor * monitor_scale_factor); + viewport_builder = viewport_builder.with_position(scaled_pos); } if let Some(inner_size_points) = self.inner_size_points { @@ -127,12 +137,12 @@ impl WindowSettings { } } -fn clamp_pos_to_monitors( +fn find_active_monitor( egui_zoom_factor: f32, event_loop: &winit::event_loop::EventLoopWindowTarget, window_size_pts: egui::Vec2, - position_px: &mut egui::Pos2, -) { + position_px: &egui::Pos2, +) -> Option { crate::profile_function!(); let monitors = event_loop.available_monitors(); @@ -142,7 +152,7 @@ fn clamp_pos_to_monitors( .primary_monitor() .or_else(|| event_loop.available_monitors().next()) else { - return; // no monitors 🤷 + return None; // no monitors 🤷 }; for monitor in monitors { @@ -159,6 +169,23 @@ fn clamp_pos_to_monitors( } } + Some(active_monitor) +} + +fn clamp_pos_to_monitors( + egui_zoom_factor: f32, + event_loop: &winit::event_loop::EventLoopWindowTarget, + window_size_pts: egui::Vec2, + position_px: &mut egui::Pos2, +) { + crate::profile_function!(); + + let Some(active_monitor) = + find_active_monitor(egui_zoom_factor, event_loop, window_size_pts, position_px) + else { + return; // no monitors 🤷 + }; + let mut window_size_px = window_size_pts * (egui_zoom_factor * active_monitor.scale_factor() as f32); // Add size of title bar. This is 32 px by default in Win 10/11.