mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-08-24 07:06:32 +00:00
fix(linux): a Wayland greeter the DRM backend can serve is not headless
fufesou reported the login screen still failing on Ubuntu 24.04 with gdm3, with the client asking for OS credentials to start an X session instead of showing the greeter. Reproduced on a real gdm greeter here. Same premise as the rest of the branch, one more consumer. `DesktopManager::new` reads seat0 through `get_values_of_seat0`, which skips a gdm/sddm Wayland session by construction, so at a greeter it finds no session at all and `get_supported_display_seat0_username` returns None from its empty-username arm. That makes `is_headless()` true, so the service advertises headless and `try_start_desktop` answers `LOGIN_MSG_DESKTOP_SESSION_NOT_READY`. The corrected `IS_X11` does not reach this one: it asks who owns seat0, not which display server is running. So ask again, with the greeter visible, when the DRM backend can capture and inject into it. At query time rather than in `new()`, because the DRM probe has not necessarily settled when the desktop manager is constructed, and the answer would latch for the process lifetime. In a normal session the latched username is a real user and the extra read is skipped.
This commit is contained in:
@@ -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<String> {
|
||||
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<String> {
|
||||
// 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
|
||||
|
||||
@@ -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(..))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user