diff --git a/bin/omarchy-launch-screensaver b/bin/omarchy-launch-screensaver index 3f8b82f8..66bb4d89 100755 --- a/bin/omarchy-launch-screensaver +++ b/bin/omarchy-launch-screensaver @@ -28,6 +28,23 @@ hypr_exec() { hyprctl dispatch "hl.dsp.exec_cmd([[$command]])" >/dev/null 2>&1 || hyprctl dispatch exec -- bash -lc "$command" >/dev/null } +SOCKET="$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" + +# Open Hyprland's event stream before spawning anything, so a terminal that maps +# quickly can't emit its openwindow event before we are listening for it. +exec {events}< <(socat -U - "UNIX-CONNECT:$SOCKET") + +# hypr_exec is async and a new window maps on whatever monitor is focused at that +# moment. Block until this monitor's screensaver actually opens before moving +# focus on -- otherwise slow-starting terminals all pile onto the last monitor. +# The read timeout is a safety net in case the window never appears. +wait_for_screensaver_window() { + local line + while IFS= read -r -t 5 -u "$events" line; do + [[ $line == openwindow\>\>*,org.omarchy.screensaver,* ]] && return 0 + done +} + for m in $(hyprctl monitors -j | jq -r '.[] | .name'); do hypr_focus_monitor "$m" @@ -46,8 +63,11 @@ for m in $(hyprctl monitors -j | jq -r '.[] | .name'); do ;; *) omarchy-notification-send -g ✋ "Screensaver only runs in Alacritty, Foot, Ghostty, or Kitty" + continue ;; esac + + wait_for_screensaver_window done hypr_focus_monitor "$focused"