Window size (and position) gets fractionally scaled incorrectly when `persistence` is enabled
- Dominant language
- Rust
- Stars
- 30.6k
- Forks
- 2.1k
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 72
Description
**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
https://github.com/emilk/egui/blob/12ad9e7b364ae2f5d60ebb7f8c1ca571f590e63a/crates/egui-winit/src/window_settings.rs#L21
Zoom factor is multiplied by the window factor
https://github.com/emilk/egui/blob/12ad9e7b364ae2f5d60ebb7f8c1ca571f590e63a/crates/egui-winit/src/window_settings.rs#L24
But in winit, `to_logical` is defined as:
```rust
pub fn to_logical(&self, scale_factor: f64) -> LogicalPosition {
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
https://github.com/emilk/egui/blob/12ad9e7b364ae2f5d60ebb7f8c1ca571f590e63a/crates/egui-winit/src/window_settings.rs#L22-L24
to
```rust
let inner_size_points = window.inner_size().to_logical::(window.scale_factor());
```
produces the correct behavior. But only when it doesn't persist the memory:
```rust
fn persist_egui_memory(&self) -> bool {
false
}
```
Edit:
The bug still exists when removing the multiplication and `persist_egui_memory` returns true.
Contributor guide
Research direction
Start in crates/egui-winit/src/window_settings.rs, especially the inner-size calculation and the persistence path referenced in the report. Reproduce the Windows scenario with a non-default zoom_factor and persist_egui_memory enabled, then trace the saved size and position across restarts. Done means the window remains roughly the same size and position without fractional scaling drift.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100