child_exec() in daemon/core/session.c sets XDG_SESSION_TYPE, XDG_SEAT, XDG_RUNTIME_DIR, and XDG_VTNR for the compositor process, but never XDG_SESSION_ID.
The session ID is returned by logind's CreateSession, which is called in the parent process after fork(). The fork must happen first because logind needs the child's PID to place the compositor in the correct cgroup. By the time child_exec() runs, the child has a separate address space and s->session_id in the child is still an empty string.
Fix:
Extend the existing sync pipe (which currently just signals EOF to unblock the child) to carry the session ID as a payload: parent writes s->session_id before closing the write end; child reads it and sets XDG_SESSION_ID via setenv before calling exec. Logind session IDs are short alphanumeric strings so a single write/read pair is sufficient.
child_exec()indaemon/core/session.csetsXDG_SESSION_TYPE,XDG_SEAT,XDG_RUNTIME_DIR, andXDG_VTNRfor the compositor process, but neverXDG_SESSION_ID.The session ID is returned by logind's
CreateSession, which is called in the parent process afterfork(). The fork must happen first because logind needs the child's PID to place the compositor in the correct cgroup. By the timechild_exec()runs, the child has a separate address space ands->session_idin the child is still an empty string.Fix:
Extend the existing sync pipe (which currently just signals EOF to unblock the child) to carry the session ID as a payload: parent writes
s->session_idbefore closing the write end; child reads it and setsXDG_SESSION_IDviasetenvbefore callingexec. Logind session IDs are short alphanumeric strings so a singlewrite/readpair is sufficient.