From c15e3c306e78755dee0b6bbf94fc61de97634c66 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 13:06:18 +0800 Subject: [PATCH 01/10] refact, option, allow linux headless Signed-off-by: fufesou --- libs/hbb_common/src/config.rs | 4 + src/platform/linux.rs | 10 ++ src/platform/linux_desktop_manager.rs | 4 + src/rendezvous_mediator.rs | 4 +- src/server/connection.rs | 147 +++++++++++++++----------- 5 files changed, 106 insertions(+), 63 deletions(-) diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index 7bdd322d3..19730e630 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -32,6 +32,10 @@ pub const COMPRESS_LEVEL: i32 = 3; const SERIAL: i32 = 3; const PASSWORD_ENC_VERSION: &str = "00"; +// config2 options +#[cfg(all(target_os = "linux"))] +pub const CONFIG_OPTION_ALLOW_LINUX_HEADLESS: &str = "allow-linux-headless"; + #[cfg(target_os = "macos")] lazy_static::lazy_static! { pub static ref ORG: Arc> = Arc::new(RwLock::new("com.carriez".to_owned())); diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 9c5a8b9fc..e254af12e 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -9,6 +9,9 @@ use hbb_common::{ message_proto::Resolution, regex::{Captures, Regex}, }; +#[cfg(all(feature = "linux_headless"))] +#[cfg(not(any(feature = "flatpak", feature = "appimage")))] +use hbb_common::config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS; use std::{ cell::RefCell, io::Write, @@ -69,6 +72,13 @@ pub struct xcb_xfixes_get_cursor_image { pub pixels: *const c_long, } +#[inline] +#[cfg(feature = "linux_headless")] +#[cfg(not(any(feature = "flatpak", feature = "appimage")))] +pub fn is_headless_allowed() -> bool { + Config::get_option(CONFIG_OPTION_ALLOW_LINUX_HEADLESS) == "Y" +} + #[inline] fn sleep_millis(millis: u64) { std::thread::sleep(Duration::from_millis(millis)); diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index fe60964cc..1382fa2ed 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -109,6 +109,10 @@ pub fn try_start_desktop(_username: &str, _passsword: &str) -> String { // No need to verify password here. return "".to_owned(); } + if username.is_empty() { + // Another user is logged in. No need to start a new xsession. + return "".to_owned(); + } if let Some(msg) = detect_headless() { return msg.to_owned(); diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 3e3b6c9b3..97a6d91d8 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -75,7 +75,9 @@ impl RendezvousMediator { } #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - crate::platform::linux_desktop_manager::start_xdesktop(); + if crate::platform::is_headless_allowed() { + crate::platform::linux_desktop_manager::start_xdesktop(); + } loop { Config::reset_online(); if Config::get_option("stop-service").is_empty() { diff --git a/src/server/connection.rs b/src/server/connection.rs index ed51a6c29..efa0f88e1 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -985,8 +985,10 @@ impl Connection { } #[cfg(feature = "linux_headless")] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if linux_desktop_manager::is_headless() { - platform_additions.insert("headless".into(), json!(true)); + if crate::platform::is_headless_allowed() { + if linux_desktop_manager::is_headless() { + platform_additions.insert("headless".into(), json!(true)); + } } if !platform_additions.is_empty() { pi.platform_additions = @@ -1375,23 +1377,42 @@ impl Connection { #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - let desktop_err = match lr.os_login.as_ref() { - Some(os_login) => { - linux_desktop_manager::try_start_desktop(&os_login.username, &os_login.password) + let is_headless_allowed = crate::platform::is_headless_allowed(); + #[cfg(all(target_os = "linux", feature = "linux_headless"))] + #[cfg(not(any(feature = "flatpak", feature = "appimage")))] + let desktop_err = if is_headless_allowed { + match lr.os_login.as_ref() { + Some(os_login) => linux_desktop_manager::try_start_desktop( + &os_login.username, + &os_login.password, + ), + None => linux_desktop_manager::try_start_desktop("", ""), } - None => linux_desktop_manager::try_start_desktop("", ""), + } else { + "".to_string() }; #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - let is_headless = linux_desktop_manager::is_headless(); + let is_headless = is_headless_allowed && linux_desktop_manager::is_headless(); #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] let wait_ipc_timeout = 10_000; + #[cfg(all(target_os = "linux", feature = "linux_headless"))] + #[cfg(not(any(feature = "flatpak", feature = "appimage")))] + let is_headless_proc = is_headless_allowed; + #[cfg(any( + feature = "flatpak", + feature = "appimage", + not(all(target_os = "linux", feature = "linux_headless")) + ))] + let is_headless_proc = false; + // If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password. #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if !desktop_err.is_empty() + if is_headless_proc + && !desktop_err.is_empty() && desktop_err != crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY { self.send_login_error(desktop_err).await; @@ -1424,22 +1445,23 @@ impl Connection { } else if self.is_recent_session() { #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if desktop_err.is_empty() { - #[cfg(target_os = "linux")] - if is_headless { - self.tx_desktop_ready.send(()).await.ok(); - let _res = timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; + if is_headless_proc { + if desktop_err.is_empty() { + if is_headless { + self.tx_desktop_ready.send(()).await.ok(); + let _res = + timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; + } + self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), true); + self.send_logon_response().await; + if self.port_forward_socket.is_some() { + return false; + } + } else { + self.send_login_error(desktop_err).await; } - self.try_start_cm(lr.my_id, lr.my_name, true); - self.send_logon_response().await; - if self.port_forward_socket.is_some() { - return false; - } - } else { - self.send_login_error(desktop_err).await; } - #[cfg(not(all(target_os = "linux", feature = "linux_headless")))] - { + if !is_headless_proc { self.try_start_cm(lr.my_id, lr.my_name, true); self.send_logon_response().await; if self.port_forward_socket.is_some() { @@ -1449,16 +1471,19 @@ impl Connection { } else if lr.password.is_empty() { #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if desktop_err.is_empty() { - self.try_start_cm(lr.my_id, lr.my_name, false); - } else { - self.send_login_error( - crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY, - ) - .await; + if is_headless_proc { + if desktop_err.is_empty() { + self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), false); + } else { + self.send_login_error( + crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY, + ) + .await; + } + } + if !is_headless_proc { + self.try_start_cm(lr.my_id, lr.my_name, false); } - #[cfg(not(all(target_os = "linux", feature = "linux_headless")))] - self.try_start_cm(lr.my_id, lr.my_name, false); } else { let mut failure = LOGIN_FAILURES .lock() @@ -1499,18 +1524,19 @@ impl Connection { .insert(self.ip.clone(), failure); #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if desktop_err.is_empty() { - self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG) + if is_headless_proc { + if desktop_err.is_empty() { + self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG) + .await; + self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), false); + } else { + self.send_login_error( + crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG, + ) .await; - self.try_start_cm(lr.my_id, lr.my_name, false); - } else { - self.send_login_error( - crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG, - ) - .await; + } } - #[cfg(not(all(target_os = "linux", feature = "linux_headless")))] - { + if !is_headless_proc { self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG) .await; self.try_start_cm(lr.my_id, lr.my_name, false); @@ -1521,23 +1547,23 @@ impl Connection { } #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if desktop_err.is_empty() { - #[cfg(target_os = "linux")] - if is_headless { - self.tx_desktop_ready.send(()).await.ok(); - let _res = - timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; + if is_headless_proc { + if desktop_err.is_empty() { + if is_headless { + self.tx_desktop_ready.send(()).await.ok(); + let _res = + timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; + } + self.send_logon_response().await; + self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), true); + if self.port_forward_socket.is_some() { + return false; + } + } else { + self.send_login_error(desktop_err).await; } - self.send_logon_response().await; - self.try_start_cm(lr.my_id, lr.my_name, true); - if self.port_forward_socket.is_some() { - return false; - } - } else { - self.send_login_error(desktop_err).await; } - #[cfg(not(all(target_os = "linux", feature = "linux_headless")))] - { + if !is_headless_proc { self.send_logon_response().await; self.try_start_cm(lr.my_id, lr.my_name, true); if self.port_forward_socket.is_some() { @@ -2361,19 +2387,16 @@ async fn start_ipc( args.push("--hide"); }; - #[cfg(target_os = "linux")] - #[cfg(not(feature = "linux_headless"))] - let user = None; - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(any(feature = "flatpak", feature = "appimage"))] + #[cfg(any(feature = "flatpak", feature = "appimage", not(all(target_os = "linux", feature = "linux_headless"))))] let user = None; #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] let mut user = None; + // Cm run as user, wait until desktop session is ready. #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if linux_desktop_manager::is_headless() { + if crate::platform::is_headless_allowed() && linux_desktop_manager::is_headless() { let mut username = linux_desktop_manager::get_username(); loop { if !username.is_empty() { From c0ead118a25a925b5d9f7b925bff6e1d0ff46523 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 14:02:13 +0800 Subject: [PATCH 02/10] refact, option, allow linux headless Signed-off-by: fufesou --- src/client.rs | 10 +++++++++- src/lang/ca.rs | 2 ++ src/lang/cn.rs | 2 ++ src/lang/cs.rs | 2 ++ src/lang/da.rs | 2 ++ src/lang/de.rs | 2 ++ src/lang/el.rs | 2 ++ src/lang/en.rs | 2 ++ src/lang/eo.rs | 2 ++ src/lang/es.rs | 2 ++ src/lang/fa.rs | 2 ++ src/lang/fr.rs | 2 ++ src/lang/hu.rs | 2 ++ src/lang/id.rs | 2 ++ src/lang/it.rs | 2 ++ src/lang/ja.rs | 2 ++ src/lang/ko.rs | 2 ++ src/lang/kz.rs | 2 ++ src/lang/lt.rs | 2 ++ src/lang/nl.rs | 2 ++ src/lang/pl.rs | 2 ++ src/lang/pt_PT.rs | 2 ++ src/lang/ptbr.rs | 2 ++ src/lang/ro.rs | 2 ++ src/lang/ru.rs | 2 ++ src/lang/sk.rs | 2 ++ src/lang/sl.rs | 2 ++ src/lang/sq.rs | 2 ++ src/lang/sr.rs | 2 ++ src/lang/sv.rs | 2 ++ src/lang/template.rs | 2 ++ src/lang/th.rs | 2 ++ src/lang/tr.rs | 2 ++ src/lang/tw.rs | 2 ++ src/lang/ua.rs | 2 ++ src/lang/vn.rs | 2 ++ src/server/connection.rs | 30 +++++++++++++++++++++--------- 37 files changed, 100 insertions(+), 10 deletions(-) diff --git a/src/client.rs b/src/client.rs index a48669899..40b3542b3 100644 --- a/src/client.rs +++ b/src/client.rs @@ -91,6 +91,8 @@ pub const LOGIN_MSG_PASSWORD_WRONG: &str = "Wrong Password"; pub const LOGIN_MSG_NO_PASSWORD_ACCESS: &str = "No Password Access"; pub const LOGIN_MSG_OFFLINE: &str = "Offline"; #[cfg(target_os = "linux")] +pub const LOGIN_SCREEN_WAYLAND: &str = "Wayland login screen"; +#[cfg(target_os = "linux")] pub const SCRAP_UBUNTU_HIGHER_REQUIRED: &str = "Wayland requires Ubuntu 21.04 or higher version."; #[cfg(target_os = "linux")] pub const SCRAP_OTHER_VERSION_OR_X11_REQUIRED: &str = @@ -2100,7 +2102,13 @@ struct LoginErrorMsgBox { lazy_static::lazy_static! { static ref LOGIN_ERROR_MAP: Arc> = { use hbb_common::config::LINK_HEADLESS_LINUX_SUPPORT; - let map = HashMap::from([(LOGIN_MSG_DESKTOP_SESSION_NOT_READY, LoginErrorMsgBox{ + let map = HashMap::from([(LOGIN_SCREEN_WAYLAND, LoginErrorMsgBox{ + msgtype: "error", + title: "login_wayland_title_tip", + text: "login_wayland_text_tip", + link: "https://rustdesk.com/docs/en/manual/linux/#login-screen", + try_again: true, + }), (LOGIN_MSG_DESKTOP_SESSION_NOT_READY, LoginErrorMsgBox{ msgtype: "session-login", title: "", text: "", diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 51a731c35..b172ec34b 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index b4a76c62e..004a9e1fc 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "管理的设备数已达到最大值"), ("Sync with recent sessions", "同步最近会话"), ("Sort tags", "对标签进行排序"), + ("login_wayland_title_tip", "无法连接"), + ("login_wayland_text_tip", "不支持 Wayland 登录界面。"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 29898eaf7..cd6e23142 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 0a4adaf36..6400e6f1c 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index c42ac5719..ff01fa645 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "Sie haben die maximale Anzahl der verwalteten Geräte erreicht."), ("Sync with recent sessions", "Synchronisierung mit den letzten Sitzungen"), ("Sort tags", "Tags sortieren"), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index eb91e9a83..d49df927a 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index 001d9133d..6563f5ada 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -73,5 +73,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("clipboard_wait_response_timeout_tip", "Timed out waiting for copy response."), ("logout_tip", "Are you sure you want to log out?"), ("exceed_max_devices", "You have reached the maximum number of managed devices."), + ("login_wayland_title_tip", "Failed to connect"), + ("login_wayland_text_tip", "Login screen of Wayland is not supported."), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index a576538ef..23965e679 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index c39bcb7f5..cf764c542 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "Has alcanzado el máximo número de dispositivos administrados."), ("Sync with recent sessions", "Sincronizar con sesiones recientes"), ("Sort tags", "Ordenar etiquetas"), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 112edf32a..9f4ece250 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 57c548e08..2fae8c90d 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 638ed3adf..69cba6c72 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index ac9df01b3..e6b1e268f 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index c89e6cf72..d7fea8cec 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "Hai raggiunto il numero massimo di dispositivi gestibili."), ("Sync with recent sessions", "Sincronizza con le sessioni recenti"), ("Sort tags", "Ordina etichette"), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 67234039d..05cb41089 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index c0b71c205..f0e1b4d4b 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 829c59c73..2732835e3 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lt.rs b/src/lang/lt.rs index 69936b2b4..ea2c80e8e 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 92bd7fd1f..91c90559a 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index af6d11659..a6196206d 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 52675daf7..91e1020bd 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 195b79804..ac374a5ec 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 378d7c035..00494e359 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 6b48ef20b..7b29c106f 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "Достигнуто максимальне количество управляемых устройств."), ("Sync with recent sessions", "Синхронизация последних сессий"), ("Sort tags", "Сортировка меток"), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index f24f55bef..2dc9e572c 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index ff5c254e0..f74220b92 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index 797328139..4ce234d23 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 3bb40f4ce..233eff041 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index ac898e38f..034643a13 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 5c710624f..42784f016 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 2b2d0f4b2..64b422ce6 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index d7bd99f25..26041d881 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index bef733f00..75f0c7a87 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 3b115a5f3..44df50c47 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 59490da1d..2441193bf 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), + ("login_wayland_title_tip", ""), + ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/server/connection.rs b/src/server/connection.rs index efa0f88e1..30a87cd80 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1007,14 +1007,22 @@ impl Connection { } #[cfg(target_os = "linux")] if !self.file_transfer.is_some() && !self.port_forward_socket.is_some() { - let dtype = crate::platform::linux::get_display_server(); - if dtype != crate::platform::linux::DISPLAY_SERVER_X11 - && dtype != crate::platform::linux::DISPLAY_SERVER_WAYLAND - { - res.set_error(format!( - "Unsupported display server type \"{}\", x11 or wayland expected", - dtype - )); + let mut msg = "".to_owned(); + if crate::platform::linux::is_login_wayland() { + msg = crate::client::LOGIN_SCREEN_WAYLAND.to_owned(); + } else { + let dtype = crate::platform::linux::get_display_server(); + if dtype != crate::platform::linux::DISPLAY_SERVER_X11 + && dtype != crate::platform::linux::DISPLAY_SERVER_WAYLAND + { + msg = format!( + "Unsupported display server type \"{}\", x11 or wayland expected", + dtype + ); + } + } + if !msg.is_empty() { + res.set_error(msg); let mut msg_out = Message::new(); msg_out.set_login_response(res); self.send(msg_out).await; @@ -2387,7 +2395,11 @@ async fn start_ipc( args.push("--hide"); }; - #[cfg(any(feature = "flatpak", feature = "appimage", not(all(target_os = "linux", feature = "linux_headless"))))] + #[cfg(any( + feature = "flatpak", + feature = "appimage", + not(all(target_os = "linux", feature = "linux_headless")) + ))] let user = None; #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] From 55972bfac53381cc11f95ed78d7432b27085b7b5 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 15:22:25 +0800 Subject: [PATCH 03/10] refact, linux headless option, debug Signed-off-by: fufesou --- src/client.rs | 2 +- src/platform/linux.rs | 26 +++++++++++++------- src/platform/linux_desktop_manager.rs | 2 +- src/rendezvous_mediator.rs | 5 ++-- src/server/connection.rs | 34 ++++++++++++--------------- 5 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/client.rs b/src/client.rs index 40b3542b3..a60251980 100644 --- a/src/client.rs +++ b/src/client.rs @@ -91,7 +91,7 @@ pub const LOGIN_MSG_PASSWORD_WRONG: &str = "Wrong Password"; pub const LOGIN_MSG_NO_PASSWORD_ACCESS: &str = "No Password Access"; pub const LOGIN_MSG_OFFLINE: &str = "Offline"; #[cfg(target_os = "linux")] -pub const LOGIN_SCREEN_WAYLAND: &str = "Wayland login screen"; +pub const LOGIN_SCREEN_WAYLAND: &str = "Wayland login screen is not supported"; #[cfg(target_os = "linux")] pub const SCRAP_UBUNTU_HIGHER_REQUIRED: &str = "Wayland requires Ubuntu 21.04 or higher version."; #[cfg(target_os = "linux")] diff --git a/src/platform/linux.rs b/src/platform/linux.rs index e254af12e..f553d63ba 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -1,5 +1,8 @@ use super::{CursorData, ResultType}; use desktop::Desktop; +#[cfg(all(feature = "linux_headless"))] +#[cfg(not(any(feature = "flatpak", feature = "appimage")))] +use hbb_common::config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS; pub use hbb_common::platform::linux::*; use hbb_common::{ allow_err, bail, @@ -9,9 +12,6 @@ use hbb_common::{ message_proto::Resolution, regex::{Captures, Regex}, }; -#[cfg(all(feature = "linux_headless"))] -#[cfg(not(any(feature = "flatpak", feature = "appimage")))] -use hbb_common::config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS; use std::{ cell::RefCell, io::Write, @@ -439,13 +439,21 @@ fn get_cm() -> bool { } pub fn is_login_wayland() -> bool { - if let Ok(contents) = std::fs::read_to_string("/etc/gdm3/custom.conf") { - contents.contains("#WaylandEnable=false") || contents.contains("WaylandEnable=true") - } else if let Ok(contents) = std::fs::read_to_string("/etc/gdm/custom.conf") { - contents.contains("#WaylandEnable=false") || contents.contains("WaylandEnable=true") - } else { - false + let files = ["/etc/gdm3/custom.conf", "/etc/gdm/custom.conf"]; + match ( + Regex::new(r"# *WaylandEnable *= *false"), + Regex::new(r"WaylandEnable *= *true"), + ) { + (Ok(pat1), Ok(pat2)) => { + for file in files { + if let Ok(contents) = std::fs::read_to_string(file) { + return pat1.is_match(&contents) || pat2.is_match(&contents); + } + } + } + _ => {} } + false } #[inline] diff --git a/src/platform/linux_desktop_manager.rs b/src/platform/linux_desktop_manager.rs index 1382fa2ed..b7caa527c 100644 --- a/src/platform/linux_desktop_manager.rs +++ b/src/platform/linux_desktop_manager.rs @@ -109,7 +109,7 @@ pub fn try_start_desktop(_username: &str, _passsword: &str) -> String { // No need to verify password here. return "".to_owned(); } - if username.is_empty() { + if !username.is_empty() { // Another user is logged in. No need to start a new xsession. return "".to_owned(); } diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 97a6d91d8..924c0c709 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -73,11 +73,10 @@ impl RendezvousMediator { allow_err!(super::lan::start_listening()); }); } + // It is ok to run xdesktop manager when the headless function is not allowed. #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if crate::platform::is_headless_allowed() { - crate::platform::linux_desktop_manager::start_xdesktop(); - } + crate::platform::linux_desktop_manager::start_xdesktop(); loop { Config::reset_online(); if Config::get_option("stop-service").is_empty() { diff --git a/src/server/connection.rs b/src/server/connection.rs index 30a87cd80..7e0f39809 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1386,6 +1386,12 @@ impl Connection { #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] let is_headless_allowed = crate::platform::is_headless_allowed(); + #[cfg(any( + feature = "flatpak", + feature = "appimage", + not(all(target_os = "linux", feature = "linux_headless")) + ))] + let is_headless_allowed = false; #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] let desktop_err = if is_headless_allowed { @@ -1406,20 +1412,10 @@ impl Connection { #[cfg(not(any(feature = "flatpak", feature = "appimage")))] let wait_ipc_timeout = 10_000; - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - let is_headless_proc = is_headless_allowed; - #[cfg(any( - feature = "flatpak", - feature = "appimage", - not(all(target_os = "linux", feature = "linux_headless")) - ))] - let is_headless_proc = false; - // If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password. #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_proc + if is_headless_allowed && !desktop_err.is_empty() && desktop_err != crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY { @@ -1453,7 +1449,7 @@ impl Connection { } else if self.is_recent_session() { #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_proc { + if is_headless_allowed { if desktop_err.is_empty() { if is_headless { self.tx_desktop_ready.send(()).await.ok(); @@ -1469,7 +1465,7 @@ impl Connection { self.send_login_error(desktop_err).await; } } - if !is_headless_proc { + if !is_headless_allowed { self.try_start_cm(lr.my_id, lr.my_name, true); self.send_logon_response().await; if self.port_forward_socket.is_some() { @@ -1479,7 +1475,7 @@ impl Connection { } else if lr.password.is_empty() { #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_proc { + if is_headless_allowed { if desktop_err.is_empty() { self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), false); } else { @@ -1489,7 +1485,7 @@ impl Connection { .await; } } - if !is_headless_proc { + if !is_headless_allowed { self.try_start_cm(lr.my_id, lr.my_name, false); } } else { @@ -1532,7 +1528,7 @@ impl Connection { .insert(self.ip.clone(), failure); #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_proc { + if is_headless_allowed { if desktop_err.is_empty() { self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG) .await; @@ -1544,7 +1540,7 @@ impl Connection { .await; } } - if !is_headless_proc { + if !is_headless_allowed { self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG) .await; self.try_start_cm(lr.my_id, lr.my_name, false); @@ -1555,7 +1551,7 @@ impl Connection { } #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_proc { + if is_headless_allowed { if desktop_err.is_empty() { if is_headless { self.tx_desktop_ready.send(()).await.ok(); @@ -1571,7 +1567,7 @@ impl Connection { self.send_login_error(desktop_err).await; } } - if !is_headless_proc { + if !is_headless_allowed { self.send_logon_response().await; self.try_start_cm(lr.my_id, lr.my_name, true); if self.port_forward_socket.is_some() { From 19c8ba719af300235db1910ad2552c49c5f3dc72 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 15:45:16 +0800 Subject: [PATCH 04/10] refact, linux headless option, ui Signed-off-by: fufesou --- .../desktop/pages/desktop_setting_page.dart | 30 +++++++++++-------- libs/hbb_common/src/config.rs | 2 +- src/flutter_ffi.rs | 9 ++++++ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index b89929ad9..81cd2af7d 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -312,20 +312,26 @@ class _GeneralState extends State<_General> { } Widget other() { - return _Card(title: 'Other', children: [ + final children = [ _OptionCheckBox(context, 'Confirm before closing multiple tabs', 'enable-confirm-closing-tabs'), - _OptionCheckBox(context, 'Adaptive Bitrate', 'enable-abr'), - if (Platform.isLinux) - Tooltip( - message: translate('software_render_tip'), - child: _OptionCheckBox( - context, - "Always use software rendering", - 'allow-always-software-render', - ), - ) - ]); + _OptionCheckBox(context, 'Adaptive Bitrate', 'enable-abr') + ]; + if (Platform.isLinux) { + children.add(Tooltip( + message: translate('software_render_tip'), + child: _OptionCheckBox( + context, + "Always use software rendering", + 'allow-always-software-render', + ), + )); + } + if (bind.mainShowOption(key: 'allow-linux-headless')) { + children.add(_OptionCheckBox( + context, 'Allow linux headless', 'allow-linux-headless')); + } + return _Card(title: 'Other', children: children); } Widget hwcodec() { diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index 19730e630..ce041e75c 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -33,7 +33,7 @@ const SERIAL: i32 = 3; const PASSWORD_ENC_VERSION: &str = "00"; // config2 options -#[cfg(all(target_os = "linux"))] +#[cfg(target_os = "linux")] pub const CONFIG_OPTION_ALLOW_LINUX_HEADLESS: &str = "allow-linux-headless"; #[cfg(target_os = "macos")] diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index c25ac78b0..67fc286e6 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -614,6 +614,15 @@ pub fn main_get_error() -> String { get_error() } +pub fn main_show_option(key: String) -> SyncReturn { + if key.eq(config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS) { + #[cfg(all(target_os = "linux", feature = "linux_headless"))] + #[cfg(not(any(feature = "flatpak", feature = "appimage")))] + return SyncReturn(true) + } + SyncReturn(false) +} + pub fn main_set_option(key: String, value: String) { if key.eq("custom-rendezvous-server") { set_option(key, value); From d761d2f00ec0b7ef1faa71b591476bfde7534ee2 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 16:09:10 +0800 Subject: [PATCH 05/10] fix build Signed-off-by: fufesou --- src/client.rs | 1 - src/flutter_ffi.rs | 8 ++++---- src/server/connection.rs | 3 ++- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client.rs b/src/client.rs index a60251980..dbd893c5a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -90,7 +90,6 @@ pub const LOGIN_MSG_PASSWORD_EMPTY: &str = "Empty Password"; pub const LOGIN_MSG_PASSWORD_WRONG: &str = "Wrong Password"; pub const LOGIN_MSG_NO_PASSWORD_ACCESS: &str = "No Password Access"; pub const LOGIN_MSG_OFFLINE: &str = "Offline"; -#[cfg(target_os = "linux")] pub const LOGIN_SCREEN_WAYLAND: &str = "Wayland login screen is not supported"; #[cfg(target_os = "linux")] pub const SCRAP_UBUNTU_HIGHER_REQUIRED: &str = "Wayland requires Ubuntu 21.04 or higher version."; diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 67fc286e6..64a221141 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -614,10 +614,10 @@ pub fn main_get_error() -> String { get_error() } -pub fn main_show_option(key: String) -> SyncReturn { - if key.eq(config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS) { - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] +pub fn main_show_option(_key: String) -> SyncReturn { + #[cfg(all(target_os = "linux", feature = "linux_headless"))] + #[cfg(not(any(feature = "flatpak", feature = "appimage")))] + if _key.eq(config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS) { return SyncReturn(true) } SyncReturn(false) diff --git a/src/server/connection.rs b/src/server/connection.rs index 7e0f39809..bc101e697 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2391,10 +2391,11 @@ async fn start_ipc( args.push("--hide"); }; + #[cfg(target_os = "linux")] #[cfg(any( feature = "flatpak", feature = "appimage", - not(all(target_os = "linux", feature = "linux_headless")) + not(feature = "linux_headless") ))] let user = None; #[cfg(all(target_os = "linux", feature = "linux_headless"))] From 540316655229262d80f57e43ca8b6ff2a363e03f Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 17:16:53 +0800 Subject: [PATCH 06/10] refact, linux headless option, debug Signed-off-by: fufesou --- src/platform/linux.rs | 6 ++++++ src/server/connection.rs | 23 ++++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/platform/linux.rs b/src/platform/linux.rs index f553d63ba..86b530342 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -79,6 +79,12 @@ pub fn is_headless_allowed() -> bool { Config::get_option(CONFIG_OPTION_ALLOW_LINUX_HEADLESS) == "Y" } +#[inline] +pub fn is_login_screen_wayland() -> bool { + let values = get_values_of_seat0_with_gdm_wayland(&[0, 2]); + is_gdm_user(&values[1]) && get_display_server_of_session(&values[0]) == DISPLAY_SERVER_WAYLAND +} + #[inline] fn sleep_millis(millis: u64) { std::thread::sleep(Duration::from_millis(millis)); diff --git a/src/server/connection.rs b/src/server/connection.rs index bc101e697..5765e59bd 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1007,21 +1007,18 @@ impl Connection { } #[cfg(target_os = "linux")] if !self.file_transfer.is_some() && !self.port_forward_socket.is_some() { - let mut msg = "".to_owned(); - if crate::platform::linux::is_login_wayland() { - msg = crate::client::LOGIN_SCREEN_WAYLAND.to_owned(); - } else { - let dtype = crate::platform::linux::get_display_server(); - if dtype != crate::platform::linux::DISPLAY_SERVER_X11 - && dtype != crate::platform::linux::DISPLAY_SERVER_WAYLAND - { - msg = format!( + let dtype = crate::platform::linux::get_display_server(); + if dtype != crate::platform::linux::DISPLAY_SERVER_X11 + && dtype != crate::platform::linux::DISPLAY_SERVER_WAYLAND + { + let msg = if crate::platform::linux::is_login_screen_wayland() { + crate::client::LOGIN_SCREEN_WAYLAND.to_owned() + } else { + format!( "Unsupported display server type \"{}\", x11 or wayland expected", dtype - ); - } - } - if !msg.is_empty() { + ) + }; res.set_error(msg); let mut msg_out = Message::new(); msg_out.set_login_response(res); From 2e256c0fca18a4651ddc803f263fa290054703ce Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 17:35:44 +0800 Subject: [PATCH 07/10] refact, wayland login screen translate Signed-off-by: fufesou --- flutter/lib/desktop/pages/desktop_home_page.dart | 2 +- src/lang/en.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index 5b03b39ef..05b0c1720 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -377,7 +377,7 @@ class _DesktopHomePageState extends State link: 'https://rustdesk.com/docs/en/manual/linux/#x11-required'); } else if (bind.mainIsLoginWayland()) { return buildInstallCard("Warning", - "Login screen using Wayland is not supported", "", () async {}, + translate("login_wayland_text_tip"), "", () async {}, help: 'Help', link: 'https://rustdesk.com/docs/en/manual/linux/#login-screen'); } diff --git a/src/lang/en.rs b/src/lang/en.rs index 6563f5ada..e9b2789a3 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -74,6 +74,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("logout_tip", "Are you sure you want to log out?"), ("exceed_max_devices", "You have reached the maximum number of managed devices."), ("login_wayland_title_tip", "Failed to connect"), - ("login_wayland_text_tip", "Login screen of Wayland is not supported."), + ("login_wayland_text_tip", "Login screen using Wayland is not supported."), ].iter().cloned().collect(); } From 3343210e8b54b66b1ea8d63f1f3aa51e11460025 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 18:02:12 +0800 Subject: [PATCH 08/10] remove translation Signed-off-by: fufesou --- flutter/lib/desktop/pages/desktop_home_page.dart | 2 +- src/client.rs | 4 ++-- src/lang/ca.rs | 2 -- src/lang/cn.rs | 2 -- src/lang/cs.rs | 2 -- src/lang/da.rs | 2 -- src/lang/de.rs | 2 -- src/lang/el.rs | 2 -- src/lang/en.rs | 2 -- src/lang/eo.rs | 2 -- src/lang/es.rs | 2 -- src/lang/fa.rs | 2 -- src/lang/fr.rs | 2 -- src/lang/hu.rs | 2 -- src/lang/id.rs | 2 -- src/lang/it.rs | 2 -- src/lang/ja.rs | 2 -- src/lang/ko.rs | 2 -- src/lang/kz.rs | 2 -- src/lang/lt.rs | 2 -- src/lang/nl.rs | 2 -- src/lang/pl.rs | 2 -- src/lang/pt_PT.rs | 2 -- src/lang/ptbr.rs | 2 -- src/lang/ro.rs | 2 -- src/lang/ru.rs | 2 -- src/lang/sk.rs | 2 -- src/lang/sl.rs | 2 -- src/lang/sq.rs | 2 -- src/lang/sr.rs | 2 -- src/lang/sv.rs | 2 -- src/lang/template.rs | 2 -- src/lang/th.rs | 2 -- src/lang/tr.rs | 2 -- src/lang/tw.rs | 2 -- src/lang/ua.rs | 2 -- src/lang/vn.rs | 2 -- 37 files changed, 3 insertions(+), 73 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index 05b0c1720..0911808d0 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -377,7 +377,7 @@ class _DesktopHomePageState extends State link: 'https://rustdesk.com/docs/en/manual/linux/#x11-required'); } else if (bind.mainIsLoginWayland()) { return buildInstallCard("Warning", - translate("login_wayland_text_tip"), "", () async {}, + translate("Login screen using Wayland is not supported"), "", () async {}, help: 'Help', link: 'https://rustdesk.com/docs/en/manual/linux/#login-screen'); } diff --git a/src/client.rs b/src/client.rs index dbd893c5a..e98e6bd3a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -2103,8 +2103,8 @@ lazy_static::lazy_static! { use hbb_common::config::LINK_HEADLESS_LINUX_SUPPORT; let map = HashMap::from([(LOGIN_SCREEN_WAYLAND, LoginErrorMsgBox{ msgtype: "error", - title: "login_wayland_title_tip", - text: "login_wayland_text_tip", + title: "Login Error", + text: "Login screen using Wayland is not supported", link: "https://rustdesk.com/docs/en/manual/linux/#login-screen", try_again: true, }), (LOGIN_MSG_DESKTOP_SESSION_NOT_READY, LoginErrorMsgBox{ diff --git a/src/lang/ca.rs b/src/lang/ca.rs index b172ec34b..51a731c35 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 004a9e1fc..b4a76c62e 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "管理的设备数已达到最大值"), ("Sync with recent sessions", "同步最近会话"), ("Sort tags", "对标签进行排序"), - ("login_wayland_title_tip", "无法连接"), - ("login_wayland_text_tip", "不支持 Wayland 登录界面。"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index cd6e23142..29898eaf7 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 6400e6f1c..0a4adaf36 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index ff01fa645..c42ac5719 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "Sie haben die maximale Anzahl der verwalteten Geräte erreicht."), ("Sync with recent sessions", "Synchronisierung mit den letzten Sitzungen"), ("Sort tags", "Tags sortieren"), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index d49df927a..eb91e9a83 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index e9b2789a3..001d9133d 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -73,7 +73,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("clipboard_wait_response_timeout_tip", "Timed out waiting for copy response."), ("logout_tip", "Are you sure you want to log out?"), ("exceed_max_devices", "You have reached the maximum number of managed devices."), - ("login_wayland_title_tip", "Failed to connect"), - ("login_wayland_text_tip", "Login screen using Wayland is not supported."), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 23965e679..a576538ef 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index cf764c542..c39bcb7f5 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "Has alcanzado el máximo número de dispositivos administrados."), ("Sync with recent sessions", "Sincronizar con sesiones recientes"), ("Sort tags", "Ordenar etiquetas"), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 9f4ece250..112edf32a 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 2fae8c90d..57c548e08 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 69cba6c72..638ed3adf 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index e6b1e268f..ac9df01b3 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index d7fea8cec..c89e6cf72 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "Hai raggiunto il numero massimo di dispositivi gestibili."), ("Sync with recent sessions", "Sincronizza con le sessioni recenti"), ("Sort tags", "Ordina etichette"), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 05cb41089..67234039d 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index f0e1b4d4b..c0b71c205 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 2732835e3..829c59c73 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lt.rs b/src/lang/lt.rs index ea2c80e8e..69936b2b4 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 91c90559a..92bd7fd1f 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index a6196206d..af6d11659 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 91e1020bd..52675daf7 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index ac374a5ec..195b79804 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 00494e359..378d7c035 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 7b29c106f..6b48ef20b 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", "Достигнуто максимальне количество управляемых устройств."), ("Sync with recent sessions", "Синхронизация последних сессий"), ("Sort tags", "Сортировка меток"), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 2dc9e572c..f24f55bef 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index f74220b92..ff5c254e0 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index 4ce234d23..797328139 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 233eff041..3bb40f4ce 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 034643a13..ac898e38f 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 42784f016..5c710624f 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 64b422ce6..2b2d0f4b2 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 26041d881..d7bd99f25 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 75f0c7a87..bef733f00 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 44df50c47..3b115a5f3 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 2441193bf..59490da1d 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -524,7 +524,5 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("exceed_max_devices", ""), ("Sync with recent sessions", ""), ("Sort tags", ""), - ("login_wayland_title_tip", ""), - ("login_wayland_text_tip", ""), ].iter().cloned().collect(); } From ddaefddc6e3d6f9046df2f1f0d1ffd6eb266f98e Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 21:28:42 +0800 Subject: [PATCH 09/10] refact, linux headless option Signed-off-by: fufesou --- .../lib/desktop/pages/desktop_home_page.dart | 4 +- src/server/connection.rs | 195 ++++++++---------- 2 files changed, 86 insertions(+), 113 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index 0911808d0..32ca6c20d 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -372,12 +372,12 @@ class _DesktopHomePageState extends State } else if (Platform.isLinux) { if (bind.mainCurrentIsWayland()) { return buildInstallCard( - "Warning", translate("wayland_experiment_tip"), "", () async {}, + "Warning", "wayland_experiment_tip", "", () async {}, help: 'Help', link: 'https://rustdesk.com/docs/en/manual/linux/#x11-required'); } else if (bind.mainIsLoginWayland()) { return buildInstallCard("Warning", - translate("Login screen using Wayland is not supported"), "", () async {}, + "Login screen using Wayland is not supported", "", () async {}, help: 'Help', link: 'https://rustdesk.com/docs/en/manual/linux/#login-screen'); } diff --git a/src/server/connection.rs b/src/server/connection.rs index 5765e59bd..4173d4f02 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -191,10 +191,7 @@ pub struct Connection { pressed_modifiers: HashSet, #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - rx_cm_stream_ready: mpsc::Receiver<()>, - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - tx_desktop_ready: mpsc::Sender<()>, + linux_headless_handle: LinuxHeadlessHandle, closed: bool, delay_response_instant: Instant, } @@ -266,6 +263,10 @@ impl Connection { let (tx_cm_stream_ready, _rx_cm_stream_ready) = mpsc::channel(1); #[cfg(not(any(target_os = "android", target_os = "ios")))] let (_tx_desktop_ready, rx_desktop_ready) = mpsc::channel(1); + #[cfg(all(target_os = "linux", feature = "linux_headless"))] + #[cfg(not(any(feature = "flatpak", feature = "appimage")))] + let linux_headless_handle = + LinuxHeadlessHandle::new(_rx_cm_stream_ready, _tx_desktop_ready); #[cfg(not(any(target_os = "android", target_os = "ios")))] let tx_cloned = tx.clone(); @@ -322,10 +323,7 @@ impl Connection { pressed_modifiers: Default::default(), #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - rx_cm_stream_ready: _rx_cm_stream_ready, - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - tx_desktop_ready: _tx_desktop_ready, + linux_headless_handle, closed: false, delay_response_instant: Instant::now(), }; @@ -1380,43 +1378,22 @@ impl Connection { } } - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - let is_headless_allowed = crate::platform::is_headless_allowed(); #[cfg(any( feature = "flatpak", feature = "appimage", not(all(target_os = "linux", feature = "linux_headless")) ))] - let is_headless_allowed = false; + let err_msg = "".to_owned(); #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - let desktop_err = if is_headless_allowed { - match lr.os_login.as_ref() { - Some(os_login) => linux_desktop_manager::try_start_desktop( - &os_login.username, - &os_login.password, - ), - None => linux_desktop_manager::try_start_desktop("", ""), - } - } else { - "".to_string() - }; - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - let is_headless = is_headless_allowed && linux_desktop_manager::is_headless(); - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - let wait_ipc_timeout = 10_000; + let err_msg = self + .linux_headless_handle + .try_start_desktop(lr.os_login.as_ref()); // If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password. - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_allowed - && !desktop_err.is_empty() - && desktop_err != crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY + if !err_msg.is_empty() && err_msg != crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY { - self.send_login_error(desktop_err).await; + self.send_login_error(err_msg).await; return true; } @@ -1444,46 +1421,26 @@ impl Connection { self.send_login_error("Connection not allowed").await; return false; } else if self.is_recent_session() { - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_allowed { - if desktop_err.is_empty() { - if is_headless { - self.tx_desktop_ready.send(()).await.ok(); - let _res = - timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; - } - self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), true); - self.send_logon_response().await; - if self.port_forward_socket.is_some() { - return false; - } - } else { - self.send_login_error(desktop_err).await; - } - } - if !is_headless_allowed { - self.try_start_cm(lr.my_id, lr.my_name, true); + if err_msg.is_empty() { + #[cfg(all(target_os = "linux", feature = "linux_headless"))] + #[cfg(not(any(feature = "flatpak", feature = "appimage")))] + self.linux_headless_handle.wait_desktop_cm_ready().await; + self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), true); self.send_logon_response().await; if self.port_forward_socket.is_some() { return false; } + } else { + self.send_login_error(err_msg).await; } } else if lr.password.is_empty() { - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_allowed { - if desktop_err.is_empty() { - self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), false); - } else { - self.send_login_error( - crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY, - ) - .await; - } - } - if !is_headless_allowed { + if err_msg.is_empty() { self.try_start_cm(lr.my_id, lr.my_name, false); + } else { + self.send_login_error( + crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY, + ) + .await; } } else { let mut failure = LOGIN_FAILURES @@ -1523,53 +1480,31 @@ impl Connection { .lock() .unwrap() .insert(self.ip.clone(), failure); - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_allowed { - if desktop_err.is_empty() { - self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG) - .await; - self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), false); - } else { - self.send_login_error( - crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG, - ) - .await; - } - } - if !is_headless_allowed { + if err_msg.is_empty() { self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG) .await; self.try_start_cm(lr.my_id, lr.my_name, false); + } else { + self.send_login_error( + crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG, + ) + .await; } } else { if failure.0 != 0 { LOGIN_FAILURES.lock().unwrap().remove(&self.ip); } - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] - if is_headless_allowed { - if desktop_err.is_empty() { - if is_headless { - self.tx_desktop_ready.send(()).await.ok(); - let _res = - timeout(wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; - } - self.send_logon_response().await; - self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), true); - if self.port_forward_socket.is_some() { - return false; - } - } else { - self.send_login_error(desktop_err).await; - } - } - if !is_headless_allowed { + if err_msg.is_empty() { + #[cfg(all(target_os = "linux", feature = "linux_headless"))] + #[cfg(not(any(feature = "flatpak", feature = "appimage")))] + self.linux_headless_handle.wait_desktop_cm_ready().await; self.send_logon_response().await; self.try_start_cm(lr.my_id, lr.my_name, true); if self.port_forward_socket.is_some() { return false; } + } else { + self.send_login_error(err_msg).await; } } } @@ -2388,15 +2323,7 @@ async fn start_ipc( args.push("--hide"); }; - #[cfg(target_os = "linux")] - #[cfg(any( - feature = "flatpak", - feature = "appimage", - not(feature = "linux_headless") - ))] - let user = None; - #[cfg(all(target_os = "linux", feature = "linux_headless"))] - #[cfg(not(any(feature = "flatpak", feature = "appimage")))] + #[allow(unused_mut)] let mut user = None; // Cm run as user, wait until desktop session is ready. @@ -2601,6 +2528,52 @@ impl Drop for Connection { } } +#[cfg(all(target_os = "linux", feature = "linux_headless"))] +#[cfg(not(any(feature = "flatpak", feature = "appimage")))] +struct LinuxHeadlessHandle { + pub is_headless_allowed: bool, + pub is_headless: bool, + pub wait_ipc_timeout: u64, + pub rx_cm_stream_ready: mpsc::Receiver<()>, + pub tx_desktop_ready: mpsc::Sender<()>, +} + +#[cfg(all(target_os = "linux", feature = "linux_headless"))] +#[cfg(not(any(feature = "flatpak", feature = "appimage")))] +impl LinuxHeadlessHandle { + pub fn new(rx_cm_stream_ready: mpsc::Receiver<()>, tx_desktop_ready: mpsc::Sender<()>) -> Self { + let is_headless_allowed = crate::platform::is_headless_allowed(); + let is_headless = is_headless_allowed && linux_desktop_manager::is_headless(); + Self { + is_headless_allowed, + is_headless, + wait_ipc_timeout: 10_000, + rx_cm_stream_ready, + tx_desktop_ready, + } + } + + pub fn try_start_desktop(&mut self, os_login: Option<&OSLogin>) -> String { + if self.is_headless_allowed { + match os_login { + Some(os_login) => { + linux_desktop_manager::try_start_desktop(&os_login.username, &os_login.password) + } + None => linux_desktop_manager::try_start_desktop("", ""), + } + } else { + "".to_string() + } + } + + pub async fn wait_desktop_cm_ready(&mut self) { + if self.is_headless { + self.tx_desktop_ready.send(()).await.ok(); + let _res = timeout(self.wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await; + } + } +} + mod raii { use super::*; pub struct ConnectionID(i32); From 64b680e7cf5904493c8466de4e23a66900c66809 Mon Sep 17 00:00:00 2001 From: fufesou Date: Sat, 29 Jul 2023 22:26:14 +0800 Subject: [PATCH 10/10] fix build Signed-off-by: fufesou --- src/server/connection.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/connection.rs b/src/server/connection.rs index 4173d4f02..f3e059696 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2324,6 +2324,7 @@ async fn start_ipc( }; #[allow(unused_mut)] + #[cfg(target_os = "linux")] let mut user = None; // Cm run as user, wait until desktop session is ready.