From ca315d8256c39c3637300d8a8353067a044626b6 Mon Sep 17 00:00:00 2001 From: CheerfulPianissimo Date: Sat, 23 Mar 2024 23:36:31 +0530 Subject: [PATCH 1/6] feat(clipboard): fix issue #106 clipboard flag ignored if path is qualified to file --- Cargo.lock | 39 +++++++++++++++++++++++++++++ wayshot/src/wayshot.rs | 57 ++++++++++++++++++++++-------------------- 2 files changed, 69 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc317536..04fcbd3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,6 +112,10 @@ name = "cc" version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +dependencies = [ + "jobserver", + "libc", +] [[package]] name = "cfg-if" @@ -337,6 +341,12 @@ dependencies = [ "thread_local", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "hashbrown" version = "0.14.3" @@ -394,6 +404,7 @@ dependencies = [ "num-traits", "png", "qoi", + "webp", ] [[package]] @@ -412,6 +423,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "jobserver" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] + [[package]] name = "jpeg-decoder" version = "0.3.1" @@ -463,6 +483,16 @@ dependencies = [ "wayland-protocols-wlr", ] +[[package]] +name = "libwebp-sys" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829b6b604f31ed6d2bccbac841fe0788de93dbd87e4eb1ba2c4adfe8c012a838" +dependencies = [ + "cc", + "glob", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -995,6 +1025,15 @@ dependencies = [ "wl-clipboard-rs", ] +[[package]] +name = "webp" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb5d8e7814e92297b0e1c773ce43d290bef6c17452dafd9fc49e5edb5beba71" +dependencies = [ + "libwebp-sys", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/wayshot/src/wayshot.rs b/wayshot/src/wayshot.rs index 1a2ca746..5340765f 100644 --- a/wayshot/src/wayshot.rs +++ b/wayshot/src/wayshot.rs @@ -1,4 +1,5 @@ use std::{ + fs::File, io::{stdout, BufWriter, Cursor, Write}, process::Command, }; @@ -123,40 +124,42 @@ fn main() -> Result<()> { } }; + let mut buffer = Cursor::new(Vec::new()); + image_buffer.write_to(&mut buffer, requested_encoding)?; + if let Some(file) = file { - image_buffer.save(file)?; + let mut file = File::create(file)?; + file.write_all(buffer.get_ref())?; } else { - let mut buffer = Cursor::new(Vec::new()); - image_buffer.write_to(&mut buffer, requested_encoding)?; - if stdout_print { let stdout = stdout(); let mut writer = BufWriter::new(stdout.lock()); writer.write_all(buffer.get_ref())?; } - if cli.clipboard { - let mut opts = Options::new(); - match unsafe { fork() } { - // Having the image persistently available on the clipboard requires a wayshot process to be alive. - // Fork the process with a child detached from the main process and have the parent exit - Ok(ForkResult::Parent { .. }) => { - return Ok(()); - } - Ok(ForkResult::Child) => { - opts.foreground(true); // Offer the image till something else is available on the clipboard - opts.copy( - Source::Bytes(buffer.into_inner().into()), - MimeType::Autodetect, - )?; - } - Err(e) => { - tracing::warn!("Fork failed with error: {e}, couldn't offer image on the clipboard persistently. - Use a clipboard manager to record screenshot."); - opts.copy( - Source::Bytes(buffer.into_inner().into()), - MimeType::Autodetect, - )?; - } + } + + if cli.clipboard { + let mut opts = Options::new(); + match unsafe { fork() } { + // Having the image persistently available on the clipboard requires a wayshot process to be alive. + // Fork the process with a child detached from the main process and have the parent exit + Ok(ForkResult::Parent { .. }) => { + return Ok(()); + } + Ok(ForkResult::Child) => { + opts.foreground(true); // Offer the image till something else is available on the clipboard + opts.copy( + Source::Bytes(buffer.into_inner().into()), + MimeType::Autodetect, + )?; + } + Err(e) => { + tracing::warn!("Fork failed with error: {e}, couldn't offer image on the clipboard persistently. + Use a clipboard manager to record screenshot."); + opts.copy( + Source::Bytes(buffer.into_inner().into()), + MimeType::Autodetect, + )?; } } } From 70976dc3d8fbcd8d29417160833278c02e5406a2 Mon Sep 17 00:00:00 2001 From: CheerfulPianissimo Date: Sat, 23 Mar 2024 23:41:24 +0530 Subject: [PATCH 2/6] feat(clipboard): clarify flag description of --clipboard --- wayshot/src/cli.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wayshot/src/cli.rs b/wayshot/src/cli.rs index c0508e9e..1a09a43c 100644 --- a/wayshot/src/cli.rs +++ b/wayshot/src/cli.rs @@ -15,7 +15,8 @@ pub struct Cli { #[arg(value_name = "OUTPUT")] pub file: Option, - /// Copy image to clipboard along with [OUTPUT] or stdout. Wayshot persists in the background to offer the image till the clipboard is overwritten. + /// Copy image to clipboard. Can be used simultaneously with [OUTPUT] or stdout. + /// Wayshot persists in the background offering the image till the clipboard is overwritten. #[arg(long)] pub clipboard: bool, From 588e2d4adee515ecf3647ebad1bd69105938b587 Mon Sep 17 00:00:00 2001 From: CheerfulPianissimo Date: Sat, 23 Mar 2024 23:55:37 +0530 Subject: [PATCH 3/6] feat(clipboard): enable multiline comment description for --clipboard feature flag Signed-off-by: Shinyzenith --- wayshot/src/cli.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wayshot/src/cli.rs b/wayshot/src/cli.rs index 1a09a43c..a441b748 100644 --- a/wayshot/src/cli.rs +++ b/wayshot/src/cli.rs @@ -17,7 +17,7 @@ pub struct Cli { /// Copy image to clipboard. Can be used simultaneously with [OUTPUT] or stdout. /// Wayshot persists in the background offering the image till the clipboard is overwritten. - #[arg(long)] + #[arg(long, verbatim_doc_comment)] pub clipboard: bool, /// Log level to be used for printing to stderr From fede62e46b1aa8ecd49375bb4cddd60b8dc1f1dc Mon Sep 17 00:00:00 2001 From: CheerfulPianissimo Date: Sun, 24 Mar 2024 18:19:32 +0530 Subject: [PATCH 4/6] feat(clipboard): reduce buffer allocations for encoding image --- wayshot/src/wayshot.rs | 77 +++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/wayshot/src/wayshot.rs b/wayshot/src/wayshot.rs index 04b20649..c6f446b1 100644 --- a/wayshot/src/wayshot.rs +++ b/wayshot/src/wayshot.rs @@ -127,45 +127,54 @@ fn main() -> Result<()> { } }; - let mut buffer = Cursor::new(Vec::new()); - image_buffer.write_to(&mut buffer, requested_encoding)?; - if let Some(file) = file { - let mut file = File::create(file)?; - file.write_all(buffer.get_ref())?; - } else { - if stdout_print { - let stdout = stdout(); - let mut writer = BufWriter::new(stdout.lock()); - writer.write_all(buffer.get_ref())?; + image_buffer.save(file)?; + } else if stdout_print { + let mut buffer = Cursor::new(Vec::new()); + image_buffer.write_to(&mut buffer, requested_encoding)?; + let stdout = stdout(); + let mut writer = BufWriter::new(stdout.lock()); + writer.write_all(buffer.get_ref())?; + if cli.clipboard { + clipboard_daemonize(buffer)?; } } - if cli.clipboard { - let mut opts = Options::new(); - match unsafe { fork() } { - // Having the image persistently available on the clipboard requires a wayshot process to be alive. - // Fork the process with a child detached from the main process and have the parent exit - Ok(ForkResult::Parent { .. }) => { - return Ok(()); - } - Ok(ForkResult::Child) => { - opts.foreground(true); // Offer the image till something else is available on the clipboard - opts.copy( - Source::Bytes(buffer.into_inner().into()), - MimeType::Autodetect, - )?; - } - Err(e) => { - tracing::warn!("Fork failed with error: {e}, couldn't offer image on the clipboard persistently. - Use a clipboard manager to record screenshot."); - opts.copy( - Source::Bytes(buffer.into_inner().into()), - MimeType::Autodetect, - )?; - } - } + if !stdout_print && cli.clipboard { + let mut buffer = Cursor::new(Vec::new()); + image_buffer.write_to(&mut buffer, requested_encoding)?; + clipboard_daemonize(buffer)?; } Ok(()) } + +/// Daemonize and copy the given buffer containing the encoded image to the clipboard +fn clipboard_daemonize(buffer: Cursor>) -> Result<()> { + let mut opts = Options::new(); + match unsafe { fork() } { + // Having the image persistently available on the clipboard requires a wayshot process to be alive. + // Fork the process with a child detached from the main process and have the parent exit + Ok(ForkResult::Parent { .. }) => { + return Ok(()); + } + Ok(ForkResult::Child) => { + opts.foreground(true); // Offer the image till something else is available on the clipboard + opts.copy( + Source::Bytes(buffer.into_inner().into()), + MimeType::Autodetect, + )?; + } + Err(e) => { + tracing::warn!( + "Fork failed with error: {e}, couldn't offer image on the clipboard persistently. + Use a clipboard manager to record screenshot." + ); + opts.copy( + Source::Bytes(buffer.into_inner().into()), + MimeType::Autodetect, + )?; + } + } + Ok(()) +} From 7dcfaabd94c6274265c1579e7b6d6f5fb690885b Mon Sep 17 00:00:00 2001 From: CheerfulPianissimo Date: Sun, 24 Mar 2024 20:57:07 +0530 Subject: [PATCH 5/6] feat(clipboard): improve code quality --- wayshot/src/wayshot.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/wayshot/src/wayshot.rs b/wayshot/src/wayshot.rs index c6f446b1..45c905c9 100644 --- a/wayshot/src/wayshot.rs +++ b/wayshot/src/wayshot.rs @@ -127,6 +127,7 @@ fn main() -> Result<()> { } }; + let mut image_buf: Option>> = None; if let Some(file) = file { image_buffer.save(file)?; } else if stdout_print { @@ -135,14 +136,18 @@ fn main() -> Result<()> { let stdout = stdout(); let mut writer = BufWriter::new(stdout.lock()); writer.write_all(buffer.get_ref())?; - if cli.clipboard { - clipboard_daemonize(buffer)?; - } + image_buf = Some(buffer); } - if !stdout_print && cli.clipboard { - let mut buffer = Cursor::new(Vec::new()); - image_buffer.write_to(&mut buffer, requested_encoding)?; + if cli.clipboard { + let buffer = match image_buf { + Some(buf) => buf, + None => { + let mut buffer = Cursor::new(Vec::new()); + image_buffer.write_to(&mut buffer, requested_encoding)?; + buffer + } + }; clipboard_daemonize(buffer)?; } From ff8f394e9ef4fa5eca87fed3ed5575037ddeeca8 Mon Sep 17 00:00:00 2001 From: CheerfulPianissimo Date: Tue, 26 Mar 2024 18:42:35 +0530 Subject: [PATCH 6/6] feat(clipboard): code style change: perform match inside function call --- wayshot/src/wayshot.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wayshot/src/wayshot.rs b/wayshot/src/wayshot.rs index 45c905c9..b8a9420b 100644 --- a/wayshot/src/wayshot.rs +++ b/wayshot/src/wayshot.rs @@ -140,15 +140,14 @@ fn main() -> Result<()> { } if cli.clipboard { - let buffer = match image_buf { + clipboard_daemonize(match image_buf { Some(buf) => buf, None => { let mut buffer = Cursor::new(Vec::new()); image_buffer.write_to(&mut buffer, requested_encoding)?; buffer } - }; - clipboard_daemonize(buffer)?; + })?; } Ok(())