detached 7d47882

README.md RawHistoryFolder

[!WARNING] Early alpha. Built for NeferWL, and works on other compositors with the standard capture protocols (see Compatibility). Expect bugs and breaking config changes.


Usage

Bind nefercap to a key in your compositor. For NeferWL:

bind.cmd+p = spawn nefercap

Press the key: a selector covers every monitor. Pick what to capture, press Tab to switch between screenshot and recording, then confirm.

Chips at the top left show the mode (SHOT or REC) and the target (R Region, M Monitor, W Workspace). The active ones and the selection border take the mode color: cyan for screenshots, red for recordings. Each key press also shows a short toast in the center and pulses the border. While you drag a region, everything else fades out, leaving the region, its size and the guides.

After a screenshot, a green frame briefly flashes over the captured area. It is drawn after the capture, so it never appears in the image.

While recording on NeferWL, a border marks the target and a small REC / Stop HUD shows the time. Neither appears in the video. Press the key again, or click Stop, to finish the file. Other compositors show no indicator: the selector says so, and the same key (or nefercap stop) finishes the file.

Input Action
Drag Capture a rectangle
Click Capture the monitor
W, then Enter Capture the current workspace, or the monitor (with a warning) when there is none
M, then Enter Capture the monitor
1–9 Pick that monitor
R Back to rectangle selection
G Show or hide the thirds guides
Tab Switch shot ⇄ rec
Esc Cancel

On NeferWL a workspace recording follows that workspace, even when you switch to another one. Elsewhere W offers only the workspace currently shown, and records the monitor. A monitor recording follows whatever the monitor shows.

Features

  • One shortcut. Screenshot and recording share one selector; the same key stops a recording.
  • Frozen screenshots. The screenshot selector shows a still copy of the screen, and the screenshot is exactly that copy.
  • Clean video. With NeferWL the compositor keeps the border and HUD out of the recording.
  • Clipboard. Screenshots can be saved, copied, or both.
  • Small footprint. One capture in flight, reused buffers, no redraw while idle. Allocation tests guard the hot paths.
  • Scriptable. nefercap screenshot and nefercap record run without the selector.

Configuration

~/.config/nefercap/config (or $XDG_CONFIG_HOME/nefercap/config):

selector.grid = on
selector.freeze = on
screenshot.dir = ~/Pictures/Screenshots
screenshot.output = file+clipboard
video.dir = ~/Videos
Key Values Default
selector.grid on, off on
selector.freeze on, off on
screenshot.dir absolute or ~/ path $XDG_PICTURES_DIR/Screenshots
screenshot.output file, file+clipboard, clipboard file
video.dir absolute or ~/ path $XDG_VIDEOS_DIR

With selector.freeze = on, nefercap shot and the all-in-one selector in screenshot mode show the screen as it was when the selector opened, and capture that image. Press F in the selector to switch between the frozen and the live screen; the screenshot follows what is shown. Recording always selects and records the live screen. Rotated outputs, and outputs wider or taller than 4096 pixels, stay live.

Unknown keys, duplicates and invalid values are reported before the selector opens. Files are private, named with a timestamp, never overwritten, and their path is printed on stdout.

Commands

nefercap              # all-in-one: stop the recording, else open the selector
nefercap shot         # selector, screenshot only
nefercap rec          # selector, recording only
nefercap stop         # stop the active recording
nefercap status       # print the recording state
nefercap version      # print the version

Scripted commands never open the selector:

nefercap outputs
nefercap screenshot -output DP-1 -file shot.png
nefercap screenshot -output DP-1 -region 0,0,1920x1080 -clipboard
nefercap record -output DP-1 -fps 30 -duration 10s -file clip.mp4

nefercap -h lists every flag. Regions use output-local logical coordinates. -size WxH sets an even output resolution for odd-sized sources.

Requirements

  • Go 1.27 to build.
  • A Wayland compositor with ext_image_copy_capture_manager_v1, ext_output_image_capture_source_manager_v1 and zwlr_layer_shell_v1 v4.
  • Vulkan, libxkbcommon, linux-dmabuf and linux-drm-syncobj for the selector.
  • FFmpeg with libx264 to record.
  • wl-copy (wl-clipboard) for clipboard screenshots.

NeferWL's optional capture extension adds workspace and region sources and keeps the HUD out of the video. Without it nefercap uses only the standard protocols.

Compatibility

Compositor Screenshots, recording (outputs, regions) Workspaces Hidden workspace Recording indicator
NeferWL yes yes yes yes, imposed by the compositor
sway, river (wlroots ≥ 0.19), Hyprland, niri, COSMIC assumed assumed, where ext-workspace-v1 exists: active only no no
KDE Plasma assumed no no no
GNOME unsupported no no no

