diff --git a/src/server/drm_capturer.rs b/src/server/drm_capturer.rs index 0de88ee24..754b37f38 100644 --- a/src/server/drm_capturer.rs +++ b/src/server/drm_capturer.rs @@ -1095,9 +1095,6 @@ pub(super) fn get_primary_index() -> usize { ProbeState::Available(_, list) => list.clone(), _ => return 0, }; - if !wayland_outputs_askable() { - return 0; - } let wl = scrap::wayland::display::get_displays(); if wl.displays.is_empty() { return 0; @@ -1108,18 +1105,16 @@ pub(super) fn get_primary_index() -> usize { .unwrap_or(0) } -/// Whether the compositor can be asked for its outputs here. A login screen has none, and -/// `get_displays()` does not cache that failure, so it reopens a connection every call. Both -/// callers treat an empty list as "no augmentation", so skipping cannot change either answer. -fn wayland_outputs_askable() -> bool { - !crate::platform::linux::is_login_screen_wayland_cached() -} - /// DRM reports every monitor at physical size and origin (0,0), stacking a multi-monitor client. +/// +/// Asked at login screens too, on purpose: a greeter runs a compositor, and the socket fallback in +/// hbb_common lets the enumerator reach it with no environment variables. Where that fallback +/// cannot answer, the list comes back empty and everything stays unaugmented, which is what the +/// old is-login-screen gate produced unconditionally. fn augment_with_wayland_geometry(drm: &[DrmDisplayInfo]) -> Vec { let mut infos: Vec = drm.iter().map(display_info_from_drm).collect(); // Below two displays there is nothing to augment, compositor or not. - if drm.len() < 2 || !wayland_outputs_askable() { + if drm.len() < 2 { return infos; } let wl = scrap::wayland::display::get_displays(); diff --git a/src/server/wayland.rs b/src/server/wayland.rs index e51ca89c5..4764359c2 100644 --- a/src/server/wayland.rs +++ b/src/server/wayland.rs @@ -153,29 +153,18 @@ pub(super) async fn update_uinput_resolution() { if !crate::input_service::wayland_use_uinput() { return; } - // A greeter's `--server` gets no compositor variables, so the enumerator cannot answer and - // the device would keep its default range. The DRM displays are the ones being captured, so - // their coordinate space matches by construction; ask them first rather than after a failure. - let rect = if crate::platform::linux::is_login_screen_wayland_cached() { - let Some(rect) = drm_desktop_rect_for_uinput() else { + // Compositor first at a login screen too: a greeter runs one, and the hbb_common socket + // fallback reaches it with no environment variables. The DRM union is the fallback, and it is + // a real loss to land there on a multi-monitor host: DRM has no origins, so its union rect + // mis-maps the pointer whenever the compositor arranged the outputs side by side. + scrap::wayland::display::clear_wayland_displays_cache(); + let rect = match scrap::wayland::display::get_desktop_rect_for_uinput() + .or_else(drm_desktop_rect_for_uinput) + { + Some(rect) => rect, + None => { log::warn!("Failed to get desktop rect for uinput"); return; - }; - log::info!( - "uinput desktop rect taken from the DRM display list (no compositor here): {rect:?}" - ); - rect - } else { - scrap::wayland::display::clear_wayland_displays_cache(); - // Also for a compositor that answers late: the DRM list beats no answer. - match scrap::wayland::display::get_desktop_rect_for_uinput() - .or_else(drm_desktop_rect_for_uinput) - { - Some(rect) => rect, - None => { - log::warn!("Failed to get desktop rect for uinput"); - return; - } } }; // Re-snapshot the baseline on every call: this runs at session init and after every hotplug, and