Hyprland session environment and desktop integration diagnosis

On this page

A command working in a terminal but failing from a desktop binding often indicates different environments. An active service with no working interface may be connected to the wrong graphical session. Separate startup source, environment and actual interface behaviour.

Start with three questions

Which component failed? Who launched it? Which session does it connect to? Record the trigger and timestamp before reading its logs. Restarting everything first can remove useful evidence.

Shell and user-service environments differ

.zshrc may add ~/.local/bin to PATH, but the user service manager does not execute that file. Check terminal resolution:

command -v ghostty
printf '%s\n' "$PATH"

Compare relevant variables with systemctl --user show-environment; avoid publishing the complete environment.

For a custom session setup, import the required variables after the compositor creates them and before dependent services start:

systemctl --user import-environment WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE HYPRLAND_INSTANCE_SIGNATURE
dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE HYPRLAND_INSTANCE_SIGNATURE

Run these inside the correct graphical session. A remote shell without Wayland state cannot repair it by importing absent values. With distribution session management or UWSM, follow its lifecycle rather than layering unrelated scripts on top.

Ordering and service lifetime

After= controls ordering without starting a dependency; Wants= requests one; PartOf= propagates stop/restart operations. They require a real session target and lifecycle owner.

This illustrative doc-shell.service assumes an existing, correctly managed hyprland-session.target, /usr/bin/qs and Caelestia installation:

[Unit]
Description=Example desktop shell
PartOf=hyprland-session.target
After=graphical-session-pre.target
ConditionEnvironment=WAYLAND_DISPLAY

[Service]
ExecStart=/usr/bin/qs -c caelestia -n
Restart=on-failure
RestartSec=2

[Install]
WantedBy=hyprland-session.target

Do not enable it alongside an existing shell service. ConditionEnvironment checks presence, not whether the Wayland socket is still alive. The session manager must stop its services when the session ends. systemd session conventions

Screen sharing and file selection

Applications use xdg-desktop-portal and selected backends for desktop interfaces. Installing a backend does not prove requests reach it.

Check actual service names for the distribution:

systemctl --user status xdg-desktop-portal.service xdg-desktop-portal-hyprland.service
journalctl --user -u xdg-desktop-portal.service -b -n 80 --no-pager

Inspect XDG_CURRENT_DESKTOP, backend selection, session state and PipeWire. Working file selection with failed screen sharing calls for screencast-specific diagnosis. Different interfaces can use different backends; do not blindly remove all others. Hyprland portal

Input and audio

Test native Wayland, XWayland, GTK and Qt applications separately. A running Fcitx5 process is only the first condition; application integration and the current input group also matter. See Neovim input.

wpctl status
wpctl get-volume @DEFAULT_AUDIO_SINK@

Confirm default devices and actual playback streams before debugging shell controls. Changing the default output and moving an existing stream are distinct operations; applications may retain their route.

Choose a narrow recovery action

SymptomVerify firstRecovery scope
Shell disappears but windows workQML and shell service logsRepair/restart the shell
Binding cannot launch programExecutable path and environmentCorrect the command or service environment
Shell survives logoutTarget membership and processesFix stop propagation
Screen sharing is blankPortal, PipeWire, sessionRepair relevant backend/connection
Only some themes updateTemplate output and reloadRepair that application's pipeline

Repeat the original trigger after recovery and test logout/login. A runtime repair does not prove the next startup sequence is correct.