Draw idle as one timeline, and let the power button answer to its owner

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
Gabriel Brown
2026-08-24 20:33:44 -04:00
parent 6f0ce639d9
commit e1ff25fc66
23 changed files with 2655 additions and 174 deletions
+152 -15
View File
@@ -91,23 +91,159 @@ cmd_close() {
hyprctl eval "hl.monitor({ output = \"$internal\", disable = true })" >/dev/null
}
# Re-enable on open, preferring what the person chose for this panel in
# Settings (the same displays store monitors.lua reads at startup) and
# falling back to the panel's preferred mode.
# The stored display record for one output, rendered as hl.monitor arguments.
#
# This exists because the four-key version it replaces was a clobber. Opening
# the lid emitted mode, position="auto" and scale and nothing else -- and an
# hl.monitor call REPLACES the rule for that output whole, so every other field
# the person had chosen for the panel went with it. Transform, VRR, bit depth,
# colour profile, SDR trim, mirroring and, worst of all, the position: a panel
# arranged to the left of an external display jumped back to automatic
# placement, taking its workspaces with it, every time the lid was opened.
#
# So the rule is rebuilt from the same store config/dot/hypr/monitors.lua reads
# at startup, with the same validation, so that opening the lid produces the
# rule a reload would have produced. Mirroring that file field for field is the
# point; the two must not be able to disagree about what a saved record means.
#
# The two failure directions are deliberately different, exactly as they are
# there:
#
# * mode, scale or transform unreadable -- or a half-written position, where
# a record carries some layout fields but not a valid pair -- refuses the
# WHOLE record. Nothing is printed and the caller falls back to the panel's
# preferred mode. Guessing a position can strand an output where no cursor
# can reach it.
# * an unreadable colour, VRR, SDR or mirror value drops only itself. The
# geometry survives, and the worst it costs is a wrong shade.
#
# Every value that reaches the emitted string is validated first -- modes and
# positions against a numeric pattern, connector names against the same
# `[%w_.-]` class monitors.lua uses, colour profiles against a fixed set -- so
# nothing from the settings file can carry a quote into the Lua that is built
# from it.
monitor_rule() {
local name="$1" settings="${XDG_CONFIG_HOME:-$HOME/.config}/panama/settings.json"
[[ -r "$settings" ]] || return 0
jq -r --arg name "$name" '
def numeric: if type == "number" and (isnan | not) and (isinfinite | not)
then . else null end;
def whole: numeric | if . != null and . == floor then . else null end;
. as $root
| ($root.displays[$name] // null) as $e
| if ($e | type) != "object" then "" else
# ── Geometry: all of it, or none of it ───────────────────────────────
($e.mode | if type == "string"
and test("^[0-9]+x[0-9]+@[0-9]+(\\.[0-9]+)?$")
then . else null end) as $mode
| ($mode | if . == null then null
else capture("^(?<w>[0-9]+)x(?<h>[0-9]+)@(?<r>[0-9.]+)$")
| [(.w | tonumber), (.h | tonumber), (.r | tonumber)]
end) as $dim
| (if $dim == null or $dim[0] <= 0 or $dim[1] <= 0 or $dim[2] <= 0
then null else $mode end) as $mode
# A scale is only valid if it divides the mode into whole logical
# pixels; Hyprland refuses the rest, and monitors.lua refuses them here
# first so the two agree about which records are usable.
| ($e.scale | numeric | if . != null and . > 0 and . <= 4
then . else null end) as $rawScale
| (if $mode == null or $rawScale == null then null
else ($dim[0] / $rawScale) as $lw
| ($dim[1] / $rawScale) as $lh
| if ((($lw - ($lw | round)) | fabs) < 0.0001)
and ((($lh - ($lh | round)) | fabs) < 0.0001)
then $rawScale else null end
end) as $scale
| ($e.transform | whole
| if . != null and . >= 0 and . <= 3 then . else null end) as $transform
# Legacy records carry no layout fields at all and keep automatic
# placement. A record that carries SOME of them and gets one wrong is
# refused outright rather than half-honoured.
| (($e.x != null) or ($e.y != null) or ($e.primary != null)) as $hasLayout
| ($e.x | whole | if . != null and . >= -100000 and . <= 100000
then . else null end) as $x
| ($e.y | whole | if . != null and . >= -100000 and . <= 100000
then . else null end) as $y
| ($hasLayout
and ($x == null or $y == null or ($e.primary | type) != "boolean")) as $layoutBroken
# ── Extended fields: each one drops on its own ───────────────────────
| ($e.bitdepth | if . == 8 or . == 10 then . else null end) as $bitdepth
| ($e.colorProfile
| if . == "auto" or . == "srgb" or . == "wide" or . == "hdr"
then . else null end) as $cm
# -1 means "follow the global VRR policy", which is said by leaving the
# key out; 3 is the global policy value and not a per-display choice.
| ($e.vrrMode | whole | if . != null and . >= 0 and . <= 2
then . else null end) as $vrr
# Neutral is 1.0 and is left out rather than written: naming it pins the
# display to it, which is not the same as leaving the trim alone.
| ($e.sdrBrightness | numeric
| if . != null and . >= 0.8 and . <= 2.0 and (((. - 1) | fabs) >= 0.001)
then . else null end) as $sdrBrightness
| ($e.sdrSaturation | numeric
| if . != null and . >= 0.8 and . <= 1.2 and (((. - 1) | fabs) >= 0.001)
then . else null end) as $sdrSaturation
# A mirror needs a target that is not itself and not another mirror --
# Hyprland has no chain to follow -- and the primary may not mirror at
# all, since the arrangement is anchored on it.
| ($e.mirrorOf
| if type == "string" and . != "" and . != $name
and test("^[A-Za-z0-9_.-]+$")
then . else null end) as $mirrorName
| (if $mirrorName == null or $e.primary == true then null
else ($root.displays[$mirrorName] // null) as $target
| if ($target | type) == "object"
and ($target.mirrorOf | type) == "string"
and $target.mirrorOf != ""
then null else $mirrorName end
end) as $mirror
# A mirror shows its target picture in its target place, so the saved
# position is not ours to ask for.
| (if $mirror != null then "auto"
elif $hasLayout then "\($x)x\($y)"
else "auto" end) as $position
| if $mode == null or $scale == null or $transform == null or $layoutBroken
then ""
else ([ "mode = \"\($mode)\"",
"position = \"\($position)\"",
"scale = \($scale)",
"transform = \($transform)" ]
+ (if $bitdepth == null then [] else ["bitdepth = \($bitdepth)"] end)
+ (if $cm == null then [] else ["cm = \"\($cm)\""] end)
+ (if $vrr == null then [] else ["vrr = \($vrr)"] end)
+ (if $sdrBrightness == null then []
else ["sdrbrightness = \($sdrBrightness)"] end)
+ (if $sdrSaturation == null then []
else ["sdrsaturation = \($sdrSaturation)"] end)
+ (if $mirror == null then [] else ["mirror = \"\($mirror)\""] end)
) | join(", ")
end
end
' "$settings" 2>/dev/null || true
}
# Re-enable on open, restoring what the person chose for this panel in Settings
# -- the whole record, not the three fields that used to survive -- and falling
# back to the panel's preferred mode when there is no usable record.
cmd_open() {
"$HW" laptop || exit 0
local internal entry mode scale
local internal rule
internal="$(internal_connector)"
[[ -n "$internal" ]] || exit 0
entry="$(jq -c --arg name "$internal" '.displays[$name] // empty' \
"${XDG_CONFIG_HOME:-$HOME/.config}/panama/settings.json" 2>/dev/null)"
if [[ -n "$entry" ]]; then
mode="$(jq -r '.mode' <<<"$entry")"
scale="$(jq -r '.scale' <<<"$entry")"
hyprctl eval "hl.monitor({ output = \"$internal\", mode = \"$mode\", position = \"auto\", scale = $scale })" >/dev/null
else
hyprctl eval "hl.monitor({ output = \"$internal\", mode = \"preferred\", position = \"auto\", scale = \"auto\" })" >/dev/null
fi
# The connector name is interpolated into Lua too, and it comes from
# hyprctl rather than from us. Same class monitors.lua accepts.
[[ "$internal" =~ ^[A-Za-z0-9_.-]+$ ]] || exit 0
rule="$(monitor_rule "$internal")"
[[ -n "$rule" ]] || rule='mode = "preferred", position = "auto", scale = "auto"'
hyprctl eval "hl.monitor({ output = \"$internal\", $rule })" >/dev/null
}
case "${1:-status}" in
@@ -124,8 +260,9 @@ usage: panama-lid [status|guard|close|open]
connected; exits immediately on a machine that needs none
close docked lid closed: turn the internal panel off (bound to the lid
switch by keybinds.lua); does nothing undocked
open lid opened: turn the internal panel back on, restoring the mode
and scale chosen in Settings
open lid opened: turn the internal panel back on, restoring the whole
display record chosen in Settings -- position, mode, scale,
transform, and the colour, VRR and mirror fields when they are set
USAGE
;;
*) printf 'panama-lid: unknown command: %s\n' "$1" >&2; exit 2 ;;