Files
omarchy-setup/profiles/machines/hp-laptop/bin/fix-stuck-displays
T
noconnorandClaude Opus 5.5 87a31858fd 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
2026-10-16 16:01:54 -04:00

54 lines
2.0 KiB
Bash
Executable File

#!/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