Cross-platform screen capture for macOS, Linux, Windows, and Android.
Frametap lets you capture your entire screen, a specific monitor, a window, or a custom region. It ships as a GUI app, a command-line tool, and a C++ library you can embed in your own apps.
brew tap krazyjakee/tap
brew install frametapcurl -fsSL https://krazyjakee.github.io/frametap/apt/frametap.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/frametap.gpg
echo "deb [signed-by=/usr/share/keyrings/frametap.gpg] https://krazyjakee.github.io/frametap/apt stable main" | sudo tee /etc/apt/sources.list.d/frametap.list
sudo apt update
sudo apt install frametapOr download the .deb directly from the Releases page and install with sudo apt install ./frametap_*.deb.
curl -fsSL https://raw.githubusercontent.com/krazyjakee/frametap/main/install.sh | shyay -S frametap-binscoop bucket add frametap https://github.com/krazyjakee/scoop-frametap
scoop install frametapwinget install krazyjakee.frametapGrab the latest release for your platform from the Releases page.
Each release includes separate downloads for:
- GUI —
frametap_gui(orframetap_gui.exe) — graphical app with live preview (desktop platforms only) - CLI —
frametap(orframetap.exe) — interactive command-line tool - Library —
lib/andinclude/— static C++ library for developers
Available platform archives:
linux— Linux x86_64windows— Windows x64macos-arm64— macOS Apple Siliconmacos-x86_64— macOS Intelandroid-arm64— Android ARM64 (library and CLI only)
Run the frametap command from a terminal:
# List available monitors
frametap --list-monitors
# Capture a monitor by ID
frametap --monitor 1
# Capture a window by ID
frametap --window 12345
# Capture a region (x,y,width,height)
frametap --region 0,0,1920,1080
# Save to a custom file
frametap --monitor 1 -o desktop.bmp
# Interactive mode (menu-driven)
frametap --interactiveRun frametap --help to see all options.
Capture modes (mutually exclusive):
--monitor <id> Capture a monitor by ID
--window <id> Capture a window by ID
--region <x>,<y>,<w>,<h> Capture a screen region
--interactive Interactive mode (menu-driven)
Options:
-o, --output <file> Output file (default: screenshot.bmp)
--list-monitors List available monitors and exit
--list-windows List available windows and exit
--check-permissions Check capture permissions and exit
-v, --version Show version and exit
-h, --help Show this help
macOS — The first time you run Frametap, macOS will ask you to grant Screen Recording permission. Go to System Settings > Privacy & Security > Screen Recording and enable it for your terminal app.
Linux (Wayland) — A system dialog will pop up asking you to pick which screen or window to share. This is normal — Wayland requires it for security.
Linux (X11) — No extra setup needed.
Windows — No extra setup needed. If you're on Remote Desktop, Frametap will automatically use a compatible capture method.
| Platform | Screenshots | Per Window | Region | Notes |
|---|---|---|---|---|
| macOS 12.3+ (ARM64 / Intel) | ✅ | ✅ | ✅ | Streaming via ScreenCaptureKit |
| macOS 10.15+ | ✅ | ❌ | ✅ | No streaming (CoreGraphics fallback) |
| Linux (Wayland) | ✅ | ✅ | ✅ | GNOME, KDE, Sway, Hyprland |
| Linux (X11) | ✅ | ✅ | ✅ | |
| Windows 10+ | ✅ | ✅ | ✅ | Streaming via DXGI |
| Windows 8+ | ✅ | ✅ | ✅ | No streaming (GDI fallback) |
| Android (ARM64) | ✅ | ❌ | ✅ | Library and CLI only |
Linux automatically detects Wayland vs X11 at runtime.
The graphical app gives you a live preview of any monitor or window on your system.
Launch the app:
./frametap_gui
The window has two panels:
- Sidebar — Lists all connected monitors and visible windows. Click any source to start capturing it. Hit Refresh to re-scan if you plug in a display or open a new window.
- Preview — Shows a live, aspect-ratio-preserving view of the selected source. Click Save PNG to save the current frame as
screenshot.pngin the working directory.
The GUI requires OpenGL 3.2+ and GLFW. See Dependencies for install instructions.
The command-line tool runs an interactive menu in your terminal.
./frametap
It will:
- Check that your system has the right permissions for screen capture
- Present a capture mode menu
- Save the result as
screenshot.bmpin the current directory
Capture mode:
1) Screen (pick a monitor)
2) Window (pick a window)
3) Region (enter coordinates)
- Screen — Lists all connected monitors with resolution and DPI scale. Enter a number to capture that monitor.
- Window — Lists all visible windows with their dimensions. Enter a number to capture that window.
- Region — Prompts for
x,y,width, andheightto capture an arbitrary rectangle.
The CLI saves a 24-bit BMP file named screenshot.bmp in the current working directory. The file is overwritten on each run.
If you'd rather build Frametap yourself instead of downloading a release, you'll need C++20 and SCons.
# Build the library
scons
# Build the CLI tool
scons cli
# Build the GUI app
scons guiThis produces:
libframetap.a(orframetap.libon Windows) — static librarycli/frametap— command-line toolgui/frametap_gui— graphical app
macOS — Xcode command-line tools (xcode-select --install). For the GUI, also install GLFW: brew install glfw.
Linux — Install the development libraries for your distro:
# Debian / Ubuntu
sudo apt install \
libx11-dev libxext-dev libxfixes-dev libxinerama-dev \
libpipewire-0.3-dev libsystemd-dev libwayland-dev \
pkg-config
# Fedora
sudo dnf install \
libX11-devel libXext-devel libXfixes-devel libXinerama-devel \
pipewire-devel systemd-devel wayland-devel \
pkg-config
# Arch
sudo pacman -S \
libx11 libxext libxfixes libxinerama \
pipewire libsystemd wayland \
pkg-configFor the GUI, also install GLFW:
# Debian / Ubuntu
sudo apt install libglfw3-dev
# Fedora
sudo dnf install glfw-devel
# Arch
sudo pacman -S glfwFor Wayland, you also need a portal backend for your compositor:
# GNOME
sudo apt install xdg-desktop-portal-gnome
# KDE
sudo apt install xdg-desktop-portal-kde
# Sway / wlroots
sudo apt install xdg-desktop-portal-wlr
# Hyprland
# install xdg-desktop-portal-hyprland from your distro or AURWindows — MSVC with C++20 support. For the GUI, install GLFW via vcpkg: vcpkg install glfw3:x64-windows-static.
Frametap also works as a static C++ library for embedding screen capture in your own applications.
#include <frametap/frametap.h>
#include <frametap/queue.h>
// Check platform readiness
auto perms = frametap::check_permissions();
if (perms.status == frametap::PermissionStatus::error) {
// perms.details has actionable advice
}
// Take a screenshot
frametap::FrameTap tap;
auto image = tap.screenshot();
// image.data = RGBA pixel buffer
// image.width, image.height = dimensions
// Stream frames
frametap::ThreadSafeQueue<frametap::Frame> queue;
tap.on_frame([&](const frametap::Frame& frame) {
queue.push(frame);
});
tap.start_async();
// ... process frames from queue ...
tap.pause(); // pause streaming
tap.resume(); // resume streaming
tap.stop();
// Enumerate monitors and windows
auto monitors = frametap::get_monitors();
auto windows = frametap::get_windows();Link the static library into your project:
# In your SConstruct
env.Append(CPPPATH=['path/to/frametap/include'])
env.Append(LIBPATH=['path/to/frametap/lib'])
env.Append(LIBS=['frametap'])
# + platform frameworks/libraries as needed| Function | Description |
|---|---|
get_monitors() |
List connected monitors with geometry and DPI scale |
get_windows() |
List visible windows (empty on Wayland — use portal picker) |
check_permissions() |
Diagnose platform permission/dependency issues |
| Method | Description |
|---|---|
FrameTap() |
Capture the full primary monitor |
FrameTap(Rect region) |
Capture a specific region |
FrameTap(Monitor monitor) |
Capture a specific monitor |
FrameTap(Window window) |
Capture a specific window |
set_region(Rect) |
Change the capture region |
on_frame(callback) |
Set frame callback (call before start) |
start() |
Start capture, blocks until stop() |
start_async() |
Start capture, returns immediately |
stop() |
Stop capture |
pause() |
Pause streaming (no frames delivered) |
resume() |
Resume streaming |
is_paused() |
Check if capture is paused |
screenshot() |
Grab a single frame |
screenshot(Rect) |
Grab a single frame of a region |
| Type | Fields |
|---|---|
Rect |
double x, y, width, height |
Monitor |
int id, x, y, width, height; std::string name; float scale |
Window |
uint64_t id; std::string name; int x, y, width, height |
ImageData |
std::vector<uint8_t> data; size_t width, height |
Frame |
ImageData image; double duration_ms |
PermissionCheck |
PermissionStatus status; std::string summary; std::vector<std::string> details |
ThreadSafeQueue<T> |
Thread-safe queue for passing frames between threads |
All errors throw frametap::CaptureError (inherits std::runtime_error) with platform-specific messages and actionable advice.
Hi! I'm krazyjakee, creator and maintainer of Frametap. If you find this project useful, consider sponsoring to help sustain and grow it: more dev time, better docs, more features, and deeper community support.
Every contribution helps maintain and improve this project and encourages me to make more projects like this!
This is optional support. The tool remains free and open-source regardless.
MIT — see LICENSE.