mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
105 lines
2.9 KiB
Rust
105 lines
2.9 KiB
Rust
use std::{env, path::PathBuf};
|
|
|
|
use anyhow::Result;
|
|
use ratatui::layout::Rect;
|
|
use strum::{Display, IntoStaticStr};
|
|
use tracing::warn;
|
|
use yazi_emulator::{Emulator, TMUX};
|
|
use yazi_shared::env_exists;
|
|
|
|
use crate::{Adapters, SHOWN, drivers};
|
|
|
|
#[derive(Clone, Copy, Debug, Display, Eq, IntoStaticStr, PartialEq)]
|
|
#[strum(serialize_all = "kebab-case")]
|
|
pub enum Adapter {
|
|
Kgp,
|
|
KgpOld,
|
|
Iip,
|
|
Sixel,
|
|
|
|
// Supported by Überzug++
|
|
X11,
|
|
Wayland,
|
|
Chafa,
|
|
}
|
|
|
|
impl Adapter {
|
|
pub async fn image_show<P>(self, path: P, max: Rect) -> Result<Rect>
|
|
where
|
|
P: Into<PathBuf>,
|
|
{
|
|
if max.is_empty() {
|
|
return Ok(Rect::default());
|
|
}
|
|
|
|
let path = path.into();
|
|
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 {
|
|
let mut adapters: Adapters = emulator.into();
|
|
if env_exists("ZELLIJ_SESSION_NAME") {
|
|
adapters.retain(|p| *p == Self::Sixel);
|
|
} else if TMUX.get() {
|
|
adapters.retain(|p| *p != Self::KgpOld);
|
|
}
|
|
if let Some(p) = adapters.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 };
|
|
}
|
|
match env::var("DISPLAY").unwrap_or_default().as_str() {
|
|
s if !s.is_empty() && !s.contains("/org.xquartz") => return Self::X11,
|
|
_ => {}
|
|
}
|
|
|
|
warn!("[Adapter] Falling back to chafa");
|
|
Self::Chafa
|
|
}
|
|
}
|