Linux: file dialogs (#7852)

This PR implements linux file dialogs and open/reveal actions.

| Open folder | Reveal path |
| --- | --- |
| ![Screenshot from 2024-02-15
16-50-49](https://github.com/zed-industries/zed/assets/1423607/b4260574-d841-4ded-821d-521f507916d1)
| ![Screenshot from 2024-02-15
16-51-36](https://github.com/zed-industries/zed/assets/1423607/1f32f451-7def-423a-9d69-de2876285b60)
|

---------

Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
Rom Grk 2024-02-16 13:34:54 -05:00 committed by GitHub
parent 43e8fdbe82
commit bea36918f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 435 additions and 40 deletions

View file

@ -96,6 +96,8 @@ objc = "0.2"
[target.'cfg(target_os = "linux")'.dependencies]
flume = "0.11"
open = "5.0.1"
ashpd = "0.7.0"
# todo!(linux) - Technically do not use `randr`, but it doesn't compile otherwise
xcb = { version = "1.3", features = ["as-raw-xcb-connection", "present", "randr", "xkb"] }
wayland-client= { version = "0.31.2" }

View file

@ -8,6 +8,7 @@ use std::{
time::Duration,
};
use ashpd::desktop::file_chooser::{OpenFileRequest, SaveFileRequest};
use async_task::Runnable;
use flume::{Receiver, Sender};
use futures::channel::oneshot;
@ -214,7 +215,7 @@ impl Platform for LinuxPlatform {
}
fn open_url(&self, url: &str) {
unimplemented!()
open::that(url);
}
fn on_open_urls(&self, callback: Box<dyn FnMut(Vec<String>)>) {
@ -225,15 +226,75 @@ impl Platform for LinuxPlatform {
&self,
options: PathPromptOptions,
) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
unimplemented!()
let (done_tx, done_rx) = oneshot::channel();
self.foreground_executor()
.spawn(async move {
let title = if options.multiple {
if !options.files {
"Open folders"
} else {
"Open files"
}
} else {
if !options.files {
"Open folder"
} else {
"Open file"
}
};
let result = OpenFileRequest::default()
.modal(true)
.title(title)
.accept_label("Select")
.multiple(options.multiple)
.directory(options.directories)
.send()
.await
.ok()
.and_then(|request| request.response().ok())
.and_then(|response| {
response
.uris()
.iter()
.map(|uri| uri.to_file_path().ok())
.collect()
});
done_tx.send(result);
})
.detach();
done_rx
}
fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
unimplemented!()
let (done_tx, done_rx) = oneshot::channel();
let directory = directory.to_owned();
self.foreground_executor()
.spawn(async move {
let result = SaveFileRequest::default()
.modal(true)
.title("Select new path")
.accept_label("Accept")
.send()
.await
.ok()
.and_then(|request| request.response().ok())
.and_then(|response| {
response
.uris()
.first()
.and_then(|uri| uri.to_file_path().ok())
});
done_tx.send(result);
})
.detach();
done_rx
}
fn reveal_path(&self, path: &Path) {
unimplemented!()
open::that(path);
}
fn on_become_active(&self, callback: Box<dyn FnMut()>) {