fix(astal-menu): stop LD_PRELOAD leaking into launched apps (Firefox crash)

astal-menu-start.sh LD_PRELOADs libgtk4-layer-shell so it loads before
libwayland-client. That preload is only needed at the daemon's own exec — the
library is resident afterwards and the variable is never re-read — but every app
started via AstalApps.launch() inherited it, and Firefox aborts at startup with
libgtk4-layer-shell preloaded (gdk_display_manager_get() before gtk_init()).

main.py now drops LD_PRELOAD from its environment right after startup, so
launched GUI apps (and backend subprocesses) run with a clean env. Verified the
layer-shell library stays mapped and the menu surface still maps afterwards.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
feat/astal-menu
Amir Alexander Abdelbaki 2026-07-05 19:14:16 +02:00
parent 277f04c65d
commit b9e80fbfbe
2 changed files with 13 additions and 2 deletions

View File

@ -13,9 +13,18 @@ toggles the running instance without spawning a new process.
from __future__ import annotations
import os
import sys
from pathlib import Path
# astal-menu-start.sh LD_PRELOADs libgtk4-layer-shell so it loads before
# libwayland-client (a load-ordering requirement of the layer-shell library). That
# only matters at *this* process's exec: the library is already resident now, so the
# variable is never read again. Drop it here so the GUI apps we launch via
# AstalApps.launch() (and the backend subprocesses) don't inherit it — Firefox, for
# one, aborts at startup with libgtk4-layer-shell preloaded.
os.environ.pop("LD_PRELOAD", None)
# Make sibling modules importable no matter the CWD.
sys.path.insert(0, str(Path(__file__).resolve().parent))

View File

@ -3,8 +3,10 @@
#
# gtk4-layer-shell must be loaded before libwayland-client; when the shell is used
# through PyGObject that ordering isn't guaranteed, so we LD_PRELOAD it (the library
# itself documents this workaround). Starts the daemon hidden — it shows only when
# menu-toggle.sh forwards a --toggle/--show/--appdrawer verb.
# itself documents this workaround). main.py drops LD_PRELOAD from its environment
# right after startup so the apps it launches don't inherit it (Firefox, for one,
# crashes with libgtk4-layer-shell preloaded). Starts the daemon hidden — it shows
# only when menu-toggle.sh forwards a --toggle/--show/--appdrawer verb.
APP="${HOME}/.config/astal-menu/main.py"
SO="$(ldconfig -p 2>/dev/null | awk '/libgtk4-layer-shell\.so/ {print $NF; exit}')"