diff --git a/wayshot/src/cli.rs b/wayshot/src/cli.rs index 7a5dc1f6..0ad61c23 100644 --- a/wayshot/src/cli.rs +++ b/wayshot/src/cli.rs @@ -18,8 +18,8 @@ pub struct Cli { #[arg(value_name = "OUTPUT", verbatim_doc_comment)] 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, verbatim_doc_comment)] pub clipboard: bool, diff --git a/wayshot/src/wayshot.rs b/wayshot/src/wayshot.rs index 4ba2955f..b8a9420b 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, }; @@ -126,43 +127,58 @@ fn main() -> Result<()> { } }; + let mut image_buf: Option>> = None; if let Some(file) = file { image_buffer.save(file)?; - } else { + } 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())?; + image_buf = Some(buffer); + } - 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 { + 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 } - } + })?; } 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(()) +}