diff --git a/Cargo.lock b/Cargo.lock index 1652708a..9de45647 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,17 +197,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "env_logger" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" -dependencies = [ - "is-terminal", - "log", - "termcolor", -] - [[package]] name = "errno" version = "0.3.4" @@ -263,12 +252,6 @@ dependencies = [ "thread_local", ] -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - [[package]] name = "image" version = "0.24.7" @@ -285,17 +268,6 @@ dependencies = [ "qoi", ] -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "jpeg-decoder" version = "0.3.0" @@ -329,10 +301,10 @@ name = "libwayshot" version = "0.3.0" dependencies = [ "image", - "log", "memmap2", "nix 0.27.1", "thiserror", + "tracing", "wayland-client", "wayland-protocols", "wayland-protocols-wlr", @@ -407,6 +379,16 @@ dependencies = [ "libc", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -443,6 +425,18 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + [[package]] name = "pkg-config" version = "0.3.27" @@ -526,6 +520,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shell-words" version = "1.1.0" @@ -574,15 +577,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "termcolor" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.49" @@ -613,6 +607,64 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + [[package]] name = "unicode-ident" version = "1.0.12" @@ -631,6 +683,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "wayland-backend" version = "0.3.2" @@ -710,11 +768,11 @@ version = "1.4.0-dev" dependencies = [ "clap", "dialoguer", - "env_logger", "flate2", "image", "libwayshot", - "log", + "tracing", + "tracing-subscriber", ] [[package]] @@ -733,15 +791,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/libwayshot/Cargo.toml b/libwayshot/Cargo.toml index 01319cc3..5be53789 100644 --- a/libwayshot/Cargo.toml +++ b/libwayshot/Cargo.toml @@ -10,10 +10,10 @@ edition = "2021" [dependencies] image = { version = "0.24", default-features = false } -log = "0.4.20" memmap2 = "0.9.0" nix = { version = "0.27.1", features = ["fs", "mman"] } thiserror = "1" +tracing = "0.1.37" wayland-client = "0.31.1" wayland-protocols = { version = "0.31.0", features = ["client", "unstable"] } wayland-protocols-wlr = { version = "0.2.0", features = ["client"] } diff --git a/libwayshot/src/dispatch.rs b/libwayshot/src/dispatch.rs index ffda8759..9b760c21 100644 --- a/libwayshot/src/dispatch.rs +++ b/libwayshot/src/dispatch.rs @@ -68,7 +68,7 @@ impl Dispatch for OutputCaptureState { }, }); } else { - log::error!("Ignoring a wl_output with version < 4."); + tracing::error!("Ignoring a wl_output with version < 4."); } } } @@ -128,12 +128,12 @@ impl Dispatch for OutputCaptureState { zxdg_output_v1::Event::LogicalPosition { x, y } => { output_info.dimensions.x = x; output_info.dimensions.y = y; - log::debug!("Logical position event fired!"); + tracing::debug!("Logical position event fired!"); } zxdg_output_v1::Event::LogicalSize { width, height } => { output_info.dimensions.width = width; output_info.dimensions.height = height; - log::debug!("Logical size event fired!"); + tracing::debug!("Logical size event fired!"); } _ => {} }; @@ -171,7 +171,7 @@ impl Dispatch for CaptureFrameState { height, stride, } => { - log::debug!("Received Buffer event"); + tracing::debug!("Received Buffer event"); if let Value(f) = format { frame.formats.push(FrameFormat { format: f, @@ -180,31 +180,31 @@ impl Dispatch for CaptureFrameState { stride, }) } else { - log::debug!("Received Buffer event with unidentified format"); + tracing::debug!("Received Buffer event with unidentified format"); exit(1); } } zwlr_screencopy_frame_v1::Event::Flags { .. } => { - log::debug!("Received Flags event"); + tracing::debug!("Received Flags event"); } zwlr_screencopy_frame_v1::Event::Ready { .. } => { // If the frame is successfully copied, a “flags” and a “ready” events are sent. Otherwise, a “failed” event is sent. // This is useful when we call .copy on the frame object. - log::debug!("Received Ready event"); + tracing::debug!("Received Ready event"); frame.state.replace(FrameState::Finished); } zwlr_screencopy_frame_v1::Event::Failed => { - log::debug!("Received Failed event"); + tracing::debug!("Received Failed event"); frame.state.replace(FrameState::Failed); } zwlr_screencopy_frame_v1::Event::Damage { .. } => { - log::debug!("Received Damage event"); + tracing::debug!("Received Damage event"); } zwlr_screencopy_frame_v1::Event::LinuxDmabuf { .. } => { - log::debug!("Received LinuxDmaBuf event"); + tracing::debug!("Received LinuxDmaBuf event"); } zwlr_screencopy_frame_v1::Event::BufferDone => { - log::debug!("Received bufferdone event"); + tracing::debug!("Received bufferdone event"); frame.buffer_done.store(true, Ordering::SeqCst); } _ => unreachable!(), diff --git a/libwayshot/src/lib.rs b/libwayshot/src/lib.rs index 88b8fffe..67c29a38 100644 --- a/libwayshot/src/lib.rs +++ b/libwayshot/src/lib.rs @@ -16,6 +16,7 @@ use std::{ os::fd::AsFd, process::exit, sync::atomic::{AtomicBool, Ordering}, + thread, }; use image::{imageops::overlay, RgbaImage}; @@ -50,7 +51,7 @@ pub mod reexport { pub use wl_output::{Transform, WlOutput}; } -type Frame = (Vec, Option<(i32, i32)>); +type Frame = (Vec, (i32, i32)); /// Struct to store region capture details. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -65,6 +66,7 @@ pub struct CaptureRegion { pub height: i32, } +#[derive(Debug)] struct IntersectingOutput { output: WlOutput, region: CaptureRegion, @@ -129,7 +131,7 @@ impl WayshotConnection { ) { Ok(x) => x, Err(e) => { - log::error!("Failed to create ZxdgOutputManagerV1 version 3. Does your compositor implement ZxdgOutputManagerV1?"); + tracing::error!("Failed to create ZxdgOutputManagerV1 version 3. Does your compositor implement ZxdgOutputManagerV1?"); panic!("{:#?}", e); } }; @@ -139,13 +141,15 @@ impl WayshotConnection { event_queue.roundtrip(&mut state)?; event_queue.roundtrip(&mut state)?; - let mut xdg_outputs: Vec = Vec::new(); - // We loop over each output and request its position data. - for (index, output) in state.outputs.clone().iter().enumerate() { - let xdg_output = zxdg_output_manager.get_xdg_output(&output.wl_output, &qh, index); - xdg_outputs.push(xdg_output); - } + let xdg_outputs: Vec = state + .outputs + .iter() + .enumerate() + .map(|(index, output)| { + zxdg_output_manager.get_xdg_output(&output.wl_output, &qh, index) + }) + .collect(); event_queue.roundtrip(&mut state)?; @@ -154,10 +158,10 @@ impl WayshotConnection { } if state.outputs.is_empty() { - log::error!("Compositor did not advertise any wl_output devices!"); + tracing::error!("Compositor did not advertise any wl_output devices!"); exit(1); } - log::debug!("Outputs detected: {:#?}", state.outputs); + tracing::debug!("Outputs detected: {:#?}", state.outputs); self.output_infos = state.outputs; Ok(()) @@ -204,8 +208,8 @@ impl WayshotConnection { ) { Ok(x) => x, Err(e) => { - log::error!("Failed to create screencopy manager. Does your compositor implement ZwlrScreencopy?"); - log::error!("err: {e}"); + tracing::error!("Failed to create screencopy manager. Does your compositor implement ZwlrScreencopy?"); + tracing::error!("err: {e}"); return Err(Error::ProtocolNotFound( "ZwlrScreencopy Manager not found".to_string(), )); @@ -234,7 +238,7 @@ impl WayshotConnection { event_queue.blocking_dispatch(&mut state)?; } - log::debug!( + tracing::debug!( "Received compositor frame buffer formats: {:#?}", state.formats ); @@ -253,13 +257,13 @@ impl WayshotConnection { ) }) .copied(); - log::debug!("Selected frame buffer format: {:#?}", frame_format); + tracing::debug!("Selected frame buffer format: {:#?}", frame_format); // Check if frame format exists. let frame_format = match frame_format { Some(format) => format, None => { - log::error!("No suitable frame format found"); + tracing::error!("No suitable frame format found"); return Err(Error::NoSupportedBufferFormat); } }; @@ -301,7 +305,7 @@ impl WayshotConnection { if let Some(state) = state.state { match state { FrameState::Failed => { - log::error!("Frame copy failed"); + tracing::error!("Frame copy failed"); return Err(Error::FramecopyFailed); } FrameState::Finished => { @@ -318,13 +322,13 @@ impl WayshotConnection { fn capture_output_frame_shm_from_file( &self, - cursor_overlay: i32, + cursor_overlay: bool, output: &WlOutput, file: &File, capture_region: Option, ) -> Result { let (state, event_queue, frame, frame_format) = - self.capture_output_frame_get_state(cursor_overlay, output, capture_region)?; + self.capture_output_frame_get_state(cursor_overlay as i32, output, capture_region)?; // Bytes of data in the frame = stride * height. let frame_bytes = frame_format.stride * frame_format.height; @@ -336,7 +340,7 @@ impl WayshotConnection { /// Get a FrameCopy instance with screenshot pixel data for any wl_output object. fn capture_output_frame( &self, - cursor_overlay: i32, + cursor_overlay: bool, output: &WlOutput, transform: Transform, capture_region: Option, @@ -358,8 +362,8 @@ impl WayshotConnection { let frame_color_type = if let Some(converter) = create_converter(frame_format.format) { converter.convert_inplace(data) } else { - log::error!("Unsupported buffer format: {:?}", frame_format.format); - log::error!("You can send a feature request for the above format to the mailing list for wayshot over at https://sr.ht/~shinyzenith/wayshot."); + tracing::error!("Unsupported buffer format: {:?}", frame_format.format); + tracing::error!("You can send a feature request for the above format to the mailing list for wayshot over at https://sr.ht/~shinyzenith/wayshot."); return Err(Error::NoSupportedBufferFormat); }; Ok(FrameCopy { @@ -373,60 +377,65 @@ impl WayshotConnection { fn create_frame_copy( &self, capture_region: CaptureRegion, - cursor_overlay: i32, + cursor_overlay: bool, ) -> Result { - let mut framecopys: Vec = Vec::new(); - - let outputs = self.get_all_outputs(); - let mut intersecting_outputs: Vec = Vec::new(); - for output in outputs.iter() { - let x1: i32 = cmp::max(output.dimensions.x, capture_region.x_coordinate); - let y1: i32 = cmp::max(output.dimensions.y, capture_region.y_coordinate); - let x2: i32 = cmp::min( - output.dimensions.x + output.dimensions.width, - capture_region.x_coordinate + capture_region.width, - ); - let y2: i32 = cmp::min( - output.dimensions.y + output.dimensions.height, - capture_region.y_coordinate + capture_region.height, - ); - - let width = x2 - x1; - let height = y2 - y1; - - if !(width <= 0 || height <= 0) { - let true_x = capture_region.x_coordinate - output.dimensions.x; - let true_y = capture_region.y_coordinate - output.dimensions.y; - let true_region = CaptureRegion { - x_coordinate: true_x, - y_coordinate: true_y, - width: capture_region.width, - height: capture_region.height, - }; - intersecting_outputs.push(IntersectingOutput { - output: output.wl_output.clone(), - region: true_region, - transform: output.transform, - }); - } - } - if intersecting_outputs.is_empty() { - log::error!("Provided capture region doesn't intersect with any outputs!"); - exit(1); - } + let frame_copies = thread::scope(|scope| -> Result<_> { + let join_handles = self + .get_all_outputs() + .into_iter() + .filter_map(|output| { + let x1: i32 = cmp::max(output.dimensions.x, capture_region.x_coordinate); + let y1: i32 = cmp::max(output.dimensions.y, capture_region.y_coordinate); + let x2: i32 = cmp::min( + output.dimensions.x + output.dimensions.width, + capture_region.x_coordinate + capture_region.width, + ); + let y2: i32 = cmp::min( + output.dimensions.y + output.dimensions.height, + capture_region.y_coordinate + capture_region.height, + ); + + let width = x2 - x1; + let height = y2 - y1; + + if width <= 0 || height <= 0 { + return None; + } - for intersecting_output in intersecting_outputs { - framecopys.push(self.capture_output_frame( - cursor_overlay, - &intersecting_output.output, - intersecting_output.transform, - Some(intersecting_output.region), - )?); - } - Ok(( - framecopys, - Some((capture_region.width, capture_region.height)), - )) + let true_x = capture_region.x_coordinate - output.dimensions.x; + let true_y = capture_region.y_coordinate - output.dimensions.y; + let true_region = CaptureRegion { + x_coordinate: true_x, + y_coordinate: true_y, + width: capture_region.width, + height: capture_region.height, + }; + Some(IntersectingOutput { + output: output.wl_output.clone(), + region: true_region, + transform: output.transform, + }) + }) + .map(|intersecting_output| { + scope.spawn(move || { + self.capture_output_frame( + cursor_overlay, + &intersecting_output.output, + intersecting_output.transform, + Some(intersecting_output.region), + ) + }) + }) + .collect::>(); + + join_handles + .into_iter() + .map(|join_handle| join_handle.join()) + .flatten() + .collect::>() + })?; + + Ok((frame_copies, (capture_region.width, capture_region.height))) } /// Take a screenshot from the specified region. @@ -435,42 +444,54 @@ impl WayshotConnection { capture_region: CaptureRegion, cursor_overlay: bool, ) -> Result { - let frame_copy = self.create_frame_copy(capture_region, cursor_overlay as i32)?; - - let mut composited_image; - - if frame_copy.0.len() == 1 { - let (width, height) = frame_copy.1.unwrap(); - let frame_copy = &frame_copy.0[0]; - - let image = frame_copy.try_into()?; - composited_image = image_util::rotate_image_buffer( - image, - frame_copy.transform, - width as u32, - height as u32, - ); - } else { - let mut images = Vec::new(); - let (frame_copy, region) = frame_copy; - let (width, height) = region.unwrap(); - for frame_copy in frame_copy { - let image = (&frame_copy).try_into()?; - let image = image_util::rotate_image_buffer( - image, - frame_copy.transform, - width as u32, - height as u32, - ); - images.push(image); - } - composited_image = images[0].clone(); - for image in images.iter().skip(1) { - overlay(&mut composited_image, image, 0, 0); - } - } - - Ok(composited_image) + let (frame_copies, (width, height)) = + self.create_frame_copy(capture_region, cursor_overlay)?; + + thread::scope(|scope| { + let rotate_join_handles = frame_copies + .into_iter() + .map(|frame_copy| { + scope.spawn(move || { + let transform = frame_copy.transform; + let image = frame_copy.try_into()?; + Ok(image_util::rotate_image_buffer( + image, + transform, + width as u32, + height as u32, + )) + }) + }) + .collect::>(); + + rotate_join_handles + .into_iter() + .map(|join_handle| join_handle.join()) + .flatten() + .fold( + None, + |possible_overlayed_image_or_error: Option>, image: Result<_>| { + if let Some(overlayed_image_or_error) = possible_overlayed_image_or_error { + if let Ok(mut overlayed_image) = overlayed_image_or_error { + if let Ok(image) = image { + overlay(&mut overlayed_image, &image, 0, 0); + Some(Ok(overlayed_image)) + } else { + Some(image) + } + } else { + Some(image) + } + } else { + Some(image) + } + }, + ) + .ok_or_else(|| { + tracing::error!("Provided capture region doesn't intersect with any outputs!"); + Error::NoOutputs + })? + }) } /// shot one ouput @@ -480,12 +501,12 @@ impl WayshotConnection { cursor_overlay: bool, ) -> Result { let frame_copy = self.capture_output_frame( - cursor_overlay as i32, + cursor_overlay, &output_info.wl_output, output_info.transform, None, )?; - (&frame_copy).try_into() + frame_copy.try_into() } /// Take a screenshot from all of the specified outputs. diff --git a/libwayshot/src/screencopy.rs b/libwayshot/src/screencopy.rs index 8ad59433..86cf86cd 100644 --- a/libwayshot/src/screencopy.rs +++ b/libwayshot/src/screencopy.rs @@ -46,10 +46,10 @@ pub struct FrameCopy { pub transform: wl_output::Transform, } -impl TryFrom<&FrameCopy> for RgbaImage { +impl TryFrom for RgbaImage { type Error = Error; - fn try_from(value: &FrameCopy) -> Result { + fn try_from(value: FrameCopy) -> Result { Ok(match value.frame_color_type { ColorType::Rgb8 | ColorType::Rgba8 => { create_image_buffer(&value.frame_format, &value.frame_mmap)? diff --git a/wayshot/Cargo.toml b/wayshot/Cargo.toml index e0e52f08..4b75d05e 100644 --- a/wayshot/Cargo.toml +++ b/wayshot/Cargo.toml @@ -16,8 +16,8 @@ flate2 = "1.0.27" [dependencies] clap = "4.4.6" -env_logger = { version = "0.10.0", default-features = false, features = ["auto-color", "color"] } -log = "0.4.20" +tracing = "0.1.37" +tracing-subscriber = "0.3.17" libwayshot = { version="0.3.0", path = "../libwayshot" } diff --git a/wayshot/src/clap.rs b/wayshot/src/clap.rs index 7163014b..37319334 100644 --- a/wayshot/src/clap.rs +++ b/wayshot/src/clap.rs @@ -8,7 +8,6 @@ pub fn set_flags() -> Command { .arg( arg!(-d - -debug) .required(false) - .conflicts_with("stdout") .action(ArgAction::SetTrue) .help("Enable debug mode"), ) diff --git a/wayshot/src/utils.rs b/wayshot/src/utils.rs index 55fe34f8..e24caf74 100644 --- a/wayshot/src/utils.rs +++ b/wayshot/src/utils.rs @@ -79,7 +79,7 @@ pub fn get_default_file_name(extension: EncodingFormat) -> String { let time = match SystemTime::now().duration_since(UNIX_EPOCH) { Ok(n) => n.as_secs().to_string(), Err(_) => { - log::error!("SystemTime before UNIX EPOCH!"); + tracing::error!("SystemTime before UNIX EPOCH!"); exit(1); } }; diff --git a/wayshot/src/wayshot.rs b/wayshot/src/wayshot.rs index 8a3769f1..b4b3c01f 100644 --- a/wayshot/src/wayshot.rs +++ b/wayshot/src/wayshot.rs @@ -1,5 +1,4 @@ use std::{ - env, error::Error, io::{stdout, BufWriter, Cursor, Write}, process::exit, @@ -11,6 +10,7 @@ mod clap; mod utils; use dialoguer::{theme::ColorfulTheme, FuzzySelect}; +use tracing::Level; use crate::utils::EncodingFormat; @@ -31,18 +31,19 @@ where fn main() -> Result<(), Box> { let args = clap::set_flags().get_matches(); - env::set_var("RUST_LOG", "wayshot=info"); - - if args.get_flag("debug") { - env::set_var("RUST_LOG", "wayshot=trace"); - } - - env_logger::init(); - log::trace!("Logger initialized."); + let level = if args.get_flag("debug") { + Level::TRACE + } else { + Level::INFO + }; + tracing_subscriber::fmt() + .with_max_level(level) + .with_writer(std::io::stderr) + .init(); let extension = if let Some(extension) = args.get_one::("extension") { let ext = extension.trim().to_lowercase(); - log::debug!("Using custom extension: {:#?}", ext); + tracing::debug!("Using custom extension: {:#?}", ext); match ext.as_str() { "jpeg" | "jpg" => EncodingFormat::Jpg, @@ -50,7 +51,7 @@ fn main() -> Result<(), Box> { "ppm" => EncodingFormat::Ppm, "qoi" => EncodingFormat::Qoi, _ => { - log::error!("Invalid extension provided.\nValid extensions:\n1) jpeg\n2) jpg\n3) png\n4) ppm\n5) qoi"); + tracing::error!("Invalid extension provided.\nValid extensions:\n1) jpeg\n2) jpg\n3) png\n4) ppm\n5) qoi"); exit(1); } } @@ -74,7 +75,7 @@ fn main() -> Result<(), Box> { if args.get_flag("listoutputs") { let valid_outputs = wayshot_conn.get_all_outputs(); for output in valid_outputs { - log::info!("{:#?}", output.name); + tracing::info!("{:#?}", output.name); } exit(1); } @@ -88,7 +89,7 @@ fn main() -> Result<(), Box> { if let Some(region) = utils::parse_geometry(slurp_region) { wayshot_conn.screenshot(region, cursor_overlay)? } else { - log::error!("Invalid geometry specification"); + tracing::error!("Invalid geometry specification"); exit(1); } } else if let Some(output_name) = args.get_one::("output") { @@ -96,7 +97,7 @@ fn main() -> Result<(), Box> { if let Some(output) = outputs.iter().find(|output| &output.name == output_name) { wayshot_conn.screenshot_single_output(output, cursor_overlay)? } else { - log::error!("No output found!\n"); + tracing::error!("No output found!\n"); exit(1); } } else if args.get_flag("chooseoutput") { @@ -108,7 +109,7 @@ fn main() -> Result<(), Box> { if let Some(index) = select_ouput(&output_names) { wayshot_conn.screenshot_single_output(&outputs[index], cursor_overlay)? } else { - log::error!("No output found!\n"); + tracing::error!("No output found!\n"); exit(1); } } else {