Files
Nomarchy/features/scripts/utils/nomarchy-launch-walker
Bernardo Magri 9fe6d9e405 fix(walker): don't spawn a duplicate elephant alongside the service
nomarchy-launch-walker guarded its manual elephant start with
`pgrep -x elephant`, which never matches the Home Manager service's actual
process name `.elephant-wrapped` (Linux truncates comm to 15 chars). So every
menu invocation spawned a second elephant that races elephant.service for the
socket — a latent source of menus intermittently coming up empty.

Gate on `systemctl --user is-active elephant.service` first, with a working
`pgrep -f elephant-wrapped` fallback for non-service setups; do the same for
walker.service. Verified in a headless system.build.vm: opening the theme menu
now keeps the elephant process count at 1 (was 2) and the menu still renders.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 13:32:12 +01:00

51 lines
2.3 KiB
Bash

#!/bin/bash
set -e
# Wrapper to launch walker with elephant provider, or fallback to rofi if walker is missing.
if command -v walker >/dev/null 2>&1; then
# The setsid backgrounded commands below MUST redirect all std fds to
# /dev/null. If they inherit stdout from a $(...) caller (e.g. nomarchy-menu
# doing `$(menu ...)`), bash waits for those fds to close on every return,
# which hangs the terminal after each menu selection.
# Prefer the Home Manager systemd user services (programs.walker.runAsService).
# The manual fallbacks below MUST check the services first: the service runs
# the wrapped binary `.elephant-wrapped`, which `pgrep -x elephant` never
# matches — so the old check spawned a *second*, competing elephant on every
# menu invocation, racing the service for the socket. Only hand-start when no
# service and no process exists (e.g. walker used outside the HM service).
if ! systemctl --user is-active --quiet elephant.service 2>/dev/null \
&& ! pgrep -x elephant >/dev/null && ! pgrep -f elephant-wrapped >/dev/null; then
setsid uwsm-app -- elephant </dev/null >/dev/null 2>&1 &
disown
fi
if ! systemctl --user is-active --quiet walker.service 2>/dev/null \
&& ! pgrep -f "walker --gapplication-service" >/dev/null; then
setsid uwsm-app -- walker --gapplication-service </dev/null >/dev/null 2>&1 &
disown
fi
# dmenu mode reads stdin and is invoked many times in quick succession
# by nomarchy-menu. Wrapping each call in uwsm-app (systemd-run --scope)
# creates a fresh transient scope per invocation, which breaks chained
# submenus — subsequent walker calls don't see a usable stdin and exit
# without showing anything. Invoke walker directly for dmenu.
if [[ "$*" == *"--dmenu"* ]]; then
exec walker "$@"
fi
exec uwsm-app -- walker --width 644 --maxheight 300 --minheight 300 "$@"
elif command -v rofi >/dev/null 2>&1; then
# Convert walker arguments to rofi arguments if possible
# This is a very basic mapping for --dmenu
if [[ "$*" == *"--dmenu"* ]]; then
exec rofi -dmenu "$@"
else
exec rofi -show drun
fi
else
notify-send "Error" "Neither walker nor rofi found." -u critical
exit 1
fi