From 9218f38d4a35c5a91aaefedf0b54d60c73e71e04 Mon Sep 17 00:00:00 2001 From: CheerfulPianissimo Date: Fri, 23 Feb 2024 22:24:41 +0530 Subject: [PATCH 1/2] Refactor screenshot save location selection code to use an enum. --- wayshot/src/utils.rs | 6 ++++++ wayshot/src/wayshot.rs | 34 +++++++++++++++++----------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/wayshot/src/utils.rs b/wayshot/src/utils.rs index e24caf74..39511538 100644 --- a/wayshot/src/utils.rs +++ b/wayshot/src/utils.rs @@ -40,6 +40,12 @@ pub fn parse_geometry(g: &str) -> Option { }) } +/// Supported locations to save the screenshot to. +pub enum SaveLocation { + File(String), + StdOut, +} + /// Supported image encoding formats. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum EncodingFormat { diff --git a/wayshot/src/wayshot.rs b/wayshot/src/wayshot.rs index b4b3c01f..212d78cd 100644 --- a/wayshot/src/wayshot.rs +++ b/wayshot/src/wayshot.rs @@ -12,7 +12,7 @@ mod utils; use dialoguer::{theme::ColorfulTheme, FuzzySelect}; use tracing::Level; -use crate::utils::EncodingFormat; +use crate::utils::{EncodingFormat, SaveLocation}; fn select_ouput(ouputs: &[T]) -> Option where @@ -59,16 +59,13 @@ fn main() -> Result<(), Box> { EncodingFormat::Png }; - let mut file_is_stdout: bool = false; - let mut file_path: Option = None; - - if args.get_flag("stdout") { - file_is_stdout = true; + let save_location = if args.get_flag("stdout") { + SaveLocation::StdOut } else if let Some(filepath) = args.get_one::("file") { - file_path = Some(filepath.trim().to_string()); + SaveLocation::File(filepath.trim().to_string()) } else { - file_path = Some(utils::get_default_file_name(extension)); - } + SaveLocation::File(utils::get_default_file_name(extension)) + }; let wayshot_conn = WayshotConnection::new()?; @@ -116,16 +113,19 @@ fn main() -> Result<(), Box> { wayshot_conn.screenshot_all(cursor_overlay)? }; - if file_is_stdout { - let stdout = stdout(); - let mut buffer = Cursor::new(Vec::new()); + match save_location { + SaveLocation::File(filepath) => { + image_buffer.save(filepath)?; + } + SaveLocation::StdOut => { + let stdout = stdout(); + let mut buffer = Cursor::new(Vec::new()); - let mut writer = BufWriter::new(stdout.lock()); - image_buffer.write_to(&mut buffer, extension)?; + let mut writer = BufWriter::new(stdout.lock()); + image_buffer.write_to(&mut buffer, extension)?; - writer.write_all(buffer.get_ref())?; - } else { - image_buffer.save(file_path.unwrap())?; + writer.write_all(buffer.get_ref())?; + } } Ok(()) From f2fd4a081017010483b09c08c52090d75ea5d59a Mon Sep 17 00:00:00 2001 From: CheerfulPianissimo Date: Sat, 24 Feb 2024 00:39:36 +0530 Subject: [PATCH 2/2] Implement clipboard integration using wl-clipboard-rs. --- Cargo.lock | 144 ++++++++++++++++++++++++++++++++++++++++- wayshot/Cargo.toml | 1 + wayshot/src/clap.rs | 10 +++ wayshot/src/utils.rs | 1 + wayshot/src/wayshot.rs | 15 +++++ 5 files changed, 169 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d5bff5d..cabf0dcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,6 +74,12 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "bytecount" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" + [[package]] name = "bytemuck" version = "1.14.0" @@ -162,6 +168,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "derive-new" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "dialoguer" version = "0.11.0" @@ -197,6 +214,12 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.8" @@ -222,6 +245,12 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.28" @@ -232,6 +261,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "fuzzy-matcher" version = "0.3.7" @@ -241,6 +276,12 @@ dependencies = [ "thread_local", ] +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "image" version = "0.24.7" @@ -257,6 +298,16 @@ dependencies = [ "qoi", ] +[[package]] +name = "indexmap" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "jpeg-decoder" version = "0.3.0" @@ -335,6 +386,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -355,6 +412,7 @@ dependencies = [ "cfg-if", "libc", "memoffset", + "pin-utils", ] [[package]] @@ -368,6 +426,16 @@ dependencies = [ "libc", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -414,18 +482,44 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "os_pipe" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "overload" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "pin-project-lite" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.27" @@ -542,6 +636,17 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.41" @@ -583,7 +688,7 @@ checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.41", ] [[package]] @@ -615,7 +720,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.41", ] [[package]] @@ -653,6 +758,20 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "tree_magic_mini" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91adfd0607cacf6e4babdb870e9bec4037c1c4b151cfd279ccefc5e0c7feaa6d" +dependencies = [ + "bytecount", + "fnv", + "lazy_static", + "nom", + "once_cell", + "petgraph", +] + [[package]] name = "unicode-ident" version = "1.0.12" @@ -761,6 +880,7 @@ dependencies = [ "libwayshot", "tracing", "tracing-subscriber", + "wl-clipboard-rs", ] [[package]] @@ -983,6 +1103,26 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "wl-clipboard-rs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57af79e973eadf08627115c73847392e6b766856ab8e3844a59245354b23d2fa" +dependencies = [ + "derive-new", + "libc", + "log", + "nix 0.26.4", + "os_pipe", + "tempfile", + "thiserror", + "tree_magic_mini", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-wlr", +] + [[package]] name = "zeroize" version = "1.7.0" diff --git a/wayshot/Cargo.toml b/wayshot/Cargo.toml index 8d4aa528..d325235c 100644 --- a/wayshot/Cargo.toml +++ b/wayshot/Cargo.toml @@ -30,6 +30,7 @@ image = { version = "0.24", default-features = false, features = [ dialoguer = { version = "0.11.0", features = ["fuzzy-select"] } +wl-clipboard-rs = "0.8.0" [[bin]] name = "wayshot" path = "src/wayshot.rs" diff --git a/wayshot/src/clap.rs b/wayshot/src/clap.rs index 37319334..f3add025 100644 --- a/wayshot/src/clap.rs +++ b/wayshot/src/clap.rs @@ -21,6 +21,7 @@ pub fn set_flags() -> Command { arg!(-f - -file ) .required(false) .conflicts_with("stdout") + .conflicts_with("clipboard") .action(ArgAction::Set) .help("Mention a custom file path"), ) @@ -34,9 +35,18 @@ pub fn set_flags() -> Command { arg!(--stdout) .required(false) .conflicts_with("file") + .conflicts_with("clipboard") .action(ArgAction::SetTrue) .help("Output the image data to standard out"), ) + .arg( + arg!(-p - -clipboard) + .required(false) + .conflicts_with("file") + .conflicts_with("stdout") + .action(ArgAction::SetTrue) + .help("Output the image data to clipboard"), + ) .arg( arg!(-e --extension ) .required(false) diff --git a/wayshot/src/utils.rs b/wayshot/src/utils.rs index 39511538..ef548517 100644 --- a/wayshot/src/utils.rs +++ b/wayshot/src/utils.rs @@ -44,6 +44,7 @@ pub fn parse_geometry(g: &str) -> Option { pub enum SaveLocation { File(String), StdOut, + Clipboard, } /// Supported image encoding formats. diff --git a/wayshot/src/wayshot.rs b/wayshot/src/wayshot.rs index 212d78cd..1bba09e2 100644 --- a/wayshot/src/wayshot.rs +++ b/wayshot/src/wayshot.rs @@ -12,6 +12,8 @@ mod utils; use dialoguer::{theme::ColorfulTheme, FuzzySelect}; use tracing::Level; +use wl_clipboard_rs::copy::{MimeType, Options, Source}; + use crate::utils::{EncodingFormat, SaveLocation}; fn select_ouput(ouputs: &[T]) -> Option @@ -61,6 +63,8 @@ fn main() -> Result<(), Box> { let save_location = if args.get_flag("stdout") { SaveLocation::StdOut + } else if args.get_flag("clipboard") { + SaveLocation::Clipboard } else if let Some(filepath) = args.get_one::("file") { SaveLocation::File(filepath.trim().to_string()) } else { @@ -126,6 +130,17 @@ fn main() -> Result<(), Box> { writer.write_all(buffer.get_ref())?; } + SaveLocation::Clipboard => { + let mut opts = Options::new(); + + let mut buffer = Cursor::new(Vec::new()); + image_buffer.write_to(&mut buffer, extension)?; + opts.serve_requests(wl_clipboard_rs::copy::ServeRequests::Only(1)); + opts.copy( + Source::Bytes(buffer.into_inner().into()), + MimeType::Autodetect, + )?; + } } Ok(())