Skip to content

Latest commit

 

History

History
183 lines (125 loc) · 5.68 KB

File metadata and controls

183 lines (125 loc) · 5.68 KB

wlgif

crates.io

Lightweight screen recorder for Wayland that captures regions as GIFs

About

Screen-to-GIF on Wayland has historically been painful. wlgif solves this with a simple, seamless workflow: select a region, record, and get a GIF. No configuration, no complexity.

Backends

wlgif supports two recording backends:

Backend Compositors How it works
portal Any (GNOME, KDE, etc...) XDG Desktop Portal + PipeWire + GStreamer
wlr wlroots-based (Sway, Hyprland, etc...) slurp + wf-recorder + ffmpeg

The backend is auto-detected, preferring portal for broader compatibility. Use --backend to override.

Unix Philosophy

wlgif follows core Unix principles:

  • Do one thing well - Screen region to GIF
  • Compose, don't reinvent - Leverages battle-tested tools instead of reimplementing capture/encoding

What this means for features: We welcome additions that make screen-to-GIF better. What we won't become: an image editor, video editor, or general-purpose media tool.

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines and HACKING.md for development.

Installation

Cargo

cargo install wlgif

Nix

wlgif is available as a nix flake via GitHub

# From GitHub
nix run github:doprz/wlgif

From Source

To build and install from source, first checkout the tag or branch you want to install, then run

cargo install --path .

This will build and install wlgif in your ~/.cargo/bin. Make sure that ~/.cargo/bin is in your $PATH variable.

Dependencies

XDG Desktop Portal Backend

Works on any Wayland compositor with portal support.

Dependency Purpose
xdg-desktop-portal Screen capture API
pipewire Media streaming
gstreamer Video encoding
ffmpeg GIF encoding

GStreamer Requirements: Requires GStreamer >= 1.14 with base plugins and additional plugin packages.

See https://crates.io/crates/gstreamer for more info.

On Debian/Ubuntu:

apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
      gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
      gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
      gstreamer1.0-libav libgstrtspserver-1.0-dev libges-1.0-dev

On Fedora:

dnf install gstreamer1-devel gstreamer1-plugins-base-devel \
      gstreamer1-plugins-good gstreamer1-plugins-bad-free \
      gstreamer1-plugin-libav gstreamer1-rtsp-server-devel \
      gst-editing-services-devel

Additional Fedora packages (RPMFusion):

dnf install gstreamer1-plugins-bad-freeworld gstreamer1-plugins-ugly

wlroots Backend

For wlroots-based compositors (Sway, Hyprland, Niri, dwl, etc.)

Dependency Purpose
slurp Region selection
wf-recorder Screen capture
ffmpeg GIF encoding

Usage

Usage: wlgif [OPTIONS]

Options:
  -b, --backend <NAME>      Recording backend (auto-detected if not specified)
  -o, --output <OUTPUT>     Output GIF file path [default: output.gif]
  -d, --duration <SECS>     Recording duration in seconds (0 = manual stop with Ctrl+C) [default: 5]
  -f, --fps <FPS>           Frames per second (10-30 recommended) [default: 15]
  -g, --geometry <WxH+X+Y>  Region geometry, skip interactive selection (WxH+X+Y)
  -w, --width <PX>          Scale output width in pixels (height auto-calculated)
      --fast                Skip palette optimization (faster, larger file)
      --keep-video          Keep intermediate video file
  -q, --quiet               Suppress status output
  -h, --help                Print help
  -V, --version             Print version

Examples:
  wlgif                     Select region, record for 5s (default behavior)
  wlgif -d 10               Record for 10 seconds
  wlgif -d 0                Manual stop with Ctrl+C
  wlgif -g 800x600+100+100  Skip selection, use geometry
  wlgif --fps 30 -w 640     30fps, scaled to 640px wide
  wlgif --backend xdg-desktop-portal    Use XDG portal backend (cross-compositor)
  wlgif --backend wlroots               Use wlroots backend (supports slurp region selection)

Dependencies:
  portal:  xdg-desktop-portal, pipewire, gstreamer
  wlr:     slurp, wf-recorder, ffmpeg

Tips

Goal Command
Smaller files wlgif -w 480 --fps 10
Higher quality wlgif --fps 30
Quick capture wlgif --fast
Scripting wlgif -q -g 800x600+0+0

How It Works

XDG Desktop Portal Backend

  1. Portal request: Asks the compositor for screen access via D-Bus
  2. Source selection: Compositor shows its native picker (window/monitor)
  3. PipeWire capture: Receives video stream from compositor
  4. GStreamer encoding: Encodes stream to MP4

wlroots Backend

  1. Region selection: slurp draws a selection overlay
  2. Capture: wf-recorder records via wlroots screencopy protocol

Backend Abstraction Layer to Gif

  1. Palette generation: ffmpeg analyzes video for optimal 256-color palette
  2. Encoding: ffmpeg applies Floyd-Steinberg dithering -> GIF

The two-pass encoding is why wlgif produces smaller, better-looking GIFs than naive single-pass conversion.

Acknowledgements

  • Ghostty for inspiration on NixOS VM testing infrastructure
  • nix.dev for the NixOS VM configuration tutorial

License

SPDX-License-Identifier: MIT

Licensed under the MIT License. See LICENSE for full details.