session: add disable-able systemd session target (#15776)

* add systemd session target

* session: stop graphical-session so we block, near other systemd cleanup

* session: don't start session ourselves if MANAGERPID is set

This avoids doing systemd stuff if we're already in a systemd-managed
session, like UWSM. Env vars and targets and such should already be
handled for us.

* session: store state, rather than rechecking env var at exit

---------

Co-authored-by: Dregu <dregu@dreg.us>
This commit is contained in:
Lucas Ritzdorf
2026-08-22 13:57:45 +02:00
committed by GitHub
co-authored by Dregu
parent d29916a91c
commit 34839b4f64
4 changed files with 25 additions and 2 deletions
+3
View File
@@ -417,6 +417,9 @@ else()
message(STATUS "SYSTEMD support is requested (NO_SYSTEMD not defined)...")
add_compile_definitions(USES_SYSTEMD)
install(FILES ${CMAKE_SOURCE_DIR}/systemd/hyprland-session.target
DESTINATION ${CMAKE_INSTALL_LIBDIR}/systemd/user)
# session file -uwsm
if(NO_UWSM)
message(STATUS "UWSM support is disabled...")
+15 -2
View File
@@ -542,7 +542,12 @@ void CCompositor::cleanEnvironment() {
if (m_desktopEnvSet)
unsetenv("XDG_CURRENT_DESKTOP");
if (m_aqBackend->hasSession() && !Env::envEnabled("HYPRLAND_NO_SD_VARS")) {
if (m_aqBackend->hasSession() && !Env::envEnabled("HYPRLAND_NO_SD_VARS") && !getenv("MANAGERPID")) {
#ifdef USES_SYSTEMD
if (m_sdSessionTarget)
// stopping hyprland-session doesn't wait for dependent services; this does
Config::Supplementary::executor()->spawn("systemctl --user stop graphical-session.target");
#endif
const auto CMD =
#ifdef USES_SYSTEMD
"systemctl --user unset-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS && hash "
@@ -789,7 +794,9 @@ void CCompositor::startCompositor() {
/* Session-less Hyprland usually means a nest, don't update the env in that case */
m_aqBackend->hasSession() &&
/* Activation environment management is not disabled */
!Env::envEnabled("HYPRLAND_NO_SD_VARS")) {
!Env::envEnabled("HYPRLAND_NO_SD_VARS") &&
/* Being executed under systemd */
!getenv("MANAGERPID")) {
const auto CMD =
#ifdef USES_SYSTEMD
"systemctl --user import-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS && hash "
@@ -797,6 +804,12 @@ void CCompositor::startCompositor() {
#endif
"dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS";
Config::Supplementary::executor()->spawn(CMD);
#ifdef USES_SYSTEMD
if (!Env::envEnabled("HYPRLAND_NO_SD_TARGET")) {
m_sdSessionTarget = true;
Config::Supplementary::executor()->spawn("systemctl --user start hyprland-session.target");
}
#endif
}
Log::logger->log(Log::DEBUG, "Running on WAYLAND_DISPLAY: {}", m_wlDisplaySocket);
+1
View File
@@ -74,6 +74,7 @@ class CCompositor {
bool m_desktopEnvSet = false;
bool m_wantsXwayland = true;
bool m_onlyConfigVerification = false;
bool m_sdSessionTarget = false;
// ------------------------------------------------- //
+6
View File
@@ -0,0 +1,6 @@
[Unit]
Description=Hyprland session
BindsTo=graphical-session.target
Wants=graphical-session-pre.target
After=graphical-session-pre.target
PropagatesStopTo=graphical-session.target