mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: fallback to CSI 16 t for certain terminals that do not support TIOCGWINSZ (#2004)
This commit is contained in:
parent
11cf555b47
commit
9d3c0c72fe
5 changed files with 65 additions and 38 deletions
2
.github/workflows/draft.yml
vendored
2
.github/workflows/draft.yml
vendored
|
|
@ -4,8 +4,6 @@ on:
|
|||
push:
|
||||
branches: [main]
|
||||
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
|
||||
schedule:
|
||||
- cron: "0 */6 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
|
|
|
|||
40
Cargo.lock
generated
40
Cargo.lock
generated
|
|
@ -117,9 +117,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.93"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
|
||||
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
|
|
@ -366,9 +366,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.21"
|
||||
version = "4.5.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
|
||||
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -376,9 +376,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.21"
|
||||
version = "4.5.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
|
||||
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -429,9 +429,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.3"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
|
|
@ -777,9 +777,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.6"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb"
|
||||
checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
|
@ -2562,9 +2562,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.36"
|
||||
version = "0.3.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
||||
checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
|
|
@ -2585,9 +2585,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
|||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
|
||||
checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
|
|
@ -2605,9 +2605,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.41.1"
|
||||
version = "1.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33"
|
||||
checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
|
|
@ -2634,9 +2634,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.16"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1"
|
||||
checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
|
|
@ -2645,9 +2645,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.12"
|
||||
version = "0.7.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"
|
||||
checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
|
|
|
|||
10
Cargo.toml
10
Cargo.toml
|
|
@ -11,10 +11,10 @@ strip = true
|
|||
|
||||
[workspace.dependencies]
|
||||
ansi-to-tui = "7.0.0"
|
||||
anyhow = "1.0.93"
|
||||
anyhow = "1.0.94"
|
||||
base64 = "0.22.1"
|
||||
bitflags = "2.6.0"
|
||||
clap = { version = "4.5.21", features = [ "derive" ] }
|
||||
clap = { version = "4.5.23", features = [ "derive" ] }
|
||||
crossterm = { version = "0.28.1", features = [ "event-stream" ] }
|
||||
dirs = "5.0.1"
|
||||
futures = "0.3.31"
|
||||
|
|
@ -29,9 +29,9 @@ scopeguard = "1.2.0"
|
|||
serde = { version = "1.0.215", features = [ "derive" ] }
|
||||
serde_json = "1.0.133"
|
||||
shell-words = "1.1.0"
|
||||
tokio = { version = "1.41.1", features = [ "full" ] }
|
||||
tokio-stream = "0.1.16"
|
||||
tokio-util = "0.7.12"
|
||||
tokio = { version = "1.42.0", features = [ "full" ] }
|
||||
tokio-stream = "0.1.17"
|
||||
tokio-util = "0.7.13"
|
||||
tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] }
|
||||
unicode-width = "0.2.0"
|
||||
uzers = "0.12.1"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ use std::mem;
|
|||
|
||||
use crossterm::terminal::WindowSize;
|
||||
|
||||
use crate::EMULATOR;
|
||||
|
||||
pub struct Dimension;
|
||||
|
||||
impl Dimension {
|
||||
|
|
@ -27,9 +29,10 @@ impl Dimension {
|
|||
#[inline]
|
||||
pub fn ratio() -> Option<(f64, f64)> {
|
||||
let s = Self::available();
|
||||
if s.width == 0 || s.height == 0 {
|
||||
return None;
|
||||
}
|
||||
Some((f64::from(s.width) / f64::from(s.columns), f64::from(s.height) / f64::from(s.rows)))
|
||||
Some(if s.width == 0 || s.height == 0 {
|
||||
(EMULATOR.cell_size?.0 as f64, EMULATOR.cell_size?.1 as f64)
|
||||
} else {
|
||||
(f64::from(s.width) / f64::from(s.columns), f64::from(s.height) / f64::from(s.rows))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,18 +11,21 @@ use crate::{Adapter, Brand, Mux, TMUX, Unknown};
|
|||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Emulator {
|
||||
pub kind: Either<Brand, Unknown>,
|
||||
pub light: bool,
|
||||
pub kind: Either<Brand, Unknown>,
|
||||
pub light: bool,
|
||||
pub cell_size: Option<(u16, u16)>,
|
||||
}
|
||||
|
||||
impl Default for Emulator {
|
||||
fn default() -> Self { Self { kind: Either::Right(Unknown::default()), light: false } }
|
||||
fn default() -> Self {
|
||||
Self { kind: Either::Right(Unknown::default()), light: false, cell_size: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl Emulator {
|
||||
pub fn detect() -> Self {
|
||||
if let Some(brand) = Brand::from_env() {
|
||||
Self { kind: Either::Left(brand), light: Self::detect_base().unwrap_or_default().light }
|
||||
Self { kind: Either::Left(brand), ..Self::detect_base().unwrap_or_default() }
|
||||
} else {
|
||||
Self::detect_full().unwrap_or_default()
|
||||
}
|
||||
|
|
@ -37,6 +40,7 @@ impl Emulator {
|
|||
SavePosition,
|
||||
Print(Mux::csi("\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\")), // Detect KGP
|
||||
Print(Mux::csi("\x1b[>q")), // Request terminal version
|
||||
Print("\x1b[16t"), // Request cell size
|
||||
Print("\x1b]11;?\x07"), // Request background color
|
||||
Print(Mux::csi("\x1b[0c")), // Request device attributes
|
||||
RestorePosition
|
||||
|
|
@ -52,7 +56,11 @@ impl Emulator {
|
|||
})
|
||||
};
|
||||
|
||||
Ok(Self { kind, light: Self::light_bg(&resp).unwrap_or_default() })
|
||||
Ok(Self {
|
||||
kind,
|
||||
light: Self::light_bg(&resp).unwrap_or_default(),
|
||||
cell_size: Self::cell_size(&resp),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn adapters(self) -> &'static [Adapter] {
|
||||
|
|
@ -117,7 +125,7 @@ impl Emulator {
|
|||
match timeout(Duration::from_secs(10), read).await {
|
||||
Err(e) => error!("read_until_da1 timed out: {buf:?}, error: {e:?}"),
|
||||
Ok(Err(e)) => error!("read_until_da1 failed: {buf:?}, error: {e:?}"),
|
||||
Ok(Ok(())) => {}
|
||||
Ok(Ok(())) => debug!("read_until_da1: {buf:?}"),
|
||||
}
|
||||
String::from_utf8_lossy(&buf).into_owned()
|
||||
}
|
||||
|
|
@ -128,12 +136,30 @@ impl Emulator {
|
|||
|
||||
execute!(
|
||||
LineWriter::new(stderr()),
|
||||
Print("\x1b[16t"), // Request cell size
|
||||
Print("\x1b]11;?\x07"), // Request background color
|
||||
Print(Mux::csi("\x1b[0c")), // Request device attributes
|
||||
)?;
|
||||
|
||||
let resp = futures::executor::block_on(Self::read_until_da1());
|
||||
Ok(Self { light: Self::light_bg(&resp).unwrap_or_default(), ..Default::default() })
|
||||
Ok(Self {
|
||||
light: Self::light_bg(&resp).unwrap_or_default(),
|
||||
cell_size: Self::cell_size(&resp),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
fn cell_size(resp: &str) -> Option<(u16, u16)> {
|
||||
let b = resp.split_at(resp.find("\x1b[6;")? + 4).1.as_bytes();
|
||||
|
||||
let h: Vec<_> = b.iter().copied().take_while(|&c| c.is_ascii_digit()).collect();
|
||||
b.get(h.len()).filter(|&&c| c == b';')?;
|
||||
|
||||
let w: Vec<_> = b[h.len() + 1..].iter().copied().take_while(|&c| c.is_ascii_digit()).collect();
|
||||
b.get(h.len() + 1 + w.len()).filter(|&&c| c == b't')?;
|
||||
|
||||
let (w, h) = unsafe { (String::from_utf8_unchecked(w), String::from_utf8_unchecked(h)) };
|
||||
Some((w.parse().ok()?, h.parse().ok()?))
|
||||
}
|
||||
|
||||
fn light_bg(resp: &str) -> Result<bool> {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue