doe 1.1.89

doe is a powerful Rust crate designed to enhance development workflow by providing an extensive collection of useful macros and utility functions. It not only simplifies common tasks but also offers convenient features for clipboard management,robust cryptographic functions,keyboard input, and mouse interaction.
Documentation
//! macOS screen capture via CoreGraphics.
//!
//! Uses `CGDisplay::screenshot` (the same entry point the `screenshots` crate
//! relied on) through the `core-graphics` crate that `doe` already depends on.
//! Displays are enumerated with `CGDisplay::active_online_displays`.

use super::image_utils::{bgra_to_rgba, remove_row_padding};
use super::Screen;
use core_graphics::display::{
    kCGNullWindowID, kCGWindowImageDefault, kCGWindowListOptionOnScreenOnly, CGDisplay,
};
use core_graphics::geometry::{CGPoint, CGRect, CGSize};
use image::RgbaImage;

/// Enumerates all active online displays.
pub fn all() -> Result<Vec<Screen>, String> {
    let ids = CGDisplay::active_online_displays();
    let mut out = Vec::with_capacity(ids.len());
    for id in ids {
        let display = CGDisplay::new(id);
        let bounds = display.bounds();
        // mode dimensions give the physical pixel size; bounds is in points.
        let (pw, ph) = pixel_dimensions(&display);
        let scale = if bounds.size.width > 0.0 {
            (pw as f64 / bounds.size.width) as f32
        } else {
            1.0
        };
        out.push(Screen {
            id,
            x: bounds.origin.x as i32,
            y: bounds.origin.y as i32,
            width: bounds.size.width as u32,
            height: bounds.size.height as u32,
            scale_factor: scale.max(1.0),
        });
    }
    Ok(out)
}

/// Best-effort physical pixel dimensions; falls back to the bounds in points
/// when the mode APIs return nothing useful (headless / off-line).
fn pixel_dimensions(display: &CGDisplay) -> (usize, usize) {
    if let Some(mode) = display.display_mode() {
        return (mode.pixel_width() as usize, mode.pixel_height() as usize);
    }
    let b = display.bounds().size;
    (b.width as usize, b.height as usize)
}

/// Captures a rectangle of the given display.
fn capture_rect(screen: &Screen, rect: CGRect) -> Result<RgbaImage, String> {
    let cg_image = CGDisplay::screenshot(
        rect,
        kCGWindowListOptionOnScreenOnly,
        kCGNullWindowID,
        kCGWindowImageDefault,
    )
    .ok_or_else(|| format!("CGDisplay::screenshot failed for display {}", screen.id))?;

    let width = cg_image.width();
    let height = cg_image.height();
    let cleaned = remove_row_padding(
        width,
        height,
        cg_image.bytes_per_row(),
        Vec::from(cg_image.data().bytes()),
    );
    bgra_to_rgba(width as u32, height as u32, cleaned)
}

pub fn capture(screen: &Screen) -> Result<RgbaImage, String> {
    let display = CGDisplay::new(screen.id);
    capture_rect(screen, display.bounds())
}

pub fn capture_area(screen: &Screen, x: i32, y: i32, width: u32, height: u32) -> Result<RgbaImage, String> {
    let display = CGDisplay::new(screen.id);
    let origin = display.bounds().origin;
    let rect = CGRect {
        origin: CGPoint::new(origin.x + x as f64, origin.y + y as f64),
        size: CGSize::new(width as f64, height as f64),
    };
    capture_rect(screen, rect)
}