From e6f8d560ab446a2010965c5f0446c48714bf05c5 Mon Sep 17 00:00:00 2001 From: dingo Date: Mon, 10 Aug 2026 15:24:04 +0700 Subject: [PATCH] Re-exec through the login shell, so the session sees /etc/profile The greeter starts this script with what pam and systemd put in the environment and nothing else. start-cosmic re-execs itself through $SHELL to pick up /etc/profile and the user's login files; not doing the same here is why the two sessions disagreed about the environment. Measured here, the difference is XDG_DATA_DIRS: empty without this, and with it the two flatpak exports directories that hold the .desktop files and icons the launcher reads. PATH is unchanged either way -- /etc/profile only appends what is missing. Differs from upstream in two ways. The recursion guard is an exported variable rather than a positional --in-login-shell flag, because a flag has to survive being quoted through another shell to be seen on the way back in, and if it ever failed to, the login would hang instead of failing; an exported variable survives exec by definition. And it uses bash's own `exec -l` rather than an extra `bash -c` hop, since this script is already bash. First in the file, deliberately: the login files may set XDG_CACHE_HOME, which is where the log goes, so this happens while there is nothing to lose. Verified the log still rotates exactly once per login. see: https://github.com/pop-os/cosmic-session/issues/23 --- data/start-hyprcosmic | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/data/start-hyprcosmic b/data/start-hyprcosmic index 5e6b51c..5f4ebf6 100755 --- a/data/start-hyprcosmic +++ b/data/start-hyprcosmic @@ -10,6 +10,52 @@ set -e +# Re-exec through the user's login shell, before anything else runs. +# +# The greeter starts this script with a minimal environment: what pam and +# systemd put there, and nothing from /etc/profile or the user's own login +# files. start-cosmic re-execs itself through $SHELL to pick those up, and not +# doing the same here is why the two sessions disagree about the environment. +# see: https://github.com/pop-os/cosmic-session/issues/23 +# +# The measurable difference on this machine is XDG_DATA_DIRS. Without this pass +# it arrives empty; /etc/profile.d/flatpak.sh is what appends the two flatpak +# exports directories, and those are where flatpak applications keep the +# .desktop files and icons the launcher looks for. PATH is untouched either way +# -- /etc/profile only appends what is missing -- so this adds and does not +# rearrange. +# +# First in the file, deliberately. The login files are allowed to set +# XDG_CACHE_HOME, which is where the log below decides to go, so this has to +# happen while there is still nothing to lose. The cost is one extra process +# and, measured here, about 35ms. +# +# The guard is an exported variable rather than start-cosmic's positional +# `--in-login-shell`. A flag has to survive being quoted through another shell +# to be seen on the way back in; if it ever failed to, the script would re-exec +# itself forever and the login would hang instead of failing. An exported +# variable survives exec by definition, so the recursion cannot happen. +# +# `exec -l` is bash's own flag and this script is bash, so start-cosmic's extra +# `bash -c` hop buys nothing. The inner `exec` means the login shell replaces +# itself with the session rather than sitting there as its parent for the rest +# of the login. +# +# Whatever goes wrong here is unlogged, because the log does not exist yet -- +# hence checking that the shell is real and runnable first rather than finding +# out from a session that dies silently. +if [[ -z "${HYPRCOSMIC_LOGIN_SHELL:-}" && -n "${SHELL:-}" && -x "${SHELL}" ]]; then + case "${SHELL##*/}" in + nologin | false) + # An account with no usable login shell still gets a desktop. + ;; + *) + export HYPRCOSMIC_LOGIN_SHELL=1 + exec -l "${SHELL}" -c "exec $(printf '%q' "$0")" + ;; + esac +fi + # The forked binaries, installed alongside rather than over the stock ones. # # Pointing at /usr/bin/cosmic-session here would be a silent no-op: the system