rdw: fix run-time panic because we are not on MainContext

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau 2023-01-17 18:26:35 +04:00
parent 3712905ec1
commit 544a407561
1 changed files with 32 additions and 30 deletions

View File

@ -99,41 +99,43 @@ impl ClipboardHandler for InnerHandler {
selection: ClipboardSelection,
mimes: Vec<String>,
) -> qemu_display::Result<(String, Vec<u8>)> {
// we have to spawn a local future, because clipboard is not Send
let (sender, receiver) = futures::channel::oneshot::channel();
glib::MainContext::default().spawn_local(async move {
let res = if let Some((clipboard, _)) = clipboard_from_selection(selection) {
let m: Vec<_> = mimes.iter().map(|s| s.as_str()).collect();
let res = clipboard.read_future(&m, glib::Priority::default()).await;
log::debug!("clipboard-read: {}", res.is_ok());
match res {
Ok((stream, mime)) => {
let out = gio::MemoryOutputStream::new_resizable();
let res = out
.splice_future(
&stream,
gio::OutputStreamSpliceFlags::CLOSE_SOURCE
| gio::OutputStreamSpliceFlags::CLOSE_TARGET,
glib::Priority::default(),
)
.await;
match res {
Ok(_) => {
let data = out.steal_as_bytes();
Ok((mime.to_string(), data.as_ref().to_vec()))
glib::MainContext::default().invoke(move || {
glib::MainContext::default().spawn_local(async move {
let res = if let Some((clipboard, _)) = clipboard_from_selection(selection) {
let m: Vec<_> = mimes.iter().map(|s| s.as_str()).collect();
let res = clipboard.read_future(&m, glib::Priority::default()).await;
log::debug!("clipboard-read: {}", res.is_ok());
match res {
Ok((stream, mime)) => {
let out = gio::MemoryOutputStream::new_resizable();
let res = out
.splice_future(
&stream,
gio::OutputStreamSpliceFlags::CLOSE_SOURCE
| gio::OutputStreamSpliceFlags::CLOSE_TARGET,
glib::Priority::default(),
)
.await;
match res {
Ok(_) => {
let data = out.steal_as_bytes();
Ok((mime.to_string(), data.as_ref().to_vec()))
}
Err(e) => Err(qemu_display::Error::Failed(format!("{}", e))),
}
Err(e) => Err(qemu_display::Error::Failed(format!("{}", e))),
}
Err(e) => Err(qemu_display::Error::Failed(format!("{}", e))),
}
Err(e) => Err(qemu_display::Error::Failed(format!("{}", e))),
}
} else {
Err(qemu_display::Error::Failed(
"Clipboard request failed".into(),
))
};
sender.send(res).unwrap()
} else {
Err(qemu_display::Error::Failed(
"Clipboard request failed".into(),
))
};
sender.send(res).unwrap()
});
});
match receiver.await {
Ok(res) => res,
Err(e) => Err(qemu_display::Error::Failed(format!(