Apps must read each display's scale, not a system-wide value
Aliases: per-display scale factor · display DPI · logical-to-physical scale
What it is
A laptop panel sits at 200% while an external monitor sits at 100%, both on. Per-monitor DPI means each display owns its own logical-to-physical pixel ratio. An app has to ask “what is the scale of the screen this window is on now,” not read one machine-wide DPI and reuse it everywhere. A global value makes the UI on one of the screens either too small to read or too large to fit. This entry is only that the ratio is per display. It is not about reloading bitmaps, what blur and misalignment look like, or how type and spacing accumulate rounding error.
Why it happens
The OS stores scale as a property of a display, not of a process. A window’s effective ratio is usually that of the screen that owns most of its area, or the screen under its center; dragging across screens changes that ownership. Early desktops treated DPI as a machine constant—one value, every window. Once mixed resolutions appear, that constant lies to one of the screens. An app that reads system DPI once at launch and caches it still uses the first screen’s ratio after a second display is plugged in, or after the window is dragged there. The transform between logical coordinates and physical pixels has to follow the current screen; otherwise hit testing, text rasterization, and border widths are multiplied by the wrong factor.
Studying it
Build a two-screen rig: one integer scale (200%), one 100% or a non-integer, and park the same window on each. Compare reading a global DPI against querying the screen the window occupies.
Independent variables: each screen’s scale, the window’s area share across screens, whether the query happens at launch or on entering that screen. Dependent variables: whether the same control is close in physical size on both screens, whether clicks land on the visible control, whether people feel they “got a different UI after the drag.”
Measuring a line labeled 1 cm with a ruler is closer to perception than inspecting screenshot pixels. If both screens are set to the same scale, per-display independence is never observed. Do not count “the two screens have different white points” or “a menu was clipped at the bezel” on this claim—those are a different multi-display cluster.
Where it stops holding
On a single screen, the global value and the per-display value coincide; there is nothing to observe. When the OS forces two screens onto one scale, a wrong global read stays hidden. Full-screen exclusive apps that never move (games, talks) only need the scale of the screen they launched on. If a browser or toolkit is already uniformly scaled by the compositor on a backing buffer, a second multiply in the app doubles the size.
Applying it
- Re-query the current screen’s scale on move-in, on hot-plug, and when the user changes that screen’s scale; do not cache the launch-time system value.
- Drive layout, hit testing, and text rasterization from the window’s current screen; do not apply the primary’s ratio to a window on the secondary.
- Scale will jump while the window straddles two screens; update from the screen with the larger area share so the window does not oscillate on the seam.
- Verify: primary at 200%, secondary at 100%, move the same window wholly onto the secondary. Controls should stay near a readable physical size, and clicks should match visible pixels. Anything that is only correct after relaunch treated scale as a process constant.
Related
- Within the group: K2.08.2 Bitmaps must reload at the destination display's resolution when moved · K2.08.3 Apps that ignore per-display scale go blurry or misaligned on high-DPI screens · K2.08.4 Font size and spacing conversions accumulate error under mixed resolutions
- Adjacent: K2.02 Multiple Displays · K1.02 Screen Size and Density Differences
- Search terms:
per-monitor DPI·display scale factor·logical pixels