From bcb8d17081f84a499fcfc236360837223bfc7165 Mon Sep 17 00:00:00 2001 From: Doublonmousse <115779707+Doublonmousse@users.noreply.github.com> Date: Sat, 9 Nov 2024 10:10:49 +0100 Subject: [PATCH 1/2] fix: improve the clipboard pasting of files for better cross compatibility use `read_future(&["text/uri-list") ...` instead of `read_text_future` when pasting files. This will make it work on the next gtk stable release (4.18) on mac os --- crates/rnote-ui/src/appwindow/actions.rs | 91 ++++++++++++++++-------- 1 file changed, 63 insertions(+), 28 deletions(-) diff --git a/crates/rnote-ui/src/appwindow/actions.rs b/crates/rnote-ui/src/appwindow/actions.rs index 500a05ac7f..35b5a84799 100644 --- a/crates/rnote-ui/src/appwindow/actions.rs +++ b/crates/rnote-ui/src/appwindow/actions.rs @@ -1160,38 +1160,73 @@ impl RnAppWindow { async move { debug!("Recognized clipboard content format: files list"); - match appwindow.clipboard().read_text_future().await { - Ok(Some(text)) => { - let file_paths = text - .lines() - .filter_map(|line| { - let file_path = if let Ok(path_uri) = url::Url::parse(line) { - path_uri.to_file_path().ok()? - } else { - PathBuf::from(&line) - }; - - if file_path.exists() { - Some(file_path) - } else { - None - } - }) - .collect::>(); - - for file_path in file_paths { - appwindow - .open_file_w_dialogs( - gio::File::for_path(&file_path), - target_pos, - true, + match appwindow + .clipboard() + .read_future(&["text/uri-list"], glib::source::Priority::DEFAULT) + .await + { + Ok((input_stream, _)) => { + let mut acc = Vec::new(); + loop { + match input_stream + .read_future( + vec![0; CLIPBOARD_INPUT_STREAM_BUFSIZE], + glib::source::Priority::DEFAULT, ) - .await; + .await + { + Ok((mut bytes, n)) => { + if n == 0 { + break; + } + acc.append(&mut bytes); + } + Err(e) => { + error!("Failed to read clipboard input stream while pasting as files list, Err: {e:?}"); + acc.clear(); + break; + } + } + } + if !acc.is_empty() { + match crate::utils::str_from_u8_nul_utf8(&acc) { + Ok(text) => { + debug!("files uri list : {:?}", text); + let file_paths = text + .lines() + .filter_map(|line| { + let file_path = if let Ok(path_uri) = url::Url::parse(line) { + path_uri.to_file_path().ok()? + } else { + PathBuf::from(&line) + }; + + if file_path.exists() { + Some(file_path) + } else { + None + } + }) + .collect::>(); + + for file_path in file_paths { + appwindow + .open_file_w_dialogs( + gio::File::for_path(&file_path), + target_pos, + true, + ) + .await; + } + } + Err(e) => error!("Failed to read `text/uri-list` from clipboard data, Err: {e:?}"), + } } } - Ok(None) => {} Err(e) => { - error!("Reading clipboard text while pasting clipboard from path failed, Err: {e:?}"); + error!( + "Reading clipboard failed while pasting as `text/uri-list`, Err: {e:?}", + ); } } } From a08e1d9e3bcaa693d5a8722f8aa4d3b19d823f3d Mon Sep 17 00:00:00 2001 From: Doublonmousse <115779707+Doublonmousse@users.noreply.github.com> Date: Sun, 24 Nov 2024 13:47:27 +0100 Subject: [PATCH 2/2] cleanup: use helper function for all `InputStream` to `Vec` reads --- crates/rnote-ui/src/appwindow/actions.rs | 96 ++++++++---------------- 1 file changed, 30 insertions(+), 66 deletions(-) diff --git a/crates/rnote-ui/src/appwindow/actions.rs b/crates/rnote-ui/src/appwindow/actions.rs index 35b5a84799..b915a5f5c8 100644 --- a/crates/rnote-ui/src/appwindow/actions.rs +++ b/crates/rnote-ui/src/appwindow/actions.rs @@ -1,6 +1,7 @@ // Imports use crate::{config, dialogs, RnAppWindow, RnCanvas}; use gettextrs::gettext; +use gtk4::gio::InputStream; use gtk4::graphene; use gtk4::{ gdk, gio, glib, glib::clone, prelude::*, PrintOperation, PrintOperationAction, Unit, @@ -1166,28 +1167,7 @@ impl RnAppWindow { .await { Ok((input_stream, _)) => { - let mut acc = Vec::new(); - loop { - match input_stream - .read_future( - vec![0; CLIPBOARD_INPUT_STREAM_BUFSIZE], - glib::source::Priority::DEFAULT, - ) - .await - { - Ok((mut bytes, n)) => { - if n == 0 { - break; - } - acc.append(&mut bytes); - } - Err(e) => { - error!("Failed to read clipboard input stream while pasting as files list, Err: {e:?}"); - acc.clear(); - break; - } - } - } + let acc = collect_clipboard_data(input_stream).await; if !acc.is_empty() { match crate::utils::str_from_u8_nul_utf8(&acc) { Ok(text) => { @@ -1249,28 +1229,7 @@ impl RnAppWindow { .await { Ok((input_stream, _)) => { - let mut acc = Vec::new(); - loop { - match input_stream - .read_future( - vec![0; CLIPBOARD_INPUT_STREAM_BUFSIZE], - glib::source::Priority::DEFAULT, - ) - .await - { - Ok((mut bytes, n)) => { - if n == 0 { - break; - } - acc.append(&mut bytes); - } - Err(e) => { - error!("Failed to read clipboard input stream, Err: {e:?}"); - acc.clear(); - break; - } - } - } + let acc = collect_clipboard_data(input_stream).await; if !acc.is_empty() { match crate::utils::str_from_u8_nul_utf8(&acc) { @@ -1313,28 +1272,7 @@ impl RnAppWindow { .await { Ok((input_stream, _)) => { - let mut acc = Vec::new(); - loop { - match input_stream - .read_future( - vec![0; CLIPBOARD_INPUT_STREAM_BUFSIZE], - glib::source::Priority::DEFAULT, - ) - .await - { - Ok((mut bytes, n)) => { - if n == 0 { - break; - } - acc.append(&mut bytes); - } - Err(e) => { - error!("Failed to read clipboard input stream while pasting as Svg, Err: {e:?}"); - acc.clear(); - break; - } - } - } + let acc = collect_clipboard_data(input_stream).await; if !acc.is_empty() { match crate::utils::str_from_u8_nul_utf8(&acc) { @@ -1441,3 +1379,29 @@ impl RnAppWindow { } } } + +async fn collect_clipboard_data(input_stream: InputStream) -> Vec { + let mut acc = Vec::new(); + loop { + match input_stream + .read_future( + vec![0; CLIPBOARD_INPUT_STREAM_BUFSIZE], + glib::source::Priority::DEFAULT, + ) + .await + { + Ok((mut bytes, n)) => { + if n == 0 { + break; + } + acc.append(&mut bytes); + } + Err(e) => { + error!("Failed to read clipboard input stream, Err: {e:?}"); + acc.clear(); + break; + } + } + } + acc +}