emilk / emilk/egui

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

Open
#3,797 1 comment 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.