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