Files
omarchycn/bin/omarchy-hyprland-monitor-clamshell
T
Stanko K.R. bfefcc7e11 Wake internal display only when leaving clamshell
The clamshell watcher polls omarchy-hyprland-monitor-clamshell every two
seconds and calls enable_internal unconditionally which re-enabled DPMS
on the internal panel each time. When the lock screen blanks the displays,
the next poll of  omarchy-hyprland-monitor-clamshell re-lights the laptop
screen, leaving it showing the lock screen indefinitely while external
monitors stayed off.

Only issue the DPMS wake when the clamshell flag was actually consumed,
i.e. on the lid-open transition the wake was meant for.

If the lid-open even fails to turn on the screen for whatever reason,
then pressing a key or moving the mouse will re-light the screen. This
is configured in `input.lua` via `key_press_enables_dpms = true` and
`mouse_move_enables_dpms = true`
2026-07-18 15:18:05 +02:00

148 lines
3.6 KiB
Bash
Executable File

#!/bin/bash
# omarchy:summary=Apply clamshell display state to Hyprland monitors
# omarchy:hidden=true
TOGGLES_DIR="$HOME/.local/state/omarchy/toggles/hypr"
CLAMSHELL_FLAG="$TOGGLES_DIR/internal-monitor-clamshell.lua"
MANUAL_DISABLE_FLAG="$TOGGLES_DIR/internal-monitor-disable.lua"
SCALE_STATE="$TOGGLES_DIR/internal-monitor-scale"
INTERNAL=$(hyprctl monitors all -j | jq -r '.[] | select(.name | test("^(eDP|LVDS|DSI)-")).name' | head -n 1)
valid_scale() {
[[ $1 =~ ^[0-9]+([.][0-9]+)?$ ]]
}
scales_match() {
local left="$1"
local right="$2"
valid_scale "$left" && valid_scale "$right" || return 1
awk -v left="$left" -v right="$right" 'BEGIN {
diff = left - right
if (diff < 0) diff = -diff
exit(diff < 0.001 ? 0 : 1)
}'
}
configured_monitor_scale() {
local monitor_lua="$HOME/.config/hypr/monitors.lua"
[[ -f $monitor_lua ]] || return 0
local scale
scale=$(sed -n 's/^local omarchy_monitor_scale = //p' "$monitor_lua" | head -1)
if [[ -z $scale ]]; then
scale=$(sed -nE 's/^hl\.monitor\(\{ output = "", mode = "preferred", position = "auto", scale = ([^ ]+) \}\)/\1/p' "$monitor_lua" | head -1)
fi
echo "$scale"
}
current_internal_scale() {
[[ -n $INTERNAL ]] || return 0
hyprctl monitors all -j | jq -r --arg internal "$INTERNAL" '.[] | select(.name == $internal and .disabled != true) | .scale' | head -1
}
store_internal_scale() {
local scale="$1"
valid_scale "$scale" || return 0
mkdir -p "$TOGGLES_DIR"
printf '%s\n' "$scale" >"$SCALE_STATE"
}
remember_internal_scale() {
local scale
scale=$(current_internal_scale)
store_internal_scale "$scale"
}
read_monitor_scale() {
local scale
scale=$(configured_monitor_scale)
if valid_scale "$scale"; then
echo "$scale"
return
fi
if [[ -f $SCALE_STATE ]]; then
scale=$(<"$SCALE_STATE")
if valid_scale "$scale"; then
echo "$scale"
return
fi
fi
echo 2
}
enable_internal_output() {
[[ -n $INTERNAL ]] || return 0
local scale="${1:-}"
[[ -n $scale ]] || scale=$(read_monitor_scale)
hyprctl eval "hl.monitor({ output = \"$INTERNAL\", mode = \"preferred\", position = \"auto\", scale = $scale })" >/dev/null 2>&1 || true
}
sync_internal_scale() {
[[ -n $INTERNAL ]] || return 0
local desired_scale
local active_scale
desired_scale=$(read_monitor_scale)
active_scale=$(current_internal_scale)
scales_match "$active_scale" "$desired_scale" && return 0
enable_internal_output "$desired_scale"
}
dpms_internal() {
local action="$1"
[[ -n $INTERNAL ]] || return 0
hyprctl dispatch "hl.dsp.dpms({ action = \"$action\", monitor = \"$INTERNAL\" })" >/dev/null 2>&1 || true
}
enable_internal() {
local changed=0
if [[ -f $CLAMSHELL_FLAG ]]; then
rm -f "$CLAMSHELL_FLAG"
changed=1
fi
if (( changed )); then
hyprctl reload >/dev/null 2>&1 || true
fi
[[ -f $MANUAL_DISABLE_FLAG ]] && omarchy-hyprland-monitor-external-active && return 0
sync_internal_scale
if (( changed )); then
dpms_internal enable
fi
}
disable_internal() {
[[ -n $INTERNAL ]] || exit 0
[[ -f $MANUAL_DISABLE_FLAG ]] && return 0
mkdir -p "$TOGGLES_DIR"
remember_internal_scale
local config
config=$(printf 'hl.monitor({ output = "%s", disabled = true })' "$INTERNAL")
if [[ ! -f $CLAMSHELL_FLAG ]] || [[ $(< "$CLAMSHELL_FLAG") != $config ]]; then
printf '%s\n' "$config" >"$CLAMSHELL_FLAG"
hyprctl reload >/dev/null 2>&1 || true
fi
}
omarchy-hyprland-monitor-internal recover >/dev/null 2>&1 || true
omarchy-hyprland-monitor-internal-mirror recover >/dev/null 2>&1 || true
if omarchy-hw-clamshell && omarchy-hyprland-monitor-external-active; then
disable_internal
else
enable_internal
fi