Add FileTransfer (drag & drop / copy & paste files)
Host->Guest is easy; Guest->Host is not there yet because we have to do something for the (O_PATH) fd passing such as converting to inode numbers and getting an O_PATH fd back through the VMM, which requires modifying libkrun/muvm to have a connection channel.. Or we should switch this from vsock to a virtgpu channel where it would be easier to handle.
This commit is contained in:
parent
762dd2dd84
commit
2561342e0c
5 changed files with 216 additions and 20 deletions
|
|
@ -53,6 +53,7 @@ impl FileChooser {
|
|||
docs: self.docs.clone(),
|
||||
guest_root: self.guest_root.clone(),
|
||||
for_save: false,
|
||||
persistent: true,
|
||||
directory: options.get_as("directory")?.unwrap_or(false),
|
||||
})
|
||||
.perform(async || self.host.open_file(parent_window, title, options).await)
|
||||
|
|
@ -73,6 +74,7 @@ impl FileChooser {
|
|||
docs: self.docs.clone(),
|
||||
guest_root: self.guest_root.clone(),
|
||||
for_save: true,
|
||||
persistent: true,
|
||||
directory: false,
|
||||
})
|
||||
.perform(async || self.host.save_file(parent_window, title, options).await)
|
||||
|
|
@ -93,6 +95,7 @@ impl FileChooser {
|
|||
docs: self.docs.clone(),
|
||||
guest_root: self.guest_root.clone(),
|
||||
for_save: true,
|
||||
persistent: true,
|
||||
directory: false,
|
||||
})
|
||||
.perform(async || self.host.save_files(parent_window, title, options).await)
|
||||
|
|
@ -106,11 +109,13 @@ impl FileChooser {
|
|||
}
|
||||
}
|
||||
|
||||
struct FileTransformer {
|
||||
docs: DocumentsProxy<'static>,
|
||||
guest_root: PathBuf,
|
||||
for_save: bool,
|
||||
directory: bool,
|
||||
#[derive(Clone)]
|
||||
pub struct FileTransformer {
|
||||
pub docs: DocumentsProxy<'static>,
|
||||
pub guest_root: PathBuf,
|
||||
pub for_save: bool,
|
||||
pub persistent: bool,
|
||||
pub directory: bool,
|
||||
}
|
||||
|
||||
// ref: send_response_in_thread_func
|
||||
|
|
@ -134,6 +139,14 @@ impl ResultTransformer for FileTransformer {
|
|||
.async_map(|u| self.add_path_as_doc(u))
|
||||
.await
|
||||
.flatten()
|
||||
.map(|path| match url::Url::from_file_path(&path) {
|
||||
Ok(url) => Some(url.to_string()),
|
||||
Err(err) => {
|
||||
warn!(?err, ?path, "could not make url from returned path");
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
results.insert("uris", guest_uris.into());
|
||||
|
|
@ -150,7 +163,7 @@ const DIRECTORY: u32 = 1 << 3;
|
|||
// https://github.com/flatpak/xdg-desktop-portal/blob/10e712e06aa8eb9cd0e59c73c5be62ba53e981a4/src/xdp-documents.c#L71
|
||||
|
||||
impl FileTransformer {
|
||||
async fn add_path_as_doc(&self, path: PathBuf) -> Option<String> {
|
||||
pub async fn add_path_as_doc(&self, path: PathBuf) -> Option<PathBuf> {
|
||||
use rustix::fs::{Mode, OFlags};
|
||||
|
||||
let o_path_fd = match rustix::fs::open(
|
||||
|
|
@ -166,8 +179,8 @@ impl FileTransformer {
|
|||
};
|
||||
|
||||
let flags = REUSE_EXISTING
|
||||
| PERSISTENT
|
||||
| AS_NEEDED_BY_APP
|
||||
| if self.persistent { PERSISTENT } else { 0 }
|
||||
| if self.directory { DIRECTORY } else { 0 };
|
||||
|
||||
// XXX: portal impl can return writable=false but host frontend does not pass that back..
|
||||
|
|
@ -212,14 +225,7 @@ impl FileTransformer {
|
|||
return None;
|
||||
}
|
||||
};
|
||||
let path = self.guest_root.join(doc_id).join(filename);
|
||||
match url::Url::from_file_path(&path) {
|
||||
Ok(url) => Some(url.to_string()),
|
||||
Err(err) => {
|
||||
warn!(?err, ?path, "could not make url from returned path");
|
||||
None
|
||||
}
|
||||
}
|
||||
Some(self.guest_root.join(doc_id).join(filename))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue