diff --git a/yazi-adapter/src/adapter.rs b/yazi-adapter/src/adapter.rs index e77d72a4..4f5234cb 100644 --- a/yazi-adapter/src/adapter.rs +++ b/yazi-adapter/src/adapter.rs @@ -6,7 +6,7 @@ use tracing::warn; use yazi_shared::env_exists; use super::{Iterm2, Kitty, KittyOld}; -use crate::{Chafa, Emulator, Sixel, Ueberzug, SHOWN, TMUX}; +use crate::{Chafa, Emulator, Sixel, Ueberzug, SHOWN, TMUX, WSL}; #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum Adapter { @@ -108,7 +108,7 @@ impl Adapter { if env_exists("DISPLAY") { return Self::X11; } - if std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok() { + if *WSL { return Self::KittyOld; } diff --git a/yazi-adapter/src/lib.rs b/yazi-adapter/src/lib.rs index 09f07985..a5132314 100644 --- a/yazi-adapter/src/lib.rs +++ b/yazi-adapter/src/lib.rs @@ -20,7 +20,7 @@ use kitty::*; use kitty_old::*; use sixel::*; use ueberzug::*; -use yazi_shared::{env_exists, RoCell}; +use yazi_shared::{env_exists, in_wsl, RoCell}; pub use crate::image::*; @@ -32,10 +32,14 @@ static ESCAPE: RoCell<&'static str> = RoCell::new(); static START: RoCell<&'static str> = RoCell::new(); static CLOSE: RoCell<&'static str> = RoCell::new(); +// WSL support +pub static WSL: RoCell = RoCell::new(); + // Image state static SHOWN: RoCell> = RoCell::new(); pub fn init() { + // Tmux support TMUX.init(env_exists("TMUX") && env_exists("TMUX_PANE")); ESCAPE.init(if *TMUX { "\x1b\x1b" } else { "\x1b" }); START.init(if *TMUX { "\x1bPtmux;\x1b\x1b" } else { "\x1b" }); @@ -50,6 +54,10 @@ pub fn init() { .status(); } + // WSL support + WSL.init(in_wsl()); + + // Image state SHOWN.with(<_>::default); ADAPTOR.init(Adapter::matches()); diff --git a/yazi-boot/src/actions/debug.rs b/yazi-boot/src/actions/debug.rs index 53b9faa7..25ca2391 100644 --- a/yazi-boot/src/actions/debug.rs +++ b/yazi-boot/src/actions/debug.rs @@ -39,11 +39,7 @@ impl Actions { writeln!(s, " shared.in_ssh_connection: {:?}", yazi_shared::in_ssh_connection())?; writeln!(s, "\nWSL")?; - writeln!( - s, - " /proc/sys/fs/binfmt_misc/WSLInterop: {:?}", - std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok() - )?; + writeln!(s, " WSL: {:?}", *yazi_adapter::WSL)?; writeln!(s, "\nVariables")?; writeln!(s, " SHELL : {:?}", env::var_os("SHELL"))?; diff --git a/yazi-core/src/manager/watcher.rs b/yazi-core/src/manager/watcher.rs index b49d0b2f..b8a86d86 100644 --- a/yazi-core/src/manager/watcher.rs +++ b/yazi-core/src/manager/watcher.rs @@ -1,7 +1,7 @@ use std::{collections::{HashMap, HashSet}, time::Duration}; use anyhow::Result; -use notify_fork::{RecommendedWatcher, RecursiveMode, Watcher as _Watcher}; +use notify_fork::{PollWatcher, RecommendedWatcher, RecursiveMode, Watcher as _Watcher}; use parking_lot::RwLock; use tokio::{fs, pin, sync::{mpsc::{self, UnboundedReceiver}, watch}}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; @@ -27,20 +27,23 @@ impl Watcher { let (out_tx, out_rx) = mpsc::unbounded_channel(); let out_tx_ = out_tx.clone(); - let watcher = RecommendedWatcher::new( - move |res: Result| { - let Ok(event) = res else { return }; - if event.kind.is_access() { - return; - } - for path in event.paths { - out_tx_.send(Url::from(path)).ok(); - } - }, - Default::default(), - ); + let handler = move |res: Result| { + let Ok(event) = res else { return }; + if event.kind.is_access() { + return; + } + for path in event.paths { + out_tx_.send(Url::from(path)).ok(); + } + }; + + let config = notify_fork::Config::default().with_poll_interval(Duration::from_millis(500)); + if *yazi_adapter::WSL { + tokio::spawn(Self::fan_in(in_rx, PollWatcher::new(handler, config).unwrap())); + } else { + tokio::spawn(Self::fan_in(in_rx, RecommendedWatcher::new(handler, config).unwrap())); + } - tokio::spawn(Self::fan_in(in_rx, watcher.unwrap())); tokio::spawn(Self::fan_out(out_rx)); Self { in_tx, out_tx } } @@ -76,7 +79,7 @@ impl Watcher { }); } - async fn fan_in(mut rx: watch::Receiver>, mut watcher: RecommendedWatcher) { + async fn fan_in(mut rx: watch::Receiver>, mut watcher: impl notify_fork::Watcher) { loop { let (mut to_unwatch, mut to_watch): (HashSet<_>, HashSet<_>) = { let (new, old) = (&*rx.borrow_and_update(), &*WATCHED.read()); diff --git a/yazi-shared/src/env.rs b/yazi-shared/src/env.rs index 430004a5..29e2c6e2 100644 --- a/yazi-shared/src/env.rs +++ b/yazi-shared/src/env.rs @@ -1,6 +1,18 @@ #[inline] pub fn env_exists(name: &str) -> bool { std::env::var_os(name).is_some_and(|s| !s.is_empty()) } +#[inline] +pub fn in_wsl() -> bool { + #[cfg(target_os = "linux")] + { + std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok() + } + #[cfg(not(target_os = "linux"))] + { + false + } +} + #[inline] pub fn in_ssh_connection() -> bool { env_exists("SSH_CLIENT") || env_exists("SSH_TTY") || env_exists("SSH_CONNECTION")