Skip to content

Commit a0a2331

Browse files
authored
fix: fallback to PollWatcher on WSL (#1574)
1 parent 69e7c8f commit a0a2331

File tree

5 files changed

+42
-23
lines changed

5 files changed

+42
-23
lines changed

yazi-adapter/src/adapter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use tracing::warn;
66
use yazi_shared::env_exists;
77

88
use super::{Iterm2, Kitty, KittyOld};
9-
use crate::{Chafa, Emulator, Sixel, Ueberzug, SHOWN, TMUX};
9+
use crate::{Chafa, Emulator, Sixel, Ueberzug, SHOWN, TMUX, WSL};
1010

1111
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
1212
pub enum Adapter {
@@ -108,7 +108,7 @@ impl Adapter {
108108
if env_exists("DISPLAY") {
109109
return Self::X11;
110110
}
111-
if std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok() {
111+
if *WSL {
112112
return Self::KittyOld;
113113
}
114114

yazi-adapter/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use kitty::*;
2020
use kitty_old::*;
2121
use sixel::*;
2222
use ueberzug::*;
23-
use yazi_shared::{env_exists, RoCell};
23+
use yazi_shared::{env_exists, in_wsl, RoCell};
2424

2525
pub use crate::image::*;
2626

@@ -32,10 +32,14 @@ static ESCAPE: RoCell<&'static str> = RoCell::new();
3232
static START: RoCell<&'static str> = RoCell::new();
3333
static CLOSE: RoCell<&'static str> = RoCell::new();
3434

35+
// WSL support
36+
pub static WSL: RoCell<bool> = RoCell::new();
37+
3538
// Image state
3639
static SHOWN: RoCell<arc_swap::ArcSwapOption<ratatui::layout::Rect>> = RoCell::new();
3740

3841
pub fn init() {
42+
// Tmux support
3943
TMUX.init(env_exists("TMUX") && env_exists("TMUX_PANE"));
4044
ESCAPE.init(if *TMUX { "\x1b\x1b" } else { "\x1b" });
4145
START.init(if *TMUX { "\x1bPtmux;\x1b\x1b" } else { "\x1b" });
@@ -50,6 +54,10 @@ pub fn init() {
5054
.status();
5155
}
5256

57+
// WSL support
58+
WSL.init(in_wsl());
59+
60+
// Image state
5361
SHOWN.with(<_>::default);
5462

5563
ADAPTOR.init(Adapter::matches());

yazi-boot/src/actions/debug.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,7 @@ impl Actions {
3939
writeln!(s, " shared.in_ssh_connection: {:?}", yazi_shared::in_ssh_connection())?;
4040

4141
writeln!(s, "\nWSL")?;
42-
writeln!(
43-
s,
44-
" /proc/sys/fs/binfmt_misc/WSLInterop: {:?}",
45-
std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok()
46-
)?;
42+
writeln!(s, " WSL: {:?}", *yazi_adapter::WSL)?;
4743

4844
writeln!(s, "\nVariables")?;
4945
writeln!(s, " SHELL : {:?}", env::var_os("SHELL"))?;

yazi-core/src/manager/watcher.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{collections::{HashMap, HashSet}, time::Duration};
22

33
use anyhow::Result;
4-
use notify_fork::{RecommendedWatcher, RecursiveMode, Watcher as _Watcher};
4+
use notify_fork::{PollWatcher, RecommendedWatcher, RecursiveMode, Watcher as _Watcher};
55
use parking_lot::RwLock;
66
use tokio::{fs, pin, sync::{mpsc::{self, UnboundedReceiver}, watch}};
77
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
@@ -27,20 +27,23 @@ impl Watcher {
2727
let (out_tx, out_rx) = mpsc::unbounded_channel();
2828

2929
let out_tx_ = out_tx.clone();
30-
let watcher = RecommendedWatcher::new(
31-
move |res: Result<notify_fork::Event, notify_fork::Error>| {
32-
let Ok(event) = res else { return };
33-
if event.kind.is_access() {
34-
return;
35-
}
36-
for path in event.paths {
37-
out_tx_.send(Url::from(path)).ok();
38-
}
39-
},
40-
Default::default(),
41-
);
30+
let handler = move |res: Result<notify_fork::Event, notify_fork::Error>| {
31+
let Ok(event) = res else { return };
32+
if event.kind.is_access() {
33+
return;
34+
}
35+
for path in event.paths {
36+
out_tx_.send(Url::from(path)).ok();
37+
}
38+
};
39+
40+
let config = notify_fork::Config::default().with_poll_interval(Duration::from_millis(500));
41+
if *yazi_adapter::WSL {
42+
tokio::spawn(Self::fan_in(in_rx, PollWatcher::new(handler, config).unwrap()));
43+
} else {
44+
tokio::spawn(Self::fan_in(in_rx, RecommendedWatcher::new(handler, config).unwrap()));
45+
}
4246

43-
tokio::spawn(Self::fan_in(in_rx, watcher.unwrap()));
4447
tokio::spawn(Self::fan_out(out_rx));
4548
Self { in_tx, out_tx }
4649
}
@@ -76,7 +79,7 @@ impl Watcher {
7679
});
7780
}
7881

79-
async fn fan_in(mut rx: watch::Receiver<HashSet<Url>>, mut watcher: RecommendedWatcher) {
82+
async fn fan_in(mut rx: watch::Receiver<HashSet<Url>>, mut watcher: impl notify_fork::Watcher) {
8083
loop {
8184
let (mut to_unwatch, mut to_watch): (HashSet<_>, HashSet<_>) = {
8285
let (new, old) = (&*rx.borrow_and_update(), &*WATCHED.read());

yazi-shared/src/env.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
#[inline]
22
pub fn env_exists(name: &str) -> bool { std::env::var_os(name).is_some_and(|s| !s.is_empty()) }
33

4+
#[inline]
5+
pub fn in_wsl() -> bool {
6+
#[cfg(target_os = "linux")]
7+
{
8+
std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok()
9+
}
10+
#[cfg(not(target_os = "linux"))]
11+
{
12+
false
13+
}
14+
}
15+
416
#[inline]
517
pub fn in_ssh_connection() -> bool {
618
env_exists("SSH_CLIENT") || env_exists("SSH_TTY") || env_exists("SSH_CONNECTION")

0 commit comments

Comments
 (0)