-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Description
Description
When calling set_outer_position() or request_inner_size() to move/resize a window to a position on a different monitor with a different scale factor, winit converts the coordinates using the current window's monitor scale factor instead of the target monitor's scale factor.
This is the write-side counterpart to #2645, which documents the same fundamental issue for read operations (outer_position(), MonitorHandle::position()).
Environment
- macOS (tested on Tahoe 26.1)
- Multi-monitor setup with different scale factors (e.g., Retina 2.0x + external 1.0x)
Reproduction
- Connect a Retina display (scale factor 2.0) and an external display (scale factor 1.0)
- Launch application on the 1.0x monitor
- Save a window position from the 2.0x monitor (e.g., physical position (1728, 68))
- Call set_outer_position(PhysicalPosition::new(1728, 68)) to restore
Expected: Window appears at physical position (1728, 68) on the 2.0x monitor
Actual: Window appears at physical position (3456, 136) — coordinates are doubled
Root Cause
In the macOS backend, set_outer_position converts PhysicalPosition to the internal coordinate system using backingScaleFactor() from the window's current monitor. When the target position is on a different monitor, this conversion is incorrect.
Similarly, request_inner_size uses the current monitor's scale factor when converting physical size to logical size for setContentSize:.
Impact
Applications that save/restore window position across sessions cannot correctly restore windows to monitors with different scale factors than the launch monitor. The position/size error is proportional to the scale factor ratio between monitors.
Workaround
We currently compensate by pre-multiplying coordinates by (current_scale / target_scale) before calling these methods, but this requires:
- Knowing which monitor the window will land on
- Different strategies for high→low vs low→high DPI transitions
- A two-phase approach for high→low transitions due to size clamping
Related Issues
MonitorHandle::positionandMonitorHandle::sizemetrics are unclear #2645 — Same root cause, but for read operations (outer_position(), MonitorHandle::position())- HiDPI scaling finetuning #837 — HiDPI scaling architecture discussion
macOS version
ProductName: macOS
ProductVersion: 26.1
BuildVersion: 25B78Winit version
0.30