Configure the Kuycon by what it is, not where it is plugged in

The panel's 4500x3000 mode, 1.5 scale, and 10-bit request were a rule
for connector DP-2 outright, which handed them to whatever monitor a
stranger's machine had on its most common DisplayPort connector. The
rule is now matched by description, the per-output prefs loop covers
every connector including DP-2, and the displays contract pins the
policy to the description rather than the port.
This commit is contained in:
Gabriel Brown
2026-08-21 17:43:33 -04:00
parent 7d633eb06e
commit 9f563c8f94
3 changed files with 38 additions and 29 deletions
+1 -1
View File
@@ -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 |
+30 -27
View File
@@ -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,32 +125,10 @@ local function display_position(entry, fallback)
return fallback
end
local shipped_mode = "4500x3000@60"
local shipped_scale = 1.5
local shipped_transform = 0
local dp2 = 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,
-- 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
-- falls back to a lower mode, drop this line first.
bitdepth = 10,
-- "auto" = sRGB at 8bpc, wide gamut at 10bpc. Not HDR; see header.
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.
-- 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
if output ~= "DP-2" then
local entry = display_entry(output)
if entry ~= nil then
hl.monitor({
@@ -162,7 +140,32 @@ for output, _ in pairs(displays) do
})
end
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 kuycon = display_entry("DP-2")
hl.monitor({
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
-- falls back to a lower mode, drop this line first.
bitdepth = 10,
-- "auto" = sRGB at 8bpc, wide gamut at 10bpc. Not HDR; see header.
cm = "auto",
})
-- Any monitor not named above: sane defaults rather than nothing.
hl.monitor({
+8 -2
View File
@@ -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)