Profiles: machines, roles and shared layers
The repo was one machine's capture. It is now a set of profiles built from layers under profiles/: machines/ hp-laptop, macbook-air-m2, coder-desktop roles/ developer, devops, ai-agents features/ handoff (lan-mouse) shared base, personal, personal-desktop A profile resolves to its includes (depth first), any --roles, then itself; for a path several layers provide, the last wins. install.sh --show prints the layers and which one owns each file. Hyprland settings no longer share a file: base's hyprland.lua loads ~/.config/hypr/layers/*.lua with Omarchy's own require_all, and bindings.lua stays stock so nothing binds twice. Verified with Hyprland 0.56.2 --verify-config for all three profiles, plus a broken probe layer to prove the directory is loaded. packages.txt gains per-line arch (Arch Linux ARM lacks opencode, codex, mise, shellcheck) and cmd= (skip when dotfiles' ~/.local/bin already provides the command), and an [ignore] section that replaces capture.sh's hard-coded list. Tab-separated records would have collapsed empty fields under read, so package records use the unit separator. hp-laptop: re-captured. monitors.lua catch-all scale is now 1, shell.json has four new plugins, fix-stuck-displays has its connector-name fix, navbar-cat is gone, plugin-manager and omarchy-phone are pinned, the herdr-hud working tree is re-diffed and bin/herdr-web rides along. Its handoff peer is now the Air (192.168.1.49); the old default list was the HP's own addresses, written from the Air's side. macbook-air-m2: captured read-only over SSH as it is (no themes, plugins or bar changes). Its LAN_MOUSE_POINTER_SCALE=0.7 moves from the shared unit into a lan-mouse.service.d drop-in in its own layer. coder-desktop: the Omarchy settings covert-cloud's image used to patch in by hand (Virtual-1 at 1920x1080, no animations, stay-awake, Retro 82 once), for the image to apply at a pinned commit. Roles reach it per workspace via install.sh --roles ... --no-clobber. capture.sh writes each file back into the layer that owns it, and refuses to run before the first layered install unless --force, since the old file shapes would land in shared layers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153egowV1Xw2RNjZnSyZicc
This commit is contained in:
+53
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
# Release display pipes the kernel left enabled on unplugged connectors.
|
||||
#
|
||||
# After suspend/resume (or unplugging a USB-C display) i915 can leave a
|
||||
# connector "disconnected" but still "enabled" on a pipe that Hyprland has
|
||||
# forgotten. That pipe then blocks every other external output from
|
||||
# modesetting (black screens, or a ~5 s re-modeset loop).
|
||||
#
|
||||
# Fix: force the connector on so Hyprland sees it, disable it from Hyprland
|
||||
# (which releases the pipe), force it off, then return it to auto-detect.
|
||||
# Never `hyprctl reload` here: a reload re-enables the connector while it is
|
||||
# forced on and re-sticks the pipe.
|
||||
|
||||
log() { echo "fix-stuck-displays: $*"; logger -t fix-stuck-displays -- "$*"; }
|
||||
|
||||
wait_for() { # wait_for <seconds> <command...>
|
||||
local n=$(( $1 * 4 )); shift
|
||||
for _ in $(seq "$n"); do "$@" && return 0; sleep 0.25; done
|
||||
return 1
|
||||
}
|
||||
|
||||
stuck=()
|
||||
for d in /sys/class/drm/card*-*; do
|
||||
[[ -f $d/status && -f $d/enabled ]] || continue
|
||||
[[ $d == *eDP* ]] && continue
|
||||
[[ $(<"$d/status") == disconnected && $(<"$d/enabled") == enabled ]] && stuck+=("$d")
|
||||
done
|
||||
|
||||
if (( ${#stuck[@]} == 0 )); then
|
||||
log "no stuck connectors"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
systemctl --user stop hyprmoncfgd
|
||||
|
||||
for d in "${stuck[@]}"; do
|
||||
out=${d##*/}; out=${out#card*-}
|
||||
log "releasing $out"
|
||||
echo on | sudo -n tee "$d/status" >/dev/null
|
||||
wait_for 5 sh -c "hyprctl monitors all | grep -q '^Monitor $out '" || log "$out never appeared in Hyprland"
|
||||
hyprctl eval "hl.monitor({ output = \"$out\", disabled = true })" >/dev/null
|
||||
wait_for 5 grep -qx disabled "$d/enabled" || log "$out still enabled after disable"
|
||||
echo off | sudo -n tee "$d/status" >/dev/null
|
||||
sleep 1
|
||||
echo detect | sudo -n tee "$d/status" >/dev/null
|
||||
log "$out now $(<"$d/status") $(<"$d/enabled")"
|
||||
done
|
||||
|
||||
# Drop any low-refresh fallback hyprmoncfgd wrote while outputs were failing.
|
||||
rm -f ~/.config/hyprmoncfg/display-fallbacks.json
|
||||
|
||||
# hyprmoncfgd re-applies the matching profile (modes, positions) on startup.
|
||||
systemctl --user start hyprmoncfgd
|
||||
Reference in New Issue
Block a user