refact: remove linux headless (#15866)

* refact: remove linux headless

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(linux): probe DRM availability asynchronously on login

Signed-off-by: fufesou <linlong1266@gmail.com>

* revert changes in drm_capturer.rs

Signed-off-by: fufesou <linlong1266@gmail.com>

* Update submodule hbb_common

Signed-off-by: fufesou <linlong1266@gmail.com>

* docs(linux): clarify DRM availability comments

Remove stale headless and unauthenticated-request
wording, and document the Available-only login-screen gate.

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(linux): remove unreachable session cleanup branch

Remove the obsolete empty-session path and
clarify the intended use of cached DRM availability.

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou
2026-08-18 15:02:50 +08:00
committed by GitHub
parent 0c00d576dd
commit b0008edcb5
99 changed files with 133 additions and 2944 deletions

View File

@@ -101,18 +101,6 @@ const RESTART_REMOTE_DEVICE_GRACE: Duration = Duration::from_secs(5 * 60);
pub const VIDEO_QUEUE_SIZE: usize = 120;
const MAX_DECODE_FAIL_COUNTER: usize = 3;
#[cfg(target_os = "linux")]
pub const LOGIN_MSG_DESKTOP_NOT_INITED: &str = "Desktop env is not inited";
pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY: &str = "Desktop session not ready";
pub const LOGIN_MSG_DESKTOP_XSESSION_FAILED: &str = "Desktop xsession failed";
pub const LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER: &str = "Desktop session another user login";
pub const LOGIN_MSG_DESKTOP_XORG_NOT_FOUND: &str = "Desktop xorg not found";
// ls /usr/share/xsessions/
pub const LOGIN_MSG_DESKTOP_NO_DESKTOP: &str = "Desktop none";
pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY: &str =
"Desktop session not ready, password empty";
pub const LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG: &str =
"Desktop session not ready, password wrong";
pub const LOGIN_MSG_PASSWORD_EMPTY: &str = "Empty Password";
pub const LOGIN_MSG_PASSWORD_WRONG: &str = "Wrong Password";
pub const LOGIN_MSG_2FA_WRONG: &str = "Wrong 2FA Code";
@@ -2739,6 +2727,16 @@ impl LoginConfigHandler {
} else {
Bytes::new()
};
let os_login: MessageField<OSLogin> = if self.conn_type == ConnType::TERMINAL {
Some(OSLogin {
username: os_username,
password: os_password,
..Default::default()
})
.into()
} else {
Default::default()
};
let mut lr = LoginRequest {
username: pure_id,
password: password.into(),
@@ -2748,12 +2746,7 @@ impl LoginConfigHandler {
option: self.get_option_message(true).into(),
session_id: self.session_id,
version: crate::VERSION.to_string(),
os_login: Some(OSLogin {
username: os_username,
password: os_password,
..Default::default()
})
.into(),
os_login,
hwid,
avatar,
..Default::default()
@@ -3348,55 +3341,12 @@ struct LoginErrorMsgBox {
lazy_static::lazy_static! {
static ref LOGIN_ERROR_MAP: Arc<HashMap<&'static str, LoginErrorMsgBox>> = {
use config::LINK_HEADLESS_LINUX_SUPPORT;
let map = HashMap::from([(LOGIN_SCREEN_WAYLAND, LoginErrorMsgBox{
msgtype: "error",
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{
msgtype: "session-login",
title: "",
text: "",
link: "",
try_again: true,
}), (LOGIN_MSG_DESKTOP_XSESSION_FAILED, LoginErrorMsgBox{
msgtype: "session-re-login",
title: "",
text: "",
link: "",
try_again: true,
}), (LOGIN_MSG_DESKTOP_SESSION_ANOTHER_USER, LoginErrorMsgBox{
msgtype: "info-nocancel",
title: "another_user_login_title_tip",
text: "another_user_login_text_tip",
link: "",
try_again: false,
}), (LOGIN_MSG_DESKTOP_XORG_NOT_FOUND, LoginErrorMsgBox{
msgtype: "info-nocancel",
title: "xorg_not_found_title_tip",
text: "xorg_not_found_text_tip",
link: LINK_HEADLESS_LINUX_SUPPORT,
try_again: true,
}), (LOGIN_MSG_DESKTOP_NO_DESKTOP, LoginErrorMsgBox{
msgtype: "info-nocancel",
title: "no_desktop_title_tip",
text: "no_desktop_text_tip",
link: LINK_HEADLESS_LINUX_SUPPORT,
try_again: true,
}), (LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_EMPTY, LoginErrorMsgBox{
msgtype: "session-login-password",
title: "",
text: "",
link: "",
try_again: true,
}), (LOGIN_MSG_DESKTOP_SESSION_NOT_READY_PASSWORD_WRONG, LoginErrorMsgBox{
msgtype: "session-login-re-password",
title: "",
text: "",
link: "",
try_again: true,
}), (LOGIN_MSG_NO_PASSWORD_ACCESS, LoginErrorMsgBox{
msgtype: "wait-remote-accept-nook",
title: "Prompt",
@@ -3665,17 +3615,7 @@ pub async fn handle_hash(
hasher.finalize()[..].into()
};
let is_terminal = lc.read().unwrap().conn_type.eq(&ConnType::TERMINAL);
let (os_username, os_password) = if is_terminal {
("".to_owned(), "".to_owned())
} else {
(
lc.read().unwrap().get_option("os-username"),
lc.read().unwrap().get_option("os-password"),
)
};
send_login(lc.clone(), os_username, os_password, password, peer).await;
send_login(lc.clone(), String::new(), String::new(), password, peer).await;
lc.write().unwrap().hash = hash;
true
}

View File

@@ -105,7 +105,7 @@ lazy_static::lazy_static! {
// Is server logic running. The server code can invoked to run by the main process if --server is not running.
static ref SERVER_RUNNING: Arc<RwLock<bool>> = Default::default();
static ref IS_MAIN: bool = std::env::args().nth(1).map_or(true, |arg| !arg.starts_with("--"));
static ref IS_CM: bool = std::env::args().nth(1) == Some("--cm".to_owned()) || std::env::args().nth(1) == Some("--cm-no-ui".to_owned());
static ref IS_CM: bool = std::env::args().nth(1) == Some("--cm".to_owned());
}
pub struct SimpleCallOnReturn {

View File

@@ -713,14 +713,6 @@ pub fn core_main() -> Option<Vec<String>> {
// call connection manager to establish connections
// meanwhile, return true to call flutter window to show control panel
crate::ui_interface::start_option_status_sync();
} else if args[0] == "--cm-no-ui" {
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
crate::ui_interface::start_option_status_sync();
crate::flutter::connection_manager::start_cm_no_ui();
}
return None;
} else if args[0] == "--whiteboard" {
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{

View File

@@ -1552,20 +1552,8 @@ pub mod connection_manager {
}
}
#[inline]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub fn start_cm_no_ui() {
start_listen_ipc(false);
}
#[inline]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
fn start_listen_ipc_thread() {
start_listen_ipc(true);
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
fn start_listen_ipc(new_thread: bool) {
fn start_listen_ipc() {
use crate::ui_cm_interface::{start_ipc, ConnectionManager};
#[cfg(target_os = "linux")]
@@ -1574,17 +1562,13 @@ pub mod connection_manager {
let cm = ConnectionManager {
ui_handler: FlutterHandler {},
};
if new_thread {
std::thread::spawn(move || start_ipc(cm));
} else {
start_ipc(cm);
}
std::thread::spawn(move || start_ipc(cm));
}
#[inline]
pub fn cm_init() {
#[cfg(not(any(target_os = "android", target_os = "ios")))]
start_listen_ipc_thread();
start_listen_ipc();
}
#[cfg(target_os = "android")]

View File

@@ -962,14 +962,6 @@ pub fn main_get_error() -> String {
get_error()
}
pub fn main_show_option(_key: String) -> SyncReturn<bool> {
#[cfg(target_os = "linux")]
if _key.eq(config::keys::OPTION_ALLOW_LINUX_HEADLESS) {
return SyncReturn(true);
}
SyncReturn(false)
}
pub fn main_set_option(key: String, value: String) {
#[cfg(target_os = "android")]
{

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "هذا الملف مطابق لملف موجود عن القرين."),
("show_monitors_tip", "عرض الشاشات في شريط الادوات"),
("View Mode", "وضع العرض"),
("login_linux_tip", "تحتاج الى تسجيل الدخول حساب لينكس البعيد وتفعيل جلسة سطح مكتب X"),
("verify_rustdesk_password_tip", "تحقق من كلمة مرور RustDesk"),
("remember_account_tip", "تذكر هذا الحساب"),
("os_account_desk_tip", "هذا الحساب مستخدم لتسجيل الدخول الى سطح المكتب البعيد وتفعيل الجلسة"),
("OS Account", "حساب نظام التشغيل"),
("another_user_login_title_tip", "مستخدم اخر مسجل دخول حاليا"),
("another_user_login_text_tip", "قطع الاتصال"),
("xorg_not_found_title_tip", "Xorg غير موجود"),
("xorg_not_found_text_tip", "الرجاء تثبيت Xorg"),
("no_desktop_title_tip", "لا يتوفر سطح مكتب"),
("no_desktop_text_tip", "الرجاء تثبيت سطح مكتب GNOME"),
("No need to elevate", "لا حاجة للارتقاء"),
("System Sound", "صوت النظام"),
("Default", "الافتراضي"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Файл ідэнтычны файлу абанента"),
("show_monitors_tip", "Паказваць маніторы на панэлі інструментаў"),
("View Mode", "Рэжым прагляду"),
("login_linux_tip", "Каб уключыць сеанс працоўнага стала X, трэба ўвайсці ў аддалены ўліковы запіс Linux."),
("verify_rustdesk_password_tip", "Пацвердзіць пароль RustDesk"),
("remember_account_tip", "Запомніць гэты ўліковы запіс"),
("os_account_desk_tip", "Гэты ўліковы запіс выкарыстоўваецца для ўваходу ў аддаленую аперацыйную сістэму і ўключэння сеанса працоўнага стала ў рэжыме headless."),
("OS Account", "Акаўнт АС"),
("another_user_login_title_tip", "Іншы карыстальнік ужо ўвайшоў у сістэму"),
("another_user_login_text_tip", "Адключыць"),
("xorg_not_found_title_tip", "Xorg не знойдзены"),
("xorg_not_found_text_tip", "Усталюйце Xorg"),
("no_desktop_title_tip", "Няма даступных працоўных сталоў"),
("no_desktop_text_tip", "Усталюйце GNOME Desktop"),
("No need to elevate", "Павышэнне правоў не патрабуецца"),
("System Sound", "Сістэмны гук"),
("Default", "Стандартна"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Файлът съвпада с този от другата страна."),
("show_monitors_tip", "Показване на мониторите в лентата с инструменти"),
("View Mode", "Режим на изглед"),
("login_linux_tip", "Трябва да влезете в отдалечен Linux акаунт, за да активирате X сесия на работния плот"),
("verify_rustdesk_password_tip", "Проверете RustDesk паролата"),
("remember_account_tip", "Запомнете този акаунт"),
("os_account_desk_tip", "Този акаунт се използва за влизане в отдалечената операционна система и позволява на десктоп сесия без моинитор"),
("OS Account", "Профил в операционната система"),
("another_user_login_title_tip", "Друг потребител вече е влязъл"),
("another_user_login_text_tip", "Прекъснете връзката"),
("xorg_not_found_title_tip", "Xorg не е намерен"),
("xorg_not_found_text_tip", "Моля, инсталирайте Xorg"),
("no_desktop_title_tip", "Няма наличен работен плот"),
("no_desktop_text_tip", "Моля, инсталирайте работен плот GNOME"),
("No need to elevate", "Няма нужда за повишаване на права"),
("System Sound", "Системен звук"),
("Default", "По подразбиране"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Aquest fitxer és idèntic al del client."),
("show_monitors_tip", "Mostra les pantalles a la barra d'eines"),
("View Mode", "Mode espectador"),
("login_linux_tip", "És necessari que inicieu prèviament sessió amb un entorn d'escriptori x11 habilitat"),
("verify_rustdesk_password_tip", "Verifica la contrasenya del RustDesk"),
("remember_account_tip", "Recorda aquest compte"),
("os_account_desk_tip", "S'utilitza aquest compte per iniciar la sessió al sistema remot i habilitar el mode sense cap pantalla connectada"),
("OS Account", "Compte d'usuari"),
("another_user_login_title_tip", "Altre usuari ha iniciat ja una sessió"),
("another_user_login_text_tip", "Desconnecta"),
("xorg_not_found_title_tip", "No s'ha trobat l'entorn Xorg"),
("xorg_not_found_text_tip", "Instal·leu el Xorg"),
("no_desktop_title_tip", "Cap escriptori disponible"),
("no_desktop_text_tip", "Instal·leu l'entorn d'escriptori GNOME"),
("No need to elevate", "No calen permisos ampliats"),
("System Sound", "So del sistema"),
("Default", "per defecte"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "此文件与对方的一致"),
("show_monitors_tip", "在工具栏上显示监视器"),
("View Mode", "浏览模式"),
("login_linux_tip", "登录被控端的 Linux 账户,才能启用 X 桌面"),
("verify_rustdesk_password_tip", "验证 RustDesk 密码"),
("remember_account_tip", "记住此账户"),
("os_account_desk_tip", "在无显示器的环境下,此账户用于登录被控系统,并启用桌面"),
("OS Account", "系统账户"),
("another_user_login_title_tip", "其他用户已登录"),
("another_user_login_text_tip", "断开"),
("xorg_not_found_title_tip", "Xorg 未安装"),
("xorg_not_found_text_tip", "请安装 Xorg"),
("no_desktop_title_tip", "desktop 未安装"),
("no_desktop_text_tip", "请安装 desktop"),
("No need to elevate", "无需提升权限"),
("System Sound", "系统音频"),
("Default", "默认"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Tento soubor je totožný se souborem partnera."),
("show_monitors_tip", "Zobrazit monitory na panelu nástrojů"),
("View Mode", "Režim zobrazení"),
("login_linux_tip", "Chcete-li povolit relaci plochy X, musíte se přihlásit ke vzdálenému účtu systému Linux."),
("verify_rustdesk_password_tip", "Ověření hesla RustDesk"),
("remember_account_tip", "Zapamatovat si tento účet"),
("os_account_desk_tip", "Tento účet se používá k přihlášení do vzdáleného operačního systému a k povolení relace plochy v režimu headless."),
("OS Account", "Účet operačního systému"),
("another_user_login_title_tip", "Další uživatel je již přihlášen"),
("another_user_login_text_tip", "Odpojit"),
("xorg_not_found_title_tip", "Xorg nebyl nalezen"),
("xorg_not_found_text_tip", "Prosím, nainstalujte Xorg"),
("no_desktop_title_tip", "Není k dispozici žádná plocha"),
("no_desktop_text_tip", "Nainstalujte si prosím prostředí GNOME"),
("No need to elevate", "Není třeba navýšení"),
("System Sound", "Systémový zvuk"),
("Default", "Výchozí"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Denne fil er identisk med modpartens."),
("show_monitors_tip", "Vis skærme i værktøjsbjælken"),
("View Mode", "Visningstilstand"),
("login_linux_tip", "Du skal logge på en fjernstyret Linux konto for at aktivere en X skrivebordssession"),
("verify_rustdesk_password_tip", "Bekræft RustDesk adgangskode"),
("remember_account_tip", "Husk denne konto"),
("os_account_desk_tip", "Denne konto benyttes til at logge på fjernsystemet, og aktivere skrivebordssessionen i hovedløs tilstand"),
("OS Account", "Styresystem konto"),
("another_user_login_title_tip", "En anden bruger er allerede logget ind"),
("another_user_login_text_tip", "Frakobl"),
("xorg_not_found_title_tip", "Xorg ikke fundet"),
("xorg_not_found_text_tip", "Installér venlist Xorg"),
("no_desktop_title_tip", "Intet skrivebordsmiljø er tilgængeligt"),
("no_desktop_text_tip", "Installér venligst GNOME skrivebordet"),
("No need to elevate", "Ingen grund til at elevere"),
("System Sound", "Systemlyd"),
("Default", "Standard"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Diese Datei ist identisch mit der Datei der Gegenstelle."),
("show_monitors_tip", "Bildschirme in der Symbolleiste anzeigen"),
("View Mode", "Ansichtsmodus"),
("login_linux_tip", "Sie müssen sich an einem entfernten Linux-Konto anmelden, um eine X-Desktop-Sitzung zu eröffnen."),
("verify_rustdesk_password_tip", "RustDesk-Passwort bestätigen"),
("remember_account_tip", "Dieses Konto merken"),
("os_account_desk_tip", "Dieses Konto wird verwendet, um sich beim entfernten Betriebssystem anzumelden und die Desktop-Sitzung im Headless-Modus zu aktivieren."),
("OS Account", "Betriebssystem-Konto"),
("another_user_login_title_tip", "Ein anderer Benutzer ist bereits angemeldet."),
("another_user_login_text_tip", "Trennen"),
("xorg_not_found_title_tip", "Xorg nicht gefunden."),
("xorg_not_found_text_tip", "Bitte installieren Sie Xorg."),
("no_desktop_title_tip", "Es ist keine Desktopumgebung verfügbar."),
("no_desktop_text_tip", "Bitte installieren Sie den GNOME-Desktop."),
("No need to elevate", "Erhöhung der Rechte nicht erforderlich"),
("System Sound", "Systemsound"),
("Default", "Systemstandard"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Αυτό το αρχείο είναι πανομοιότυπο με αυτό του απομακρυσμένου σταθμού."),
("show_monitors_tip", "Εμφάνιση οθονών στη γραμμή εργαλείων"),
("View Mode", "Λειτουργία προβολής"),
("login_linux_tip", "Πρέπει να συνδεθείτε σε έναν απομακρυσμένο λογαριασμό Linux για να ενεργοποιήσετε μια συνεδρία επιφάνειας εργασίας X"),
("verify_rustdesk_password_tip", "Επιβεβαιώστε τον κωδικό του RustDesk"),
("remember_account_tip", "Απομνημόνευση αυτού του λογαριασμού"),
("os_account_desk_tip", "Αυτός ο λογαριασμός χρησιμοποιείται για σύνδεση στο απομακρυσμένο λειτουργικό σύστημα και ενεργοποίηση της συνεδρίας επιφάνειας εργασίας σε headless"),
("OS Account", "Λογαριασμός λειτουργικού συστήματος"),
("another_user_login_title_tip", "Υπάρχει ήδη άλλος συνδεδεμένος χρήστης"),
("another_user_login_text_tip", "Αποσύνδεση"),
("xorg_not_found_title_tip", "Δεν βρέθηκε το Xorg"),
("xorg_not_found_text_tip", "Παρακαλώ εγκαταστήστε το Xorg"),
("no_desktop_title_tip", "Δεν υπάρχει διαθέσιμο περιβάλλον επιφάνειας εργασίας"),
("no_desktop_text_tip", "Παρακαλώ εγκαταστήστε το περιβάλλον GNOME"),
("No need to elevate", "Δεν χρειάζεται ανύψωση"),
("System Sound", "Ήχος συστήματος"),
("Default", "Προκαθορισμένο"),

View File

@@ -155,17 +155,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "This file is identical with the peer's one."),
("show_monitors_tip", "Show monitors in toolbar"),
("View Mode", "View mode"),
("login_linux_tip", "You need to login to remote Linux account to enable a X desktop session"),
("verify_rustdesk_password_tip", "Verify RustDesk password"),
("remember_account_tip", "Remember this account"),
("os_account_desk_tip", "This account is used to login the remote OS and enable the desktop session in headless"),
("OS Account", "OS account"),
("another_user_login_title_tip", "Another user already logged in"),
("another_user_login_text_tip", "Disconnect"),
("xorg_not_found_title_tip", "Xorg not found"),
("xorg_not_found_text_tip", "Please install Xorg"),
("no_desktop_title_tip", "No desktop environment is available"),
("no_desktop_text_tip", "Please install GNOME desktop"),
("System Sound", "System sound"),
("Copy Fingerprint", "Copy fingerprint"),
("no fingerprints", "No fingerprints"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Ĉi tiu dosiero estas identa kun tiu de la samulo."),
("show_monitors_tip", "Montri monitorojn en la ilobreto"),
("View Mode", "Rigarda reĝimo"),
("login_linux_tip", "Vi devas ensaluti al la fora Linuksa konto por ebligi X-labortablan sesion"),
("verify_rustdesk_password_tip", "Kontroli RustDesk-pasvorton"),
("remember_account_tip", "Memori ĉi tiun konton"),
("os_account_desk_tip", "Ĉi tiu konto estas uzata por ensaluti al la fora operaciumo kaj ebligi la labortablan sesion en senekrana reĝimo"),
("OS Account", "Konto de operaciumo"),
("another_user_login_title_tip", "Alia uzanto jam ensalutis"),
("another_user_login_text_tip", "Malkonekti"),
("xorg_not_found_title_tip", "Xorg ne trovita"),
("xorg_not_found_text_tip", "Bonvolu instali Xorg"),
("no_desktop_title_tip", "Neniu labortabla medio disponeblas"),
("no_desktop_text_tip", "Bonvolu instali GNOME-labortablon"),
("No need to elevate", "Ne necesas altigi"),
("System Sound", "Sistema sono"),
("Default", "Implicita"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Este archivo es idéntico al del par."),
("show_monitors_tip", "Mostrar monitores en la barra de herramientas"),
("View Mode", "Modo Vista"),
("login_linux_tip", "Necesitas iniciar sesión con la cueneta del Linux remoto para activar una sesión de escritorio X"),
("verify_rustdesk_password_tip", "Verificar la contraseña de RustDesk"),
("remember_account_tip", "Recordar esta cuenta"),
("os_account_desk_tip", "Esta cueneta se usa para iniciar sesión en el sistema operativo remoto y habilitar la sesión de escritorio en headless."),
("OS Account", "Cuenta del SO"),
("another_user_login_title_tip", "Otro usuario ya ha iniciado sesión"),
("another_user_login_text_tip", "Desconectar"),
("xorg_not_found_title_tip", "Xorg no hallado"),
("xorg_not_found_text_tip", "Por favor, instala Xorg"),
("no_desktop_title_tip", "No hay escritorio disponible"),
("no_desktop_text_tip", "Por favor, instala GNOME Desktop"),
("No need to elevate", "No es necesario elevar privilegios"),
("System Sound", "Sonido del Sistema"),
("Default", "Predeterminado"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "See fail on partneri omaga identne."),
("show_monitors_tip", "Kuva kuvarid tööriistaribal"),
("View Mode", "Kuvarežiim"),
("login_linux_tip", "X-töölaua seansi lubamiseks pead sisse logima Linuxi kaugkontosse."),
("verify_rustdesk_password_tip", "Kinnita RustDeski parool"),
("remember_account_tip", "Jäta see konto meelde"),
("os_account_desk_tip", "Seda kontot kasutatakse kaug-opsüsteemi sisselogimiseks ja töölaua seansi lubamiseks headless-režiimis."),
("OS Account", "Opsüsteemi konto"),
("another_user_login_title_tip", "Teine kasutaja on juba sisse logitud"),
("another_user_login_text_tip", "Ühenda lahti"),
("xorg_not_found_title_tip", "Xorg-i ei leitud"),
("xorg_not_found_text_tip", "Palun paigalda Xorg"),
("no_desktop_title_tip", "Töölaud pole saadaval"),
("no_desktop_text_tip", "Palun paigalda GNOME Desktop"),
("No need to elevate", "Kõrgendamine pole vajalik"),
("System Sound", "Süsteemiheli"),
("Default", "Vaikimisi"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Fitxategi hau parekidearen berdina da."),
("show_monitors_tip", "Erakutsi monitoreak tresna-barran"),
("View Mode", "Ikuspen modua"),
("login_linux_tip", "Urruneko Linux kontu batera hasi behar duzu saioa X mahaigain saio bat gaitzeko"),
("verify_rustdesk_password_tip", "Berretsi RustDesk pasahitza"),
("remember_account_tip", "Gogoratu kontu hau"),
("os_account_desk_tip", "Kontu hau bururik gabe urruneko SE hasi eta mahaigaineko saioa gaitzeko erabiltzen da"),
("OS Account", "SE kontua"),
("another_user_login_title_tip", "Beste erabiltzaile batek saioa hasi du dagoeneko"),
("another_user_login_text_tip", "Deskonektatu"),
("xorg_not_found_title_tip", "Ez da Xorg aurkitu"),
("xorg_not_found_text_tip", "Mesedez, instalatu ezazu Xorg"),
("no_desktop_title_tip", "Ez dago mahaigainik eskuragarri"),
("no_desktop_text_tip", "Mesedez, instalatu ezazu GNOME Desktop"),
("No need to elevate", "Ez da beharrezkoa pribilegioen maila igotzea"),
("System Sound", "Sistemaren soinua"),
("Default", "Lehenetsia"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "این فایل با فایل همتا یکسان است."),
("show_monitors_tip", "نمایش مانیتورها در نوار ابزار"),
("View Mode", "حالت مشاهده"),
("login_linux_tip", "برای فعال کردن دسکتاپ X، باید به حساب لینوکس راه دور وارد شوید"),
("verify_rustdesk_password_tip", "رمز عبور RustDesk را تأیید کنید"),
("remember_account_tip", "این حساب را به خاطر بسپارید"),
("os_account_desk_tip", "این حساب برای ورود به سیستم عامل راه دور و فعال کردن جلسه دسکتاپ در هدلس استفاده می شود"),
("OS Account", "حساب کاربری سیستم عامل"),
("another_user_login_title_tip", "کاربر دیگری قبلاً وارد شده است"),
("another_user_login_text_tip", "قطع شدن"),
("xorg_not_found_title_tip", "پیدا نشد Xorg"),
("xorg_not_found_text_tip", "لطفا Xorg را نصب کنید"),
("no_desktop_title_tip", "هیچ دسکتاپی در دسترس نیست"),
("no_desktop_text_tip", "لطفا دسکتاپ گنوم را نصب کنید"),
("No need to elevate", "نیازی به ارتقاء نیست"),
("System Sound", "صدای سیستم"),
("Default", "پیش فرض"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Saman niminen tiedosto on jo olemassa"),
("show_monitors_tip", "Näytä kaikki käytettävissä olevat näytöt"),
("View Mode", "Näkymätila"),
("login_linux_tip", "Kirjaudu sisään Linux käyttäjätunnuksellasi"),
("verify_rustdesk_password_tip", "Vahvista RustDesk salasanasi kirjautumista varten"),
("remember_account_tip", "Muista tilini kirjautumista varten"),
("os_account_desk_tip", "Käytä käyttöjärjestelmän käyttäjätiliä kirjautumiseen"),
("OS Account", "Käyttöjärjestelmän tili"),
("another_user_login_title_tip", "Toinen käyttäjä on kirjautunut sisään"),
("another_user_login_text_tip", "Etäistunto keskeytetään, koska toinen käyttäjä on ottanut hallinnan."),
("xorg_not_found_title_tip", "Xorg ei löydy"),
("xorg_not_found_text_tip", "X11 palvelinta ei löydetty. Vaihda Xorg ympäristöön jatkaaksesi."),
("no_desktop_title_tip", "Työpöytää ei havaittu"),
("no_desktop_text_tip", "Työpöytäympäristöä ei löydy. Asenna esimerkiksi GNOME tai XFCE."),
("No need to elevate", "Oikeuksien korotusta ei tarvita"),
("System Sound", "Järjestelmän ääni"),
("Default", "Oletus"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Ce fichier est identique à celui sur lappareil distant."),
("show_monitors_tip", "Afficher les écrans dans la barre doutils"),
("View Mode", "Mode vue"),
("login_linux_tip", "Vous devez vous connecter au compte Linux distant pour établir une session de bureau X"),
("verify_rustdesk_password_tip", "Vérifier le mot de passe RustDesk"),
("remember_account_tip", "Se souvenir de ce compte"),
("os_account_desk_tip", "Ce compte est utilisé pour se connecter au système dexploitation distant et activer la session de bureau en mode sans affichage"),
("OS Account", "Compte du système dexploitation"),
("another_user_login_title_tip", "Un autre utilisateur est déjà connecté"),
("another_user_login_text_tip", "Déconnecter"),
("xorg_not_found_title_tip", "Xorg introuvable"),
("xorg_not_found_text_tip", "Veuillez installer Xorg"),
("no_desktop_title_tip", "Aucun environnement de bureau nest disponible"),
("no_desktop_text_tip", "Veuillez installer lenvironnement de bureau GNOME"),
("No need to elevate", "Élever les privilèges nest pas nécessaire"),
("System Sound", "Son système"),
("Default", "Défaut"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "ფაილი იდენტურია დისტანციურ კვანძზე არსებული ფაილის"),
("show_monitors_tip", "მონიტორების ჩვენება ხელსაწყოთა პანელზე"),
("View Mode", "ნახვის რეჟიმი"),
("login_linux_tip", "X სამუშაო მაგიდის სესიის ჩასართავად, საჭიროა დისტანციურ Linux ანგარიშში შესვლა."),
("verify_rustdesk_password_tip", "დაადასტურეთ RustDesk-ის პაროლი"),
("remember_account_tip", "დაიმახსოვრეთ ეს ანგარიში"),
("os_account_desk_tip", "ეს ანგარიში გამოიყენება დისტანციურ ოპერაციულ სისტემაში შესასვლელად და headless რეჟიმში სამუშაო მაგიდის სესიის ჩასართავად."),
("OS Account", "ოპერაციული სისტემის ანგარიში"),
("another_user_login_title_tip", "სხვა მომხმარებელი უკვე შესულია სისტემაში"),
("another_user_login_text_tip", "გათიშვა"),
("xorg_not_found_title_tip", "Xorg ვერ მოიძებნა"),
("xorg_not_found_text_tip", "დააინსტალირეთ Xorg"),
("no_desktop_title_tip", "სამუშაო მაგიდა არ არის ხელმისაწვდომი"),
("no_desktop_text_tip", "დააინსტალირეთ GNOME Desktop"),
("No need to elevate", "უფლებების აწევა არ არის საჭირო"),
("System Sound", "სისტემური ხმა"),
("Default", "ნაგულისხმევი"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "આ ફાઇલ પહેલેથી જ અસ્તિત્વમાં છે."),
("show_monitors_tip", "ટૂલબારમાં મોનિટર બતાવો"),
("View Mode", "વ્યુ મોડ"),
("login_linux_tip", "રિમોટ Linux સત્ર માટે તમારે લોગિન કરવું પડશે"),
("verify_rustdesk_password_tip", "RustDesk પાસવર્ડ ચકાસો"),
("remember_account_tip", "આ ખાતું યાદ રાખો"),
("os_account_desk_tip", "એક્સેસ માટે OS ખાતાનો ઉપયોગ કરો"),
("OS Account", "OS ખાતું"),
("another_user_login_title_tip", "બીજો યુઝર પહેલેથી લોગિન છે"),
("another_user_login_text_tip", "ડિસ્કનેક્ટ કરો અને ફરી પ્રયાસ કરો"),
("xorg_not_found_title_tip", "Xorg મળ્યું નથી"),
("xorg_not_found_text_tip", "કૃપા કરીને Xorg ઇન્સ્ટોલ કરો"),
("no_desktop_title_tip", "કોઈ ડેસ્કટોપ ઉપલબ્ધ નથી"),
("no_desktop_text_tip", "કૃપા કરીને Linux ડેસ્કટોપ ઇન્સ્ટોલ કરો"),
("No need to elevate", "એલિવેટ કરવાની જરૂર નથી"),
("System Sound", "સિસ્ટમ સાઉન્ડ"),
("Default", "ડિફોલ્ટ"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "קובץ זה זהה לקובץ שבצד העמית."),
("show_monitors_tip", "הצג מסכים בסרגל כלים"),
("View Mode", "מצב תצוגה"),
("login_linux_tip", "עליך להתחבר לחשבון Linux מרוחק כדי לאפשר פעילות שולחן עבודה X"),
("verify_rustdesk_password_tip", "אמת סיסמת RustDesk"),
("remember_account_tip", "זכור חשבון זה"),
("os_account_desk_tip", "חשבון זה משמש להתחברות למערכת ההפעלה המרוחקת ולהפעלת שולחן עבודה במצב לא מקוון"),
("OS Account", "חשבון מערכת הפעלה"),
("another_user_login_title_tip", "משתמש אחר כבר התחבר"),
("another_user_login_text_tip", "נתק"),
("xorg_not_found_title_tip", "Xorg לא נמצא"),
("xorg_not_found_text_tip", "אנא התקן Xorg"),
("no_desktop_title_tip", "אין שולחן עבודה זמין"),
("no_desktop_text_tip", "אנא התקן שולחן עבודה GNOME"),
("No need to elevate", "אין צורך בהעלאת הרשאות"),
("System Sound", "צליל מערכת"),
("Default", "ברירת מחדל"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "यह फ़ाइल पहले से ही मौजूद है।"),
("show_monitors_tip", "टूलबार में मॉनिटर दिखाएं"),
("View Mode", "व्यू मोड"),
("login_linux_tip", "रिमोट Linux सत्र शुरू करने के लिए आपको लॉगिन करना होगा"),
("verify_rustdesk_password_tip", "RustDesk पासवर्ड सत्यापित करें"),
("remember_account_tip", "इस खाते को याद रखें"),
("os_account_desk_tip", "रिमोट डेस्कटॉप को एक्सेस करने के लिए OS खाते का उपयोग करें"),
("OS Account", "OS खाता"),
("another_user_login_title_tip", "एक अन्य उपयोगकर्ता पहले से ही लॉगिन है"),
("another_user_login_text_tip", "डिस्कनेक्ट करें और पुनः प्रयास करें"),
("xorg_not_found_title_tip", "Xorg नहीं मिला"),
("xorg_not_found_text_tip", "कृपया Xorg इंस्टॉल करें"),
("no_desktop_title_tip", "कोई डेस्कटॉप उपलब्ध नहीं है"),
("no_desktop_text_tip", "कृपया Linux डेस्कटॉप इंस्टॉल करें"),
("No need to elevate", "एलीवेट करने की आवश्यकता नहीं है"),
("System Sound", "सिस्टम साउंड"),
("Default", "डिफ़ॉल्ट"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Ova je datoteka identična partnerskoj datoteci."),
("show_monitors_tip", "Prikažite monitore na alatnoj traci"),
("View Mode", "Način prikaza"),
("login_linux_tip", "Da biste omogućili sesiju X radne površine, morate se prijaviti na udaljeni Linux račun."),
("verify_rustdesk_password_tip", "Provjera lozinke za RustDesk"),
("remember_account_tip", "Zapamti ovaj račun"),
("os_account_desk_tip", "Ovaj se račun koristi za prijavu na udaljeni operativni sustav i za omogućavanje sesije radne površine u bezglavom načinu rada."),
("OS Account", "Račun operativnog sustava"),
("another_user_login_title_tip", "Drugi korisnik je već prijavljen"),
("another_user_login_text_tip", "Prekini vezu"),
("xorg_not_found_title_tip", "Xorg nije pronađen"),
("xorg_not_found_text_tip", "Molimo instalirajte Xorg"),
("no_desktop_title_tip", "Nema dostupne radne površine"),
("no_desktop_text_tip", "Molimo instalirajte GNOME"),
("No need to elevate", "Nije potrebno povećanje"),
("System Sound", "Zvuk sustava"),
("Default", "Zadano"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Ez a fájl megegyezik a távoli állomás fájljával."),
("show_monitors_tip", "Képernyők megjelenítése az eszköztáron"),
("View Mode", "Nézet mód"),
("login_linux_tip", "Az X-asztal munkamenet megnyitásához be kell jelentkeznie egy távoli Linux-fiókba."),
("verify_rustdesk_password_tip", "RustDesk jelszó megerősítése"),
("remember_account_tip", "Emlékezzen erre a fiókra"),
("os_account_desk_tip", "Ezzel a fiókkal bejelentkezhet a távoli operációs rendszerbe, és aktiválhatja az asztali munkamenetet fej nélküli módban."),
("OS Account", "OS fiók"),
("another_user_login_title_tip", "Egy másik felhasználó már bejelentkezett."),
("another_user_login_text_tip", "Különálló"),
("xorg_not_found_title_tip", "Xorg nem található."),
("xorg_not_found_text_tip", "Telepítse az Xorgot."),
("no_desktop_title_tip", "Nem áll rendelkezésre asztali környezet."),
("no_desktop_text_tip", "Telepítse a GNOME asztali környezetet."),
("No need to elevate", "Nem szükséges megemelni"),
("System Sound", "Rendszer hangok"),
("Default", "Alapértelmezett"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Data ini identik dengan milik rekan"),
("show_monitors_tip", "Tampilkan monitor di toolbar"),
("View Mode", "Mode Tampilan"),
("login_linux_tip", "Anda harus masuk ke akun remote linux untuk mengaktifkan sesi X desktop"),
("verify_rustdesk_password_tip", "Verifikasi Kata Sandi RustDesk"),
("remember_account_tip", "Ingat akun ini"),
("os_account_desk_tip", "Akun ini digunakan untuk masuk ke sistem operasi remote dan mengaktifkan sesi desktop dalam mode tanpa tampilan (headless)"),
("OS Account", "Akun OS"),
("another_user_login_title_tip", "Akun ini sedang digunakan"),
("another_user_login_text_tip", "Putuskan koneksi diperangkat lain"),
("xorg_not_found_title_tip", "Xorg tidak ditemukan"),
("xorg_not_found_text_tip", "Silahkan install Xorg"),
("no_desktop_title_tip", "Desktop tidak tersedia"),
("no_desktop_text_tip", "Silahkan install GNOME Desktop"),
("No need to elevate", "Tidak perlu elevasi"),
("System Sound", "Suara Sistem"),
("Default", "Default"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Questo file è identico a quello nel dispositivo remoto."),
("show_monitors_tip", "Visualizza schermi nella barra strumenti"),
("View Mode", "Modalità visualizzazione"),
("login_linux_tip", "Accedi all'account Linux remoto"),
("verify_rustdesk_password_tip", "Conferma password RustDesk"),
("remember_account_tip", "Ricorda questo account"),
("os_account_desk_tip", "Questo account viene usato per accedere al sistema operativo remoto e attivare la sessione desktop in modalità non presidiata."),
("OS Account", "Account sistema operativo"),
("another_user_login_title_tip", "È già loggato un altro utente."),
("another_user_login_text_tip", "Separato"),
("xorg_not_found_title_tip", "Xorg non trovato."),
("xorg_not_found_text_tip", "Installa Xorg."),
("no_desktop_title_tip", "Non è presente alcun ambiente desktop disponibile."),
("no_desktop_text_tip", "Installa il desktop GNOME."),
("No need to elevate", "Elevazione dei privilegi non richiesta"),
("System Sound", "Dispositivo audio sistema"),
("Default", "Predefinita"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "このファイルはリモートコンピューターと同一です。"),
("show_monitors_tip", "ツールバーにディスプレイを表示する"),
("View Mode", "表示モード"),
("login_linux_tip", "X デスクトップのセッションにログインするには、リモートコンピューターのLinuxアカウントにログインする必要があります。"),
("verify_rustdesk_password_tip", "RustDesk のパスワードを確認する"),
("remember_account_tip", "このアカウントを記憶する"),
("os_account_desk_tip", "このアカウントは、リモートコンピューターの OS にログインし、ヘッドレスでセッションを有効化するために使用されます。"),
("OS Account", "OS のアカウント"),
("another_user_login_title_tip", "他のユーザーがすでにログインしています"),
("another_user_login_text_tip", "切断しました"),
("xorg_not_found_title_tip", "Xorg サーバーが見つかりませんでした。"),
("xorg_not_found_text_tip", "Xorg をインストールしてください"),
("no_desktop_title_tip", "デスクトップ環境が見つかりませんでした。"),
("no_desktop_text_tip", "GNOME デスクトップ環境をインストールしてください"),
("No need to elevate", "権限昇格の必要はありません"),
("System Sound", "システム音声"),
("Default", "既定"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "이 파일은 상대방의 파일과 일치합니다."),
("show_monitors_tip", "도구 모음에 모니터 표시"),
("View Mode", "보기 모드"),
("login_linux_tip", "X 데스크탑을 활성화하려면 제어되는 터미널의 Linux 계정에 로그인하세요"),
("verify_rustdesk_password_tip", "RustDesk 비밀번호 확인"),
("remember_account_tip", "이 계정 기억하기"),
("os_account_desk_tip", "이 계정은 원격 OS에 로그인하고 헤드리스에서 데스크탑 세션을 활성화하는 데 사용됩니다."),
("OS Account", "OS 계정"),
("another_user_login_title_tip", "다른 사용자가 이미 로그인했습니다"),
("another_user_login_text_tip", "연결 끊기"),
("xorg_not_found_title_tip", "Xorg를 찾을 수 없습니다"),
("xorg_not_found_text_tip", "Xorg를 설치해 주세요"),
("no_desktop_title_tip", "사용 가능한 데스크탑 환경이 없습니다"),
("no_desktop_text_tip", "GNOME 데스크탑을 설치해 주세요"),
("No need to elevate", "권한 상승이 필요없습니다"),
("System Sound", "시스템 소리"),
("Default", "기본"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Бұл файыл пирдікімен бірдей."),
("show_monitors_tip", "Мониторларды құралдар тақтасында көрсету"),
("View Mode", "Көру модасы"),
("login_linux_tip", "X жұмыс үстелі сешін іске қосу үшін қашықтағы Linux есепкісіне кіруіңіз керек"),
("verify_rustdesk_password_tip", "RustDesk құпия сөзін тексеру"),
("remember_account_tip", "Бұл есепкіні есте сақтау"),
("os_account_desk_tip", "Бұл есепкі қашықтағы OS-қа кіру және headless режимде жұмыс үстелі сешін іске қосу үшін қолданылады"),
("OS Account", "OS есепкісі"),
("another_user_login_title_tip", "Басқа қолданушы әлдеқашан кіріп қойған"),
("another_user_login_text_tip", "Ажырату"),
("xorg_not_found_title_tip", "Xorg табылмады"),
("xorg_not_found_text_tip", "Xorg орнатуды өтінеміз"),
("no_desktop_title_tip", "Жұмыс үстелі ортасы қолжетімсіз"),
("no_desktop_text_tip", "GNOME жұмыс үстелін орнатуды өтінеміз"),
("No need to elevate", "Артықшылықты көтерудің қажеті жоқ"),
("System Sound", "Жүйе дыбысы"),
("Default", "Әдепкі"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Failas yra identiškas nuotoliniame kompiuteryje esančiam failui."),
("show_monitors_tip", "Rodyti monitorius įrankių juostoje"),
("View Mode", "Peržiūros režimas"),
("login_linux_tip", "Norėdami įjungti X darbalaukio seansą, turite būti prisijungę prie nuotolinės Linux paskyros."),
("verify_rustdesk_password_tip", "Įveskite kliento RustDesk slaptažodį"),
("remember_account_tip", "Prisiminti šią paskyrą"),
("os_account_desk_tip", "Ši paskyra naudojama norint prisijungti prie nuotolinės OS ir įgalinti darbalaukio seansą režimu headless"),
("OS Account", "OS paskyra"),
("another_user_login_title_tip", "Kitas vartotojas jau yra prisijungęs"),
("another_user_login_text_tip", "Atjungti"),
("xorg_not_found_title_tip", "Xorg nerastas"),
("xorg_not_found_text_tip", "Prašom įdiegti Xorg"),
("no_desktop_title_tip", "Nėra pasiekiamų nuotolinių darbalaukių"),
("no_desktop_text_tip", "Prašom įdiegti GNOME Desktop"),
("No need to elevate", "Teisių kelti nereikia"),
("System Sound", "Sistemos garsas"),
("Default", "Numatytasis"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Šis fails ir identisks sesijas failam."),
("show_monitors_tip", "Rādīt monitorus rīkjoslā"),
("View Mode", "Skatīšanas režīms"),
("login_linux_tip", "Jums ir jāpiesakās attālajā Linux kontā, lai iespējotu X darbvirsmas sesiju"),
("verify_rustdesk_password_tip", "Pārbaudīt RustDesk paroli"),
("remember_account_tip", "Atcerēties šo kontu"),
("os_account_desk_tip", "Šis konts tiek izmantots, lai pieteiktos attālajā operētājsistēmā un iespējotu darbvirsmas sesiju fonā"),
("OS Account", "OS konts"),
("another_user_login_title_tip", "Cits lietotājs jau ir pieteicies"),
("another_user_login_text_tip", "Atvienot"),
("xorg_not_found_title_tip", "Xorg nav atrasts"),
("xorg_not_found_text_tip", "Lūdzu, instalējiet Xorg"),
("no_desktop_title_tip", "Nav pieejama darbvirsma"),
("no_desktop_text_tip", "Lūdzu, instalējiet GNOME darbvirsmu"),
("No need to elevate", "Nav nepieciešams paaugstināt"),
("System Sound", "Sistēmas skaņa"),
("Default", "Noklusējums"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "ഈ ഫയൽ നിലവിലുണ്ട്."),
("show_monitors_tip", "ടൂൾബാറിൽ മോണിറ്ററുകൾ കാണിക്കുക"),
("View Mode", "വ്യൂ മോഡ്"),
("login_linux_tip", "റിമോട്ട് ലിനക്സ് സെഷനായി ലോഗിൻ ചെയ്യണം"),
("verify_rustdesk_password_tip", "RustDesk പാസ്‌വേഡ് പരിശോധിക്കുക"),
("remember_account_tip", "ഈ അക്കൗണ്ട് ഓർമ്മിക്കുക"),
("os_account_desk_tip", "ആക്‌സസിനായി OS അക്കൗണ്ട് ഉപയോഗിക്കുക"),
("OS Account", "OS അക്കൗണ്ട്"),
("another_user_login_title_tip", "മറ്റൊരു ഉപയോക്താവ് ലോഗിൻ ചെയ്തിട്ടുണ്ട്"),
("another_user_login_text_tip", "വിച്ഛേദിച്ച ശേഷം വീണ്ടും ശ്രമിക്കുക"),
("xorg_not_found_title_tip", "Xorg കണ്ടെത്താനായില്ല"),
("xorg_not_found_text_tip", "ദയവായി Xorg ഇൻസ്റ്റാൾ ചെയ്യുക"),
("no_desktop_title_tip", "ഡെസ്ക്ടോപ്പ് ലഭ്യമല്ല"),
("no_desktop_text_tip", "ദയവായി ലിനക്സ് ഡെസ്ക്ടോപ്പ് ഇൻസ്റ്റാൾ ചെയ്യുക"),
("No need to elevate", "എലവേറ്റ് ചെയ്യേണ്ടതില്ല"),
("System Sound", "സിസ്റ്റം സൗണ്ട്"),
("Default", "ഡിഫോൾട്ട്"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Denne filen er identisk med motpartens fil."),
("show_monitors_tip", "Vis skjermer i verktøylinjen"),
("View Mode", "Visningsmodus"),
("login_linux_tip", "Du må logge inn på den eksterne Linux-kontoen for å aktivere en X-skrivebordssesjon"),
("verify_rustdesk_password_tip", "Verifiser RustDesk-passord"),
("remember_account_tip", "Husk denne kontoen"),
("os_account_desk_tip", "Denne kontoen brukes til å logge inn på det eksterne operativsystemet og aktivere skrivebordssesjonen i hodeløs modus"),
("OS Account", "OS-konto"),
("another_user_login_title_tip", "En annen bruker er allerede logget inn"),
("another_user_login_text_tip", "Koble fra"),
("xorg_not_found_title_tip", "Xorg ikke funnet"),
("xorg_not_found_text_tip", "Vennligst installer Xorg"),
("no_desktop_title_tip", "Ingen skrivebordsmiljø er tilgjengelig"),
("no_desktop_text_tip", "Vennligst installer GNOME-skrivebordet"),
("No need to elevate", "Ikke behov for elevering"),
("System Sound", "Systemlyd"),
("Default", "Standard"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Dit bestand is identiek aan het bestand van het externe station."),
("show_monitors_tip", "Monitoren weergeven in de werkbalk"),
("View Mode", "Toeschouwermodus"),
("login_linux_tip", "Toegang tot het externe Linux-account"),
("verify_rustdesk_password_tip", "Bevestiging wachtwoord RustDesk"),
("remember_account_tip", "Onthoud dit account"),
("os_account_desk_tip", "Dit account wordt gebruikt om toegang te krijgen tot het externe besturingssysteem en de bureaubladsessie in onbeheerde modus te activeren."),
("OS Account", "Besturingssysteem account"),
("another_user_login_title_tip", "Een andere gebruiker is al ingelogd."),
("another_user_login_text_tip", "Afzonderlijk"),
("xorg_not_found_title_tip", "Xorg niet gevonden."),
("xorg_not_found_text_tip", "Installeer Xorg."),
("no_desktop_title_tip", "Er is geen desktop beschikbaar."),
("no_desktop_text_tip", "Installeer de GNOME desktop."),
("No need to elevate", "Niet nodig om te verhogen"),
("System Sound", "Systeemgeluid"),
("Default", "Standaard"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Ten plik jest identyczny z plikiem na drugim komputerze."),
("show_monitors_tip", "Pokaż monitory w zasobniku"),
("View Mode", "Tylko podgląd (wyłącza możliwość interakcji)"),
("login_linux_tip", "Musisz zalogować się na zdalne konto, by zezwolić na sesję pulpitu X"),
("verify_rustdesk_password_tip", "Weryfikuj hasło RustDesk"),
("remember_account_tip", "Zapamiętaj to konto"),
("os_account_desk_tip", "To konto jest używane do logowania do zdalnych systemów i włącza bezobsługowe sesje pulpitu"),
("OS Account", "Konto systemowe"),
("another_user_login_title_tip", "Inny użytkownik jest już zalogowany"),
("another_user_login_text_tip", "Rozłącz"),
("xorg_not_found_title_tip", "Nie znaleziono Xorg"),
("xorg_not_found_text_tip", "Proszę zainstalować Xorg"),
("no_desktop_title_tip", "Żaden pulpit nie jest dostępny"),
("no_desktop_text_tip", "Proszę zainstalować pulpit GNOME"),
("No need to elevate", "Podniesienie uprawnień nie jest wymagane"),
("System Sound", "Dźwięk systemowy"),
("Default", "Domyślne"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Este ficheiro é idêntico ao do destino."),
("show_monitors_tip", "Mostrar monitores na barra de ferramentas"),
("View Mode", "Modo de visualização"),
("login_linux_tip", "É necessário iniciar sessão na conta Linux remota para ativar uma sessão de ambiente de trabalho X"),
("verify_rustdesk_password_tip", "Verificar palavra-passe do RustDesk"),
("remember_account_tip", "Memorizar esta conta"),
("os_account_desk_tip", "Esta conta é usada para iniciar sessão no SO remoto e ativar a sessão de ambiente de trabalho em modo headless"),
("OS Account", "Conta do SO"),
("another_user_login_title_tip", "Outro utilizador já tem sessão iniciada"),
("another_user_login_text_tip", "Desligar"),
("xorg_not_found_title_tip", "Xorg não encontrado"),
("xorg_not_found_text_tip", "Instale o Xorg"),
("no_desktop_title_tip", "Não há nenhum ambiente de trabalho disponível"),
("no_desktop_text_tip", "Instale o ambiente de trabalho GNOME"),
("No need to elevate", "Não é necessário elevar"),
("System Sound", "Som do sistema"),
("Default", "Predefinido"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Este arquivo é idêntico ao do parceiro."),
("show_monitors_tip", "Mostrar telas na barra de ferramentas"),
("View Mode", "Modo de visualização"),
("login_linux_tip", "Você precisa fazer login na conta Linux remota para habilitar uma sessão de desktop X"),
("verify_rustdesk_password_tip", "Verifique a senha do RustDesk"),
("remember_account_tip", "Lembrar desta conta"),
("os_account_desk_tip", "Esta conta é usada para fazer login no Sistema Operacional remoto e habilitar a sessão da área de trabalho em headless"),
("OS Account", "Conta do Sistema Operacional"),
("another_user_login_title_tip", "Outro usuário já está logado"),
("another_user_login_text_tip", "Desconectar"),
("xorg_not_found_title_tip", "Xorg não encontrado"),
("xorg_not_found_text_tip", "Por favor, instale o Xorg"),
("no_desktop_title_tip", "Nenhuma área de trabalho está disponível"),
("no_desktop_text_tip", "Por favor, instale a área de trabalho do GNOME"),
("No need to elevate", "Não há necessidade de elevar"),
("System Sound", "Som do Sistema"),
("Default", "Padrão"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Acest fișier este identic cu cel al dispozitivului pereche."),
("show_monitors_tip", "Afișează monitoare în bara de instrumente"),
("View Mode", "Mod vizualizare"),
("login_linux_tip", "Este necesar să te conectezi la contul de Linux de la distanță pentru a începe o sesiune cu un desktop care folosește X11"),
("verify_rustdesk_password_tip", "Verifică parola RustDesk"),
("remember_account_tip", "Reține contul"),
("os_account_desk_tip", "Acest cont este utilizat pentru conectarea la sistemul de operare la distanță și începerea sesiunii cu desktopul în modul fără afișaj."),
("OS Account", "Cont OS"),
("another_user_login_title_tip", "Un alt utilizator este deja conectat"),
("another_user_login_text_tip", "Deconectare"),
("xorg_not_found_title_tip", "Xorg nu a fost găsit"),
("xorg_not_found_text_tip", "Instalează Xorg"),
("no_desktop_title_tip", "Nu este disponibil niciun mediu desktop"),
("no_desktop_text_tip", "Instalează mediul desktop GNOME"),
("No need to elevate", "Nu sunt necesare permisiuni de administrator"),
("System Sound", "Sunet sistem"),
("Default", "Implicit"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Файл идентичен файлу на удалённом узле"),
("show_monitors_tip", "Показывать мониторы на панели инструментов"),
("View Mode", "Режим просмотра"),
("login_linux_tip", "Чтобы включить сеанс рабочего стола X, необходимо войти в удалённый аккаунт Linux."),
("verify_rustdesk_password_tip", "Подтвердить пароль RustDesk"),
("remember_account_tip", "Запомнить этот аккаунт"),
("os_account_desk_tip", "Этот аккаунт используется для входа в удалённую ОС и включения сеанса рабочего стола в режиме headless."),
("OS Account", "Аккаунт ОС"),
("another_user_login_title_tip", "Другой пользователь уже вошёл в систему"),
("another_user_login_text_tip", "Отключить"),
("xorg_not_found_title_tip", "Xorg не найден"),
("xorg_not_found_text_tip", "Установите Xorg"),
("no_desktop_title_tip", "Нет доступных рабочих столов"),
("no_desktop_text_tip", "Установите GNOME Desktop"),
("No need to elevate", "Повышение прав не требуется"),
("System Sound", "Системный звук"),
("Default", "По умолчанию"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Custu archìviu est pretzisu a su chi b'at in su dispositivu remotu."),
("show_monitors_tip", "Mustra sos ischermos in s'istanga de sos trastes"),
("View Mode", "Modalidade de visualizatzione"),
("login_linux_tip", "Intra a su contu de Linux remotu"),
("verify_rustdesk_password_tip", "Cunfirma sa crae de RustDesk"),
("remember_account_tip", "Ammenta custu contu"),
("os_account_desk_tip", "Custu contu s'impreat pro intrare a su sistema operativu remotu e ativare sa sessione de s'elaboradore in modalidade non presidiada."),
("OS Account", "Contu sistema operativu"),
("another_user_login_title_tip", "Un'àteru utente at giai fatu s'atzessu."),
("another_user_login_text_tip", "Separadu"),
("xorg_not_found_title_tip", "Xorg no atzapadu."),
("xorg_not_found_text_tip", "Installa Xorg."),
("no_desktop_title_tip", "Non b'at perunu ambiente de elaboradore a disponimentu."),
("no_desktop_text_tip", "Installa s'ambiente de elaboradore GNOME."),
("No need to elevate", "Crèschida de sos privilègios non pedida"),
("System Sound", "Dispositivu àudio de sistema"),
("Default", "Predefinida"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Tento súbor je identický so súborom partnera."),
("show_monitors_tip", "Zobraziť monitory na paneli nástrojov"),
("View Mode", "Režim zobrazenia"),
("login_linux_tip", "Ak chcete povoliť reláciu Desktop X, musíte sa prihlásiť do vzdialeného konta Linuxu."),
("verify_rustdesk_password_tip", "Overenie hesla RustDesk"),
("remember_account_tip", "Zapamätať si tento účet"),
("os_account_desk_tip", "Toto konto sa používa na prihlásenie do vzdialeného operačného systému a na povolenie relácie pracovnej plochy v režime headless."),
("OS Account", "Účet operačného systému"),
("another_user_login_title_tip", "Ďalší používateľ je už prihlásený"),
("another_user_login_text_tip", "Odpojiť"),
("xorg_not_found_title_tip", "Xorg nebol nájdený"),
("xorg_not_found_text_tip", "Prosím, nainštalujte Xorg"),
("no_desktop_title_tip", "Nie je k dispozícii žiadna plocha"),
("no_desktop_text_tip", "Nainštalujte si prostredie GNOME"),
("No need to elevate", "Navýšenie nie je potrebné"),
("System Sound", "Systémový zvuk"),
("Default", "Predvolené"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Datoteka je enaka partnerjevi"),
("show_monitors_tip", "Prikaži monitorje v orodni vrstici"),
("View Mode", "Način prikazovanja"),
("login_linux_tip", "Prijaviti se morate v oddaljeni Linux račun in omogočiti namizno sejo X."),
("verify_rustdesk_password_tip", "Preveri geslo za RustDesk"),
("remember_account_tip", "Zapomni si ta račun"),
("os_account_desk_tip", "Ta račun se uporabi za prijavo v oddaljeni sistem in omogči namizno sejo v napravi brez monitorja."),
("OS Account", "Račun operacijskega sistema"),
("another_user_login_title_tip", "Prijavljen je že drug uporabnik"),
("another_user_login_text_tip", "Prekini"),
("xorg_not_found_title_tip", "Xorg ni najden"),
("xorg_not_found_text_tip", "Namestite Xorg"),
("no_desktop_title_tip", "Namizno okolje ni na voljo"),
("no_desktop_text_tip", "Namestite GNOME"),
("No need to elevate", "Povzdig pravic ni potreben"),
("System Sound", "Sistemski zvok"),
("Default", "Privzeto"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Ky skedar është identik me atë të peer-it."),
("show_monitors_tip", "Shfaq monitorët në shiritin e veglave"),
("View Mode", "Modaliteti i pamjes"),
("login_linux_tip", "Duhet të hyni në llogarinë Linux në distancë për të aktivizuar një seancë desktopi X"),
("verify_rustdesk_password_tip", "Verifiko fjalëkalimin e RustDesk"),
("remember_account_tip", "Mbaj mend këtë llogari"),
("os_account_desk_tip", "Kjo llogari përdoret për të hyrë në OS-në në distancë dhe për të aktivizuar seancën e desktopit pa ekran"),
("OS Account", "Llogaria e OS"),
("another_user_login_title_tip", "Një përdorues tjetër ka hyrë tashmë"),
("another_user_login_text_tip", "Shkëput"),
("xorg_not_found_title_tip", "Xorg nuk u gjet"),
("xorg_not_found_text_tip", "Ju lutemi instaloni Xorg"),
("no_desktop_title_tip", "Nuk ka asnjë mjedis desktopi të disponueshëm"),
("no_desktop_text_tip", "Ju lutemi instaloni desktopin GNOME"),
("No need to elevate", "Nuk ka nevojë për ngritje privilegjesh"),
("System Sound", "Tingulli i sistemit"),
("Default", "I parazgjedhur"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Ova datoteka je identična sa onom kod klijenta."),
("show_monitors_tip", "Prikaži monitore u traci alata"),
("View Mode", "Režim prikaza"),
("login_linux_tip", "Potrebno je da se prijavite na udaljeni Linux nalog da biste omogućili X desktop sesiju"),
("verify_rustdesk_password_tip", "Potvrdi RustDesk lozinku"),
("remember_account_tip", "Zapamti ovaj nalog"),
("os_account_desk_tip", "Ovaj nalog se koristi za prijavu na udaljeni OS i omogućavanje desktop sesije u headless režimu"),
("OS Account", "OS nalog"),
("another_user_login_title_tip", "Drugi korisnik je već prijavljen"),
("another_user_login_text_tip", "Prekini vezu"),
("xorg_not_found_title_tip", "Xorg nije pronađen"),
("xorg_not_found_text_tip", "Molimo instalirajte Xorg"),
("no_desktop_title_tip", "Nijedno desktop okruženje nije dostupno"),
("no_desktop_text_tip", "Molimo instalirajte GNOME desktop"),
("No need to elevate", "Nema potrebe za podizanjem privilegija"),
("System Sound", "Sistemski zvuk"),
("Default", "Podrazumevano"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Den här filen är identisk med klientens."),
("show_monitors_tip", "Visa skärmar i verktygsfältet"),
("View Mode", "Visningsläge"),
("login_linux_tip", "Du måste logga in på Linux-fjärrkontot för att aktivera en X-skrivbordssession"),
("verify_rustdesk_password_tip", "Verifiera RustDesk-lösenord"),
("remember_account_tip", "Kom ihåg detta konto"),
("os_account_desk_tip", "Detta konto används för att logga in på fjärroperativsystemet och aktivera skrivbordssessionen i obevakat läge"),
("OS Account", "OS-konto"),
("another_user_login_title_tip", "En annan användare är redan inloggad"),
("another_user_login_text_tip", "Koppla ifrån"),
("xorg_not_found_title_tip", "Xorg hittades inte"),
("xorg_not_found_text_tip", "Installera Xorg"),
("no_desktop_title_tip", "Ingen skrivbordsmiljö är tillgänglig"),
("no_desktop_text_tip", "Installera GNOME-skrivbordet"),
("No need to elevate", "Ingen behörighetshöjning behövs"),
("System Sound", "Systemljud"),
("Default", "Standard"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "ஒரே_மாதிரியான_கோப்பு_குறிப்பு"),
("show_monitors_tip", "மானிட்டர்களை_காட்டு_குறிப்பு"),
("View Mode", "காட்சி முறை"),
("login_linux_tip", "லினக்ஸ்_உள்நுழைவு_குறிப்பு"),
("verify_rustdesk_password_tip", "rustdesk_கடவுச்சொல்_சரிபார்ப்பு_குறிப்பு"),
("remember_account_tip", "கணக்கை_நினைவில்_கொள்_குறிப்பு"),
("os_account_desk_tip", "os_கணக்கு_டெஸ்க்_குறிப்பு"),
("OS Account", "OS கணக்கு"),
("another_user_login_title_tip", "மற்றொரு_பயனர்_உள்நுழைவு_தலைப்பு_குறிப்பு"),
("another_user_login_text_tip", "மற்றொரு_பயனர்_உள்நுழைவு_உரை_குறிப்பு"),
("xorg_not_found_title_tip", "xorg_காணப்படவில்லை_தலைப்பு_குறிப்பு"),
("xorg_not_found_text_tip", "xorg_காணப்படவில்லை_உரை_குறிப்பு"),
("no_desktop_title_tip", "டெஸ்க்டாப்_இல்லை_தலைப்பு_குறிப்பு"),
("no_desktop_text_tip", "டெஸ்க்டாப்_இல்லை_உரை_குறிப்பு"),
("No need to elevate", "உயர்த்த தேவையில்லை"),
("System Sound", "சிஸ்டம் ஒலி"),
("Default", "இயல்புநிலை"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", ""),
("show_monitors_tip", ""),
("View Mode", ""),
("login_linux_tip", ""),
("verify_rustdesk_password_tip", ""),
("remember_account_tip", ""),
("os_account_desk_tip", ""),
("OS Account", ""),
("another_user_login_title_tip", ""),
("another_user_login_text_tip", ""),
("xorg_not_found_title_tip", ""),
("xorg_not_found_text_tip", ""),
("no_desktop_title_tip", ""),
("no_desktop_text_tip", ""),
("No need to elevate", ""),
("System Sound", ""),
("Default", ""),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "ไฟล์นี้เหมือนกับไฟล์ของอีกฝั่ง"),
("show_monitors_tip", "แสดงหน้าจอในแถบเครื่องมือ"),
("View Mode", "โหมดการดู"),
("login_linux_tip", "คุณจำเป็นจะต้องเข้าสู่ระบบไปยังบัญชีลินุกซ์ปลายทางเพื่อใช้งานเดสก์ท็อปเซสชัน X"),
("verify_rustdesk_password_tip", "ยืนยันความถูกต้องรหัสผ่านของ RustDesk"),
("remember_account_tip", "จดจำบัญชีนี้"),
("os_account_desk_tip", "บัญชีนี้จะถูกใช้ในการเข้าสู่ระบบเครื่องปลายทางและเริ่มใช้งานเดสก์ท็อปเซสชันแบบ headless"),
("OS Account", "บัญชีระบบปฏิบัติการ"),
("another_user_login_title_tip", "ผู้ใช้งานอื่นเข้าสู่ระบบอยู่แล้ว"),
("another_user_login_text_tip", "ยกเลิกการเชื่อมต่อ"),
("xorg_not_found_title_tip", "ไม่พบ Xorg"),
("xorg_not_found_text_tip", "กรุณาติดตั้ง Xorg"),
("no_desktop_title_tip", "ไม่มีหน้าเดสก์ท็อปที่ใช้งานได้"),
("no_desktop_text_tip", "กรุณาติดตั้ง GNOME เดสกท็อป"),
("No need to elevate", "ไม่จำเป็นต้องยกระดับสิทธิ์การใช้งาน"),
("System Sound", "เสียงของระบบ"),
("Default", "ค่าเริ่มต้น"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Bu dosya, cihazın dosyası ile aynıdır."),
("show_monitors_tip", "Monitörleri araç çubuğunda göster"),
("View Mode", "Görünüm Modu"),
("login_linux_tip", "X masaüstü oturumu başlatmak için uzaktaki Linux hesabına giriş yapmanız gerekiyor"),
("verify_rustdesk_password_tip", "RustDesk parolasını doğrulayın"),
("remember_account_tip", "Bu hesabı hatırla"),
("os_account_desk_tip", "Bu hesap, uzaktaki işletim sistemine giriş yapmak ve başsız masaüstü oturumunu etkinleştirmek için kullanılır."),
("OS Account", "İşletim Sistemi Hesabı"),
("another_user_login_title_tip", "Başka bir kullanıcı zaten oturum açtı"),
("another_user_login_text_tip", "Bağlantıyı Kapat"),
("xorg_not_found_title_tip", "Xorg bulunamadı"),
("xorg_not_found_text_tip", "Lütfen Xorg'u yükleyin"),
("no_desktop_title_tip", "Masaüstü mevcut değil"),
("no_desktop_text_tip", "Lütfen GNOME masaüstünü yükleyin"),
("No need to elevate", "Yükseltmeye gerek yok"),
("System Sound", "Sistem Sesi"),
("Default", "Varsayılan"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "此檔案與對方的檔案一致。"),
("show_monitors_tip", "在工具列中顯示顯示器"),
("View Mode", "瀏覽模式"),
("login_linux_tip", "需要登入到遠端 Linux 使用者帳戶才能啟用 X 桌面環境"),
("verify_rustdesk_password_tip", "驗證 RustDesk 密碼"),
("remember_account_tip", "記住此使用者帳戶"),
("os_account_desk_tip", "此使用者帳戶將用於登入遠端作業系統並啟用無頭模式 (headless mode) 的桌面連線"),
("OS Account", "作業系統使用者帳戶"),
("another_user_login_title_tip", "另一個使用者已經登入"),
("another_user_login_text_tip", "斷開連線"),
("xorg_not_found_title_tip", "找不到 Xorg"),
("xorg_not_found_text_tip", "請安裝 Xorg"),
("no_desktop_title_tip", "沒有可用的桌面環境"),
("no_desktop_text_tip", "請安裝 GNOME 桌面"),
("No need to elevate", "不需要提升權限"),
("System Sound", "系統音效"),
("Default", "預設"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Цей файл ідентичний з тим, що на вузлі"),
("show_monitors_tip", "Показувати монітори на панелі інструментів"),
("View Mode", "Режим перегляду"),
("login_linux_tip", "Вам необхідно увійти у віддалений обліковий запис Linux, щоб увімкнути стільничний сеанс X"),
("verify_rustdesk_password_tip", "Перевірте пароль RustDesk"),
("remember_account_tip", "Запамʼятати цей обліковий запис"),
("os_account_desk_tip", "Цей обліковий запис використовується для входу до віддаленої ОС та вмикання сеансу стільниці в режимі без графічного інтерфейсу"),
("OS Account", "Користувач ОС"),
("another_user_login_title_tip", "Інший користувач вже в системі"),
("another_user_login_text_tip", "Відʼєднатися"),
("xorg_not_found_title_tip", "Xorg не знайдено"),
("xorg_not_found_text_tip", "Будь ласка, встановіть Xorg"),
("no_desktop_title_tip", "Жодне стільничне середовище не доступне"),
("no_desktop_text_tip", "Будь ласка, встановіть стільничне середовище GNOME"),
("No need to elevate", "Немає потреби в розширенні прав"),
("System Sound", "Системний звук"),
("Default", "Типово"),

View File

@@ -464,17 +464,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("identical_file_tip", "Tệp này giống hệt ở phía đối tác."),
("show_monitors_tip", "Hiện màn hình trên thanh công cụ"),
("View Mode", "Chế độ xem"),
("login_linux_tip", "Cần đăng nhập tài khoản Linux để kích hoạt X session."),
("verify_rustdesk_password_tip", "Xác thực mật khẩu RustDesk"),
("remember_account_tip", "Nhớ tài khoản này"),
("os_account_desk_tip", "Tài khoản OS được dùng để đăng nhập và chạy session không màn hình (headless)."),
("OS Account", "Tài khoản OS"),
("another_user_login_title_tip", "Người dùng khác đã đăng nhập"),
("another_user_login_text_tip", "Ngắt kết nối hiện tại"),
("xorg_not_found_title_tip", "Không tìm thấy Xorg"),
("xorg_not_found_text_tip", "Vui lòng cài đặt Xorg"),
("no_desktop_title_tip", "Không có desktop"),
("no_desktop_text_tip", "Vui lòng cài đặt GNOME hoặc desktop khác."),
("No need to elevate", "Không cần nâng quyền"),
("System Sound", "Âm thanh hệ thống"),
("Default", "Mặc định"),

View File

@@ -14,7 +14,7 @@ use hbb_common::{
allow_err,
anyhow::anyhow,
bail,
config::{keys::OPTION_ALLOW_LINUX_HEADLESS, Config},
config::Config,
libc::{c_char, c_int, c_long, c_uint, c_ulong, c_void},
log,
message_proto::{DisplayInfo, Resolution},
@@ -235,11 +235,6 @@ pub struct xcb_xfixes_get_cursor_image {
pub pixels: *const c_long,
}
#[inline]
pub fn is_headless_allowed() -> bool {
Config::get_option(OPTION_ALLOW_LINUX_HEADLESS) == "Y"
}
#[inline]
pub fn is_login_screen_wayland() -> bool {
let values = get_values_of_seat0_with_gdm_wayland(&[0, 2]);
@@ -863,18 +858,6 @@ fn stop_rustdesk_servers() {
));
}
#[inline]
fn stop_subprocess() {
let _ = run_cmds(&format!(
r##"ps -ef | grep '/etc/{}/xorg.conf' | grep -v grep | awk '{{print $2}}' | xargs -r kill -9"##,
crate::get_app_name().to_lowercase(),
));
let _ = run_cmds(&format!(
r##"ps -ef | grep -E '{} +--cm-no-ui' | grep -v grep | awk '{{print $2}}' | xargs -r kill -9"##,
crate::get_app_name().to_lowercase(),
));
}
fn should_start_server(
try_x11: bool,
is_display_changed: bool,
@@ -888,13 +871,7 @@ fn should_start_server(
let mut start_new = false;
let mut should_kill = false;
if desktop.is_headless() {
if !uid.is_empty() {
// From having a monitor to not having a monitor.
*uid = "".to_owned();
should_kill = true;
}
} else if is_display_changed || desktop.uid != *uid && !desktop.uid.is_empty() {
if is_display_changed || desktop.uid != *uid && !desktop.uid.is_empty() {
*uid = desktop.uid.clone();
if try_x11 {
set_x11_env(&desktop);
@@ -953,7 +930,6 @@ fn force_stop_server() {
pub fn start_os_service() {
check_if_stop_service();
stop_rustdesk_servers();
stop_subprocess();
start_uinput_service();
std::thread::spawn(|| {
@@ -1003,8 +979,7 @@ pub fn start_os_service() {
desktop.refresh();
update_active_user_lookup_cache(&desktop);
// Duplicate logic here with should_start_server
// Login wayland will try to start a headless --server.
// Duplicate logic here with should_start_server.
if desktop.username == "root" || desktop.is_login_wayland() {
// try kill subprocess "--server"
stop_server(&mut user_server);
@@ -1019,7 +994,6 @@ pub fn start_os_service() {
&mut last_restart,
&mut server,
) {
stop_subprocess();
force_stop_server();
// Run the login-screen --server as the active seat0 session user (the greeter
// account) rather than root, so the DRM capture GPU/EGL convert never loads the
@@ -1072,7 +1046,6 @@ pub fn start_os_service() {
&mut last_restart,
&mut user_server,
) {
stop_subprocess();
force_stop_server();
start_server(Some(&desktop), &mut user_server);
}
@@ -1082,17 +1055,14 @@ pub fn start_os_service() {
stop_server(&mut server);
}
let keeps_headless = sid.is_empty() && desktop.is_headless();
let keeps_session = sid == desktop.sid;
if keeps_headless || keeps_session {
if keeps_session {
// for fixing https://github.com/rustdesk/rustdesk/issues/3129 to avoid too much dbus calling,
sleep_millis(500);
} else {
sleep_millis(super::SERVICE_INTERVAL);
}
if !desktop.is_headless() {
sid = desktop.sid.clone();
}
sid = desktop.sid.clone();
}
if let Some(ps) = user_server.take().as_mut() {
@@ -1249,7 +1219,6 @@ fn is_flatpak() -> bool {
std::path::PathBuf::from("/.flatpak-info").exists()
}
// Headless is enabled, always return true.
pub fn is_prelogin() -> bool {
if is_flatpak() {
return false;
@@ -1860,7 +1829,6 @@ mod desktop {
pub xauth: String,
pub home: String,
pub dbus: String,
pub is_rustdesk_subprocess: bool,
pub wl_display: String,
}
@@ -1875,11 +1843,6 @@ mod desktop {
super::is_gdm_user(&self.username) && self.protocol == DISPLAY_SERVER_WAYLAND
}
#[inline]
pub fn is_headless(&self) -> bool {
self.sid.is_empty() || self.is_rustdesk_subprocess
}
fn get_display_xauth_wayland(&mut self) {
for _ in 1..=10 {
// Prefer Wayland-related variables first when multiple portal processes match.
@@ -2117,25 +2080,11 @@ mod desktop {
last
}
fn set_is_subprocess(&mut self) {
self.is_rustdesk_subprocess = false;
let cmd = format!(
"ps -ef | grep '{}/xorg.conf' | grep -v grep | wc -l",
crate::get_app_name().to_lowercase()
);
if let Ok(res) = run_cmds(&cmd) {
if res.trim() != "0" {
self.is_rustdesk_subprocess = true;
}
}
}
pub fn refresh(&mut self) {
if !self.sid.is_empty() && is_active_and_seat0(&self.sid) {
// Xwayland display and xauth may not be available in a short time after login.
if is_xwayland_running() && !self.is_login_wayland() {
self.get_display_xauth_xwayland();
self.is_rustdesk_subprocess = false;
} else if self.is_wayland() {
self.get_display_xauth_wayland();
}
@@ -2145,7 +2094,6 @@ mod desktop {
let seat0_values = get_values_of_seat0_with_gdm_wayland(&[0, 1, 2]);
if seat0_values[0].is_empty() {
*self = Self::default();
self.is_rustdesk_subprocess = false;
return;
}
@@ -2156,7 +2104,6 @@ mod desktop {
if self.is_login_wayland() {
self.display = "".to_owned();
self.xauth = "".to_owned();
self.is_rustdesk_subprocess = false;
// Resolve HOME even on this path. Upstream returned without it because nothing then
// consumed a login-Wayland Desktop, but the drm build starts a `--server` as the
// greeter uid here, and a child with no HOME has nowhere to put its config. The
@@ -2183,11 +2130,9 @@ mod desktop {
} else {
self.get_display_xauth_wayland();
}
self.is_rustdesk_subprocess = false;
} else {
self.get_display_x11();
self.get_xauth_x11();
self.set_is_subprocess();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -20,9 +20,6 @@ pub mod delegate;
#[cfg(target_os = "linux")]
pub mod linux;
#[cfg(target_os = "linux")]
pub mod linux_desktop_manager;
#[cfg(target_os = "linux")]
pub mod gtk_sudo;

View File

@@ -143,11 +143,6 @@ impl RendezvousMediator {
allow_err!(super::lan::start_listening());
});
}
// It is ok to run xdesktop manager when the headless function is not allowed.
#[cfg(target_os = "linux")]
if crate::is_server() {
crate::platform::linux_desktop_manager::start_xdesktop();
}
scrap::codec::test_av1();
*LAST_NOT_DEPLOYED_REGISTER.lock().await = None;
loop {

View File

@@ -12,8 +12,6 @@ use crate::clipboard::{update_clipboard, ClipboardSide};
use crate::clipboard_file::*;
#[cfg(target_os = "android")]
use crate::keyboard::client::map_key_to_control_key;
#[cfg(target_os = "linux")]
use crate::platform::linux_desktop_manager;
#[cfg(any(target_os = "windows", target_os = "linux"))]
use crate::platform::WallPaperRemover;
#[cfg(windows)]
@@ -117,39 +115,6 @@ fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
x == 0
}
#[cfg(target_os = "linux")]
fn should_check_linux_headless_os_auth_before_desktop_start(
is_headless_allowed: bool,
username: &str,
) -> bool {
is_headless_allowed && !username.trim().is_empty()
}
#[cfg(target_os = "linux")]
fn linux_desktop_start_credentials(
is_headless_allowed: bool,
os_login: Option<&OSLogin>,
) -> Option<(String, String)> {
if !is_headless_allowed {
return None;
}
if let Some(os_login) = os_login.filter(|os_login| !os_login.username.trim().is_empty()) {
return Some((os_login.username.clone(), os_login.password.clone()));
}
Some((String::new(), String::new()))
}
#[cfg(target_os = "linux")]
fn should_record_linux_headless_os_auth_failure(
is_headless_allowed: bool,
username: &str,
err_msg: &str,
) -> bool {
is_headless_allowed
&& !username.trim().is_empty()
&& err_msg == crate::client::LOGIN_MSG_PASSWORD_WRONG
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
fn should_use_terminal_os_login_scope(is_terminal: bool, os_login_username: &str) -> bool {
cfg!(target_os = "windows") && is_terminal && !os_login_username.trim().is_empty()
@@ -208,8 +173,6 @@ struct Session {
struct StartCmIpcPara {
rx_to_cm: mpsc::UnboundedReceiver<ipc::Data>,
tx_from_cm: mpsc::UnboundedSender<ipc::Data>,
rx_desktop_ready: mpsc::Receiver<()>,
tx_cm_stream_ready: mpsc::Sender<()>,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
@@ -351,8 +314,6 @@ pub struct Connection {
options_in_login: Option<OptionMessage>,
#[cfg(not(any(target_os = "ios")))]
pressed_modifiers: HashSet<rdev::Key>,
#[cfg(target_os = "linux")]
linux_headless_handle: LinuxHeadlessHandle,
closed: bool,
#[cfg(not(any(target_os = "android", target_os = "ios")))]
start_cm_ipc_para: Option<StartCmIpcPara>,
@@ -435,14 +396,10 @@ const SESSION_TIMEOUT: Duration = Duration::from_secs(30);
/// Whether the DRM backend can serve a Wayland login screen here.
///
/// The cached probe, not the blocking one: this is a routing gate. Available-only ON PURPOSE, and
/// deliberately NOT symmetric with the seat0 adoption gate: that one only starts Xorg on a
/// definitive Unavailable (never over a maybe-live greeter), while admission only accepts on a
/// definitive Available (never a greeter nothing can yet capture). Both err toward refuse-and-retry
/// during an unsettled probe; admitting there would black-screen a client on a helper-less box.
/// A cold cache probes off-thread; admission still requires a definitive `Available` verdict.
#[cfg(all(target_os = "linux", feature = "drm"))]
fn drm_can_serve_login_screen() -> bool {
super::drm_capturer::is_available_cached()
super::drm_capturer::availability_cached() == super::drm_capturer::Availability::Available
}
/// Without the feature nothing can capture a Wayland greeter, so the refusal stands.
@@ -484,14 +441,6 @@ impl Connection {
let (tx_input, _rx_input) = std_mpsc::channel();
let (tx_from_authed, mut rx_from_authed) = mpsc::unbounded_channel::<ipc::Data>();
let mut hbbs_rx = crate::hbbs_http::sync::signal_receiver();
#[cfg(not(any(target_os = "android", target_os = "ios")))]
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(target_os = "linux")]
let linux_headless_handle =
LinuxHeadlessHandle::new(_rx_cm_stream_ready, _tx_desktop_ready);
let (tx_post_seq, rx_post_seq) = mpsc::unbounded_channel();
tokio::spawn(async move {
Self::post_seq_loop(rx_post_seq).await;
@@ -568,15 +517,11 @@ impl Connection {
options_in_login: None,
#[cfg(not(any(target_os = "ios")))]
pressed_modifiers: Default::default(),
#[cfg(target_os = "linux")]
linux_headless_handle,
closed: false,
#[cfg(not(any(target_os = "android", target_os = "ios")))]
start_cm_ipc_para: Some(StartCmIpcPara {
rx_to_cm,
tx_from_cm,
rx_desktop_ready,
tx_cm_stream_ready,
}),
auto_disconnect_timer: None,
authed_conn_id: None,
@@ -1854,12 +1799,6 @@ impl Connection {
if crate::platform::current_is_wayland() {
platform_additions.insert("is_wayland".into(), json!(true));
}
#[cfg(target_os = "linux")]
if crate::platform::is_headless_allowed() {
if linux_desktop_manager::is_headless() {
platform_additions.insert("headless".into(), json!(true));
}
}
}
#[cfg(target_os = "windows")]
{
@@ -2690,14 +2629,7 @@ impl Connection {
tokio::spawn(async move {
#[cfg(windows)]
let tx_from_cm_clone = p.tx_from_cm.clone();
if let Err(err) = start_ipc(
p.rx_to_cm,
p.tx_from_cm,
p.rx_desktop_ready,
p.tx_cm_stream_ready,
)
.await
{
if let Err(err) = start_ipc(p.rx_to_cm, p.tx_from_cm).await {
log::warn!("ipc to connection manager exit: {}", err);
// https://github.com/rustdesk/rustdesk-server-pro/discussions/382#discussioncomment-10525725, cm may start failed
#[cfg(windows)]
@@ -2831,59 +2763,6 @@ impl Connection {
#[cfg(not(any(target_os = "android", target_os = "ios")))]
if !should_use_terminal_os_login_scope(self.terminal, &lr.os_login.username) {
#[cfg(not(target_os = "linux"))]
self.try_start_cm_ipc();
}
#[cfg(target_os = "linux")]
if should_check_linux_headless_os_auth_before_desktop_start(
self.linux_headless_handle.is_headless_allowed,
&lr.os_login.username,
) {
let (_failure, res) = self.check_failure(0).await;
if !res {
return true;
}
}
#[cfg(not(target_os = "linux"))]
let err_msg = "".to_owned();
#[cfg(target_os = "linux")]
let err_msg = match self
.linux_headless_handle
.try_start_desktop(lr.os_login.as_ref())
.await
{
LinuxDesktopStartOutcome::Finished(err_msg) => err_msg,
LinuxDesktopStartOutcome::Busy => {
self.send_login_error(crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY)
.await;
return true;
}
};
// If err is LOGIN_MSG_DESKTOP_SESSION_NOT_READY, just keep this msg and go on checking password.
if !err_msg.is_empty() && err_msg != crate::client::LOGIN_MSG_DESKTOP_SESSION_NOT_READY
{
#[cfg(target_os = "linux")]
if should_record_linux_headless_os_auth_failure(
self.linux_headless_handle.is_headless_allowed,
&lr.os_login.username,
&err_msg,
) {
let (failure, res) = self.check_failure(0).await;
if !res {
return true;
}
self.update_failure(failure, false, 0);
}
self.send_login_error(err_msg).await;
return true;
}
#[cfg(target_os = "linux")]
if !should_use_terminal_os_login_scope(self.terminal, &lr.os_login.username) {
// In headless mode, the desktop check above settles the snapshot used by CM routing.
self.try_start_cm_ipc();
}
@@ -2930,33 +2809,19 @@ impl Connection {
}
return true;
} else if self.is_recent_session(false) {
if err_msg.is_empty() {
#[cfg(target_os = "linux")]
self.linux_headless_handle.wait_desktop_cm_ready().await;
if !self.send_logon_response_and_keep_alive().await {
return false;
}
self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), self.authorized);
} else {
self.send_login_error(err_msg).await;
if !self.send_logon_response_and_keep_alive().await {
return false;
}
self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), self.authorized);
} else if lr.password.is_empty() {
if err_msg.is_empty() {
#[cfg(not(any(target_os = "android", target_os = "ios")))]
if should_use_terminal_os_login_scope(self.terminal, &lr.os_login.username) {
if let Some(keep_alive) =
self.prepare_terminal_login_for_authorization().await
{
return keep_alive;
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
if should_use_terminal_os_login_scope(self.terminal, &lr.os_login.username) {
if let Some(keep_alive) = self.prepare_terminal_login_for_authorization().await
{
return keep_alive;
}
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;
}
self.try_start_cm(lr.my_id, lr.my_name, false);
} else {
let (failure, res) = self.check_failure(0).await;
if !res {
@@ -2965,28 +2830,15 @@ impl Connection {
if !self.validate_password(allow_logon_screen_password) {
self.update_failure_with_scope(failure, false, 0, FailureScope::Default);
self.check_update_temporary_password(false);
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,
)
self.send_login_error(crate::client::LOGIN_MSG_PASSWORD_WRONG)
.await;
}
self.try_start_cm(lr.my_id, lr.my_name, false);
} else {
self.update_failure_with_scope(failure, true, 0, FailureScope::Default);
if err_msg.is_empty() {
#[cfg(target_os = "linux")]
self.linux_headless_handle.wait_desktop_cm_ready().await;
if !self.send_logon_response_and_keep_alive().await {
return false;
}
self.try_start_cm(lr.my_id, lr.my_name, self.authorized);
} else {
self.send_login_error(err_msg).await;
if !self.send_logon_response_and_keep_alive().await {
return false;
}
self.try_start_cm(lr.my_id, lr.my_name, self.authorized);
}
}
} else if let Some(message::Union::Auth2fa(tfa)) = msg.union {
@@ -6139,13 +5991,10 @@ pub fn claim_pending_switch_sides_uuid(id: &str, uuid: &uuid::Uuid) -> bool {
#[cfg(not(any(target_os = "android", target_os = "ios")))]
// IPC bootstrap summary:
// - Resolve target CM socket (headless/non-headless, optional UID-scoped path on Linux).
// - Start CM when missing, then bridge bidirectional messages between this task and CM IPC.
async fn start_ipc(
mut rx_to_cm: mpsc::UnboundedReceiver<ipc::Data>,
tx_from_cm: mpsc::UnboundedSender<ipc::Data>,
mut _rx_desktop_ready: mpsc::Receiver<()>,
tx_stream_ready: mpsc::Sender<()>,
) -> ResultType<()> {
use hbb_common::anyhow::anyhow;
@@ -6155,139 +6004,51 @@ async fn start_ipc(
}
sleep(1.).await;
}
#[cfg(target_os = "linux")]
let headless_cm = crate::is_server()
&& crate::platform::is_headless_allowed()
&& linux_desktop_manager::is_headless();
#[cfg(not(target_os = "linux"))]
let headless_cm = false;
let mut stream = None;
if !headless_cm {
if let Ok(s) = crate::ipc::connect(1000, "_cm").await {
stream = Some(s);
}
if let Ok(s) = crate::ipc::connect(1000, "_cm").await {
stream = Some(s);
}
if stream.is_none() {
#[allow(unused_mut)]
#[allow(unused_assignments)]
let mut args = vec!["--cm"];
#[allow(unused_mut)]
#[cfg(target_os = "linux")]
let mut user = None;
// Cm run as user, wait until desktop session is ready.
#[cfg(target_os = "linux")]
if headless_cm {
let mut username = linux_desktop_manager::get_cached_username();
loop {
if !username.is_empty() {
break;
let args = vec!["--cm"];
let run_done;
if crate::platform::is_root() {
let mut res = Ok(None);
for _ in 0..10 {
#[cfg(not(any(target_os = "linux")))]
{
log::debug!("Start cm");
res = crate::platform::run_as_user(args.clone());
}
// `_rx_desktop_ready` is used as a wake-up signal from desktop/session state changes
// (for example wait_desktop_cm_ready paths). It is not itself a proof of CM readiness.
let wait_result = timeout(1_000, _rx_desktop_ready.recv()).await;
if matches!(wait_result, Ok(None)) {
return Err(anyhow!(
"Desktop-ready channel closed before a Linux session became available"
));
}
username = linux_desktop_manager::get_cached_username();
}
let uid = {
let username_for_cmd = username.clone();
let mut uid_cmd = hbb_common::tokio::process::Command::new("id");
// TODO:
// Keep current behavior for now to minimize change risk.
// If usernames starting with '-' are observed in the field, prefer:
// `id -u -- <username>` to avoid option-parsing ambiguity.
// Already verified that `id -u -- <username>` works as expected on macOS and Ubuntu 24.04.
uid_cmd.arg("-u").arg(&username_for_cmd).kill_on_drop(true);
let output = timeout(10_000, uid_cmd.output())
.await
.map_err(|_| anyhow!("Timed out querying uid for {}", username))?
.map_err(|e| anyhow!("Failed to run `id -u {}`: {}", username, e))?;
if !output.status.success() {
bail!("Failed to query uid for {}", username);
}
let output = String::from_utf8_lossy(&output.stdout);
let output = output.trim();
if output.parse::<u32>().is_err() {
bail!("Invalid uid {}", output);
}
output.to_string()
};
user = Some((uid, username));
args = vec!["--cm-no-ui"];
}
#[cfg(target_os = "linux")]
let cm_uid: Option<u32> = match &user {
Some((uid, _)) => Some(
uid.parse::<u32>()
.map_err(|_| anyhow!("Invalid uid {}", uid))?,
),
None => None,
};
#[cfg(target_os = "linux")]
if let Some(uid) = cm_uid {
if let Ok(s) = crate::ipc::connect_for_uid(1000, uid, "_cm").await {
stream = Some(s);
}
}
if stream.is_none() {
let run_done;
if crate::platform::is_root() {
let mut res = Ok(None);
for _ in 0..10 {
#[cfg(not(any(target_os = "linux")))]
{
log::debug!("Start cm");
res = crate::platform::run_as_user(args.clone());
}
#[cfg(target_os = "linux")]
{
log::debug!("Start cm");
res = crate::platform::run_as_user(
args.clone(),
user.clone(),
None::<(&str, &str)>,
);
}
if res.is_ok() {
break;
}
log::error!("Failed to run cm: {res:?}");
sleep(1.).await;
}
if let Some(task) = res? {
super::CHILD_PROCESS.lock().unwrap().push(task);
}
run_done = true;
} else {
run_done = false;
}
if !run_done {
log::debug!("Start cm");
super::CHILD_PROCESS
.lock()
.unwrap()
.push(crate::run_me(args)?);
}
for _ in 0..20 {
sleep(0.3).await;
#[cfg(target_os = "linux")]
{
if let Some(uid) = cm_uid {
if let Ok(s) = crate::ipc::connect_for_uid(1000, uid, "_cm").await {
stream = Some(s);
break;
}
continue;
}
log::debug!("Start cm");
res = crate::platform::run_as_user(args.clone(), None, None::<(&str, &str)>);
}
if let Ok(s) = crate::ipc::connect(1000, "_cm").await {
stream = Some(s);
if res.is_ok() {
break;
}
log::error!("Failed to run cm: {res:?}");
sleep(1.).await;
}
if let Some(task) = res? {
super::CHILD_PROCESS.lock().unwrap().push(task);
}
run_done = true;
} else {
run_done = false;
}
if !run_done {
log::debug!("Start cm");
super::CHILD_PROCESS
.lock()
.unwrap()
.push(crate::run_me(args)?);
}
for _ in 0..20 {
sleep(0.3).await;
if let Ok(s) = crate::ipc::connect(1000, "_cm").await {
stream = Some(s);
break;
}
}
}
@@ -6295,7 +6056,6 @@ async fn start_ipc(
bail!("Failed to connect to connection manager");
}
let _res = tx_stream_ready.send(()).await;
let mut stream = stream.ok_or(anyhow!("none stream"))?;
loop {
tokio::select! {
@@ -6609,84 +6369,6 @@ impl Drop for Connection {
}
}
// Login requests are unauthenticated here, so only one may reach loginctl/PAM at a time.
#[cfg(target_os = "linux")]
static LINUX_DESKTOP_START_IN_FLIGHT: std::sync::atomic::AtomicBool =
std::sync::atomic::AtomicBool::new(false);
#[cfg(target_os = "linux")]
struct LinuxDesktopStartGuard;
#[cfg(target_os = "linux")]
impl Drop for LinuxDesktopStartGuard {
fn drop(&mut self) {
LINUX_DESKTOP_START_IN_FLIGHT.store(false, Ordering::Release);
}
}
#[cfg(target_os = "linux")]
enum LinuxDesktopStartOutcome {
Finished(String),
Busy,
}
#[cfg(target_os = "linux")]
struct LinuxHeadlessHandle {
pub is_headless_allowed: bool,
pub wait_ipc_timeout: u64,
pub rx_cm_stream_ready: mpsc::Receiver<()>,
pub tx_desktop_ready: mpsc::Sender<()>,
}
#[cfg(target_os = "linux")]
impl LinuxHeadlessHandle {
pub fn new(rx_cm_stream_ready: mpsc::Receiver<()>, tx_desktop_ready: mpsc::Sender<()>) -> Self {
let is_headless_allowed = crate::is_server() && crate::platform::is_headless_allowed();
Self {
is_headless_allowed,
wait_ipc_timeout: 10_000,
rx_cm_stream_ready,
tx_desktop_ready,
}
}
pub async fn try_start_desktop(
&mut self,
os_login: Option<&OSLogin>,
) -> LinuxDesktopStartOutcome {
let Some((username, password)) =
linux_desktop_start_credentials(self.is_headless_allowed, os_login)
else {
return LinuxDesktopStartOutcome::Finished(String::new());
};
if LINUX_DESKTOP_START_IN_FLIGHT.swap(true, Ordering::AcqRel) {
return LinuxDesktopStartOutcome::Busy;
}
let guard = LinuxDesktopStartGuard;
let err_msg = match tokio::task::spawn_blocking(move || {
let _guard = guard;
linux_desktop_manager::try_start_desktop(&username, &password)
})
.await
{
Ok(err_msg) => err_msg,
Err(err) => {
log::error!("Linux desktop start task failed: {err}");
crate::client::LOGIN_MSG_DESKTOP_XSESSION_FAILED.to_owned()
}
};
LinuxDesktopStartOutcome::Finished(err_msg)
}
pub async fn wait_desktop_cm_ready(&mut self) {
// A value captured at construction can lag behind a seat0 transition.
if self.is_headless_allowed && linux_desktop_manager::is_headless() {
self.tx_desktop_ready.send(()).await.ok();
let _res = timeout(self.wait_ipc_timeout, self.rx_cm_stream_ready.recv()).await;
}
}
}
extern "C" fn connection_shutdown_hook() {
// https://stackoverflow.com/questions/35980148/why-does-an-atexit-handler-panic-when-it-accesses-stdout
// Please make sure there is no print in the call stack

View File

@@ -821,15 +821,14 @@ impl Drop for UinputRefreshGuard {
}
}
/// Never probes, never blocks: the form the ROUTING gates must use. Seconds of IPC inside
/// `wayland::clear()`, `is_inited()` or the display enumeration trips "deadline has elapsed".
/// Never probes or blocks. Use in hot paths such as `wayland::clear()`, `is_inited()`, and display
/// enumeration, where seconds of IPC would trip "deadline has elapsed".
pub(crate) fn is_available_cached() -> bool {
matches!(&*DRM_STATE.lock().unwrap(), ProbeState::Available(..))
}
/// The three honest answers the availability machinery can give. `Unsettled` — another probe in
/// flight, or a failure still below the disable threshold — is not a verdict, and the
/// login-screen headless decision must not read it as one.
/// A tri-state assessment of DRM capture availability.
/// `Unsettled` means a probe is in flight or failures have not reached the disable threshold.
#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) enum Availability {
Available,
@@ -843,9 +842,8 @@ pub(crate) enum Availability {
fn availability() -> Availability {
let (verdict, stale_no) = {
let st = DRM_STATE.lock().unwrap();
// A settled "no" STAYS the answer while an off-thread re-probe re-verifies it; going
// Unknown at expiry would reopen an Unsettled window every TTL on a helper-less box, and
// the login decision reads Unsettled as a possible greeter.
// Keep a settled "no" while an off-thread probe re-verifies it, avoiding a transient
// Unsettled result whenever the negative cache expires.
let stale_no =
matches!(&*st, ProbeState::Unavailable(since) if since.elapsed() >= NEGATIVE_TTL);
let verdict = match &*st {
@@ -878,10 +876,8 @@ fn availability() -> Availability {
probe_and_publish()
}
/// The non-blocking tri-state, for decisions on the LOGIN REQUEST path that must never wait: an
/// unauthenticated peer reaches that path, so a probe there would let it park a worker for the
/// probe deadline. Unknown kicks the probe off-thread and answers Unsettled, which the login
/// decision treats as a possibly servable greeter (no Xorg) until the state settles.
/// Non-blocking login-path assessment.
/// Unknown starts a probe off-thread; callers require `Available` before admitting a session.
pub(crate) fn availability_cached() -> Availability {
let (verdict, stale_no) = {
let st = DRM_STATE.lock().unwrap();

View File

@@ -272,30 +272,6 @@ function msgbox(type, title, content, link="", callback=null, height=180, width=
handler.send2fa(res.code, res.trust_this_device || false);
msgbox("connecting", "Connecting...", "Logging in...");
};
} else if (type == "session-login" || type == "session-re-login") {
callback = function (res) {
if (!res) {
view.close();
return;
}
handler.login(res.osusername, res.ospassword, "", false);
if (!is_port_forward) {
if (is_file_transfer) handler.msgbox("connecting", "Connecting...", "Logging in...");
else msgbox("connecting", "Connecting...", "Logging in...");
}
};
} else if (type.indexOf("session-login") >= 0) {
callback = function (res) {
if (!res) {
view.close();
return;
}
handler.login(res.osusername, res.ospassword, res.password, res.remember);
if (!is_port_forward) {
if (is_file_transfer) handler.msgbox("connecting", "Connecting...", "Logging in...");
else msgbox("connecting", "Connecting...", "Logging in...");
}
};
} else if (type.indexOf("insecure-connection") >= 0) {
callback = function (res) {
if (!res) {

View File

@@ -41,7 +41,7 @@ class MsgboxComponent: Reactor.Component {
}
function getIcon(color) {
if (this.type == "input-password" || this.type == "session-login" || this.type == "session-login-password" || this.type == "input-2fa") {
if (this.type == "input-password" || this.type == "input-2fa") {
return <svg viewBox="0 0 505 505"><circle cx="252.5" cy="252.5" r="252.5" fill={color}/><path d="M271.9 246.1c29.2 17.5 67.6 13.6 92.7-11.5 29.7-29.7 29.7-77.8 0-107.4s-77.8-29.7-107.4 0c-25.1 25.1-29 63.5-11.5 92.7L118.1 347.4l26.2 26.2 26.4 26.4 10.6-10.6-10.1-10.1 9.7-9.7 10.1 10.1 10.6-10.6-10.1-10 9.7-9.7 10.1 10.1 10.6-10.6-26.4-26.3 76.4-76.5z" fill="#fff"/><circle cx="337.4" cy="154.4" r="17.7" fill={color}/></svg>;
}
if (this.type == "connecting") {
@@ -50,7 +50,7 @@ class MsgboxComponent: Reactor.Component {
if (this.type == "success") {
return <svg viewBox="0 0 512 512"><circle cx="256" cy="256" r="256" fill={color} /><path fill="#fff" d="M235.472 392.08l-121.04-94.296 34.416-44.168 74.328 57.904 122.672-177.016 46.032 31.888z"/></svg>;
}
if (this.type.indexOf("error") >= 0 || this.type == "re-input-password" || this.type == "input-2fa" || this.type == "session-re-login" || this.type == "session-login-re-password") {
if (this.type.indexOf("error") >= 0 || this.type == "re-input-password" || this.type == "input-2fa") {
return <svg viewBox="0 0 512 512"><ellipse cx="256" cy="256" rx="256" ry="255.832" fill={color}/><g fill="#fff"><path d="M376.812 337.18l-39.592 39.593-201.998-201.999 39.592-39.592z"/><path d="M376.818 174.825L174.819 376.824l-39.592-39.592 201.999-201.999z"/></g></svg>;
}
return null;
@@ -74,37 +74,11 @@ class MsgboxComponent: Reactor.Component {
</div>;
}
function getInputUserPasswordContent() {
return <div .form>
<div>{translate("OS Username")}</div>
<div .username><input name='osusername' type='text' .outline-focus /></div>
<div>{translate("OS Password")}</div>
<PasswordComponent name='ospassword' />
<div></div>
</div>;
}
function getXsessionPasswordContent() {
return <div .form>
<div>{translate("OS Username")}</div>
<div .username><input name='osusername' type='text' .outline-focus /></div>
<div>{translate("OS Password")}</div>
<PasswordComponent name='ospassword' />
<div>{translate('Please enter your password')}</div>
<PasswordComponent />
<div><button|checkbox(remember) {ts}>{translate('Remember password')}</button></div>
</div>;
}
function getContent() {
if (this.type == "input-password") {
return this.getInputPasswordContent();
} else if (this.type == "input-2fa") {
return this.get2faContent();
} else if (this.type == "session-login") {
return this.getInputUserPasswordContent();
} else if (this.type == "session-login-password") {
return this.getXsessionPasswordContent();
} else if (this.type == "custom-os-password") {
var ts = this.autoLogin ? { checked: true } : {};
return <div .form>
@@ -116,13 +90,13 @@ class MsgboxComponent: Reactor.Component {
}
function getColor() {
if (this.type == "input-password" || this.type == "input-2fa" || this.type == "custom-os-password" || this.type == "session-login" || this.type == "session-login-password") {
if (this.type == "input-password" || this.type == "input-2fa" || this.type == "custom-os-password") {
return "#AD448E";
}
if (this.type == "success") {
return "#32bea6";
}
if (this.type.indexOf("error") >= 0 || this.type == "re-input-password" || this.type == "session-re-login" || this.type == "session-login-re-password") {
if (this.type.indexOf("error") >= 0 || this.type == "re-input-password") {
return "#e04f5f";
}
return "#2C8CFF";
@@ -242,16 +216,6 @@ class MsgboxComponent: Reactor.Component {
this.update();
return;
}
if (this.type == "session-re-login") {
this.type = "session-login";
this.update();
return;
}
if (this.type == "session-login-re-password") {
this.type = "session-login-password";
this.update();
return;
}
var values = this.getValues();
if (this.callback) {
var self = this;
@@ -352,21 +316,6 @@ class MsgboxComponent: Reactor.Component {
return;
}
}
if (this.type == "session-login") {
values.osusername = (values.osusername || "").trim();
values.ospassword = (values.ospassword || "").trim();
if (!values.osusername || !values.ospassword) {
return;
}
}
if (this.type == "session-login-password") {
values.password = (values.password || "").trim();
values.osusername = (values.osusername || "").trim();
values.ospassword = (values.ospassword || "").trim();
if (!values.osusername || !values.ospassword || !values.password) {
return;
}
}
if (this.type == "multiple-sessions-nocancel") {
values.sid = (this.$$(select))[0].value;
}