eww-hypr-workspace-listener 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #!/usr/bin/env zsh
  2. function update-workspaces {
  3. if ((${urgent} != 0)); then
  4. jq -e --null-input \
  5. --argjson 'active' "${active}" \
  6. --argjson 'urgent' "${urgent}" \
  7. 'any($active.[]; .active == $urgent)' >/dev/null && urgent=0
  8. fi
  9. jq --null-input -c \
  10. --argjson 'existing' "${existing}" \
  11. --argjson 'active_id' "${active}" \
  12. --argjson 'always_show' '[1,2,3,4,5,6,7,8,9]' \
  13. --argjson 'urgent_id' "${urgent}" \
  14. '$existing | map_values([.[], ($always_show.[] |
  15. {id: ., name: . | tostring, windows: 0, monitor: null})] |
  16. unique_by(.name) |
  17. map((.monitor != null and
  18. .id == $active_id.[.monitor].active) as $active |
  19. (.id == $urgent_id and ($active | not) and .monitor != null) as $urgent |
  20. if (((.name | startswith(".")) and ($active | not))
  21. or ((.name == "special") and (.id == -99))) then empty else
  22. .class = (if $active then "hypr-ws-button-active"
  23. else if $urgent then "hypr-ws-button-urgent"
  24. else "hypr-ws-button" end end) |
  25. .changecmd = ((try "~/.config/hypr/scripts/switch-workspace switch \(.name | tonumber)"
  26. catch empty) // "hyprctl dispatch workspace \(.id)") end))'
  27. }
  28. function get-workspaces {
  29. hyprctl -j workspaces | \
  30. jq '[group_by(.monitor).[] | {(.[0].monitor): (. | .[0].monitor as $mon | map({id: .id, windows: .windows, name: .name, monitor: $mon}))}] | add'
  31. }
  32. function get-active {
  33. hyprctl -j monitors | \
  34. jq -c 'map({(.name): {active: .activeWorkspace.id}}) | add'
  35. }
  36. # args: (address: string)
  37. function get-workspace-for-window-address {
  38. hyprctl -j clients | jq --arg 'addr' "0x${1}" \
  39. '.[] | select(.address == $addr) | .workspace.id'
  40. }
  41. function handle {
  42. case "${1}" in
  43. urgent\>\>*)
  44. urgent="$(get-workspace-for-window-address "${1:8}")"
  45. update-workspaces
  46. ;;
  47. workspace\>\>*)
  48. active="$(get-active)"
  49. update-workspaces
  50. ;;
  51. openwindow*|closewindow*|*workspace*|movewindow*)
  52. existing="$(get-workspaces)"
  53. update-workspaces
  54. ;;
  55. esac
  56. }
  57. let urgent=0
  58. local active="$(get-active)"
  59. local existing="$(get-workspaces)"
  60. update-workspaces
  61. socat -U - "unix-connect:/tmp/hypr/${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" |
  62. while read line; do
  63. handle "${line}"
  64. done