From 5e794818601ba0a7bab881b83f19aa4a2250a442 Mon Sep 17 00:00:00 2001 From: fufesou Date: Tue, 28 Mar 2023 20:20:45 +0800 Subject: [PATCH] linux, refact desktop env Signed-off-by: fufesou --- libs/hbb_common/src/platform/linux.rs | 2 +- src/platform/linux.rs | 10 +- src/platform/linux_desktop.rs | 358 ++++++++++---------------- src/rendezvous_mediator.rs | 2 - src/server.rs | 34 --- src/server/connection.rs | 50 ++-- 6 files changed, 163 insertions(+), 293 deletions(-) diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index cf1cf6da5..1d826ea97 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -135,7 +135,7 @@ pub fn get_values_of_seat0_with_gdm_wayland(indices: &[usize]) -> Vec { fn _get_values_of_seat0(indices: &[usize], ignore_gdm_wayland: bool) -> Vec { if let Ok(output) = run_loginctl(None) { for line in String::from_utf8_lossy(&output.stdout).lines() { - if !line.contains("gdm") && line.contains("seat0") { + if line.contains("seat0") { if let Some(sid) = line.split_whitespace().next() { if is_active(sid) { if ignore_gdm_wayland { diff --git a/src/platform/linux.rs b/src/platform/linux.rs index c1da431a4..857372bd7 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -1,4 +1,4 @@ -use super::linux_desktop::GNOME_SESSION_BINARY; +use super::linux_desktop::{get_desktop_env, Desktop}; use super::{CursorData, ResultType}; use desktop::Desktop; pub use hbb_common::platform::linux::*; @@ -382,13 +382,13 @@ pub fn start_os_service() { #[inline] pub fn get_active_user_id_name() -> (String, String) { - let vec_id_name = get_values_of_seat0(&[1, 2]); - (vec_id_name[0].clone(), vec_id_name[1].clone()) + let desktop = get_desktop_env(); + (desktop.uid.clone(), desktop.username.clone()) } #[inline] pub fn get_active_userid() -> String { - get_values_of_seat0(&[1])[0].clone() + get_desktop_env().uid.clone() } fn get_cm() -> bool { @@ -434,7 +434,7 @@ fn _get_display_manager() -> String { #[inline] pub fn get_active_username() -> String { - get_values_of_seat0(&[2])[0].clone() + get_desktop_env().username.clone() } pub fn get_active_user_home() -> Option { diff --git a/src/platform/linux_desktop.rs b/src/platform/linux_desktop.rs index 0d25b3743..0cd66512a 100644 --- a/src/platform/linux_desktop.rs +++ b/src/platform/linux_desktop.rs @@ -17,7 +17,8 @@ use users::{get_user_by_name, os::unix::UserExt, User}; lazy_static::lazy_static! { static ref DESKTOP_RUNNING: Arc = Arc::new(AtomicBool::new(false)); - static ref DESKTOP_INST: Arc>> = Arc::new(Mutex::new(None)); + static ref DESKTOP_ENV: Arc> = Arc::new(Mutex::new(Desktop::new())); + static ref CHILD_FLAGS: Arc>> = Arc::new(Mutex::new(None)); } pub const VIRTUAL_X11_DESKTOP: &str = "xfce4"; @@ -37,7 +38,8 @@ pub enum Protocal { } #[derive(Debug, Clone)] -pub struct DesktopEnv { +pub struct Desktop { + pub sid: String, pub protocal: Protocal, pub username: String, pub uid: String, @@ -46,24 +48,31 @@ pub struct DesktopEnv { } #[derive(Debug)] -pub struct Desktop { - env: DesktopEnv, +struct ChildFlags { child_exit: Arc, is_child_running: Arc, } fn check_update_env() { - let mut inst = DESKTOP_INST.lock().unwrap(); - if let Some(inst) = &mut (*inst) { - if !inst.is_child_running.load(Ordering::SeqCst) { - inst.child_exit.store(true, Ordering::SeqCst); - let old_env = inst.env.clone(); - allow_err!(inst.env.refresh()); - if !inst.env.is_same_env(&old_env) { - inst.env.update_env(); - log::debug!("desktop env changed, {:?}", &inst.env); - } + let mut child_flags = CHILD_FLAGS.lock().unwrap(); + let mut desktop = DESKTOP_ENV.lock().unwrap(); + + if let Some(child_flags) = &mut (*child_flags) { + if child_flags.is_child_running.load(Ordering::SeqCst) { + return; } + child_flags.child_exit.store(true, Ordering::SeqCst); + } + + if !desktop.sid.is_empty() && is_active(&desktop.sid) { + return; + } + + let old_desktop = desktop.clone(); + desktop.refresh(); + if !desktop.is_same_env(&old_desktop) { + desktop.update_env(); + log::debug!("desktop env changed, {:?}", &desktop); } } @@ -74,7 +83,7 @@ pub fn start_xdesktop() { } else { log::info!("Wait desktop: none"); } - *DESKTOP_INST.lock().unwrap() = Some(Desktop::new()); + *CHILD_FLAGS.lock().unwrap() = Some(ChildFlags::new()); let interval = time::Duration::from_millis(super::SERVICE_INTERVAL); DESKTOP_RUNNING.store(true, Ordering::SeqCst); @@ -90,19 +99,24 @@ pub fn stop_xdesktop() { DESKTOP_RUNNING.store(false, Ordering::SeqCst); } -pub fn get_desktop_env() -> Option { - match &*DESKTOP_INST.lock().unwrap() { - Some(inst) => Some(inst.env.clone()), - None => None, - } +#[inline] +pub fn get_desktop_env() -> Desktop { + DESKTOP_ENV.lock().unwrap().clone() } -pub fn try_start_x_session(username: &str, password: &str) -> ResultType { - let mut inst = DESKTOP_INST.lock().unwrap(); - if let Some(inst) = &mut (*inst) { - let _ = inst.try_start_x_session(username, password)?; - log::debug!("try_start_x_session, username: {}, {:?}", &username, &inst); - Ok(inst.env.clone()) +pub fn try_start_x_session(username: &str, password: &str) -> ResultType { + let mut child_flags = CHILD_FLAGS.lock().unwrap(); + let mut desktop_lock = DESKTOP_ENV.lock().unwrap(); + let mut desktop = Desktop::new(); + if let Some(child_flags) = &mut (*child_flags) { + let _ = child_flags.try_start_x_session(&mut desktop, username, password)?; + log::debug!( + "try_start_x_session, username: {}, {:?}", + &username, + &child_flags + ); + *desktop_lock = desktop.clone(); + Ok(desktop) } else { bail!(crate::server::LOGIN_MSG_XDESKTOP_NOT_INITED); } @@ -111,8 +125,8 @@ pub fn try_start_x_session(username: &str, password: &str) -> ResultType bool { let wait_begin = Instant::now(); while wait_begin.elapsed().as_secs() < timeout_secs { - let seat0 = get_values_of_seat0(&[0]); - if !seat0[0].is_empty() { + let uid = &get_values_of_seat0(&[1])[0]; + if !uid.is_empty() { return true; } @@ -132,11 +146,12 @@ fn wait_xdesktop(timeout_secs: u64) -> bool { false } -impl DesktopEnv { +impl Desktop { pub fn new() -> Self { let xauth = get_env_var("XAUTHORITY"); Self { + sid: "".to_owned(), protocal: Protocal::Unknown, username: "".to_owned(), uid: "".to_owned(), @@ -150,29 +165,43 @@ impl DesktopEnv { } fn update_env(&self) { - if self.is_ready() { + if self.is_x11() { std::env::set_var("DISPLAY", &self.display); std::env::set_var("XAUTHORITY", &self.xauth); std::env::set_var(ENV_DESKTOP_PROTOCAL, &self.protocal.to_string()); } else { std::env::set_var("DISPLAY", ""); std::env::set_var("XAUTHORITY", ""); - std::env::set_var(ENV_DESKTOP_PROTOCAL, &Protocal::Unknown.to_string()); + std::env::set_var(ENV_DESKTOP_PROTOCAL, &self.protocal.to_string()); } } pub fn is_same_env(&self, other: &Self) -> bool { - self.protocal == other.protocal + self.sid == other.sid + && self.protocal == other.protocal && self.uid == other.uid && self.display == other.display && self.xauth == other.xauth } - #[inline(always)] - pub fn is_ready(&self) -> bool { + #[inline] + pub fn is_x11(&self) -> bool { self.protocal == Protocal::X11 } + #[inline] + pub fn is_wayland(&self) -> bool { + self.protocal == Protocal::Wayland + } + + #[inline] + pub fn is_ready(&self) -> bool { + match self.protocal { + Protocal::X11 | Protocal::Wayland => true, + _ => false, + } + } + // The logic mainly fron https://github.com/neutrinolabs/xrdp/blob/34fe9b60ebaea59e8814bbc3ca5383cabaa1b869/sesman/session.c#L334. fn get_avail_display() -> ResultType { let display_range = 0..51; @@ -185,6 +214,7 @@ impl DesktopEnv { bail!("No avaliable display found in range {:?}", display_range) } + #[inline] fn is_x_server_running(display: u32) -> bool { Path::new(&format!("/tmp/.X11-unix/X{}", display)).exists() || Path::new(&format!("/tmp/.X{}-lock", display)).exists() @@ -233,148 +263,6 @@ impl DesktopEnv { } } - // fixme: reduce loginctl - fn get_env_seat0(&mut self) -> ResultType { - let output = Command::new("loginctl").output()?; - for line in String::from_utf8_lossy(&output.stdout).lines() { - if !line.contains("gdm") && line.contains("seat0") { - if let Some(sid) = line.split_whitespace().nth(0) { - if Self::is_active(sid)? { - if let Some(uid) = line.split_whitespace().nth(1) { - self.uid = uid.to_owned(); - } - if let Some(u) = line.split_whitespace().nth(2) { - self.username = u.to_owned(); - } - - self.protocal = Protocal::Unknown; - let type_output = Command::new("loginctl") - .args(vec!["show-session", "-p", "Type", sid]) - .output()?; - let type_stdout = String::from_utf8_lossy(&type_output.stdout); - - if type_stdout.contains("x11") { - self.protocal = Protocal::X11; - break; - } else if type_stdout.contains("wayland") { - self.protocal = Protocal::Wayland; - } - } - } - } - } - Ok(self.is_ready()) - } - - // some case, there is no seat0 https://github.com/rustdesk/rustdesk/issues/73 - fn get_env_active(&mut self) -> ResultType { - let output = Command::new("loginctl").output()?; - - // set active Xorg session - for line in String::from_utf8_lossy(&output.stdout).lines() { - if line.contains("sessions listed.") { - continue; - } - if let Some(sid) = line.split_whitespace().nth(0) { - if Self::is_active(sid)? { - if Self::get_display_server_of_session(sid) == ENV_DESKTOP_PROTOCAL__X11 { - if let Some(uid) = line.split_whitespace().nth(1) { - self.uid = uid.to_owned(); - } - if let Some(u) = line.split_whitespace().nth(2) { - self.username = u.to_owned(); - } - - self.protocal = Protocal::X11; - } - } - } - } - // // set active xfce4 session - // for line in String::from_utf8_lossy(&output.stdout).lines() { - // if let Some(sid) = line.split_whitespace().nth(0) { - // if Self::is_active(sid)? { - // let tty_output = Command::new("loginctl") - // .args(vec!["show-session", "-p", "TTY", sid]) - // .output()?; - // let tty: String = String::from_utf8_lossy(&tty_output.stdout) - // .replace("TTY=", "") - // .trim_end() - // .into(); - - // let xfce_panel_info = - // run_cmds(format!("ps -e | grep \"{}.\\\\+{}\"", tty, XFCE4_PANEL))?; - // if xfce_panel_info.trim_end().to_string() != "" { - // if let Some(uid) = line.split_whitespace().nth(1) { - // self.uid = uid.to_owned(); - // } - // if let Some(u) = line.split_whitespace().nth(2) { - // self.username = u.to_owned(); - // } - // } - // } - // } - // } - Ok(self.is_ready()) - } - - // fixme: dup - fn get_display_server_of_session(session: &str) -> String { - if let Ok(output) = Command::new("loginctl") - .args(vec!["show-session", "-p", "Type", session]) - .output() - // Check session type of the session - { - let display_server = String::from_utf8_lossy(&output.stdout) - .replace("Type=", "") - .trim_end() - .into(); - if display_server == "tty" { - // If the type is tty... - if let Ok(output) = Command::new("loginctl") - .args(vec!["show-session", "-p", "TTY", session]) - .output() - // Get the tty number - { - let tty: String = String::from_utf8_lossy(&output.stdout) - .replace("TTY=", "") - .trim_end() - .into(); - if let Ok(xorg_results) = - run_cmds(format!("ps -e | grep \"{}.\\\\+Xorg\"", tty)) - // And check if Xorg is running on that tty - { - if xorg_results.trim_end().to_string() != "" { - // If it is, manually return "x11", otherwise return tty - ENV_DESKTOP_PROTOCAL__X11.to_owned() - } else { - display_server - } - } else { - // If any of these commands fail just fall back to the display server - display_server - } - } else { - display_server - } - } else { - // If the session is not a tty, then just return the type as usual - display_server - } - } else { - "".to_owned() - } - } - - // fixme: remove - fn is_active(sid: &str) -> ResultType { - let output = Command::new("loginctl") - .args(vec!["show-session", "-p", "State", sid]) - .output()?; - - Ok(String::from_utf8_lossy(&output.stdout).contains("active")) - } - fn get_display_by_user(user: &str) -> String { // log::debug!("w {}", &user); if let Ok(output) = std::process::Command::new("w").arg(&user).output() { @@ -455,38 +343,47 @@ impl DesktopEnv { } } - fn refresh(&mut self) -> ResultType { + fn refresh(&mut self) { *self = Self::new(); - if self.get_env_seat0()? || self.get_env_active()? { - self.get_display(); - self.get_xauth(); - Ok(true) - } else { - Ok(false) + + let seat0_values = get_values_of_seat0(&[0, 1, 2]); + if seat0_values[0].is_empty() { + return; } + + self.sid = seat0_values[0].clone(); + self.uid = seat0_values[1].clone(); + self.username = seat0_values[2].clone(); + self.protocal = get_display_server_of_session(&self.sid).into(); + self.get_display(); + self.get_xauth(); } } -impl Drop for Desktop { +impl Drop for ChildFlags { fn drop(&mut self) { self.stop_children(); } } -impl Desktop { +impl ChildFlags { fn fatal_exit() { std::process::exit(0); } pub fn new() -> Self { Self { - env: DesktopEnv::new(), child_exit: Arc::new(AtomicBool::new(true)), is_child_running: Arc::new(AtomicBool::new(false)), } } - fn try_start_x_session(&mut self, username: &str, password: &str) -> ResultType<()> { + fn try_start_x_session( + &mut self, + desktop: &mut Desktop, + username: &str, + password: &str, + ) -> ResultType<()> { match get_user_by_name(username) { Some(userinfo) => { let mut client = pam::Client::with_password(pam_get_service_name())?; @@ -495,22 +392,24 @@ impl Desktop { .set_credentials(username, password); match client.authenticate() { Ok(_) => { - if self.env.is_ready() && self.env.username == username { + if desktop.is_x11() && desktop.username == username { return Ok(()); } - self.env.username = username.to_string(); - self.env.uid = userinfo.uid().to_string(); - self.env.protocal = Protocal::Unknown; - match self.start_x_session(&userinfo, password) { + // to-do: sid is empty if xorg is managed by this process + desktop.sid = "".to_owned(); + desktop.username = username.to_string(); + desktop.uid = userinfo.uid().to_string(); + desktop.protocal = Protocal::Unknown; + match self.start_x_session(desktop, &userinfo, password) { Ok(_) => { - log::info!("Succeeded to start x11, update env {:?}", &self.env); - self.env.update_env(); + log::info!("Succeeded to start x11, update env {:?}", &desktop); + desktop.update_env(); Ok(()) } Err(e) => { - self.env = DesktopEnv::new(); - self.env.update_env(); + *desktop = Desktop::new(); + desktop.update_env(); bail!("failed to start x session, {}", e); } } @@ -526,19 +425,24 @@ impl Desktop { } } - fn start_x_session(&mut self, userinfo: &User, password: &str) -> ResultType<()> { + fn start_x_session( + &mut self, + desktop: &mut Desktop, + userinfo: &User, + password: &str, + ) -> ResultType<()> { self.stop_children(); - let display_num = DesktopEnv::get_avail_display()?; + let display_num = Desktop::get_avail_display()?; // "xServer_ip:display_num.screen_num" - self.env.display = format!(":{}", display_num); + desktop.display = format!(":{}", display_num); let uid = userinfo.uid(); let gid = userinfo.primary_group_id(); let envs = HashMap::from([ ("SHELL", userinfo.shell().to_string_lossy().to_string()), ("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin".to_owned()), - ("USER", self.env.username.clone()), + ("USER", desktop.username.clone()), ("UID", userinfo.uid().to_string()), ("HOME", userinfo.home_dir().to_string_lossy().to_string()), ( @@ -549,7 +453,7 @@ impl Desktop { // ("XAUTHORITY", self.xauth.clone()), // (ENV_DESKTOP_PROTOCAL, XProtocal::X11.to_string()), ]); - let env = self.env.clone(); + let desktop_clone = desktop.clone(); self.child_exit.store(false, Ordering::SeqCst); let is_child_running = self.is_child_running.clone(); @@ -560,7 +464,7 @@ impl Desktop { match Self::start_x_session_thread( tx_res.clone(), is_child_running, - env, + desktop_clone, uid, gid, display_num, @@ -579,7 +483,7 @@ impl Desktop { match rx_res.recv_timeout(Duration::from_millis(10_000)) { Ok(res) => { if res == "" { - self.env.protocal = Protocal::X11; + desktop.protocal = Protocal::X11; Ok(()) } else { bail!(res) @@ -594,7 +498,7 @@ impl Desktop { fn start_x_session_thread( tx_res: SyncSender, is_child_running: Arc, - env: DesktopEnv, + desktop: Desktop, uid: u32, gid: u32, display_num: u32, @@ -604,16 +508,16 @@ impl Desktop { let mut client = pam::Client::with_password(pam_get_service_name())?; client .conversation_mut() - .set_credentials(&env.username, &password); + .set_credentials(&desktop.username, &password); client.authenticate()?; - client.set_item(pam::PamItemType::TTY, &env.display)?; + client.set_item(pam::PamItemType::TTY, &desktop.display)?; client.open_session()?; // fixme: FreeBSD kernel needs to login here. // see: https://github.com/neutrinolabs/xrdp/blob/a64573b596b5fb07ca3a51590c5308d621f7214e/sesman/session.c#L556 - let (child_xorg, child_wm) = Self::start_x11(&env, uid, gid, display_num, &envs)?; + let (child_xorg, child_wm) = Self::start_x11(&desktop, uid, gid, display_num, &envs)?; is_child_running.store(true, Ordering::SeqCst); log::info!("Start xorg and wm done, notify and wait xtop x11"); @@ -646,25 +550,25 @@ impl Desktop { } fn start_x11( - env: &DesktopEnv, + desktop: &Desktop, uid: u32, gid: u32, display_num: u32, envs: &HashMap<&str, String>, ) -> ResultType<(Child, Child)> { - log::debug!("envs of user {}: {:?}", &env.username, &envs); + log::debug!("envs of user {}: {:?}", &desktop.username, &envs); - DesktopEnv::add_xauth_cookie(&env.xauth, &env.display, uid, gid, &envs)?; + Desktop::add_xauth_cookie(&desktop.xauth, &desktop.display, uid, gid, &envs)?; // Start Xorg - let mut child_xorg = Self::start_x_server(&env.xauth, &env.display, uid, gid, &envs)?; + let mut child_xorg = + Self::start_x_server(&desktop.xauth, &desktop.display, uid, gid, &envs)?; log::info!("xorg started, wait 10 secs to ensuer x server is running"); let max_wait_secs = 10; // wait x server running - if let Err(e) = - DesktopEnv::wait_x_server_running(child_xorg.id(), display_num, max_wait_secs) + if let Err(e) = Desktop::wait_x_server_running(child_xorg.id(), display_num, max_wait_secs) { match Self::wait_xorg_exit(&mut child_xorg) { Ok(msg) => log::info!("{}", msg), @@ -678,12 +582,12 @@ impl Desktop { log::info!( "xorg is running, start x window manager with DISPLAY: {}, XAUTHORITY: {}", - &env.display, - &env.xauth + &desktop.display, + &desktop.xauth ); - std::env::set_var("DISPLAY", &env.display); - std::env::set_var("XAUTHORITY", &env.xauth); + std::env::set_var("DISPLAY", &desktop.display); + std::env::set_var("XAUTHORITY", &desktop.xauth); // start window manager (startwm.sh) let child_wm = match Self::start_x_window_manager(uid, gid, &envs) { Ok(c) => c, @@ -803,10 +707,10 @@ impl Desktop { } fn try_wait_stop_x11(child_xorg: &mut Child, child_wm: &mut Child) -> bool { - let mut inst = DESKTOP_INST.lock().unwrap(); + let mut child_flags = CHILD_FLAGS.lock().unwrap(); let mut exited = true; - if let Some(inst) = &mut (*inst) { - if inst.child_exit.load(Ordering::SeqCst) { + if let Some(child_flags) = &mut (*child_flags) { + if child_flags.child_exit.load(Ordering::SeqCst) { exited = true; } else { exited = Self::try_wait_x11_child_exit(child_xorg, child_wm); @@ -814,8 +718,8 @@ impl Desktop { if exited { println!("=============================MYDEBUG begin to wait x11 children exit"); Self::wait_x11_children_exit(child_xorg, child_wm); - inst.is_child_running.store(false, Ordering::SeqCst); - inst.child_exit.store(true, Ordering::SeqCst); + child_flags.is_child_running.store(false, Ordering::SeqCst); + child_flags.child_exit.store(true, Ordering::SeqCst); } } exited @@ -949,3 +853,13 @@ impl ToString for Protocal { } } } + +impl From for Protocal { + fn from(value: String) -> Self { + match &value as &str { + ENV_DESKTOP_PROTOCAL__X11 => Protocal::X11, + ENV_DESKTOP_PROTOCAL_WAYLAND => Protocal::Wayland, + _ => Protocal::Unknown, + } + } +} diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 339a45bf3..5a68a4a03 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -54,8 +54,6 @@ impl RendezvousMediator { pub async fn start_all() { let mut nat_tested = false; check_zombie(); - #[cfg(target_os = "linux")] - crate::server::check_xdesktop(); let server = new_server(); if Config::get_nat_type() == NatType::UNKNOWN_NAT as i32 { crate::test_nat_type(); diff --git a/src/server.rs b/src/server.rs index 81c967ba1..681e7bed1 100644 --- a/src/server.rs +++ b/src/server.rs @@ -356,40 +356,6 @@ pub fn check_zombie() { }); } -#[cfg(target_os = "linux")] -pub fn check_xdesktop() { - std::thread::spawn(|| { - use crate::platform::linux_desktop::{get_desktop_env, DesktopEnv}; - let mut desktop_env = DesktopEnv::new(); - loop { - let new_env = match get_desktop_env() { - Some(env) => env, - None => DesktopEnv::new(), - }; - - if new_env.is_ready() { - if !desktop_env.is_ready() { - desktop_env = new_env.clone(); - } else { - if !desktop_env.is_same_env(&new_env) { - log::info!("xdesktop env diff {:?} to {:?}", &new_env, desktop_env); - break; - } - } - } else { - if desktop_env.is_ready() { - log::info!("xdesktop env diff {:?} to {:?}", &new_env, desktop_env); - break; - } - } - - std::thread::sleep(Duration::from_millis(300)); - } - - crate::RendezvousMediator::restart(); - }); -} - /// Start the host server that allows the remote peer to control the current machine. /// /// # Arguments diff --git a/src/server/connection.rs b/src/server/connection.rs index 36190485e..a5c63a80e 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1073,43 +1073,35 @@ impl Connection { fn try_start_desktop(_username: &str, _passsword: &str) -> String { #[cfg(target_os = "linux")] - { - if _username.is_empty() { - match crate::platform::linux_desktop::get_desktop_env() { - Some(desktop_env) => { - if desktop_env.is_ready() { - "" - } else { - LOGIN_MSG_XSESSION_NOT_READY - } - } - None => LOGIN_MSG_XDESKTOP_NOT_INITED, - } - .to_owned() + if _username.is_empty() { + let desktop = crate::platform::linux_desktop::get_desktop_env(); + if desktop.is_ready() { + "" } else { - match crate::platform::linux_desktop::try_start_x_session(_username, _passsword) { - Ok(desktop_env) => { - if desktop_env.is_ready() { - if _username != desktop_env.username { - LOGIN_MSG_XSESSION_ANOTHER_USER_READTY.to_owned() - } else { - "".to_owned() - } + LOGIN_MSG_XSESSION_NOT_READY + } + .to_owned() + } else { + match crate::platform::linux_desktop::try_start_x_session(_username, _passsword) { + Ok(desktop) => { + if desktop.is_ready() { + if _username != desktop.username { + LOGIN_MSG_XSESSION_ANOTHER_USER_READTY.to_owned() } else { - LOGIN_MSG_XSESSION_NOT_READY.to_owned() + "".to_owned() } + } else { + LOGIN_MSG_XSESSION_NOT_READY.to_owned() } - Err(e) => { - log::error!("Failed to start xsession {}", e); - LOGIN_MSG_XSESSION_FAILED.to_owned() - } + } + Err(e) => { + log::error!("Failed to start xsession {}", e); + LOGIN_MSG_XSESSION_FAILED.to_owned() } } } #[cfg(not(target_os = "linux"))] - { - "".to_owned() - } + "".to_owned() } fn validate_one_password(&self, password: String) -> bool {