Workspaces need ext-workspace-v1; with NeferWL's extension the selector outlines the workspace frame (a workspace smaller than its monitor), and the HUD sits in it (placed when the recording starts: if the workspace frame changes during the recording, the video follows it and the HUD stays in place). Without the extension W outlines the whole monitor and captures the workspace currently shown, as its monitor. Without the extension a region is cropped from the monitor frame. Assumed means it follows from the protocols the compositor advertises; only NeferWL is tested.

A compositor may refuse a capture client; the capture then ends with an error.

Output is SDR, and video is silent H.264 in fragmented MP4. Audio, pause and cursor capture are not supported. Rotated outputs (any non-normal output transform) are not supported: the capture fails with an error naming the transform.

Install

On Arch Linux, install from the AUR:

paru -S nefercap-bin   # latest release, pre-built
paru -S nefercap-git   # latest main, built from source

Pre-built archives are on the releases page. To build from a checkout:

make bin    # builds bin/nefercap
make pkg    # builds an Arch package of HEAD into dist/

The packages install /usr/bin/nefercap: NeferWL allows that path to capture by default. Elsewhere (for example ~/.local/bin, or go run), NeferWL refuses capture until root lists the path in /etc/neferwl/capture-allow.

Development

internal/core owns capture and selection state and imports only the standard library and internal/ports. internal/adapters holds Wayland, selector, HUD, PNG and FFmpeg code; internal/app wires them.

make check
make race
make mocks-check
staticcheck ./...

Test doubles are generated by Mockery v3.

License

GPL-3.0. See LICENSE.

