diff --git a/AGENTS.md b/AGENTS.md index 21e631f1d..fe8b73ec7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -71,6 +71,7 @@ * Prefer purely additive changes: layer new (`#[cfg]`-gated) blocks or new functions around existing code instead of restructuring it. The ideal diff for a fix adds lines and modifies/deletes none. * Do not extract or reshape existing code just to enable your new code; look for a mechanism that leaves existing lines untouched (e.g. hide/show an existing object instead of refactoring its construction into a helper for rebuilding). +* Accept a little duplication over a restructure. A new function that repeats a few lines of an existing one is a better diff than reshaping the original so both can share it. * Put new logic in self-contained functions in the module it belongs to (platform-specific logic in `src/platform/`, with `use` inside the function body to avoid churning shared import blocks). Call sites in shared files (`src/tray.rs`, `src/core_main.rs`, `src/server/connection.rs`, …) should be thin one-line hooks. ## Reviewing a PR diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 4fba6e669..f0979c2d1 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -2058,6 +2058,21 @@ mod desktop { sleep_millis(300); } + if self.display.is_empty() { + // logind stores the value pam_systemd was handed at session creation, which is not + // necessarily a local display: it can be qualified with this host (`myhost:0`) or + // name an X forwarding endpoint (`localhost:10.0`), and some setups record a bare + // `:`. Strip this host, then require a display number. `localhost` is deliberately + // left in place: a non-empty display here suppresses every fallback below, both + // `get_display_by_user` and the `:0` default, so anything not local must not pass. + let display = Self::get_display_from_session(&self.sid) + .replace(&hbb_common::whoami::hostname(), ""); + if display.strip_prefix(':').map_or(false, |number| { + number.starts_with(|c: char| c.is_ascii_digit()) + }) { + self.display = display; + } + } if self.display.is_empty() { self.display = Self::get_display_by_user(&self.username); } @@ -2070,6 +2085,34 @@ mod desktop { .replace("localhost", ""); } + fn get_display_from_session(session: &str) -> String { + if session.is_empty() { + return String::new(); + } + + match Command::new(CMD_LOGINCTL.as_str()) + .args(["show-session", "-p", "Display", session]) + .output() + { + Ok(output) if output.status.success() => String::from_utf8_lossy(&output.stdout) + .trim() + .strip_prefix("Display=") + .unwrap_or_default() + .to_owned(), + Ok(output) => { + log::debug!( + "Failed to get display for session {session}: {}", + output.status + ); + String::new() + } + Err(err) => { + log::debug!("Failed to get display for session {session}: {err}"); + String::new() + } + } + } + fn get_home(&mut self) { self.home = "".to_string();