windows: Fix fs watch when file doesn't exist or is a symlink (#22660)

Closes #22659

More context can be found in attached issue.

This is specific to Windows:

1. Add parent directory watching for fs watch when the file doesn't
exist. For example, when Zed is first launched and `settings.json` isn't
there.
2. Add proper symlink handling for fs watch. For example, when
`settings.json` is a symlink.

This is exactly same as how we handle it on Linux.

Release Notes:

- Fixed an issue where items on the Welcome page could not be toggled on
Windows, either on first launch or when `settings.json` is a symlink.
This commit is contained in:
tims 2025-01-07 23:50:22 +05:30 committed by GitHub
parent d58f006498
commit d3fc00d5a0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 56 additions and 72 deletions

View file

@ -153,8 +153,8 @@ pub fn initialize_workspace(
})
.detach();
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
initialize_linux_file_watcher(cx);
#[cfg(not(target_os = "macos"))]
initialize_file_watcher(cx);
if let Some(specs) = cx.gpu_specs() {
log::info!("Using GPU: {:?}", specs);
@ -235,8 +235,8 @@ fn feature_gate_zed_pro_actions(cx: &mut AppContext) {
}
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
fn initialize_linux_file_watcher(cx: &mut ViewContext<Workspace>) {
if let Err(e) = fs::linux_watcher::global(|_| {}) {
fn initialize_file_watcher(cx: &mut ViewContext<Workspace>) {
if let Err(e) = fs::fs_watcher::global(|_| {}) {
let message = format!(
db::indoc! {r#"
inotify_init returned {}
@ -264,6 +264,36 @@ fn initialize_linux_file_watcher(cx: &mut ViewContext<Workspace>) {
}
}
#[cfg(target_os = "windows")]
fn initialize_file_watcher(cx: &mut ViewContext<Workspace>) {
if let Err(e) = fs::fs_watcher::global(|_| {}) {
let message = format!(
db::indoc! {r#"
ReadDirectoryChangesW initialization failed: {}
This may occur on network filesystems and WSL paths. For troubleshooting see: https://zed.dev/docs/windows
"#},
e
);
let prompt = cx.prompt(
PromptLevel::Critical,
"Could not start ReadDirectoryChangesW",
Some(&message),
&["Troubleshoot and Quit"],
);
cx.spawn(|_, mut cx| async move {
if prompt.await == Ok(0) {
cx.update(|cx| {
cx.open_url("https://zed.dev/docs/windows");
cx.quit()
})
.ok();
}
})
.detach()
}
}
fn show_software_emulation_warning_if_needed(
specs: gpui::GpuSpecs,
cx: &mut ViewContext<Workspace>,