Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Window size (and position) gets fractionally scaled incorrectly when persistence is enabled #3797

Open
museun opened this issue Jan 9, 2024 · 1 comment
Labels
bug Something is broken

Comments

@museun
Copy link

museun commented Jan 9, 2024

Describe the bug
When persistence is enabled in eframe and zoom_factor is changed from the default, closing the window causes the saved window size to be scaled incorrectly.

This also affects positioning when the application is ran a second time.

To Reproduce
Steps to reproduce the behavior:
1: Enable persistence
2: In the AppCreator change the zoom_factor to something greater than 1.0
3: Close window
4: Restart application

Expected behavior
The window should roughly be in the same place and with the same size on repeated starts.

Screenshots

Desktop (please complete the following information):

  • OS: Windows
  • Version 0.25.0

Additional context
It boils down to this:
In this function

pub fn from_window(egui_zoom_factor: f32, window: &winit::window::Window) -> Self {

Zoom factor is multiplied by the window factor

.to_logical::<f32>(egui_zoom_factor as f64 * window.scale_factor());

But in winit, to_logical is defined as:

pub fn to_logical<X: Pixel>(&self, scale_factor: f64) -> LogicalPosition<X> {
    assert!(validate_scale_factor(scale_factor));
    let x = self.x.into() / scale_factor;
    let y = self.y.into() / scale_factor;
    LogicalPosition::new(x, y).cast()
}

at: https://github.com/rust-windowing/winit/blob/v0.29.4/src/dpi.rs#L273-L278

Assume:
We set the zoom_factor to 2.0
The window scale_factor is 1.0

2.0 * 1.0 is 2.0

to_logical(2.0) will divide the width and height by 2.0
(reducing the window size by half, each time)

The inverse also holds, if the zoom_factor is set to 0.5, the window's size grows each run.

Removing the multiplication, e.g. changing

let inner_size_points = window
.inner_size()
.to_logical::<f32>(egui_zoom_factor as f64 * window.scale_factor());

to

let inner_size_points = window.inner_size().to_logical::<f32>(window.scale_factor());

produces the correct behavior. But only when it doesn't persist the memory:

fn persist_egui_memory(&self) -> bool {
    false
}

Edit:
The bug still exists when removing the multiplication and persist_egui_memory returns true.

@museun museun added the bug Something is broken label Jan 9, 2024
@museun
Copy link
Author

museun commented Jan 9, 2024

With persist_egui_memory = true and the zoom_factor * window_scale_factor() is restored, the window size is correct.

But, the

WindowSettings::inner_position_pixels
WindowSettings::outer_position_pixels

sizes are now scaled by the zoom_factor on save.

With zoom_factor = 2.0

// the value after loading
WindowSettings {
    inner_position_pixels: Some(
        [216.0 239.0],
    ),
    outer_position_pixels: Some(
        [208.0 208.0],
    ),
    fullscreen: false,
    inner_size_points: Some(
        [400.0 300.0],
    ),
}

// the value before saving
WindowSettings {
    inner_position_pixels: Some(
        [424.0 447.0],
    ),
    outer_position_pixels: Some(
        [416.0 416.0],
    ),
    fullscreen: false,
    inner_size_points: Some(
        [400.0 300.0],
    ),
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is broken
Projects
Status: No status
Development

No branches or pull requests

2 participants