mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-25 01:38:02 +02:00
Wayland: guess the origin (0,0) output for a fresh window's fractional scale
When there is no focused or recently-focused window to key off of (the typical first-window-at-startup case), glfwGetWaylandCurrentMonitorFractionalScale fell back to the registry-first output (monitors[0]). Registry/connector order is semi-arbitrary and uncorrelated with where a compositor actually places a new window, so on a multi-monitor setup with mixed fractional scales the first window could be born at the wrong size. Prefer the output at the logical origin (0, 0) instead: the compositor's top-left/primary output is a better guess for initial placement than registry order. Fall back to monitors[0] when no output reports (0, 0). Since xdg_output geometry (including position) arrives asynchronously and x/y read zero until it does, wait for every monitor's logical geometry before trusting the reported positions, so an as-yet-unpositioned output cannot spuriously match (0, 0). Discussed in #10268. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjwP6hQjA6GMuiM7Mf9VAx
This commit is contained in:
27
glfw/wl_monitor.c
vendored
27
glfw/wl_monitor.c
vendored
@@ -351,8 +351,31 @@ GLFWAPI double glfwGetWaylandCurrentMonitorFractionalScale(void)
|
||||
if (window && window->wl.monitorsCount > 0)
|
||||
monitor = window->wl.monitors[0];
|
||||
}
|
||||
if (!monitor)
|
||||
monitor = _glfw.monitors[0];
|
||||
if (!monitor) {
|
||||
// No focused window to key off of (typically the first window at
|
||||
// startup). Prefer the output at the logical origin (0, 0): the
|
||||
// compositor's top-left/primary output is a better guess for where a
|
||||
// new window will be placed than registry order. Fall back to the
|
||||
// first output if no output reports position (0, 0).
|
||||
//
|
||||
// xdg_output geometry arrives asynchronously and x/y remain zero until
|
||||
// it does, so wait for every monitor's logical geometry before trusting
|
||||
// the reported positions (otherwise an as-yet-unpositioned output would
|
||||
// spuriously match (0, 0)).
|
||||
for (int i = 0; i < _glfw.monitorCount; i++) {
|
||||
_GLFWmonitor *m = _glfw.monitors[i];
|
||||
while (m->wl.xdg_output && m->wl.xdg_logical_width <= 0) {
|
||||
if (wl_display_roundtrip(_glfw.wl.display) < 0) break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < _glfw.monitorCount; i++) {
|
||||
_GLFWmonitor *m = _glfw.monitors[i];
|
||||
if (m->wl.xdg_output && m->wl.xdg_logical_width > 0 &&
|
||||
m->wl.x == 0 && m->wl.y == 0) { monitor = m; break; }
|
||||
}
|
||||
if (!monitor)
|
||||
monitor = _glfw.monitors[0];
|
||||
}
|
||||
|
||||
if (!monitor->wl.xdg_output)
|
||||
return monitor->wl.scale > 0 ? (double)monitor->wl.scale : 1.0;
|
||||
|
||||
Reference in New Issue
Block a user