-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Description
summary
When a window is created on a high-DPI monitor (scale 2.0), programmatically moved to a low-DPI monitor (scale 1.0) and resized, then manually dragged back to the original monitor, the window size incorrectly resets to the original default size instead of maintaining the programmatically set size.
repro
hardware
- macOS with dual monitor setup
- Monitor 0: High-DPI (Retina, scale factor 2.0)
- Monitor 1: Low-DPI (external, scale factor 1.0)
clone from my example based on a branch of v0.30.12
Minimal reproduction example and debug logging available at:
https://github.com/natepiano/winit/tree/macos-scale-restore-bug
git clone https://github.com/natepiano/winit.git
cd winit
cargo run --example macos_scale_restore_bug
repro steps
- Launch example on Monitor 0 (Retina) - window appears at 800x600 logical
- Press 'R' to programmatically move to Monitor 1 and resize to 600x400
- Drag window back to Monitor 0
- BUG: Window resets to 800x600 instead of staying at 600x400
workaround
If you manually resize the window (even slightly) on Monitor 1 before dragging back, the bug does not occur. Try it yourself to see the difference.
hypothetical root cause
AppKit internally tracks "user intended size" per scale factor. When a window is created at size X on scale=2, AppKit remembers X as the intended size for scale=2.
-
Programmatic resize via setContentSize does NOT update this internal tracking
-
Manual resize via windowDidEndLiveResize DOES update the tracking
When the window returns to scale=2, AppKit "helpfully" restores the original size it has cached for that scale factor.
Debug logging in the example shows:
[DEFERRED RESIZE] Now applying 600x400 physical at scale=1 ✓ Correct
[RESIZE] 1200x800 physical (600x400 logical at scale 2) ✓ Initially correct when dragged back
[winit macOS] windowWillStartLiveResize
[winit macOS] frameDidChange: logical 800x600 ✗ BUG: Reset to default
caveat
This is just a hypothesis - i don't for sure know what's happening but i do know that for now in my code on my system i need to provide a workaround for this situation.
Possible Fix
Winit may need to work around this AppKit behavior by either:
- Re-applying the desired size after detecting an unwanted reset during frameDidChange
- Triggering whatever internal state update windowDidEndLiveResize performs after programmatic resizes
macOS version
ProductName: macOS
ProductVersion: 26.1
BuildVersion: 25B78Winit version
0.30.12