miniscreenshot-wgpu 0.1.0

wgpu screenshot helper for the miniscreenshot ecosystem. Re-exports wgpu.
Documentation

miniscreenshot

A pluggable, multi-crate Rust workspace for taking screenshots of windowed applications or the entire desktop.


Crate overview

Crate Description
miniscreenshot CoreScreenshot type, PNG / PPM / PGM encoding, ScreenshotProvider / AsyncScreenshotProvider traits
miniscreenshot-softbuffer softbuffer integration + re-export. Enable the winit feature to re-export winit alongside softbuffer.
miniscreenshot-wgpu wgpu texture readback + re-export
miniscreenshot-wayland Wayland wlr-screencopy-v1 system capture + re-exports
miniscreenshot-x11 X11 (XGetImage / MIT-SHM) system capture + re-exports
miniscreenshot-portal XDG Desktop Portal (ashpd) system capture; works on GNOME, KDE, wlroots, and inside Flatpak/Snap
miniscreenshot-skia skia-safe re-export + surface screenshot helper
miniscreenshot-vello vello re-export + pixel readback support

Design goals

  • Pluggable — each rendering backend is a separate crate. Applications depend only on what they use.
  • No version conflicts — every driver crate re-exports its underlying library (e.g., miniscreenshot_wgpu::wgpu). Depending on a driver crate is sufficient; no separate wgpu/winit/… dependency required.
  • Low-friction output formats — PNG (default), PPM and PGM are supported out of the box. Format is inferred from the file extension.
  • System screenshots — Linux Wayland via zwlr_screencopy_manager_v1 (wlroots-based compositors: Sway, Hyprland, …), X11 via XGetImage with an MIT-SHM fast path, and XDG Desktop Portal via ashpd (GNOME, KDE, Flatpak, Snap).

Quick start

Core crate

[dependencies]
miniscreenshot = "0.1"
use miniscreenshot::Screenshot;

// Build from raw RGBA8 pixel data
let data = vec![255u8, 0, 0, 255]; // 1×1 red pixel
let shot = Screenshot::from_rgba(1, 1, data);

// Save — format inferred from extension (.png / .ppm / .pgm)
shot.save("screenshot.png").unwrap();

// Or encode to bytes explicitly
let png_bytes: Vec<u8> = shot.encode_png().unwrap();
let ppm_bytes: Vec<u8> = shot.encode_ppm();   // lossless, trivial format
let pgm_bytes: Vec<u8> = shot.encode_pgm();   // grayscale

softbuffer backend

[dependencies]
miniscreenshot-softbuffer = "0.1"
use miniscreenshot_softbuffer::{softbuffer, screenshot_from_xrgb};

// softbuffer stores pixels as u32 XRGB8888 values
let pixels: &[u32] = /* buffer.deref() from softbuffer */ &[];
let shot = screenshot_from_xrgb(pixels, width, height);
shot.save("screenshot.png").unwrap();

softbuffer + winit pairing

When you want to create a softbuffer::Surface from a winit::Window, enable the winit feature. This re-exports winit alongside softbuffer at the same version, avoiding dependency conflicts.

[dependencies]
miniscreenshot-softbuffer = { version = "0.1", features = ["winit"] }
use miniscreenshot_softbuffer::winit::window::Window;
use miniscreenshot_softbuffer::softbuffer;
use std::rc::Rc;

// Rc<Window> implements the raw-handle traits softbuffer needs.
let window: Rc<Window> = /* create window */;
let ctx = softbuffer::Context::new(window.clone()).unwrap();
let surface = softbuffer::Surface::new(&ctx, window.clone()).unwrap();

See the softbuffer_winit_scene_screenshot example for a complete demo.

wgpu backend

[dependencies]
miniscreenshot-wgpu = "0.1"
use miniscreenshot_wgpu::{wgpu, capture_texture};

// `texture` must have been created with TextureUsages::COPY_SRC
let shot = capture_texture(&device, &queue, &texture).unwrap();
shot.save("screenshot.png").unwrap();

Wayland system screenshot

[dependencies]
miniscreenshot-wayland = "0.1"
use miniscreenshot_wayland::WaylandCapture;

let mut cap = WaylandCapture::connect().expect("connect to Wayland");
println!("{} output(s) found", cap.output_count());

// Capture first monitor
let shot = cap.capture_output(0).expect("capture");
shot.save("screenshot.png").unwrap();

// Or capture all monitors at once
let shots = cap.capture_all().expect("capture all");

Compositor requirements: Requires a Wayland compositor that implements zwlr_screencopy_manager_v1 (wlroots-based — Sway, Hyprland, weston, cage, labwc, …). GNOME-on-Wayland and KWin do not implement this protocol and will return WaylandCaptureError::NoScreencopyManager. Use miniscreenshot-portal instead on these compositors.

X11 system screenshot

[dependencies]
miniscreenshot-x11 = "0.1"
use miniscreenshot_x11::X11Capture;

let mut cap = X11Capture::connect().expect("connect to X11");
println!("{} screen(s) found", cap.screen_count());

// Capture first screen
let shot = cap.capture_screen(0).expect("capture");
shot.save("screenshot.png").unwrap();

// Or capture all screens at once
let shots = cap.capture_all().expect("capture all");

Server requirements: Requires a reachable X11 server ($DISPLAY set). Uses MIT-SHM when available for a fast-path capture; otherwise falls back to a plain XGetImage transfer over the wire.

Screenshot portal (GNOME / KDE / Flatpak)

[dependencies]
miniscreenshot-portal = "0.1"

Blocking usage (default):

use miniscreenshot_portal::PortalCapture;

let mut cap = PortalCapture::connect().expect("connect to portal");
let shot = cap.capture_interactive().expect("capture");
shot.save("screenshot.png").unwrap();

Async usage:

[dependencies]
miniscreenshot-portal = { version = "0.1", default-features = false, features = ["tokio"] }
use miniscreenshot_portal::PortalCapture;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut cap = PortalCapture::connect_async().await?;
    let shot = cap.capture_interactive_async().await?;
    shot.save("screenshot.png")?;
    Ok(())
}

Portal requirements: Requires a running desktop session with $XDG_RUNTIME_DIR and a portal implementation (xdg-desktop-portal + a backend such as xdg-desktop-portal-gnome, -kde, -wlr, or -gtk). GNOME always shows a confirmation dialog; KDE and wlroots may or may not depending on backend policy. Works inside Flatpak and Snap sandboxes. Use this crate on GNOME or KWin instead of miniscreenshot-wayland.

ScreenshotProvider trait

All driver crates implement (or wrap types that implement) the core ScreenshotProvider trait, making backends interchangeable:

use miniscreenshot::ScreenshotProvider;

fn take_and_save<P: ScreenshotProvider>(provider: &mut P)
where P::Error: std::fmt::Debug
{
    let shot = provider.take_screenshot().unwrap();
    shot.save("output.png").unwrap();
}

Optional features

# Winit (for softbuffer + winit integration)
miniscreenshot-softbuffer = { version = "0.1", features = ["winit"] }

Async traits

The core miniscreenshot crate exposes the AsyncScreenshotProvider trait with zero additional dependencies (the trait uses return-position impl Trait). It is always available — no feature flag required:

miniscreenshot = "0.1"

Portal features

miniscreenshot-portal exposes runtime and API-surface features. Enabling a runtime (tokio or async-std) automatically enables the async API surface.

# Default: tokio runtime + blocking API + async API
miniscreenshot-portal = "0.1"

# Async-only with tokio (no blocking convenience methods)
miniscreenshot-portal = { version = "0.1", default-features = false, features = ["tokio"] }

# Async-only with async-std
miniscreenshot-portal = { version = "0.1", default-features = false, features = ["async-std"] }

The tokio and async-std runtime features are mutually exclusive. The blocking API-surface feature is independent. The async API surface is implied by whichever runtime you select, but can also be enabled standalone if you want to provide your own executor.


Output formats

Format Method Notes
PNG encode_png() / save("file.png") Lossless, widely supported
PPM encode_ppm() / save("file.ppm") Binary P6, trivial to parse
PGM encode_pgm() / save("file.pgm") Binary P5 grayscale (BT.601 luma)

Examples

Each crate ships with a self-contained examples/<crate_short>_scene_screenshot.rs that renders a scene (or synthesises a buffer) and saves a PNG.

Crate Command Headless?
miniscreenshot (core) cargo run -p miniscreenshot --example core_scene_screenshot Yes
miniscreenshot-softbuffer cargo run -p miniscreenshot-softbuffer --example softbuffer_scene_screenshot Yes
miniscreenshot-softbuffer (winit) cargo run -p miniscreenshot-softbuffer --example softbuffer_winit_scene_screenshot --features winit No (needs a display)
miniscreenshot-wgpu cargo run -p miniscreenshot-wgpu --example wgpu_scene_screenshot Yes
miniscreenshot-wayland cargo run -p miniscreenshot-wayland --example wayland_scene_screenshot No (needs wlroots-based Wayland compositor)
miniscreenshot-x11 cargo run -p miniscreenshot-x11 --example x11_scene_screenshot No (needs $DISPLAY / X11 server)
miniscreenshot-portal cargo run -p miniscreenshot-portal --example portal_scene_screenshot No (needs desktop session with portal)
miniscreenshot-portal (async) cargo run -p miniscreenshot-portal --example portal_async_scene_screenshot --features async No (needs desktop session with portal)
miniscreenshot-skia cargo run -p miniscreenshot-skia --example skia_scene_screenshot Yes
miniscreenshot-vello cargo run -p miniscreenshot-vello --example vello_scene_screenshot Yes

Build all examples at once:

task examples:build

Build and run all headless examples:

task examples

License

Licensed under either of Apache License 2.0 or MIT License at your option.