From eea3c757c0ad97077735d90085c9062c60f0f59f Mon Sep 17 00:00:00 2001 From: candifloss Date: Mon, 8 Dec 2025 16:12:03 +0530 Subject: [PATCH] Add module `output.rs` for image file path - Modularity - Avoid code duplication - FIx comments in `core.rs` --- src/core.rs | 2 +- src/fullscreen.rs | 28 +++++----------------------- src/output.rs | 26 ++++++++++++++++++++++++++ src/window.rs | 32 +++++++++++++------------------- 4 files changed, 45 insertions(+), 43 deletions(-) create mode 100644 src/output.rs diff --git a/src/core.rs b/src/core.rs index 54f9a82..26fe4cf 100644 --- a/src/core.rs +++ b/src/core.rs @@ -52,7 +52,7 @@ impl XContext { /// /// `ctxt` – connection + screen info\ /// `x_coord,y_coord` – top-left corner of the rectangle\ -/// `w,h` – size of the rectangle +/// `width,height` – size of the rectangle /// /// Returns: a `Vec` containing RGBA pixel data. pub fn capture_rect( diff --git a/src/fullscreen.rs b/src/fullscreen.rs index aa20a12..872d353 100644 --- a/src/fullscreen.rs +++ b/src/fullscreen.rs @@ -1,8 +1,8 @@ mod core; +mod output; -use chrono::Local; use core::{XContext, capture_rect, save_png}; -use std::fs; +use output::make_screenshot_path; fn main() -> anyhow::Result<()> { // Create a connection to the X11 server and read screen information. @@ -12,31 +12,13 @@ fn main() -> anyhow::Result<()> { // We pass (0,0) as the top-left corner and use the screen width/height. let img = capture_rect(&ctx, 0, 0, ctx.width, ctx.height)?; - // Build the output file path. - // Example: - // ~/Pictures/Screenshots/screenshot_20250116094530.png - // - // Using a timestamp prevents overwriting old screenshots. - let timestamp = Local::now().format("%Y%m%d%H%M%S").to_string(); - - // Start from the user's home directory (fallback: current dir). - let mut path = dirs::home_dir().unwrap_or_else(|| ".".into()); - path.push("Pictures"); - path.push("Screenshots"); - - // Make sure the directory exists. - fs::create_dir_all(&path)?; - - // Add the actual filename. - path.push(format!("screenshot_{timestamp}.png")); - - // Convert path to string for save_png(). + // Output file path + let path = make_screenshot_path()?; let path_str = path.to_string_lossy(); // Write the captured RGBA image to a PNG file. save_png(&path_str, ctx.width, ctx.height, &img)?; - println!("Saved {path_str}"); - + println!("Saved screenshot: {path_str}"); Ok(()) } diff --git a/src/output.rs b/src/output.rs new file mode 100644 index 0000000..51cf128 --- /dev/null +++ b/src/output.rs @@ -0,0 +1,26 @@ +use chrono::Local; +use dirs::home_dir; +use std::fs; +use std::path::PathBuf; + +/// Build the full output path: +/// ``` +/// ~/Pictures/Screenshots/screenshot_YYYYMMDDHHMMSS.png +/// ``` +/// The directory is created automatically if it doesn't exist. +pub fn make_screenshot_path() -> anyhow::Result { + let timestamp = Local::now().format("%Y%m%d%H%M%S").to_string(); + + // Get $HOME (fallback: current working directory) + let mut path = home_dir().unwrap_or_else(|| ".".into()); + path.push("Pictures"); + path.push("Screenshots"); + + // Ensure the directory exists. + fs::create_dir_all(&path)?; + + // Add filename. + path.push(format!("screenshot_{timestamp}.png")); + + Ok(path) +} diff --git a/src/window.rs b/src/window.rs index 18c3193..1d38faf 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,9 +1,10 @@ mod core; +mod output; use core::{XContext, capture_rect, save_png}; +use output::make_screenshot_path; -use chrono::Local; -use std::fs; +use std::convert::TryFrom; use x11rb::protocol::xproto::{AtomEnum, ConnectionExt, GetGeometryReply, Window}; fn main() -> anyhow::Result<()> { @@ -11,34 +12,27 @@ fn main() -> anyhow::Result<()> { let ctx = XContext::new()?; // Try to get the currently active window using EWMH (_NET_ACTIVE_WINDOW). - let window = get_active_window(&ctx).unwrap_or_else(|| { - eprintln!("Could not get active window. Falling back to input focus."); - get_focused_window(&ctx).unwrap_or(ctx.root) - }); + let window = get_active_window(&ctx) + .or_else(|| get_focused_window(&ctx)) + .unwrap_or(ctx.root); // Read the size and position of that window. let geom = get_window_geometry(&ctx, window)?; - let x = u16::try_from(geom.x.max(0)).unwrap(); - let y = u16::try_from(geom.y.max(0)).unwrap(); + let x = u16::try_from(geom.x.max(0))?; + let y = u16::try_from(geom.y.max(0))?; // Capture only the window rectangle. let img = capture_rect(&ctx, x, y, geom.width, geom.height)?; - // Build output path: ~/Pictures/Screenshots/window_TIMESTAMP.png - let timestamp = Local::now().format("%Y%m%d%H%M%S").to_string(); - - let mut path = dirs::home_dir().unwrap_or_else(|| ".".into()); - path.push("Pictures"); - path.push("Screenshots"); - fs::create_dir_all(&path)?; - path.push(format!("window_{timestamp}.png")); - + // Get output file path + let path = make_screenshot_path()?; let path_str = path.to_string_lossy(); + + // Save image to path save_png(&path_str, geom.width, geom.height, &img)?; - println!("Saved {path_str}"); - + println!("Saved screenshot: {path_str}"); Ok(()) }