fix: linux, env TERM (#12325)

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou
2025-07-17 08:46:32 +08:00
committed by GitHub
parent e711f73451
commit 475bef63d7
3 changed files with 156 additions and 8 deletions

81
Cargo.lock generated
View File

@@ -1790,6 +1790,15 @@ dependencies = [
"dirs-sys 0.3.7",
]
[[package]]
name = "dirs"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
dependencies = [
"dirs-sys 0.3.7",
]
[[package]]
name = "dirs"
version = "5.0.1"
@@ -5090,7 +5099,16 @@ version = "0.7.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
dependencies = [
"phf_shared",
"phf_shared 0.7.24",
]
[[package]]
name = "phf"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
dependencies = [
"phf_shared 0.11.3",
]
[[package]]
@@ -5099,8 +5117,18 @@ version = "0.7.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
dependencies = [
"phf_generator",
"phf_shared",
"phf_generator 0.7.24",
"phf_shared 0.7.24",
]
[[package]]
name = "phf_codegen"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
dependencies = [
"phf_generator 0.11.3",
"phf_shared 0.11.3",
]
[[package]]
@@ -5109,17 +5137,36 @@ version = "0.7.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
dependencies = [
"phf_shared",
"phf_shared 0.7.24",
"rand 0.6.5",
]
[[package]]
name = "phf_generator"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
dependencies = [
"phf_shared 0.11.3",
"rand 0.8.5",
]
[[package]]
name = "phf_shared"
version = "0.7.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
dependencies = [
"siphasher",
"siphasher 0.2.3",
]
[[package]]
name = "phf_shared"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
dependencies = [
"siphasher 1.0.1",
]
[[package]]
@@ -6146,6 +6193,7 @@ dependencies = [
"system_shutdown",
"tao",
"tauri-winrt-notification",
"terminfo",
"termios 0.3.3",
"totp-rs",
"tray-icon",
@@ -6674,6 +6722,12 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
[[package]]
name = "siphasher"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]]
name = "slab"
version = "0.4.9"
@@ -7033,8 +7087,8 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "013d134ae4a25ee744ad6129db589018558f620ddfa44043887cdd45fa08e75c"
dependencies = [
"phf",
"phf_codegen",
"phf 0.7.24",
"phf_codegen 0.7.24",
"serde_json 0.9.10",
]
@@ -7069,6 +7123,19 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "terminfo"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "666cd3a6681775d22b200409aad3b089c5b99fb11ecdd8a204d9d62f8148498f"
dependencies = [
"dirs 4.0.0",
"fnv",
"nom",
"phf 0.11.3",
"phf_codegen 0.11.3",
]
[[package]]
name = "termios"
version = "0.2.2"

View File

@@ -180,6 +180,7 @@ once_cell = {version = "1.18", optional = true}
nix = { version = "0.29", features = ["term", "process"]}
gtk = "0.18"
termios = "0.3"
terminfo = "0.8"
[target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.13"

View File

@@ -10,7 +10,6 @@ use hbb_common::{
libc::{c_char, c_int, c_long, c_void},
log,
message_proto::{DisplayInfo, Resolution},
platform::linux::{CMD_PS, CMD_SH},
regex::{Captures, Regex},
};
use std::{
@@ -25,6 +24,7 @@ use std::{
},
time::{Duration, Instant},
};
use terminfo::{capability as cap, Database};
use users::{get_user_by_name, os::unix::UserExt};
use wallpaper;
@@ -33,8 +33,20 @@ type Xdo = *const c_void;
pub const PA_SAMPLE_RATE: u32 = 48000;
static mut UNMODIFIED: bool = true;
const INVALID_TERM_VALUES: [&str; 3] = ["", "unknown", "dumb"];
const SHELL_PROCESSES: [&str; 4] = ["bash", "zsh", "fish", "sh"];
lazy_static::lazy_static! {
pub static ref IS_X11: bool = hbb_common::platform::linux::is_x11_or_headless();
static ref DATABASE_XTERM_256COLOR: Option<Database> = {
match Database::from_name("xterm-256color") {
Ok(database) => Some(database),
Err(err) => {
log::error!("Failed to initialize xterm-256color database: {}", err);
None
}
}
};
}
thread_local! {
@@ -256,6 +268,70 @@ fn start_uinput_service() {
});
}
/// Suggests the best terminal type based on the environment.
///
/// The function prioritizes terminal types in the following order:
/// 1. `screen-256color`: Preferred when running inside `tmux` or `screen` sessions,
/// as these multiplexers often support advanced terminal features.
/// 2. `xterm-256color`: Selected if the terminal supports 256 colors, which is
/// suitable for modern terminal applications.
/// 3. `xterm`: Used as a fallback for basic terminal compatibility.
///
/// Terminals like `linux` and `vt100` are excluded because they lack support for
/// modern features required by many applications.
fn suggest_best_term() -> String {
if is_running_in_tmux() || is_running_in_screen() {
return "screen-256color".to_string();
}
if term_supports_256_colors("xterm-256color") {
return "xterm-256color".to_string();
}
"xterm".to_string()
}
fn is_running_in_tmux() -> bool {
std::env::var("TMUX").is_ok()
}
fn is_running_in_screen() -> bool {
std::env::var("STY").is_ok()
}
fn supports_256_colors(db: &Database) -> bool {
db.get::<cap::MaxColors>().map_or(false, |n| n.0 >= 256)
}
fn term_supports_256_colors(term: &str) -> bool {
match term {
"xterm-256color" => DATABASE_XTERM_256COLOR
.as_ref()
.map_or(false, |db| supports_256_colors(db)),
_ => Database::from_name(term).map_or(false, |db| supports_256_colors(&db)),
}
}
fn get_cur_term(uid: &str) -> Option<String> {
if uid.is_empty() {
return None;
}
if let Ok(term) = std::env::var("TERM") {
if !INVALID_TERM_VALUES.contains(&term.as_str()) {
return Some(term);
}
}
for proc in SHELL_PROCESSES {
// Construct a regex pattern to match either the process name followed by '$' or 'bin/' followed by the process name.
let term = get_env("TERM", uid, &format!("{}$|bin/{}", proc, proc));
if !INVALID_TERM_VALUES.contains(&term.as_str()) {
return Some(term);
}
}
None
}
#[inline]
fn try_start_server_(desktop: Option<&Desktop>) -> ResultType<Option<Child>> {
match desktop {
@@ -273,6 +349,10 @@ fn try_start_server_(desktop: Option<&Desktop>) -> ResultType<Option<Child>> {
if !desktop.home.is_empty() {
envs.push(("HOME", desktop.home.clone()));
}
envs.push((
"TERM",
get_cur_term(&desktop.uid).unwrap_or_else(|| suggest_best_term()),
));
run_as_user(
vec!["--server"],
Some((desktop.uid.clone(), desktop.username.clone())),