diff --git a/bin/omarchy-restart-shell b/bin/omarchy-restart-shell index 3896ada2..908c65c5 100755 --- a/bin/omarchy-restart-shell +++ b/bin/omarchy-restart-shell @@ -3,9 +3,21 @@ # omarchy:summary=Restart the Omarchy shell # omarchy:examples=omarchy restart shell -CONFIG_DIR="$OMARCHY_PATH/shell" +omarchy_root="${OMARCHY_PATH:-/usr/share/omarchy}" +if [[ ! -f $omarchy_root/shell/shell.qml && -f /usr/share/omarchy/shell/shell.qml ]]; then + omarchy_root=/usr/share/omarchy +fi -if [[ $(omarchy-shell lock isLocked 2>/dev/null || true) == "true" ]]; then +CONFIG_DIR="$omarchy_root/shell" +[[ -f $CONFIG_DIR/shell.qml ]] || { echo "Omarchy shell config not found: $CONFIG_DIR" >&2; exit 1; } + +export OMARCHY_PATH="$omarchy_root" +export PATH="$omarchy_root/bin:/usr/local/bin:/usr/bin:/bin:$PATH" + +omarchy_shell_bin=/usr/bin/omarchy-shell +[[ -x $omarchy_shell_bin ]] || omarchy_shell_bin=omarchy-shell + +if [[ $("$omarchy_shell_bin" lock isLocked 2>/dev/null || true) == "true" ]]; then echo "Refusing to restart Omarchy shell while the session is locked." >&2 exit 1 fi diff --git a/bin/omarchy-upgrade-to-4 b/bin/omarchy-upgrade-to-4 index 16644a56..c1c00906 100755 --- a/bin/omarchy-upgrade-to-4 +++ b/bin/omarchy-upgrade-to-4 @@ -111,6 +111,7 @@ target_home=$(getent passwd "$target_user" | cut -d: -f6) [[ -n $target_home && -d $target_home ]] || fail "Home directory for '$target_user' was not found." target_uid=$(id -u "$target_user") target_runtime_dir="/run/user/$target_uid" +package_path="/usr/share/omarchy/bin:/usr/local/bin:/usr/bin:/bin:$target_home/.local/bin" as_root() { if (( EUID == 0 )); then @@ -306,11 +307,28 @@ EOF fi fi +sudo_keepalive_pid="" +hyprland_config_reload_suppressed=0 + +cleanup_on_exit() { + local exit_status=$? + + if (( hyprland_config_reload_suppressed )) && declare -F restore_hyprland_config_reload >/dev/null; then + restore_hyprland_config_reload >/dev/null 2>&1 || true + fi + + if [[ -n ${sudo_keepalive_pid:-} ]]; then + kill "$sudo_keepalive_pid" 2>/dev/null || true + fi + + exit "$exit_status" +} +trap cleanup_on_exit EXIT + if (( EUID != 0 )); then sudo -v while true; do sudo -n true; sleep 60; done 2>/dev/null & sudo_keepalive_pid=$! - trap 'kill "$sudo_keepalive_pid" 2>/dev/null || true' EXIT fi backup_suffix=$(date +%Y%m%d%H%M%S) @@ -539,21 +557,40 @@ remove_retired_default_packages() { cleanup_legacy_user_paths() { log "Cleaning legacy user command shims" - run_as_user env TARGET_HOME="$target_home" bash <<'USER_CLEANUP' + run_as_user env TARGET_HOME="$target_home" BACKUP_SUFFIX="$backup_suffix" bash <<'USER_CLEANUP' set -euo pipefail local_bin="$TARGET_HOME/.local/bin" -legacy_root="$TARGET_HOME/.local/share/omarchy/bin/" -[[ -d $local_bin ]] || exit 0 -shopt -s nullglob -for link in "$local_bin"/omarchy*; do - [[ -L $link ]] || continue - target=$(readlink "$link" || true) - case "$target" in - "$legacy_root"*|../share/omarchy/bin/*|*.local/share/omarchy/bin/*) - rm -f "$link" - ;; - esac -done +legacy_root="$TARGET_HOME/.local/share/omarchy" +legacy_bin="$legacy_root/bin/" +if [[ -d $local_bin ]]; then + shopt -s nullglob + for link in "$local_bin"/omarchy*; do + [[ -L $link ]] || continue + target=$(readlink "$link" || true) + case "$target" in + "$legacy_bin"*|../share/omarchy/bin/*|*.local/share/omarchy/bin/*) + rm -f "$link" + ;; + esac + done +fi + +# Existing terminals still have OMARCHY_PATH=$HOME/.local/share/omarchy and +# often have $OMARCHY_PATH/bin early in PATH. Make that stale path resolve to +# the package-backed tree for the rest of the live session, while backing up +# the old git checkout for inspection/rollback. +if [[ -e /usr/share/omarchy ]]; then + mkdir -p "$TARGET_HOME/.local/share" + if [[ -L $legacy_root ]]; then + ln -sfn /usr/share/omarchy "$legacy_root" + elif [[ -e $legacy_root ]]; then + backup="$legacy_root.omarchy-upgrade-to-4.$BACKUP_SUFFIX.bak" + mv "$legacy_root" "$backup" + ln -sfn /usr/share/omarchy "$legacy_root" + else + ln -sfn /usr/share/omarchy "$legacy_root" + fi +fi USER_CLEANUP } @@ -638,10 +675,18 @@ start_omarchy_shell_session() { # Reboot is still the real cutover, but start the new shell in the current # Wayland session when possible so users do not sit without a bar after the # retired waybar/walker/elephant processes are stopped. - command -v quickshell >/dev/null 2>&1 || { warn "quickshell is not available; Omarchy shell will start after reboot."; return 1; } - [[ -d /usr/share/omarchy/shell ]] || { warn "/usr/share/omarchy/shell is missing; Omarchy shell will start after reboot."; return 1; } + local quickshell_bin omarchy_shell_bin shell_log + quickshell_bin=$(command -v quickshell || true) + [[ -n $quickshell_bin ]] || { warn "quickshell is not available; Omarchy shell will start after reboot."; return 1; } + omarchy_shell_bin=/usr/bin/omarchy-shell + [[ -x $omarchy_shell_bin ]] || omarchy_shell_bin=$(command -v omarchy-shell || true) + [[ -n $omarchy_shell_bin ]] || { warn "omarchy-shell is not available; Omarchy shell will start after reboot."; return 1; } + [[ -f /usr/share/omarchy/shell/shell.qml ]] || { warn "/usr/share/omarchy/shell is missing; Omarchy shell will start after reboot."; return 1; } [[ -d $target_runtime_dir ]] || { warn "No running user session found; Omarchy shell will start after reboot."; return 1; } + shell_log="$target_home/.local/state/omarchy/omarchy-shell-upgrade.log" + run_as_user mkdir -p "$target_home/.local/state/omarchy" >/dev/null 2>&1 || true + local wayland_display hyprland_signature wayland_display=$(discover_wayland_display || true) [[ -n $wayland_display ]] || { warn "No Wayland display found; Omarchy shell will start after reboot."; return 1; } @@ -661,20 +706,27 @@ start_omarchy_shell_session() { XDG_CURRENT_DESKTOP=Hyprland \ XDG_SESSION_DESKTOP=Hyprland \ XDG_SESSION_TYPE=wayland \ + QT_QPA_PLATFORM=wayland \ + GDK_BACKEND=wayland,x11,* \ DESKTOP_SESSION=hyprland \ OMARCHY_PATH=/usr/share/omarchy \ - PATH="/usr/share/omarchy/bin:$PATH" \ + PATH="$package_path" \ bash -c ' - if [[ $(omarchy-shell lock isLocked 2>/dev/null || true) == "true" ]]; then + omarchy_shell_bin=$1 + quickshell_bin=$2 + shell_log=$3 + if [[ $("$omarchy_shell_bin" lock isLocked 2>/dev/null || true) == "true" ]]; then exit 2 fi pkill -x quickshell 2>/dev/null || true sleep 0.2 - setsid quickshell -n -p /usr/share/omarchy/shell >/dev/null 2>&1 & - ' || { warn "Could not start Omarchy shell in the current session; it will start after reboot."; return 1; } + : >"$shell_log" + setsid "$quickshell_bin" -n -p /usr/share/omarchy/shell >>"$shell_log" 2>&1 & + ' bash "$omarchy_shell_bin" "$quickshell_bin" "$shell_log" \ + || { warn "Could not start Omarchy shell in the current session; it will start after reboot. See $shell_log"; return 1; } local attempt - for attempt in {1..20}; do + for attempt in {1..60}; do if run_as_user env \ HOME="$target_home" \ USER="$target_user" \ @@ -682,17 +734,92 @@ start_omarchy_shell_session() { XDG_RUNTIME_DIR="$target_runtime_dir" \ DBUS_SESSION_BUS_ADDRESS="unix:path=$target_runtime_dir/bus" \ OMARCHY_PATH=/usr/share/omarchy \ - PATH="/usr/share/omarchy/bin:$PATH" \ - omarchy-shell shell ping >/dev/null 2>&1; then + PATH="$package_path" \ + "$omarchy_shell_bin" shell ping >/dev/null 2>&1; then return 0 fi sleep 0.25 done - warn "Omarchy shell did not respond in the current session; it will start after reboot." + warn "Omarchy shell did not respond in the current session; it will start after reboot. See $shell_log" return 1 } +run_hyprctl_session() { + local wayland_display hyprland_signature hyprctl_bin + [[ -d $target_runtime_dir ]] || return 1 + + hyprctl_bin=/usr/bin/hyprctl + [[ -x $hyprctl_bin ]] || hyprctl_bin=$(command -v hyprctl || true) + [[ -n $hyprctl_bin ]] || return 1 + + wayland_display=$(discover_wayland_display || true) + [[ -n $wayland_display ]] || return 1 + + hyprland_signature=$(discover_hyprland_signature || true) + [[ -n $hyprland_signature ]] || return 1 + + run_as_user env \ + HOME="$target_home" \ + USER="$target_user" \ + LOGNAME="$target_user" \ + XDG_RUNTIME_DIR="$target_runtime_dir" \ + WAYLAND_DISPLAY="$wayland_display" \ + HYPRLAND_INSTANCE_SIGNATURE="$hyprland_signature" \ + DBUS_SESSION_BUS_ADDRESS="unix:path=$target_runtime_dir/bus" \ + XDG_CURRENT_DESKTOP=Hyprland \ + XDG_SESSION_DESKTOP=Hyprland \ + XDG_SESSION_TYPE=wayland \ + DESKTOP_SESSION=hyprland \ + OMARCHY_PATH=/usr/share/omarchy \ + PATH="$package_path" \ + "$hyprctl_bin" "$@" +} + +suppress_hyprland_config_reload() { + log "Suppressing live Hyprland reloads during the config swap" + + local changed=0 + if run_hyprctl_session keyword misc:disable_autoreload true >/dev/null 2>&1; then + changed=1 + fi + if run_hyprctl_session eval 'hl.config({ misc = { disable_autoreload = true }, debug = { suppress_errors = true } })' >/dev/null 2>&1; then + changed=1 + fi + run_hyprctl_session keyword debug:suppress_errors true >/dev/null 2>&1 || true + + if (( changed )); then + hyprland_config_reload_suppressed=1 + else + warn "Could not disable Hyprland auto-reload; the live session may briefly report config errors." + fi +} + +restore_hyprland_config_reload() { + (( hyprland_config_reload_suppressed )) || return 0 + + run_hyprctl_session keyword misc:disable_autoreload false >/dev/null 2>&1 || true + run_hyprctl_session eval 'hl.config({ misc = { disable_autoreload = false } })' >/dev/null 2>&1 || true + run_hyprctl_session keyword debug:suppress_errors false >/dev/null 2>&1 || true + run_hyprctl_session eval 'hl.config({ debug = { suppress_errors = false } })' >/dev/null 2>&1 || true + hyprland_config_reload_suppressed=0 +} + +reload_hyprland_config_after_upgrade() { + log "Reloading Hyprland config with a full reset" + + if run_hyprctl_session reload full-reset >/dev/null 2>&1; then + restore_hyprland_config_reload + return 0 + fi + + warn "hyprctl reload full-reset failed; trying a regular Hyprland reload. If this session is still running an older Hyprland, reboot will complete the cutover." + if ! run_hyprctl_session reload >/dev/null 2>&1; then + warn "Could not reload the live Hyprland session; the new config will load after reboot." + fi + restore_hyprland_config_reload +} + enable_system_service() { local unit="$1" as_root systemctl enable "$unit" >/dev/null 2>&1 || warn "Could not enable $unit; it may not be installed on this system." @@ -1089,9 +1216,11 @@ remove_conflicting_legacy_packages install_omarchy_4_packages cleanup_legacy_user_paths apply_system_transition +suppress_hyprland_config_reload apply_user_transition cleanup_retired_services remove_retired_default_packages +reload_hyprland_config_after_upgrade if start_omarchy_shell_session; then stop_retired_session_processes else @@ -1102,8 +1231,8 @@ cat <