Resolution, refresh rate, scale, and rotation, applied through
hl.monitor{} and stored per output.
This is the only setting in Panama where a wrong value can leave the
user unable to SEE the screen well enough to undo it: a mode the panel
cannot show, or a scale that makes everything unreadable, is not
recoverable through the UI that caused it. So a change is never applied
irreversibly. It is applied, then reverted automatically after fifteen
seconds unless confirmed, and confirming is what writes it to the
settings store -- letting the countdown run leaves nothing behind.
The contract tests that property specifically: it applies a scale, waits
out the countdown, and asserts the display came back and that nothing
was stored. A regression there is not a broken feature, it is a user
staring at a blank monitor.
Modes are grouped by resolution with refresh rates beside them. The
panel reports 35, many differing only in refresh-rate rounding -- 60.00
and 59.94 -- which as a flat list of buttons is noise rather than
choice; equal rounded pairs collapse, leaving 21.
Only mode, scale, and transform are configurable. Colour management and
bit depth stay in monitors.lua because they carry a documented screencopy
tradeoff that a settings page cannot explain at the moment you would be
changing it.
Also replaces the display policy rows with the schema-bound ones, so the
page no longer restates labels that PreferenceSchema already holds.
Claude-Session: https://claude.ai/code/session_01BRvzt4H8XXLPVH5MyYdk9L
68 lines
2.8 KiB
Lua
68 lines
2.8 KiB
Lua
-- ─────────────────────────────────────────────────────────────────────────────
|
|
-- Monitors
|
|
--
|
|
-- Kuycon P20 on DP-2: 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.
|
|
--
|
|
-- On HDR --------------------------------------------------------------------
|
|
-- GNOME runs this panel in bt2100/HDR. Hyprland CAN do that (cm = "hdr"), but
|
|
-- on 0.56.x it currently breaks screencopy: grim screenshots come back empty,
|
|
-- and OBS/Sunshine capture and hyprlock's blurred background go with them.
|
|
-- Root cause is still open upstream. Since screen capture matters more here
|
|
-- than an HDR desktop, the desktop runs SDR at 10-bit and HDR is handed to
|
|
-- fullscreen games only, via render.cm_auto_hdr in looks.lua.
|
|
--
|
|
-- To try full-time HDR anyway, set cm = "hdr" below (or override it in
|
|
-- overrides.lua) and read the notes in that file first.
|
|
-- ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
local prefs = require("prefs")
|
|
|
|
-- Per-output overrides written by Panama Settings, keyed by output name:
|
|
-- { ["DP-2"] = { mode = "3840x2160@60", scale = 2, transform = 0 } }
|
|
--
|
|
-- Only mode, scale, and transform are read. Colour management and bit depth
|
|
-- stay here, because those are the settings with a documented reason attached
|
|
-- (see the header) rather than preferences, and a settings page has no way to
|
|
-- explain the screencopy tradeoff at the moment you would be changing it.
|
|
local displays = prefs.get("displays", {})
|
|
|
|
local function override(output, field, fallback)
|
|
local entry = displays[output]
|
|
if type(entry) ~= "table" then
|
|
return fallback
|
|
end
|
|
local value = entry[field]
|
|
if value == nil or type(value) ~= type(fallback) then
|
|
return fallback
|
|
end
|
|
return value
|
|
end
|
|
|
|
hl.monitor({
|
|
output = "DP-2",
|
|
mode = override("DP-2", "mode", "4500x3000@60"),
|
|
position = "0x0",
|
|
scale = override("DP-2", "scale", 1.5),
|
|
transform = override("DP-2", "transform", 0),
|
|
|
|
-- 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({
|
|
output = "",
|
|
mode = "preferred",
|
|
position = "auto",
|
|
scale = "auto",
|
|
})
|
|
|
|
return true
|