linux, refact desktop env

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2023-03-28 20:20:45 +08:00
parent 461aa622f8
commit 5e79481860
6 changed files with 163 additions and 293 deletions

View File

@ -135,7 +135,7 @@ pub fn get_values_of_seat0_with_gdm_wayland(indices: &[usize]) -> Vec<String> {
fn _get_values_of_seat0(indices: &[usize], ignore_gdm_wayland: bool) -> Vec<String> { fn _get_values_of_seat0(indices: &[usize], ignore_gdm_wayland: bool) -> Vec<String> {
if let Ok(output) = run_loginctl(None) { if let Ok(output) = run_loginctl(None) {
for line in String::from_utf8_lossy(&output.stdout).lines() { 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 let Some(sid) = line.split_whitespace().next() {
if is_active(sid) { if is_active(sid) {
if ignore_gdm_wayland { if ignore_gdm_wayland {

View File

@ -1,4 +1,4 @@
use super::linux_desktop::GNOME_SESSION_BINARY; use super::linux_desktop::{get_desktop_env, Desktop};
use super::{CursorData, ResultType}; use super::{CursorData, ResultType};
use desktop::Desktop; use desktop::Desktop;
pub use hbb_common::platform::linux::*; pub use hbb_common::platform::linux::*;
@ -382,13 +382,13 @@ pub fn start_os_service() {
#[inline] #[inline]
pub fn get_active_user_id_name() -> (String, String) { pub fn get_active_user_id_name() -> (String, String) {
let vec_id_name = get_values_of_seat0(&[1, 2]); let desktop = get_desktop_env();
(vec_id_name[0].clone(), vec_id_name[1].clone()) (desktop.uid.clone(), desktop.username.clone())
} }
#[inline] #[inline]
pub fn get_active_userid() -> String { pub fn get_active_userid() -> String {
get_values_of_seat0(&[1])[0].clone() get_desktop_env().uid.clone()
} }
fn get_cm() -> bool { fn get_cm() -> bool {
@ -434,7 +434,7 @@ fn _get_display_manager() -> String {
#[inline] #[inline]
pub fn get_active_username() -> String { 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<PathBuf> { pub fn get_active_user_home() -> Option<PathBuf> {

View File

@ -17,7 +17,8 @@ use users::{get_user_by_name, os::unix::UserExt, User};
lazy_static::lazy_static! { lazy_static::lazy_static! {
static ref DESKTOP_RUNNING: Arc<AtomicBool> = Arc::new(AtomicBool::new(false)); static ref DESKTOP_RUNNING: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
static ref DESKTOP_INST: Arc<Mutex<Option<Desktop>>> = Arc::new(Mutex::new(None)); static ref DESKTOP_ENV: Arc<Mutex<Desktop>> = Arc::new(Mutex::new(Desktop::new()));
static ref CHILD_FLAGS: Arc<Mutex<Option<ChildFlags>>> = Arc::new(Mutex::new(None));
} }
pub const VIRTUAL_X11_DESKTOP: &str = "xfce4"; pub const VIRTUAL_X11_DESKTOP: &str = "xfce4";
@ -37,7 +38,8 @@ pub enum Protocal {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DesktopEnv { pub struct Desktop {
pub sid: String,
pub protocal: Protocal, pub protocal: Protocal,
pub username: String, pub username: String,
pub uid: String, pub uid: String,
@ -46,24 +48,31 @@ pub struct DesktopEnv {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Desktop { struct ChildFlags {
env: DesktopEnv,
child_exit: Arc<AtomicBool>, child_exit: Arc<AtomicBool>,
is_child_running: Arc<AtomicBool>, is_child_running: Arc<AtomicBool>,
} }
fn check_update_env() { fn check_update_env() {
let mut inst = DESKTOP_INST.lock().unwrap(); let mut child_flags = CHILD_FLAGS.lock().unwrap();
if let Some(inst) = &mut (*inst) { let mut desktop = DESKTOP_ENV.lock().unwrap();
if !inst.is_child_running.load(Ordering::SeqCst) {
inst.child_exit.store(true, Ordering::SeqCst); if let Some(child_flags) = &mut (*child_flags) {
let old_env = inst.env.clone(); if child_flags.is_child_running.load(Ordering::SeqCst) {
allow_err!(inst.env.refresh()); return;
if !inst.env.is_same_env(&old_env) {
inst.env.update_env();
log::debug!("desktop env changed, {:?}", &inst.env);
} }
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 { } else {
log::info!("Wait desktop: none"); 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); let interval = time::Duration::from_millis(super::SERVICE_INTERVAL);
DESKTOP_RUNNING.store(true, Ordering::SeqCst); DESKTOP_RUNNING.store(true, Ordering::SeqCst);
@ -90,19 +99,24 @@ pub fn stop_xdesktop() {
DESKTOP_RUNNING.store(false, Ordering::SeqCst); DESKTOP_RUNNING.store(false, Ordering::SeqCst);
} }
pub fn get_desktop_env() -> Option<DesktopEnv> { #[inline]
match &*DESKTOP_INST.lock().unwrap() { pub fn get_desktop_env() -> Desktop {
Some(inst) => Some(inst.env.clone()), DESKTOP_ENV.lock().unwrap().clone()
None => None,
}
} }
pub fn try_start_x_session(username: &str, password: &str) -> ResultType<DesktopEnv> { pub fn try_start_x_session(username: &str, password: &str) -> ResultType<Desktop> {
let mut inst = DESKTOP_INST.lock().unwrap(); let mut child_flags = CHILD_FLAGS.lock().unwrap();
if let Some(inst) = &mut (*inst) { let mut desktop_lock = DESKTOP_ENV.lock().unwrap();
let _ = inst.try_start_x_session(username, password)?; let mut desktop = Desktop::new();
log::debug!("try_start_x_session, username: {}, {:?}", &username, &inst); if let Some(child_flags) = &mut (*child_flags) {
Ok(inst.env.clone()) 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 { } else {
bail!(crate::server::LOGIN_MSG_XDESKTOP_NOT_INITED); bail!(crate::server::LOGIN_MSG_XDESKTOP_NOT_INITED);
} }
@ -111,8 +125,8 @@ pub fn try_start_x_session(username: &str, password: &str) -> ResultType<Desktop
fn wait_xdesktop(timeout_secs: u64) -> bool { fn wait_xdesktop(timeout_secs: u64) -> bool {
let wait_begin = Instant::now(); let wait_begin = Instant::now();
while wait_begin.elapsed().as_secs() < timeout_secs { while wait_begin.elapsed().as_secs() < timeout_secs {
let seat0 = get_values_of_seat0(&[0]); let uid = &get_values_of_seat0(&[1])[0];
if !seat0[0].is_empty() { if !uid.is_empty() {
return true; return true;
} }
@ -132,11 +146,12 @@ fn wait_xdesktop(timeout_secs: u64) -> bool {
false false
} }
impl DesktopEnv { impl Desktop {
pub fn new() -> Self { pub fn new() -> Self {
let xauth = get_env_var("XAUTHORITY"); let xauth = get_env_var("XAUTHORITY");
Self { Self {
sid: "".to_owned(),
protocal: Protocal::Unknown, protocal: Protocal::Unknown,
username: "".to_owned(), username: "".to_owned(),
uid: "".to_owned(), uid: "".to_owned(),
@ -150,29 +165,43 @@ impl DesktopEnv {
} }
fn update_env(&self) { fn update_env(&self) {
if self.is_ready() { if self.is_x11() {
std::env::set_var("DISPLAY", &self.display); std::env::set_var("DISPLAY", &self.display);
std::env::set_var("XAUTHORITY", &self.xauth); std::env::set_var("XAUTHORITY", &self.xauth);
std::env::set_var(ENV_DESKTOP_PROTOCAL, &self.protocal.to_string()); std::env::set_var(ENV_DESKTOP_PROTOCAL, &self.protocal.to_string());
} else { } else {
std::env::set_var("DISPLAY", ""); std::env::set_var("DISPLAY", "");
std::env::set_var("XAUTHORITY", ""); 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 { 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.uid == other.uid
&& self.display == other.display && self.display == other.display
&& self.xauth == other.xauth && self.xauth == other.xauth
} }
#[inline(always)] #[inline]
pub fn is_ready(&self) -> bool { pub fn is_x11(&self) -> bool {
self.protocal == Protocal::X11 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. // The logic mainly fron https://github.com/neutrinolabs/xrdp/blob/34fe9b60ebaea59e8814bbc3ca5383cabaa1b869/sesman/session.c#L334.
fn get_avail_display() -> ResultType<u32> { fn get_avail_display() -> ResultType<u32> {
let display_range = 0..51; let display_range = 0..51;
@ -185,6 +214,7 @@ impl DesktopEnv {
bail!("No avaliable display found in range {:?}", display_range) bail!("No avaliable display found in range {:?}", display_range)
} }
#[inline]
fn is_x_server_running(display: u32) -> bool { fn is_x_server_running(display: u32) -> bool {
Path::new(&format!("/tmp/.X11-unix/X{}", display)).exists() Path::new(&format!("/tmp/.X11-unix/X{}", display)).exists()
|| Path::new(&format!("/tmp/.X{}-lock", 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<bool> {
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<bool> {
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<bool> {
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 { fn get_display_by_user(user: &str) -> String {
// log::debug!("w {}", &user); // log::debug!("w {}", &user);
if let Ok(output) = std::process::Command::new("w").arg(&user).output() { if let Ok(output) = std::process::Command::new("w").arg(&user).output() {
@ -455,38 +343,47 @@ impl DesktopEnv {
} }
} }
fn refresh(&mut self) -> ResultType<bool> { fn refresh(&mut self) {
*self = Self::new(); *self = Self::new();
if self.get_env_seat0()? || self.get_env_active()? {
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_display();
self.get_xauth(); self.get_xauth();
Ok(true)
} else {
Ok(false)
}
} }
} }
impl Drop for Desktop { impl Drop for ChildFlags {
fn drop(&mut self) { fn drop(&mut self) {
self.stop_children(); self.stop_children();
} }
} }
impl Desktop { impl ChildFlags {
fn fatal_exit() { fn fatal_exit() {
std::process::exit(0); std::process::exit(0);
} }
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
env: DesktopEnv::new(),
child_exit: Arc::new(AtomicBool::new(true)), child_exit: Arc::new(AtomicBool::new(true)),
is_child_running: Arc::new(AtomicBool::new(false)), 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) { match get_user_by_name(username) {
Some(userinfo) => { Some(userinfo) => {
let mut client = pam::Client::with_password(pam_get_service_name())?; let mut client = pam::Client::with_password(pam_get_service_name())?;
@ -495,22 +392,24 @@ impl Desktop {
.set_credentials(username, password); .set_credentials(username, password);
match client.authenticate() { match client.authenticate() {
Ok(_) => { Ok(_) => {
if self.env.is_ready() && self.env.username == username { if desktop.is_x11() && desktop.username == username {
return Ok(()); return Ok(());
} }
self.env.username = username.to_string(); // to-do: sid is empty if xorg is managed by this process
self.env.uid = userinfo.uid().to_string(); desktop.sid = "".to_owned();
self.env.protocal = Protocal::Unknown; desktop.username = username.to_string();
match self.start_x_session(&userinfo, password) { desktop.uid = userinfo.uid().to_string();
desktop.protocal = Protocal::Unknown;
match self.start_x_session(desktop, &userinfo, password) {
Ok(_) => { Ok(_) => {
log::info!("Succeeded to start x11, update env {:?}", &self.env); log::info!("Succeeded to start x11, update env {:?}", &desktop);
self.env.update_env(); desktop.update_env();
Ok(()) Ok(())
} }
Err(e) => { Err(e) => {
self.env = DesktopEnv::new(); *desktop = Desktop::new();
self.env.update_env(); desktop.update_env();
bail!("failed to start x session, {}", e); 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(); self.stop_children();
let display_num = DesktopEnv::get_avail_display()?; let display_num = Desktop::get_avail_display()?;
// "xServer_ip:display_num.screen_num" // "xServer_ip:display_num.screen_num"
self.env.display = format!(":{}", display_num); desktop.display = format!(":{}", display_num);
let uid = userinfo.uid(); let uid = userinfo.uid();
let gid = userinfo.primary_group_id(); let gid = userinfo.primary_group_id();
let envs = HashMap::from([ let envs = HashMap::from([
("SHELL", userinfo.shell().to_string_lossy().to_string()), ("SHELL", userinfo.shell().to_string_lossy().to_string()),
("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin".to_owned()), ("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin".to_owned()),
("USER", self.env.username.clone()), ("USER", desktop.username.clone()),
("UID", userinfo.uid().to_string()), ("UID", userinfo.uid().to_string()),
("HOME", userinfo.home_dir().to_string_lossy().to_string()), ("HOME", userinfo.home_dir().to_string_lossy().to_string()),
( (
@ -549,7 +453,7 @@ impl Desktop {
// ("XAUTHORITY", self.xauth.clone()), // ("XAUTHORITY", self.xauth.clone()),
// (ENV_DESKTOP_PROTOCAL, XProtocal::X11.to_string()), // (ENV_DESKTOP_PROTOCAL, XProtocal::X11.to_string()),
]); ]);
let env = self.env.clone(); let desktop_clone = desktop.clone();
self.child_exit.store(false, Ordering::SeqCst); self.child_exit.store(false, Ordering::SeqCst);
let is_child_running = self.is_child_running.clone(); let is_child_running = self.is_child_running.clone();
@ -560,7 +464,7 @@ impl Desktop {
match Self::start_x_session_thread( match Self::start_x_session_thread(
tx_res.clone(), tx_res.clone(),
is_child_running, is_child_running,
env, desktop_clone,
uid, uid,
gid, gid,
display_num, display_num,
@ -579,7 +483,7 @@ impl Desktop {
match rx_res.recv_timeout(Duration::from_millis(10_000)) { match rx_res.recv_timeout(Duration::from_millis(10_000)) {
Ok(res) => { Ok(res) => {
if res == "" { if res == "" {
self.env.protocal = Protocal::X11; desktop.protocal = Protocal::X11;
Ok(()) Ok(())
} else { } else {
bail!(res) bail!(res)
@ -594,7 +498,7 @@ impl Desktop {
fn start_x_session_thread( fn start_x_session_thread(
tx_res: SyncSender<String>, tx_res: SyncSender<String>,
is_child_running: Arc<AtomicBool>, is_child_running: Arc<AtomicBool>,
env: DesktopEnv, desktop: Desktop,
uid: u32, uid: u32,
gid: u32, gid: u32,
display_num: u32, display_num: u32,
@ -604,16 +508,16 @@ impl Desktop {
let mut client = pam::Client::with_password(pam_get_service_name())?; let mut client = pam::Client::with_password(pam_get_service_name())?;
client client
.conversation_mut() .conversation_mut()
.set_credentials(&env.username, &password); .set_credentials(&desktop.username, &password);
client.authenticate()?; client.authenticate()?;
client.set_item(pam::PamItemType::TTY, &env.display)?; client.set_item(pam::PamItemType::TTY, &desktop.display)?;
client.open_session()?; client.open_session()?;
// fixme: FreeBSD kernel needs to login here. // fixme: FreeBSD kernel needs to login here.
// see: https://github.com/neutrinolabs/xrdp/blob/a64573b596b5fb07ca3a51590c5308d621f7214e/sesman/session.c#L556 // 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); is_child_running.store(true, Ordering::SeqCst);
log::info!("Start xorg and wm done, notify and wait xtop x11"); log::info!("Start xorg and wm done, notify and wait xtop x11");
@ -646,25 +550,25 @@ impl Desktop {
} }
fn start_x11( fn start_x11(
env: &DesktopEnv, desktop: &Desktop,
uid: u32, uid: u32,
gid: u32, gid: u32,
display_num: u32, display_num: u32,
envs: &HashMap<&str, String>, envs: &HashMap<&str, String>,
) -> ResultType<(Child, Child)> { ) -> 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 // 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"); log::info!("xorg started, wait 10 secs to ensuer x server is running");
let max_wait_secs = 10; let max_wait_secs = 10;
// wait x server running // wait x server running
if let Err(e) = if let Err(e) = Desktop::wait_x_server_running(child_xorg.id(), display_num, max_wait_secs)
DesktopEnv::wait_x_server_running(child_xorg.id(), display_num, max_wait_secs)
{ {
match Self::wait_xorg_exit(&mut child_xorg) { match Self::wait_xorg_exit(&mut child_xorg) {
Ok(msg) => log::info!("{}", msg), Ok(msg) => log::info!("{}", msg),
@ -678,12 +582,12 @@ impl Desktop {
log::info!( log::info!(
"xorg is running, start x window manager with DISPLAY: {}, XAUTHORITY: {}", "xorg is running, start x window manager with DISPLAY: {}, XAUTHORITY: {}",
&env.display, &desktop.display,
&env.xauth &desktop.xauth
); );
std::env::set_var("DISPLAY", &env.display); std::env::set_var("DISPLAY", &desktop.display);
std::env::set_var("XAUTHORITY", &env.xauth); std::env::set_var("XAUTHORITY", &desktop.xauth);
// start window manager (startwm.sh) // start window manager (startwm.sh)
let child_wm = match Self::start_x_window_manager(uid, gid, &envs) { let child_wm = match Self::start_x_window_manager(uid, gid, &envs) {
Ok(c) => c, Ok(c) => c,
@ -803,10 +707,10 @@ impl Desktop {
} }
fn try_wait_stop_x11(child_xorg: &mut Child, child_wm: &mut Child) -> bool { 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; let mut exited = true;
if let Some(inst) = &mut (*inst) { if let Some(child_flags) = &mut (*child_flags) {
if inst.child_exit.load(Ordering::SeqCst) { if child_flags.child_exit.load(Ordering::SeqCst) {
exited = true; exited = true;
} else { } else {
exited = Self::try_wait_x11_child_exit(child_xorg, child_wm); exited = Self::try_wait_x11_child_exit(child_xorg, child_wm);
@ -814,8 +718,8 @@ impl Desktop {
if exited { if exited {
println!("=============================MYDEBUG begin to wait x11 children exit"); println!("=============================MYDEBUG begin to wait x11 children exit");
Self::wait_x11_children_exit(child_xorg, child_wm); Self::wait_x11_children_exit(child_xorg, child_wm);
inst.is_child_running.store(false, Ordering::SeqCst); child_flags.is_child_running.store(false, Ordering::SeqCst);
inst.child_exit.store(true, Ordering::SeqCst); child_flags.child_exit.store(true, Ordering::SeqCst);
} }
} }
exited exited
@ -949,3 +853,13 @@ impl ToString for Protocal {
} }
} }
} }
impl From<String> 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,
}
}
}

View File

@ -54,8 +54,6 @@ impl RendezvousMediator {
pub async fn start_all() { pub async fn start_all() {
let mut nat_tested = false; let mut nat_tested = false;
check_zombie(); check_zombie();
#[cfg(target_os = "linux")]
crate::server::check_xdesktop();
let server = new_server(); let server = new_server();
if Config::get_nat_type() == NatType::UNKNOWN_NAT as i32 { if Config::get_nat_type() == NatType::UNKNOWN_NAT as i32 {
crate::test_nat_type(); crate::test_nat_type();

View File

@ -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. /// Start the host server that allows the remote peer to control the current machine.
/// ///
/// # Arguments /// # Arguments

View File

@ -1073,24 +1073,19 @@ impl Connection {
fn try_start_desktop(_username: &str, _passsword: &str) -> String { fn try_start_desktop(_username: &str, _passsword: &str) -> String {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
{
if _username.is_empty() { if _username.is_empty() {
match crate::platform::linux_desktop::get_desktop_env() { let desktop = crate::platform::linux_desktop::get_desktop_env();
Some(desktop_env) => { if desktop.is_ready() {
if desktop_env.is_ready() {
"" ""
} else { } else {
LOGIN_MSG_XSESSION_NOT_READY LOGIN_MSG_XSESSION_NOT_READY
} }
}
None => LOGIN_MSG_XDESKTOP_NOT_INITED,
}
.to_owned() .to_owned()
} else { } else {
match crate::platform::linux_desktop::try_start_x_session(_username, _passsword) { match crate::platform::linux_desktop::try_start_x_session(_username, _passsword) {
Ok(desktop_env) => { Ok(desktop) => {
if desktop_env.is_ready() { if desktop.is_ready() {
if _username != desktop_env.username { if _username != desktop.username {
LOGIN_MSG_XSESSION_ANOTHER_USER_READTY.to_owned() LOGIN_MSG_XSESSION_ANOTHER_USER_READTY.to_owned()
} else { } else {
"".to_owned() "".to_owned()
@ -1105,12 +1100,9 @@ impl Connection {
} }
} }
} }
}
#[cfg(not(target_os = "linux"))] #[cfg(not(target_os = "linux"))]
{
"".to_owned() "".to_owned()
} }
}
fn validate_one_password(&self, password: String) -> bool { fn validate_one_password(&self, password: String) -> bool {
if password.len() == 0 { if password.len() == 0 {