diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index 4cfde61a2..ba3da2d1a 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -229,6 +229,24 @@ pub fn is_headless() -> bool { }) } +/// The Wayland greeter on seat0, if the DRM backend can capture and inject into it. +/// +/// The cached probe, to match the routing gate in `Connection`: not yet settled answers false, +/// which is what upstream does today. +#[cfg(feature = "drm")] +fn drm_login_screen_seat0_username() -> Option { + if !crate::server::drm_capturer::is_available_cached() { + return None; + } + let values = get_values_of_seat0_with_gdm_wayland(&[0, 2]); + if !is_gdm_user(&values[1]) + || get_display_server_of_session(&values[0]) != DISPLAY_SERVER_WAYLAND + { + return None; + } + Some(values[1].clone()) +} + pub fn get_username() -> String { match &*DESKTOP_MANAGER.lock().unwrap() { Some(manager) => { @@ -275,6 +293,15 @@ impl DesktopManager { } fn get_supported_display_seat0_username(&self) -> Option { + // A Wayland greeter the DRM backend can serve is a supported display. Asked here and not in + // `new()` because the seat0 read there hides greeters, and because the DRM probe has not + // settled at startup. + #[cfg(feature = "drm")] + if self.seat0_username.is_empty() || is_gdm_user(&self.seat0_username) { + if let Some(username) = drm_login_screen_seat0_username() { + return Some(username); + } + } if is_gdm_user(&self.seat0_username) && self.seat0_display_server == DISPLAY_SERVER_WAYLAND { None diff --git a/src/server/drm_capturer.rs b/src/server/drm_capturer.rs index 8b56c58d8..5001a763f 100644 --- a/src/server/drm_capturer.rs +++ b/src/server/drm_capturer.rs @@ -823,7 +823,7 @@ impl Drop for UinputRefreshGuard { /// Never probes, never blocks: the form the ROUTING gates must use. Seconds of IPC inside /// `wayland::clear()`, `is_inited()` or the display enumeration trips "deadline has elapsed". -pub(super) fn is_available_cached() -> bool { +pub(crate) fn is_available_cached() -> bool { matches!(&*DRM_STATE.lock().unwrap(), ProbeState::Available(..)) }