laptop-config/home/bin/lid-handler.sh
2026-05-21 11:07:40 -07:00

56 lines
2.2 KiB
Bash
Executable file

#!/usr/bin/env bash
# ~/.config/hypr/scripts/lid-handler.sh
# Handles laptop lid close/open events for Hyprland.
# Called by Hyprland bindl (runs in user session context).
# Usage: lid-handler.sh close|open
set -euo pipefail
EVENT="${1:-}" # "close" or "open"
# Determine lid state if not provided
if [ -z "$EVENT" ]; then
LID_STATE=$(cat /proc/acpi/button/lid/LID0/state 2>/dev/null || cat /proc/acpi/button/lid/LID/state 2>/dev/null || echo "open")
if echo "$LID_STATE" | grep -qi "closed"; then
EVENT="close"
else
EVENT="open"
fi
fi
# Detect monitors via hyprctl
INTERNAL=$(hyprctl monitors -j 2>/dev/null | jq -r '.[] | select(.name | startswith("eDP")) | .name' | head -1 || echo "")
EXTERNAL=$(hyprctl monitors -j 2>/dev/null | jq -r '.[] | select(.name | startswith("eDP") | not) | .name' | head -1 || echo "")
# Fallback: try known names from hyprland.conf
[ -z "$INTERNAL" ] && INTERNAL="eDP-1"
[ -z "$EXTERNAL" ] && EXTERNAL="DP-3"
case "$EVENT" in
close)
if [ -n "$EXTERNAL" ]; then
# Move all workspaces to the external display first
WORKSPACES=$(hyprctl workspaces -j 2>/dev/null | jq -r '.[].id' || echo "")
for ws in $WORKSPACES; do
hyprctl dispatch moveworkspacetomonitor "$ws" "$EXTERNAL" 2>/dev/null || true
done
# Set external as primary (scale factor 1)
hyprctl keyword monitor "$EXTERNAL",preferred,auto,1 2>/dev/null || true
# Disable internal display
if [ -n "$INTERNAL" ]; then
hyprctl keyword monitor "$INTERNAL,disable" 2>/dev/null || true
fi
notify-send -t 3000 "Lid Closed" "Switched to $EXTERNAL as primary display"
else
notify-send -t 3000 "Lid Closed" "No external display detected — locking"
hyprlock 2>/dev/null || true
fi
;;
open)
# Re-enable internal display alongside external
if [ -n "$INTERNAL" ]; then
hyprctl keyword monitor "$INTERNAL,preferred,auto,1" 2>/dev/null || true
notify-send -t 3000 "Lid Opened" "Internal display $INTERNAL re-enabled"
fi
;;
esac