Created
April 18, 2026 03:53
-
-
Save abbood/578e95cb6875cc297f1daaf7d21cc93f to your computer and use it in GitHub Desktop.
hyprmon-monitor-daemon
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Logging setup | |
| LOG_DIR="$HOME/.local/share/hyprmon-daemon" | |
| LOG_FILE="$LOG_DIR/daemon.log" | |
| mkdir -p "$LOG_DIR" | |
| # Function to log with timestamp | |
| log() { | |
| echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" | |
| } | |
| log "========== DAEMON STARTED ==========" | |
| log "Hyprland instance: $HYPRLAND_INSTANCE_SIGNATURE" | |
| # Track current state | |
| LAST_STATE="" | |
| # Function to get current monitor state from Hyprland | |
| get_hyprland_state() { | |
| hyprctl monitors -j 2>/dev/null | jq -r '.[].name' | grep -E "^DP-" | sort | tr '\n' ',' || echo "" | |
| } | |
| # Function to get current monitor state from DRM (hardware) | |
| get_drm_state() { | |
| grep -h "^connected$" /sys/class/drm/card1-DP-*/status 2>/dev/null | wc -l | |
| } | |
| # Initialize with current state | |
| LAST_STATE=$(get_hyprland_state) | |
| log "Initial Hyprland state: [$LAST_STATE]" | |
| # Function to check and trigger if state changed | |
| check_state_change() { | |
| NEW_STATE=$(get_hyprland_state) | |
| if [ "$NEW_STATE" != "$LAST_STATE" ]; then | |
| log "State changed from [$LAST_STATE] to [$NEW_STATE] - TRIGGERING auto-switch" | |
| LAST_STATE=$NEW_STATE | |
| ~/.local/bin/hyprmon-auto-switch | |
| fi | |
| } | |
| # Start polling in background (every 3 seconds) | |
| ( | |
| while true; do | |
| sleep 3 | |
| # Check if DRM state doesn't match Hyprland state | |
| DRM_EXTERNAL_COUNT=$(get_drm_state) | |
| HYPR_STATE=$(get_hyprland_state) | |
| # DRM says external is connected (count > 0) but Hyprland doesn't see it | |
| if [ "$DRM_EXTERNAL_COUNT" -gt 0 ] && [ -z "$HYPR_STATE" ]; then | |
| log "[POLLING] DRM detects external monitor but Hyprland doesn't - forcing check" | |
| check_state_change | |
| # DRM says no external (count = 0) but Hyprland still sees it | |
| elif [ "$DRM_EXTERNAL_COUNT" -eq 0 ] && [ -n "$HYPR_STATE" ]; then | |
| log "[POLLING] DRM shows no external monitor but Hyprland still sees it - forcing check" | |
| check_state_change | |
| fi | |
| done | |
| ) & | |
| # Also listen to Hyprland events (for fast response when they work) | |
| socat -U - UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | \ | |
| while read -r line; do | |
| # Log ALL monitor-related events | |
| if echo "$line" | grep -qE "^monitor"; then | |
| log "RAW monitor event: $line" | |
| # Only care about external monitor (DP-*) add/remove | |
| if echo "$line" | grep -qE "^monitor(added|removed)>>DP-"; then | |
| sleep 2 | |
| log "[EVENT] External monitor event detected - checking state" | |
| check_state_change | |
| fi | |
| fi | |
| done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment