diff --git a/config/dot/hypr/README.md b/config/dot/hypr/README.md index 1767095..5adf4e8 100644 --- a/config/dot/hypr/README.md +++ b/config/dot/hypr/README.md @@ -29,7 +29,7 @@ Don't "fix" them. | `hyprland.lua` | Entry point. Each `require()` is its own error scope | | `prefs.lua` | Reads the settings file the Settings app writes. See below | | `env.lua` | Environment. Note the uwsm caveat below | -| `monitors.lua` | DP-2 geometry, scaling, and the HDR decision | +| `monitors.lua` | Monitor geometry and scaling (the Kuycon by description), and the HDR decision | | `looks.lua` | Colors, blur, glow, shadows, animations, VRR, scanout | | `input.lua` | Keyboard/mouse. Click-to-focus, like GNOME | | `rules.lua` | Window rules, gaming rules, layer rules for the shell | diff --git a/config/dot/hypr/monitors.lua b/config/dot/hypr/monitors.lua index 28f1970..4011d7c 100644 --- a/config/dot/hypr/monitors.lua +++ b/config/dot/hypr/monitors.lua @@ -1,7 +1,7 @@ -- ───────────────────────────────────────────────────────────────────────────── -- Monitors -- --- Kuycon P20 on DP-2: 4500x3000 @ 60Hz, 1.5x fractional scale. +-- Kuycon P20 (matched by description): 4500x3000 @ 60Hz, 1.5x fractional scale. -- 4500/1.5 = 3000 and 3000/1.5 = 2000, both integers, so this is a "clean" -- fractional scale and Hyprland will not complain. -- @@ -125,17 +125,38 @@ local function display_position(entry, fallback) return fallback end +-- Every connected output uses the same validated per-output store. Automatic +-- placement and the compositor's normal color policy unless the entry says +-- otherwise. +for output, _ in pairs(displays) do + local entry = display_entry(output) + if entry ~= nil then + hl.monitor({ + output = output, + mode = entry.mode, + position = display_position(entry, "auto"), + scale = entry.scale, + transform = entry.transform, + }) + end +end + +-- The Kuycon P20, matched by what it is rather than where it is plugged in. +-- This used to be a rule for connector DP-2 outright, which handed the panel's +-- 4500x3000 mode and 1.5 scale to whatever monitor a stranger's machine had on +-- its most common DisplayPort connector. Emitted after the prefs loop so a +-- saved entry for its connector still carries the mode/scale/position, while +-- this rule holds the shipped defaults and the panel-specific color policy. local shipped_mode = "4500x3000@60" local shipped_scale = 1.5 local shipped_transform = 0 -local dp2 = display_entry("DP-2") - +local kuycon = display_entry("DP-2") hl.monitor({ - output = "DP-2", - mode = dp2 and dp2.mode or shipped_mode, - position = display_position(dp2, "0x0"), - scale = dp2 and dp2.scale or shipped_scale, - transform = dp2 and dp2.transform or shipped_transform, + output = "desc:GVT Kuycon P20", + mode = kuycon and kuycon.mode or shipped_mode, + position = display_position(kuycon, "0x0"), + scale = kuycon and kuycon.scale or shipped_scale, + transform = kuycon and kuycon.transform or shipped_transform, -- 10-bit output. 4500x3000@60 at 10bpc is ~24 Gbps, right at the edge of -- DP 1.4 HBR3, so this relies on DSC. If the display fails to light up or @@ -146,24 +167,6 @@ hl.monitor({ cm = "auto", }) --- Other connected outputs use the same validated per-output store. They keep --- automatic placement and the compositor's normal color policy; DP-2 alone --- carries the panel-specific 10-bit policy documented above. -for output, _ in pairs(displays) do - if output ~= "DP-2" then - local entry = display_entry(output) - if entry ~= nil then - hl.monitor({ - output = output, - mode = entry.mode, - position = display_position(entry, "auto"), - scale = entry.scale, - transform = entry.transform, - }) - end - end -end - -- Any monitor not named above: sane defaults rather than nothing. hl.monitor({ output = "", diff --git a/tests/quickshell/displays-contract b/tests/quickshell/displays-contract index 52e7915..135c180 100755 --- a/tests/quickshell/displays-contract +++ b/tests/quickshell/displays-contract @@ -122,8 +122,14 @@ assert(by_output["DP-2"].mode == "4500x3000@60") assert(by_output["DP-2"].scale == 1.5) assert(by_output["DP-2"].transform == 0) assert(by_output["DP-2"].position == "0x0") -assert(by_output["DP-2"].bitdepth == 10) -assert(by_output["DP-2"].cm == "auto") +-- The panel-specific color policy rides the description-matched rule, not the +-- connector: a stranger's monitor on DP-2 must not inherit the Kuycon's mode +-- or its 10-bit request. +local kuycon = by_output["desc:GVT Kuycon P20"] +assert(kuycon ~= nil) +assert(kuycon.mode == "4500x3000@60") +assert(kuycon.bitdepth == 10) +assert(kuycon.cm == "auto") assert(by_output["HDMI-A-1"].mode == "2560x1440@60") assert(by_output["HDMI-A-1"].scale == 1) assert(by_output["HDMI-A-1"].transform == 1)