source
1<h1 align="center">nefercap</h1>
2
3<p align="center">
4  <a href="LICENSE"><img src="https://img.shields.io/badge/license-GPLv3-blue?style=flat-square" alt="License: GPLv3"></a>
5  <a href="https://github.com/bnema/nefercap"><img src="https://img.shields.io/badge/platform-Linux-blue?style=flat-square" alt="Platform: Linux"></a>
6  <a href="https://github.com/bnema/nefercap/commits/main"><img src="https://badgen.net/github/last-commit/bnema/nefercap/main?icon=github" alt="Last commit"></a>
7  <a href="https://github.com/bnema/nefercap/stargazers"><img src="https://badgen.net/github/stars/bnema/nefercap?icon=github" alt="GitHub stars"></a>
8</p>
9
10<p align="center">Screenshots and silent screen recording for Wayland, from one shortcut.</p>
11
12> [!WARNING]
13> **Early alpha.** Built for [NeferWL](https://github.com/bnema/neferwl), and works on other compositors with the standard capture protocols (see [Compatibility](#compatibility)). Expect bugs and breaking config changes.
14
15---
16
17## Usage
18
19Bind `nefercap` to a key in your compositor. For NeferWL:
20
21```text
22bind.cmd+p = spawn nefercap
23```
24
25Press the key: a selector covers every monitor. Pick what to capture, press **Tab** to switch between screenshot and recording, then confirm.
26
27Chips at the top left show the mode (`SHOT` or `REC`) and the target (`R Region`, `M Monitor`, `W Workspace`). The active ones and the selection border take the mode color: cyan for screenshots, red for recordings. Each key press also shows a short toast in the center and pulses the border. While you drag a region, everything else fades out, leaving the region, its size and the guides.
28
29After a screenshot, a green frame briefly flashes over the captured area. It is drawn after the capture, so it never appears in the image.
30
31While recording on NeferWL, a border marks the target and a small **REC / Stop** HUD shows the time. Neither appears in the video. Press the key again, or click Stop, to finish the file. Other compositors show no indicator: the selector says so, and the same key (or `nefercap stop`) finishes the file.
32
33| Input | Action |
34| --- | --- |
35| Drag | Capture a rectangle |
36| Click | Capture the monitor |
37| `W`, then Enter | Capture the current workspace, or the monitor (with a warning) when there is none |
38| `M`, then Enter | Capture the monitor |
39| `1`–`9` | Pick that monitor |
40| `R` | Back to rectangle selection |
41| `G` | Show or hide the thirds guides |
42| `Tab` | Switch shot ⇄ rec |
43| `Esc` | Cancel |
44
45On NeferWL a workspace recording follows that workspace, even when you switch to another one. Elsewhere `W` offers only the workspace currently shown, and records the monitor. A monitor recording follows whatever the monitor shows.
46
47## Features
48
49- **One shortcut.** Screenshot and recording share one selector; the same key stops a recording.
50- **Frozen screenshots.** The screenshot selector shows a still copy of the screen, and the screenshot is exactly that copy.
51- **Clean video.** With NeferWL the compositor keeps the border and HUD out of the recording.
52- **Clipboard.** Screenshots can be saved, copied, or both.
53- **Small footprint.** One capture in flight, reused buffers, no redraw while idle. Allocation tests guard the hot paths.
54- **Scriptable.** `nefercap screenshot` and `nefercap record` run without the selector.
55
56## Configuration
57
58`~/.config/nefercap/config` (or `$XDG_CONFIG_HOME/nefercap/config`):
59
60```ini
61selector.grid = on
62selector.freeze = on
63screenshot.dir = ~/Pictures/Screenshots
64screenshot.output = file+clipboard
65video.dir = ~/Videos
66```
67
68| Key | Values | Default |
69| --- | --- | --- |
70| `selector.grid` | `on`, `off` | `on` |
71| `selector.freeze` | `on`, `off` | `on` |
72| `screenshot.dir` | absolute or `~/` path | `$XDG_PICTURES_DIR/Screenshots` |
73| `screenshot.output` | `file`, `file+clipboard`, `clipboard` | `file` |
74| `video.dir` | absolute or `~/` path | `$XDG_VIDEOS_DIR` |
75
76With `selector.freeze = on`, `nefercap shot` and the all-in-one selector in screenshot mode show the screen as it was when the selector opened, and capture that image. Press `F` in the selector to switch between the frozen and the live screen; the screenshot follows what is shown. Recording always selects and records the live screen. Rotated outputs, and outputs wider or taller than 4096 pixels, stay live.
77
78Unknown keys, duplicates and invalid values are reported before the selector opens. Files are private, named with a timestamp, never overwritten, and their path is printed on stdout.
79
80## Commands
81
82```sh
83nefercap              # all-in-one: stop the recording, else open the selector
84nefercap shot         # selector, screenshot only
85nefercap rec          # selector, recording only
86nefercap stop         # stop the active recording
87nefercap status       # print the recording state
88nefercap version      # print the version
89```
90
91Scripted commands never open the selector:
92
93```sh
94nefercap outputs
95nefercap screenshot -output DP-1 -file shot.png
96nefercap screenshot -output DP-1 -region 0,0,1920x1080 -clipboard
97nefercap record -output DP-1 -fps 30 -duration 10s -file clip.mp4
98```
99
100`nefercap -h` lists every flag. Regions use output-local logical coordinates. `-size WxH` sets an even output resolution for odd-sized sources.
101
102## Requirements
103
104- Go 1.27 to build.
105- A Wayland compositor with `ext_image_copy_capture_manager_v1`, `ext_output_image_capture_source_manager_v1` and `zwlr_layer_shell_v1` v4.
106- Vulkan, libxkbcommon, linux-dmabuf and linux-drm-syncobj for the selector.
107- FFmpeg with `libx264` to record.
108- `wl-copy` (wl-clipboard) for clipboard screenshots.
109
110NeferWL's optional capture extension adds workspace and region sources and keeps the HUD out of the video. Without it nefercap uses only the standard protocols.
111
112## Compatibility
113
114| Compositor | Screenshots, recording (outputs, regions) | Workspaces | Hidden workspace | Recording indicator |
115| --- | --- | --- | --- | --- |
116| NeferWL | yes | yes | yes | yes, imposed by the compositor |
117| sway, river (wlroots ≥ 0.19), Hyprland, niri, COSMIC | assumed | assumed, where `ext-workspace-v1` exists: active only | no | no |
118| KDE Plasma | assumed | no | no | no |
119| GNOME | unsupported | no | no | no |
120
121Workspaces need `ext-workspace-v1`; with NeferWL's extension the selector outlines the workspace frame (a workspace smaller than its monitor), and the HUD sits in it (placed when the recording starts: if the workspace frame changes during the recording, the video follows it and the HUD stays in place). Without the extension `W` outlines the whole monitor and captures the workspace currently shown, as its monitor. Without the extension a region is cropped from the monitor frame. *Assumed* means it follows from the protocols the compositor advertises; only NeferWL is tested.
122
123A compositor may refuse a capture client; the capture then ends with an error.
124
125Output is SDR, and video is silent H.264 in fragmented MP4. Audio, pause and cursor capture are not supported. Rotated outputs (any non-normal output transform) are not supported: the capture fails with an error naming the transform.
126
127## Install
128
129On Arch Linux, install from the AUR:
130
131```sh
132paru -S nefercap-bin   # latest release, pre-built
133paru -S nefercap-git   # latest main, built from source
134```
135
136Pre-built archives are on the [releases page](https://github.com/bnema/nefercap/releases). To build from a checkout:
137
138```sh
139make bin    # builds bin/nefercap
140make pkg    # builds an Arch package of HEAD into dist/
141```
142
143The packages install `/usr/bin/nefercap`: NeferWL allows that path to capture by default. Elsewhere (for example `~/.local/bin`, or `go run`), NeferWL refuses capture until root lists the path in `/etc/neferwl/capture-allow`.
144
145## Development
146
147`internal/core` owns capture and selection state and imports only the standard library and `internal/ports`. `internal/adapters` holds Wayland, selector, HUD, PNG and FFmpeg code; `internal/app` wires them.
148
149```sh
150make check
151make race
152make mocks-check
153staticcheck ./...
154```
155
156Test doubles are generated by Mockery v3.
157
158## License
159
160GPL-3.0. See [LICENSE](LICENSE).

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 9

↑↓ moveenter openesc close