mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
119 lines
3.3 KiB
Rust
119 lines
3.3 KiB
Rust
use std::{env, fmt::Display, path::Path};
|
|
|
|
use anyhow::Result;
|
|
use ratatui::layout::Rect;
|
|
use tracing::warn;
|
|
use yazi_shared::env_exists;
|
|
|
|
use crate::{Brand, Emulator, SHOWN, TMUX, WSL, drivers};
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
|
pub enum Adapter {
|
|
Kgp,
|
|
KgpOld,
|
|
Iip,
|
|
Sixel,
|
|
|
|
// Supported by Überzug++
|
|
X11,
|
|
Wayland,
|
|
Chafa,
|
|
}
|
|
|
|
impl Display for Adapter {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::Kgp => write!(f, "kgp"),
|
|
Self::KgpOld => write!(f, "kgp-old"),
|
|
Self::Iip => write!(f, "iip"),
|
|
Self::Sixel => write!(f, "sixel"),
|
|
Self::X11 => write!(f, "x11"),
|
|
Self::Wayland => write!(f, "wayland"),
|
|
Self::Chafa => write!(f, "chafa"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Adapter {
|
|
pub async fn image_show(self, path: &Path, max: Rect) -> Result<Rect> {
|
|
if max.is_empty() {
|
|
return Ok(Rect::default());
|
|
}
|
|
|
|
match self {
|
|
Self::Kgp => drivers::Kgp::image_show(path, max).await,
|
|
Self::KgpOld => drivers::KgpOld::image_show(path, max).await,
|
|
Self::Iip => drivers::Iip::image_show(path, max).await,
|
|
Self::Sixel => drivers::Sixel::image_show(path, max).await,
|
|
Self::X11 | Self::Wayland => drivers::Ueberzug::image_show(path, max).await,
|
|
Self::Chafa => drivers::Chafa::image_show(path, max).await,
|
|
}
|
|
}
|
|
|
|
pub fn image_hide(self) -> Result<()> {
|
|
if let Some(area) = SHOWN.replace(None) { self.image_erase(area) } else { Ok(()) }
|
|
}
|
|
|
|
pub fn image_erase(self, area: Rect) -> Result<()> {
|
|
match self {
|
|
Self::Kgp => drivers::Kgp::image_erase(area),
|
|
Self::KgpOld => drivers::KgpOld::image_erase(area),
|
|
Self::Iip => drivers::Iip::image_erase(area),
|
|
Self::Sixel => drivers::Sixel::image_erase(area),
|
|
Self::X11 | Self::Wayland => drivers::Ueberzug::image_erase(area),
|
|
Self::Chafa => drivers::Chafa::image_erase(area),
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn shown_load(self) -> Option<Rect> { SHOWN.get() }
|
|
|
|
#[inline]
|
|
pub(super) fn shown_store(area: Rect) { SHOWN.set(Some(area)); }
|
|
|
|
pub(super) fn start(self) { drivers::Ueberzug::start(self); }
|
|
|
|
#[inline]
|
|
pub(super) fn needs_ueberzug(self) -> bool {
|
|
!matches!(self, Self::Kgp | Self::KgpOld | Self::Iip | Self::Sixel)
|
|
}
|
|
}
|
|
|
|
impl Adapter {
|
|
pub fn matches(emulator: Emulator) -> Self {
|
|
if emulator.kind.is_left_and(|&b| b == Brand::Microsoft) {
|
|
return Self::Sixel;
|
|
} else if WSL.get() && emulator.kind.is_left_and(|&b| b == Brand::WezTerm) {
|
|
return Self::KgpOld;
|
|
}
|
|
|
|
let mut protocols = emulator.adapters().to_owned();
|
|
#[cfg(windows)]
|
|
protocols.retain(|p| *p == Self::Iip);
|
|
if env_exists("ZELLIJ_SESSION_NAME") {
|
|
protocols.retain(|p| *p == Self::Sixel);
|
|
} else if TMUX.get() {
|
|
protocols.retain(|p| *p != Self::KgpOld);
|
|
}
|
|
if let Some(p) = protocols.first() {
|
|
return *p;
|
|
}
|
|
|
|
let supported_compositor = drivers::Ueberzug::supported_compositor();
|
|
match env::var("XDG_SESSION_TYPE").unwrap_or_default().as_str() {
|
|
"x11" => return Self::X11,
|
|
"wayland" if supported_compositor => return Self::Wayland,
|
|
"wayland" if !supported_compositor => return Self::Chafa,
|
|
_ => warn!("[Adapter] Could not identify XDG_SESSION_TYPE"),
|
|
}
|
|
if env_exists("WAYLAND_DISPLAY") {
|
|
return if supported_compositor { Self::Wayland } else { Self::Chafa };
|
|
}
|
|
if env_exists("DISPLAY") {
|
|
return Self::X11;
|
|
}
|
|
|
|
warn!("[Adapter] Falling back to chafa");
|
|
Self::Chafa
|
|
}
|
|
}
|