mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
fix: fallback to PollWatcher on WSL (#1574)
This commit is contained in:
parent
69e7c8ff0d
commit
a0a2331b3b
5 changed files with 42 additions and 23 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<bool> = RoCell::new();
|
||||
|
||||
// Image state
|
||||
static SHOWN: RoCell<arc_swap::ArcSwapOption<ratatui::layout::Rect>> = 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());
|
||||
|
|
|
|||
|
|
@ -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"))?;
|
||||
|
|
|
|||
|
|
@ -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<notify_fork::Event, notify_fork::Error>| {
|
||||
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<notify_fork::Event, notify_fork::Error>| {
|
||||
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<HashSet<Url>>, mut watcher: RecommendedWatcher) {
|
||||
async fn fan_in(mut rx: watch::Receiver<HashSet<Url>>, 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());
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue