#!/usr/bin/env bash set -e handle_event() { case $1 in focusedmon*\ |workspace*\ |openwindow*\ |closewindow*) list_workspaces;; esac } list_workspaces() { focused=`hyprctl activeworkspace -j | jq '.id'` active=`hyprctl monitors -j | jq 'map(select(.name == "'$monitor'")) | .[0].activeWorkspace.id'` # Explanation # 1. Select only workspaces on the current monitor. # 2. Remove duplicates (might be a bug with split-monitor-workspaces # 3. Create the output structure # 5. Sort hyprctl workspaces -j | jq --compact-output --monochrome-output " map( select( .monitor | contains(\"${monitor}\") ) ) | reduce .[] as \$item ( []; if any( .[]; .id == \$item.id ) then . else . + [\$item] end ) | map( { id: .id, name, active: (.id == ${active}), focused: (.id == ${focused}), has_windows: (.lastwindowtitle != \"\") } ) | sort_by(.id) " # Other lines that may be useful in the future # - Select interesting entries, ones that are focused, active or have windows # map( select (.active or .focused or .has_windows)) } monitor=$1 # List all workspaces once at the start list_workspaces # Then listen for events socat -U - "UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" | while read -r event; do handle_event "$event"; done