* Reuse SSH connections for remote theme sync * Cover remote theme sync connection reuse
81 lines
3.2 KiB
Bash
Executable File
81 lines
3.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# omarchy:summary=Mirror the current theme to your herdr machines that run Omarchy
|
|
# omarchy:args=[--available]
|
|
# omarchy:hidden=true
|
|
|
|
# omarchy-theme-set runs this in the background after every theme change. Sync is off until
|
|
# the herdr-theme-sync toggle is turned on, and a machine only accepts themes with it on too.
|
|
|
|
# Columns: id, label, SSH target, session, state.
|
|
# This machine may be listed too, and it is already on the theme, so it needs no special case.
|
|
targets=$(herdr machine list 2>/dev/null | awk -F '\t' '$5 == "enabled" { print $3 }')
|
|
|
|
# The menu offers the toggle whenever there is a machine to sync to, whether or not sync is on.
|
|
if [[ $1 == "--available" ]]; then
|
|
[[ -n $targets ]]
|
|
exit
|
|
fi
|
|
|
|
# Serialize runs and send whichever theme is current once the lock is held,
|
|
# so a slow earlier run can never overwrite a later theme change.
|
|
exec 9>"${XDG_RUNTIME_DIR:-/tmp}/omarchy-theme-set-herdr-machines.lock"
|
|
flock 9
|
|
|
|
# A theme that arrived from another machine stops here, so machines never echo it back.
|
|
# The toggle is checked once the lock is held, so turning sync off also stops a queued run.
|
|
if [[ -n $OMARCHY_THEME_SYNC_FROM ]] || ! omarchy-toggle-enabled herdr-theme-sync; then
|
|
exit 0
|
|
fi
|
|
|
|
theme=$(cat "$HOME/.local/state/omarchy/current/theme.name" 2>/dev/null)
|
|
control_dir="$XDG_RUNTIME_DIR/omarchy-theme-sync"
|
|
mkdir -m 700 -p "$control_dir"
|
|
|
|
# Runs on the remote machine under a login shell, so OMARCHY_PATH and PATH are set there.
|
|
# SSH carries no desktop session, so the environment comes from the live Hyprland instance.
|
|
# The flag is read directly, so an Omarchy that predates theme sync simply counts as off.
|
|
# Braces make bash read the whole script before running it, so nothing it runs can consume the rest.
|
|
read -r -d '' REMOTE_SCRIPT <<'EOF'
|
|
{
|
|
if [[ ! -f ~/.local/state/omarchy/toggles/herdr-theme-sync ]]; then
|
|
echo "theme sync is off"
|
|
exit
|
|
fi
|
|
|
|
if [[ $(cat ~/.local/state/omarchy/current/theme.name 2>/dev/null) == "$theme" ]]; then
|
|
echo "already on $theme"
|
|
exit
|
|
fi
|
|
|
|
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
|
|
instance=$(hyprctl instances -j 2>/dev/null | jq -r 'max_by(.time) // empty | "\(.instance) \(.wl_socket)"')
|
|
if [[ -z $instance ]]; then
|
|
echo "no Hyprland session"
|
|
exit
|
|
fi
|
|
|
|
read -r HYPRLAND_INSTANCE_SIGNATURE WAYLAND_DISPLAY <<<"$instance"
|
|
export HYPRLAND_INSTANCE_SIGNATURE WAYLAND_DISPLAY
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus"
|
|
export OMARCHY_THEME_SYNC_FROM="$from"
|
|
|
|
if omarchy theme set "$theme" >/dev/null 2>&1; then
|
|
echo "set $theme"
|
|
else
|
|
echo "failed to set $theme"
|
|
fi
|
|
} </dev/null
|
|
EOF
|
|
|
|
# Reuse each authenticated connection for ten idle minutes, so an SSH agent like
|
|
# 1Password does not need to approve every theme change. Connect one machine at a time.
|
|
# SSH joins its arguments into a shell command, so the theme travels on stdin as a quoted assignment.
|
|
for target in $targets; do
|
|
result=$(printf 'theme=%q from=%q\n%s\n' "$theme" "$(hostname)" "$REMOTE_SCRIPT" |
|
|
timeout 60 ssh -o BatchMode=yes -o ConnectTimeout=5 \
|
|
-o ControlMaster=auto -o ControlPersist=600 -o "ControlPath=$control_dir/%C" \
|
|
"$target" bash -l -s 2>&1 | tail -n 1)
|
|
echo "$(date '+%F %T') $target: ${result:-unreachable}"
|
|
done
|