From dbbbd08934bc52cdc455ca7edbfe512359218454 Mon Sep 17 00:00:00 2001 From: fufesou <13586388+fufesou@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:44:36 +0800 Subject: [PATCH] fix: clipboard, support excel xml spreadsheet (#9252) Signed-off-by: fufesou --- libs/hbb_common/protos/message.proto | 3 +++ src/clipboard.rs | 34 +++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index 4554617a7..21f9e7aea 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -326,6 +326,7 @@ enum ClipboardFormat { ImageRgba = 21; ImagePng = 22; ImageSvg = 23; + Special = 31; } message Clipboard { @@ -334,6 +335,8 @@ message Clipboard { int32 width = 3; int32 height = 4; ClipboardFormat format = 5; + // Special format name, only used when format is Special. + string special_name = 6; } message MultiClipboards { repeated Clipboard clipboards = 1; } diff --git a/src/clipboard.rs b/src/clipboard.rs index 0510eca6a..4e6295db9 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -12,6 +12,9 @@ pub const CLIPBOARD_INTERVAL: u64 = 333; // This format is used to store the flag in the clipboard. const RUSTDESK_CLIPBOARD_OWNER_FORMAT: &'static str = "dyn.com.rustdesk.owner"; +// Add special format for Excel XML Spreadsheet +const CLIPBOARD_FORMAT_EXCEL_XML_SPREADSHEET: &'static str = "XML Spreadsheet"; + lazy_static::lazy_static! { static ref ARBOARD_MTX: Arc> = Arc::new(Mutex::new(())); // cache the clipboard msg @@ -30,6 +33,7 @@ const SUPPORTED_FORMATS: &[ClipboardFormat] = &[ ClipboardFormat::ImageRgba, ClipboardFormat::ImagePng, ClipboardFormat::ImageSvg, + ClipboardFormat::Special(CLIPBOARD_FORMAT_EXCEL_XML_SPREADSHEET), ClipboardFormat::Special(RUSTDESK_CLIPBOARD_OWNER_FORMAT), ]; @@ -267,8 +271,8 @@ impl ClipboardContext { } if !force { for c in data.iter() { - if let ClipboardData::Special((_, d)) = c { - if side.is_owner(d) { + if let ClipboardData::Special((s, d)) = c { + if s == RUSTDESK_CLIPBOARD_OWNER_FORMAT && side.is_owner(d) { return Ok(vec![]); } } @@ -276,7 +280,10 @@ impl ClipboardContext { } Ok(data .into_iter() - .filter(|c| !matches!(c, ClipboardData::Special(_))) + .filter(|c| match c { + ClipboardData::Special((s, _)) => s != RUSTDESK_CLIPBOARD_OWNER_FORMAT, + _ => true, + }) .collect()) } @@ -454,12 +461,30 @@ mod proto { } } + fn special_to_proto(d: Vec, s: String) -> Clipboard { + let compressed = compress_func(&d); + let compress = compressed.len() < d.len(); + let content = if compress { + compressed + } else { + s.bytes().collect::>() + }; + Clipboard { + compress, + content: content.into(), + format: ClipboardFormat::Special.into(), + special_name: s, + ..Default::default() + } + } + fn clipboard_data_to_proto(data: ClipboardData) -> Option { let d = match data { ClipboardData::Text(s) => plain_to_proto(s, ClipboardFormat::Text), ClipboardData::Rtf(s) => plain_to_proto(s, ClipboardFormat::Rtf), ClipboardData::Html(s) => plain_to_proto(s, ClipboardFormat::Html), ClipboardData::Image(a) => image_to_proto(a), + ClipboardData::Special((s, d)) => special_to_proto(d, s), _ => return None, }; Some(d) @@ -496,6 +521,9 @@ mod proto { Ok(ClipboardFormat::ImageSvg) => Some(ClipboardData::Image(arboard::ImageData::svg( std::str::from_utf8(&data).unwrap_or_default(), ))), + Ok(ClipboardFormat::Special) => { + Some(ClipboardData::Special((clipboard.special_name, data))) + } _ => None, } }