1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 06:10:06 -04:00

Introduce global zoom_factor (#3608)

* Closes https://github.com/emilk/egui/issues/3602

You can now zoom any egui app by pressing Cmd+Plus, Cmd+Minus or Cmd+0,
just like in a browser. This will change the current `zoom_factor`
(default 1.0) which is persisted in the egui memory, and is the same for
all viewports.
You can turn off the keyboard shortcuts with `ctx.options_mut(|o|
o.zoom_with_keyboard = false);`

`zoom_factor` can also be explicitly read/written with
`ctx.zoom_factor()` and `ctx.set_zoom_factor()`.

This redefines `pixels_per_point` as `zoom_factor *
native_pixels_per_point`, where `native_pixels_per_point` is whatever is
the native scale factor for the monitor that the current viewport is in.

This adds some complexity to the interaction with winit, since we need
to know the current `zoom_factor` in a lot of places, because all egui
IO is done in ui points. I'm pretty sure this PR fixes a bunch of subtle
bugs though that used to be in this code.

`egui::gui_zoom::zoom_with_keyboard_shortcuts` is now gone, and is no
longer needed, as this is now the default behavior.

`Context::set_pixels_per_point` is still there, but it is recommended
you use `Context::set_zoom_factor` instead.
This commit is contained in:
Emil Ernerfeldt
2023-11-22 20:34:51 +01:00
committed by GitHub
parent ea53246c60
commit 63e48dc855
26 changed files with 750 additions and 579 deletions

View File

@@ -24,9 +24,14 @@ pub use window_settings::WindowSettings;
use raw_window_handle::HasRawDisplayHandle;
pub fn native_pixels_per_point(window: &Window) -> f32 {
window.scale_factor() as f32
}
#[allow(unused_imports)]
pub(crate) use profiling_scopes::*;
use winit::{
dpi::{PhysicalPosition, PhysicalSize},
event_loop::EventLoopWindowTarget,
window::{CursorGrabMode, Window, WindowButtons, WindowLevel},
};
pub fn screen_size_in_pixels(window: &Window) -> egui::Vec2 {
let size = window.inner_size();
@@ -111,7 +116,7 @@ impl State {
pointer_pos_in_points: None,
any_pointer_button_down: false,
current_cursor_icon: None,
current_pixels_per_point: 1.0,
current_pixels_per_point: native_pixels_per_point.unwrap_or(1.0),
clipboard: clipboard::Clipboard::new(display_target),
@@ -125,9 +130,13 @@ impl State {
allow_ime: false,
};
if let Some(native_pixels_per_point) = native_pixels_per_point {
slf.set_pixels_per_point(native_pixels_per_point);
}
slf.egui_input
.viewports
.entry(ViewportId::ROOT)
.or_default()
.native_pixels_per_point = native_pixels_per_point;
if let Some(max_texture_side) = max_texture_side {
slf.set_max_texture_side(max_texture_side);
}
@@ -155,19 +164,6 @@ impl State {
self.egui_input.max_texture_side = Some(max_texture_side);
}
/// Call this when a new native Window is created for rendering to initialize the `pixels_per_point`
/// for that window.
///
/// In particular, on Android it is necessary to call this after each `Resumed` lifecycle
/// event, each time a new native window is created.
///
/// Once this has been initialized for a new window then this state will be maintained by handling
/// [`winit::event::WindowEvent::ScaleFactorChanged`] events.
pub fn set_pixels_per_point(&mut self, pixels_per_point: f32) {
self.egui_input.pixels_per_point = Some(pixels_per_point);
self.current_pixels_per_point = pixels_per_point;
}
/// The number of physical pixels per logical point,
/// as configured on the current egui context (see [`egui::Context::pixels_per_point`]).
#[inline]
@@ -193,7 +189,7 @@ impl State {
///
/// Call before [`Self::update_viewport_info`]
pub fn update_viewport_info(&self, info: &mut ViewportInfo, window: &Window) {
update_viewport_info(info, window, self.pixels_per_point());
update_viewport_info(info, window, self.current_pixels_per_point);
}
/// Prepare for a new frame by extracting the accumulated input,
@@ -206,8 +202,6 @@ impl State {
pub fn take_egui_input(&mut self, window: &Window) -> egui::RawInput {
crate::profile_function!();
let pixels_per_point = self.pixels_per_point();
self.egui_input.time = Some(self.start_time.elapsed().as_secs_f64());
// TODO remove this in winit 0.29
@@ -220,7 +214,7 @@ impl State {
// See: https://github.com/rust-windowing/winit/issues/208
// This solves an issue where egui window positions would be changed when minimizing on Windows.
let screen_size_in_pixels = screen_size_in_pixels(window);
let screen_size_in_points = screen_size_in_pixels / pixels_per_point;
let screen_size_in_points = screen_size_in_pixels / self.current_pixels_per_point;
self.egui_input.screen_rect = (screen_size_in_points.x > 0.0
&& screen_size_in_points.y > 0.0)
@@ -228,7 +222,13 @@ impl State {
// Tell egui which viewport is now active:
self.egui_input.viewport_id = self.viewport_id;
self.egui_input.native_pixels_per_point = Some(native_pixels_per_point(window));
self.egui_input
.viewports
.entry(self.viewport_id)
.or_default()
.native_pixels_per_point = Some(window.scale_factor() as f32);
self.egui_input.take()
}
@@ -245,9 +245,14 @@ impl State {
use winit::event::WindowEvent;
match event {
WindowEvent::ScaleFactorChanged { scale_factor, .. } => {
let pixels_per_point = *scale_factor as f32;
self.egui_input.pixels_per_point = Some(pixels_per_point);
self.current_pixels_per_point = pixels_per_point;
let native_pixels_per_point = *scale_factor as f32;
self.egui_input
.viewports
.entry(self.viewport_id)
.or_default()
.native_pixels_per_point = Some(native_pixels_per_point);
self.current_pixels_per_point = egui_ctx.zoom_factor() * native_pixels_per_point;
EventResponse {
repaint: true,
consumed: false,
@@ -709,8 +714,7 @@ impl State {
accesskit_update,
} = platform_output;
self.current_pixels_per_point =
egui_ctx.input_for(self.viewport_id, |i| i.pixels_per_point); // someone can have changed it to scale the UI
self.current_pixels_per_point = egui_ctx.pixels_per_point(); // someone can have changed it to scale the UI
self.set_cursor_icon(window, cursor_icon);
@@ -829,15 +833,15 @@ fn update_viewport_info(viewport_info: &mut ViewportInfo, window: &Window, pixel
}
};
viewport_info.title = Some(window.title());
viewport_info.pixels_per_point = pixels_per_point;
viewport_info.monitor_size = monitor_size;
viewport_info.inner_rect = inner_rect;
viewport_info.outer_rect = outer_rect;
viewport_info.fullscreen = Some(window.fullscreen().is_some());
viewport_info.focused = Some(window.has_focus());
viewport_info.minimized = window.is_minimized().or(viewport_info.minimized);
viewport_info.fullscreen = Some(window.fullscreen().is_some());
viewport_info.inner_rect = inner_rect;
viewport_info.maximized = Some(window.is_maximized());
viewport_info.minimized = window.is_minimized().or(viewport_info.minimized);
viewport_info.monitor_size = monitor_size;
viewport_info.native_pixels_per_point = Some(window.scale_factor() as f32);
viewport_info.outer_rect = outer_rect;
viewport_info.title = Some(window.title());
}
fn open_url_in_browser(_url: &str) {
@@ -1039,178 +1043,230 @@ fn translate_cursor(cursor_icon: egui::CursorIcon) -> Option<winit::window::Curs
// ---------------------------------------------------------------------------
pub fn process_viewport_commands(
egui_ctx: &egui::Context,
info: &mut ViewportInfo,
commands: impl IntoIterator<Item = ViewportCommand>,
window: &Window,
is_viewport_focused: bool,
screenshot_requested: &mut bool,
) {
for command in commands {
process_viewport_command(
egui_ctx,
window,
command,
info,
is_viewport_focused,
screenshot_requested,
);
}
}
fn process_viewport_command(
egui_ctx: &egui::Context,
window: &Window,
command: ViewportCommand,
info: &mut ViewportInfo,
is_viewport_focused: bool,
screenshot_requested: &mut bool,
) {
crate::profile_function!();
use winit::window::ResizeDirection;
for command in commands {
match command {
ViewportCommand::Close => {
info.events.push(egui::ViewportEvent::Close);
}
ViewportCommand::StartDrag => {
// If `is_viewport_focused` is not checked on x11 the input will be permanently taken until the app is killed!
log::debug!("Processing ViewportCommand::{command:?}");
// TODO: check that the left mouse-button was pressed down recently,
// or we will have bugs on Windows.
// See https://github.com/emilk/egui/pull/1108
if is_viewport_focused {
if let Err(err) = window.drag_window() {
log::warn!("{command:?}: {err}");
}
}
}
ViewportCommand::InnerSize(size) => {
let width = size.x.max(1.0);
let height = size.y.max(1.0);
window.set_inner_size(LogicalSize::new(width, height));
}
ViewportCommand::BeginResize(direction) => {
if let Err(err) = window.drag_resize_window(match direction {
egui::viewport::ResizeDirection::North => ResizeDirection::North,
egui::viewport::ResizeDirection::South => ResizeDirection::South,
egui::viewport::ResizeDirection::West => ResizeDirection::West,
egui::viewport::ResizeDirection::NorthEast => ResizeDirection::NorthEast,
egui::viewport::ResizeDirection::SouthEast => ResizeDirection::SouthEast,
egui::viewport::ResizeDirection::NorthWest => ResizeDirection::NorthWest,
egui::viewport::ResizeDirection::SouthWest => ResizeDirection::SouthWest,
}) {
let egui_zoom_factor = egui_ctx.zoom_factor();
let pixels_per_point = egui_zoom_factor * window.scale_factor() as f32;
match command {
ViewportCommand::Close => {
info.events.push(egui::ViewportEvent::Close);
}
ViewportCommand::StartDrag => {
// If `is_viewport_focused` is not checked on x11 the input will be permanently taken until the app is killed!
// TODO: check that the left mouse-button was pressed down recently,
// or we will have bugs on Windows.
// See https://github.com/emilk/egui/pull/1108
if is_viewport_focused {
if let Err(err) = window.drag_window() {
log::warn!("{command:?}: {err}");
}
}
ViewportCommand::Title(title) => {
window.set_title(&title);
}
ViewportCommand::InnerSize(size) => {
let width_px = pixels_per_point * size.x.max(1.0);
let height_px = pixels_per_point * size.y.max(1.0);
window.set_inner_size(PhysicalSize::new(width_px, height_px));
}
ViewportCommand::BeginResize(direction) => {
if let Err(err) = window.drag_resize_window(match direction {
egui::viewport::ResizeDirection::North => ResizeDirection::North,
egui::viewport::ResizeDirection::South => ResizeDirection::South,
egui::viewport::ResizeDirection::West => ResizeDirection::West,
egui::viewport::ResizeDirection::NorthEast => ResizeDirection::NorthEast,
egui::viewport::ResizeDirection::SouthEast => ResizeDirection::SouthEast,
egui::viewport::ResizeDirection::NorthWest => ResizeDirection::NorthWest,
egui::viewport::ResizeDirection::SouthWest => ResizeDirection::SouthWest,
}) {
log::warn!("{command:?}: {err}");
}
ViewportCommand::Transparent(v) => window.set_transparent(v),
ViewportCommand::Visible(v) => window.set_visible(v),
ViewportCommand::OuterPosition(pos) => {
window.set_outer_position(LogicalPosition::new(pos.x, pos.y));
}
ViewportCommand::Title(title) => {
window.set_title(&title);
}
ViewportCommand::Transparent(v) => window.set_transparent(v),
ViewportCommand::Visible(v) => window.set_visible(v),
ViewportCommand::OuterPosition(pos) => {
window.set_outer_position(PhysicalPosition::new(
pixels_per_point * pos.x,
pixels_per_point * pos.y,
));
}
ViewportCommand::MinInnerSize(s) => {
window.set_min_inner_size((s.is_finite() && s != Vec2::ZERO).then_some(
PhysicalSize::new(pixels_per_point * s.x, pixels_per_point * s.y),
));
}
ViewportCommand::MaxInnerSize(s) => {
window.set_max_inner_size((s.is_finite() && s != Vec2::INFINITY).then_some(
PhysicalSize::new(pixels_per_point * s.x, pixels_per_point * s.y),
));
}
ViewportCommand::ResizeIncrements(s) => {
window.set_resize_increments(
s.map(|s| PhysicalSize::new(pixels_per_point * s.x, pixels_per_point * s.y)),
);
}
ViewportCommand::Resizable(v) => window.set_resizable(v),
ViewportCommand::EnableButtons {
close,
minimized,
maximize,
} => window.set_enabled_buttons(
if close {
WindowButtons::CLOSE
} else {
WindowButtons::empty()
} | if minimized {
WindowButtons::MINIMIZE
} else {
WindowButtons::empty()
} | if maximize {
WindowButtons::MAXIMIZE
} else {
WindowButtons::empty()
},
),
ViewportCommand::Minimized(v) => {
window.set_minimized(v);
info.minimized = Some(v);
}
ViewportCommand::Maximized(v) => {
window.set_maximized(v);
info.maximized = Some(v);
}
ViewportCommand::Fullscreen(v) => {
window.set_fullscreen(v.then_some(winit::window::Fullscreen::Borderless(None)));
}
ViewportCommand::Decorations(v) => window.set_decorations(v),
ViewportCommand::WindowLevel(l) => window.set_window_level(match l {
egui::viewport::WindowLevel::AlwaysOnBottom => WindowLevel::AlwaysOnBottom,
egui::viewport::WindowLevel::AlwaysOnTop => WindowLevel::AlwaysOnTop,
egui::viewport::WindowLevel::Normal => WindowLevel::Normal,
}),
ViewportCommand::Icon(icon) => {
window.set_window_icon(icon.map(|icon| {
winit::window::Icon::from_rgba(icon.rgba.clone(), icon.width, icon.height)
.expect("Invalid ICON data!")
}));
}
ViewportCommand::IMEPosition(pos) => {
window.set_ime_position(PhysicalPosition::new(
pixels_per_point * pos.x,
pixels_per_point * pos.y,
));
}
ViewportCommand::IMEAllowed(v) => window.set_ime_allowed(v),
ViewportCommand::IMEPurpose(p) => window.set_ime_purpose(match p {
egui::viewport::IMEPurpose::Password => winit::window::ImePurpose::Password,
egui::viewport::IMEPurpose::Terminal => winit::window::ImePurpose::Terminal,
egui::viewport::IMEPurpose::Normal => winit::window::ImePurpose::Normal,
}),
ViewportCommand::Focus => {
if !window.has_focus() {
window.focus_window();
}
ViewportCommand::MinInnerSize(s) => {
window.set_min_inner_size(
(s.is_finite() && s != Vec2::ZERO).then_some(LogicalSize::new(s.x, s.y)),
);
}
ViewportCommand::MaxInnerSize(s) => {
window.set_max_inner_size(
(s.is_finite() && s != Vec2::INFINITY).then_some(LogicalSize::new(s.x, s.y)),
);
}
ViewportCommand::ResizeIncrements(s) => {
window.set_resize_increments(s.map(|s| LogicalSize::new(s.x, s.y)));
}
ViewportCommand::Resizable(v) => window.set_resizable(v),
ViewportCommand::EnableButtons {
close,
minimized,
maximize,
} => window.set_enabled_buttons(
if close {
WindowButtons::CLOSE
} else {
WindowButtons::empty()
} | if minimized {
WindowButtons::MINIMIZE
} else {
WindowButtons::empty()
} | if maximize {
WindowButtons::MAXIMIZE
} else {
WindowButtons::empty()
},
),
ViewportCommand::Minimized(v) => {
window.set_minimized(v);
info.minimized = Some(v);
}
ViewportCommand::Maximized(v) => {
window.set_maximized(v);
info.maximized = Some(v);
}
ViewportCommand::Fullscreen(v) => {
window.set_fullscreen(v.then_some(winit::window::Fullscreen::Borderless(None)));
}
ViewportCommand::Decorations(v) => window.set_decorations(v),
ViewportCommand::WindowLevel(l) => window.set_window_level(match l {
egui::viewport::WindowLevel::AlwaysOnBottom => WindowLevel::AlwaysOnBottom,
egui::viewport::WindowLevel::AlwaysOnTop => WindowLevel::AlwaysOnTop,
egui::viewport::WindowLevel::Normal => WindowLevel::Normal,
}),
ViewportCommand::Icon(icon) => {
window.set_window_icon(icon.map(|icon| {
winit::window::Icon::from_rgba(icon.rgba.clone(), icon.width, icon.height)
.expect("Invalid ICON data!")
}));
}
ViewportCommand::IMEPosition(pos) => {
window.set_ime_position(LogicalPosition::new(pos.x, pos.y));
}
ViewportCommand::IMEAllowed(v) => window.set_ime_allowed(v),
ViewportCommand::IMEPurpose(p) => window.set_ime_purpose(match p {
egui::viewport::IMEPurpose::Password => winit::window::ImePurpose::Password,
egui::viewport::IMEPurpose::Terminal => winit::window::ImePurpose::Terminal,
egui::viewport::IMEPurpose::Normal => winit::window::ImePurpose::Normal,
}),
ViewportCommand::Focus => {
if !window.has_focus() {
window.focus_window();
}
ViewportCommand::RequestUserAttention(a) => {
window.request_user_attention(match a {
egui::UserAttentionType::Reset => None,
egui::UserAttentionType::Critical => {
Some(winit::window::UserAttentionType::Critical)
}
}
ViewportCommand::RequestUserAttention(a) => {
window.request_user_attention(match a {
egui::UserAttentionType::Reset => None,
egui::UserAttentionType::Critical => {
Some(winit::window::UserAttentionType::Critical)
}
egui::UserAttentionType::Informational => {
Some(winit::window::UserAttentionType::Informational)
}
});
}
ViewportCommand::SetTheme(t) => window.set_theme(match t {
egui::SystemTheme::Light => Some(winit::window::Theme::Light),
egui::SystemTheme::Dark => Some(winit::window::Theme::Dark),
egui::SystemTheme::SystemDefault => None,
}),
ViewportCommand::ContentProtected(v) => window.set_content_protected(v),
ViewportCommand::CursorPosition(pos) => {
if let Err(err) = window.set_cursor_position(LogicalPosition::new(pos.x, pos.y)) {
log::warn!("{command:?}: {err}");
egui::UserAttentionType::Informational => {
Some(winit::window::UserAttentionType::Informational)
}
});
}
ViewportCommand::SetTheme(t) => window.set_theme(match t {
egui::SystemTheme::Light => Some(winit::window::Theme::Light),
egui::SystemTheme::Dark => Some(winit::window::Theme::Dark),
egui::SystemTheme::SystemDefault => None,
}),
ViewportCommand::ContentProtected(v) => window.set_content_protected(v),
ViewportCommand::CursorPosition(pos) => {
if let Err(err) = window.set_cursor_position(PhysicalPosition::new(
pixels_per_point * pos.x,
pixels_per_point * pos.y,
)) {
log::warn!("{command:?}: {err}");
}
ViewportCommand::CursorGrab(o) => {
if let Err(err) = window.set_cursor_grab(match o {
egui::viewport::CursorGrab::None => CursorGrabMode::None,
egui::viewport::CursorGrab::Confined => CursorGrabMode::Confined,
egui::viewport::CursorGrab::Locked => CursorGrabMode::Locked,
}) {
log::warn!("{command:?}: {err}");
}
}
ViewportCommand::CursorGrab(o) => {
if let Err(err) = window.set_cursor_grab(match o {
egui::viewport::CursorGrab::None => CursorGrabMode::None,
egui::viewport::CursorGrab::Confined => CursorGrabMode::Confined,
egui::viewport::CursorGrab::Locked => CursorGrabMode::Locked,
}) {
log::warn!("{command:?}: {err}");
}
ViewportCommand::CursorVisible(v) => window.set_cursor_visible(v),
ViewportCommand::MousePassthrough(passthrough) => {
if let Err(err) = window.set_cursor_hittest(!passthrough) {
log::warn!("{command:?}: {err}");
}
}
ViewportCommand::Screenshot => {
*screenshot_requested = true;
}
ViewportCommand::CursorVisible(v) => window.set_cursor_visible(v),
ViewportCommand::MousePassthrough(passthrough) => {
if let Err(err) = window.set_cursor_hittest(!passthrough) {
log::warn!("{command:?}: {err}");
}
}
ViewportCommand::Screenshot => {
*screenshot_requested = true;
}
}
}
pub fn create_winit_window_builder(
pub fn create_winit_window_builder<T>(
egui_ctx: &egui::Context,
event_loop: &EventLoopWindowTarget<T>,
viewport_builder: ViewportBuilder,
) -> winit::window::WindowBuilder {
crate::profile_function!();
// We set sizes and positions in egui:s own ui points, which depends on the egui
// zoom_factor and the native pixels per point, so we need to know that here.
let native_pixels_per_point = event_loop
.primary_monitor()
.or_else(|| event_loop.available_monitors().next())
.map_or_else(
|| {
log::debug!("Failed to find a monitor - assuming native_pixels_per_point of 1.0");
1.0
},
|m| m.scale_factor() as f32,
);
let zoom_factor = egui_ctx.zoom_factor();
let pixels_per_point = zoom_factor * native_pixels_per_point;
let ViewportBuilder {
title,
position,
@@ -1271,27 +1327,31 @@ pub fn create_winit_window_builder(
.with_active(active.unwrap_or(true));
if let Some(inner_size) = inner_size {
window_builder = window_builder
.with_inner_size(winit::dpi::LogicalSize::new(inner_size.x, inner_size.y));
window_builder = window_builder.with_inner_size(PhysicalSize::new(
pixels_per_point * inner_size.x,
pixels_per_point * inner_size.y,
));
}
if let Some(min_inner_size) = min_inner_size {
window_builder = window_builder.with_min_inner_size(winit::dpi::LogicalSize::new(
min_inner_size.x,
min_inner_size.y,
window_builder = window_builder.with_min_inner_size(PhysicalSize::new(
pixels_per_point * min_inner_size.x,
pixels_per_point * min_inner_size.y,
));
}
if let Some(max_inner_size) = max_inner_size {
window_builder = window_builder.with_max_inner_size(winit::dpi::LogicalSize::new(
max_inner_size.x,
max_inner_size.y,
window_builder = window_builder.with_max_inner_size(PhysicalSize::new(
pixels_per_point * max_inner_size.x,
pixels_per_point * max_inner_size.y,
));
}
if let Some(position) = position {
window_builder =
window_builder.with_position(winit::dpi::LogicalPosition::new(position.x, position.y));
window_builder = window_builder.with_position(PhysicalPosition::new(
pixels_per_point * position.x,
pixels_per_point * position.y,
));
}
if let Some(icon) = icon {
@@ -1430,10 +1490,3 @@ mod profiling_scopes {
}
pub(crate) use profile_scope;
}
#[allow(unused_imports)]
pub(crate) use profiling_scopes::*;
use winit::{
dpi::{LogicalPosition, LogicalSize},
window::{CursorGrabMode, Window, WindowButtons, WindowLevel},
};

View File

@@ -18,8 +18,10 @@ pub struct WindowSettings {
}
impl WindowSettings {
pub fn from_display(window: &winit::window::Window) -> Self {
let inner_size_points = window.inner_size().to_logical::<f32>(window.scale_factor());
pub fn from_window(egui_zoom_factor: f32, window: &winit::window::Window) -> Self {
let inner_size_points = window
.inner_size()
.to_logical::<f32>(egui_zoom_factor as f64 * window.scale_factor());
let inner_position_pixels = window
.inner_position()
@@ -100,6 +102,7 @@ impl WindowSettings {
pub fn clamp_position_to_monitors<E>(
&mut self,
egui_zoom_factor: f32,
event_loop: &winit::event_loop::EventLoopWindowTarget<E>,
) {
// If the app last ran on two monitors and only one is now connected, then
@@ -116,15 +119,16 @@ impl WindowSettings {
};
if let Some(pos_px) = &mut self.inner_position_pixels {
clamp_pos_to_monitors(event_loop, inner_size_points, pos_px);
clamp_pos_to_monitors(egui_zoom_factor, event_loop, inner_size_points, pos_px);
}
if let Some(pos_px) = &mut self.outer_position_pixels {
clamp_pos_to_monitors(event_loop, inner_size_points, pos_px);
clamp_pos_to_monitors(egui_zoom_factor, event_loop, inner_size_points, pos_px);
}
}
}
fn clamp_pos_to_monitors<E>(
egui_zoom_factor: f32,
event_loop: &winit::event_loop::EventLoopWindowTarget<E>,
window_size_pts: egui::Vec2,
position_px: &mut egui::Pos2,
@@ -142,7 +146,7 @@ fn clamp_pos_to_monitors<E>(
};
for monitor in monitors {
let window_size_px = window_size_pts * (monitor.scale_factor() as f32);
let window_size_px = window_size_pts * (egui_zoom_factor * monitor.scale_factor() as f32);
let monitor_x_range = (monitor.position().x - window_size_px.x as i32)
..(monitor.position().x + monitor.size().width as i32);
let monitor_y_range = (monitor.position().y - window_size_px.y as i32)
@@ -155,10 +159,14 @@ fn clamp_pos_to_monitors<E>(
}
}
let mut window_size_px = window_size_pts * (active_monitor.scale_factor() as f32);
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.
if cfg!(target_os = "windows") {
window_size_px += egui::Vec2::new(0.0, 32.0 * active_monitor.scale_factor() as f32);
window_size_px += egui::Vec2::new(
0.0,
32.0 * egui_zoom_factor * active_monitor.scale_factor() as f32,
);
}
let monitor_position = egui::Pos2::new(
active_monitor.position().x as f32,