Skip to content

Repository files navigation

Latchshot

A lightweight yet intelligent window-aware screenshot tool for Wayland. Latchshot freezes the current desktop, snaps to the window under the pointer, and falls back to a freely drawn region when you drag.

Demo

Latchshot demo

Requirements

Latchshot targets compositors that expose the Wayland protocols needed by its custom overlay. The compositor must support:

Compositor support

Compositor Status Selection support
Niri (with a customized fork) Supported Window snapping and free-form regions
Upstream Niri Supported but limited Window snapping and free-form regions
Sway Supported Window snapping and free-form regions
Hyprland Supported Window snapping and free-form regions
Mango Supported Window snapping and free-form regions
Other compatible Wayland compositors Best effort Free-form regions only
KDE Plasma Intentionally unsupported —
GNOME Intentionally unsupported —

The generic backend is selected automatically for unknown compositors.

When upstream Niri rejects the custom WindowGeometries request, Latchshot reconstructs visible window positions from standard Niri IPC layout metadata and the frozen output pixels. If an output cannot be resolved unambiguously, window snapping is disabled for that output rather than guessing.

KDE Plasma and GNOME remain intentionally out of scope because Latchshot targets this protocol stack rather than portal- or desktop-shell-specific screenshot flows.

Copying to clipboard (the default destiniation) also requires wl-copy from wl-clipboard.

Native window capture

Clicking a highlighted window uses native toplevel capture when available, preserving compositor-provided transparency such as rounded corners. Latchshot uses Wayland's ext-image-copy-capture-v1 with foreign-toplevel identifiers, or Niri's ScreenshotWindow IPC. Niri may also copy the intermediate image to the clipboard.

If native capture is unavailable or fails, Latchshot crops the frozen desktop frame; pass --prefer-crop to enforce cropping even when the protocol is supported.

The overlay remains rectangular because Wayland does not expose compositor corner masks. Other projects, like HyprCapture, use compositor-specific hacks to capture rounded corners and introduced lots of complexity. I intentionally avoids this path.

Installation

From source

With Cargo:

cargo install latchshot

Nix

Run directly:

nix run github:so1ve/latchshot

With a Nix flake, add Latchshot to the inputs:

inputs.latchshot.url = "github:so1ve/latchshot";

Then add the package to a NixOS configuration:

{ inputs, pkgs, ... }:

{
  environment.systemPackages = [
    inputs.latchshot.packages.${pkgs.stdenv.hostPlatform.system}.default
  ];
}

Alternatively, use the overlay to make pkgs.latchshot available:

{ inputs, pkgs, ... }:

{
  nixpkgs.overlays = [
    inputs.latchshot.overlays.default
  ];

  environment.systemPackages = [
    pkgs.latchshot
  ];
}

Cachix

Use the project cache for prebuilt Nix artifacts when available:

nix.settings = {
  extra-substituters = [ "https://so1ve.cachix.org" ];
  extra-trusted-public-keys = [
    "so1ve.cachix.org-1:51jcW4FkJhiLcqPsiUx3nglRP469les8F9zjFxio1nw="
  ];
};

Usage

Run Latchshot with no destination to copy the selected screenshot to the clipboard:

latchshot

During selection:

  • Move the pointer to highlight the window underneath it.
  • Left-click a highlighted window to capture it.
  • Left-drag to select an arbitrary region.
  • Press F to capture the output under the pointer.
  • Press Esc or right-click to cancel.

Save directly to a file:

latchshot --output ~/Pictures/screenshot.png

Write PNG data to standard output:

latchshot --stdout > screenshot.png

Destinations can be combined. For example, this saves the screenshot to a file, streams it to standard output, and copies it to the clipboard:

latchshot --output ~/Pictures/screenshot.png --stdout --clipboard > screenshot-copy.png

To disable animation:

latchshot --no-animation

To disable desktop notifications:

latchshot --no-notify

To always crop clicked windows from the frozen desktop frame instead of using native window capture:

latchshot --prefer-crop

Print the discovered scene as JSON for diagnostics:

latchshot --windows

Force Niri's standard-IPC window reconstruction path for diagnostics:

LATCHSHOT_NIRI_FORCE_FALLBACK=1 latchshot

Run latchshot --help for all options. Set RUST_LOG=latchshot=debug for additional diagnostics.

Workflow Examples

Annotate with Satty, save the result as a timestamped file under ~/Pictures, and play the desktop's screenshot sound. Press Enter in Satty when finished:

file="$HOME/Pictures/latchshot-$(date +'%Y-%m-%d_%H-%M-%S').png"; latchshot --stdout | satty --filename - --output-filename "$file" --actions-on-enter=save-to-file,exit; test -s "$file" && canberra-gtk-play --id=screen-capture

The equivalent workflow with Swappy writes the annotated image when Swappy exits:

file="$HOME/Pictures/latchshot-$(date +'%Y-%m-%d_%H-%M-%S').png"; latchshot --stdout | swappy --file - --output-file "$file"; test -s "$file" && canberra-gtk-play --id=screen-capture

Library Usage

Latchshot can also be used as a Rust library. See the API documentation on docs.rs for details.

AI Usage Disclosure

GPT 5.6-Sol was used to generate compositor adapters for Hyprland, Sway and MangoWM, which I do not use. Doc comments and tests are generated under my guidance.

License

MIT. Made with ♥️ by Ray.

About

A lightweight yet intelligent window-aware screenshot tool for Wayland

Resources

Stars

9 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages