omarchy-launch-screensaver loops over the monitors, focusing each and spawning a terminal on it -- but the spawn is asynchronous. Slow-starting terminals mapped their windows after focus had already moved to the next monitor, so every screensaver landed on the last-focused monitor and the others got none (and the fullscreen rule applied inconsistently when two windows mapped at once). Listen on Hyprland's event socket and wait for each monitor's screensaver window to open before moving focus to the next one, so there is exactly one screensaver per monitor. The stream is opened before spawning so a fast-mapping window can't be missed, with a read timeout as a safety net. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
74 lines
2.5 KiB
Bash
Executable File
74 lines
2.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# omarchy:summary=Launch the Omarchy screensaver in the default terminal on the system with the correct font configuration.
|
|
|
|
if omarchy-cmd-missing tte; then
|
|
exit 1
|
|
fi
|
|
|
|
# Exit early if screensaver is already running
|
|
pgrep -f '[o]rg.omarchy.screensaver' && exit 0
|
|
|
|
# Allow screensaver to be turned off but also force started
|
|
if omarchy-toggle-enabled screensaver-off && [[ $1 != "force" ]]; then
|
|
exit 1
|
|
fi
|
|
|
|
focused=$(omarchy-hyprland-monitor-focused)
|
|
terminal=$(xdg-terminal-exec --print-id)
|
|
|
|
hypr_focus_monitor() {
|
|
hyprctl dispatch "hl.dsp.focus({ monitor = \"$1\" })" >/dev/null 2>&1 || hyprctl dispatch focusmonitor "$1" >/dev/null
|
|
}
|
|
|
|
hypr_exec() {
|
|
local command
|
|
printf -v command '%q ' "$@"
|
|
|
|
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"
|
|
|
|
case $terminal in
|
|
*Alacritty*)
|
|
hypr_exec alacritty --class=org.omarchy.screensaver --config-file "$OMARCHY_PATH/default/alacritty/screensaver.toml" -e omarchy-screensaver
|
|
;;
|
|
*ghostty*)
|
|
hypr_exec ghostty --class=org.omarchy.screensaver --config-file="$OMARCHY_PATH/default/ghostty/screensaver" --font-size=18 -e omarchy-screensaver
|
|
;;
|
|
*foot*)
|
|
hypr_exec foot --app-id=org.omarchy.screensaver --config="$OMARCHY_PATH/default/foot/screensaver.ini" -e omarchy-screensaver
|
|
;;
|
|
*kitty*)
|
|
hypr_exec kitty --class=org.omarchy.screensaver --override font_size=18 --override window_padding_width=0 -e omarchy-screensaver
|
|
;;
|
|
*)
|
|
omarchy-notification-send -g ✋ "Screensaver only runs in Alacritty, Foot, Ghostty, or Kitty"
|
|
continue
|
|
;;
|
|
esac
|
|
|
|
wait_for_screensaver_window
|
|
done
|
|
|
|
hypr_focus_monitor "$focused"
|