detached 709e2cd

Merge pull request #2 from bnema/docs/readme-refresh

docs(readme): restructure around usage, config and commands
commit
709e2cd15fcaef6a6becc930d2b86acf33aa3d9c
author
bnema · · 2026-09-30 16:36 UTC
committer
GitHub · · 2026-09-30 16:36 UTC
merge of
ddca06b + 259fd31 · diff against the first parent
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
refs
tag: v0.1.0
1 file · +79 -58
M README.md +79 -58
@@ -1,34 +1,56 @@
1-# nefercap
1+<h1 align="center">nefercap</h1>
22
3-Fast Wayland screenshots and silent video recording with a NeferGUI layer-shell selector.
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>
49
5-## Quick capture
10+<p align="center">Screenshots and silent screen recording for Wayland, from one shortcut.</p>
611
7-```sh
8-make bin
9-./bin/nefercap
10-./bin/nefercap shot
11-./bin/nefercap shot -clipboard
12-./bin/nefercap shot -clipboard -file capture.png
13-./bin/nefercap rec
14-./bin/nefercap stop
15-./bin/nefercap status
12+> [!WARNING]
13+> **Early alpha.** Built for [NeferWL](https://github.com/bnema/neferwl). Other compositors can take screenshots but cannot record. Expect bugs and breaking config changes.
14+
15+---
16+
17+## Usage
18+
19+Bind `nefercap` to a key in your compositor. For NeferWL:
20+
21+```text
22+bind.cmd+p = spawn nefercap
1623 ```
1724
18-`nefercap` without a command is all-in-one: it stops an active recording, otherwise opens the selector in shot mode. **Tab** switches shot ⇄ rec and keeps the chosen region, monitor or workspace; Enter or a click confirms in the current mode. It takes no flags except `-debug` and reads its settings from the config file. `shot` and `rec` keep a fixed mode (no Tab) and accept `-file`/`-clipboard` (shot) to override the config per run. A neutral badge at the top left of every overlay always shows the mode: `SHOT` or `REC`.
25+Press the key: a selector covers every monitor. Pick what to capture, press **Tab** to switch between screenshot and recording, then confirm. A badge at the top left shows the mode: `SHOT` or `REC`.
1926
20-The selector covers the connected outputs, up to nine:
27+While recording, a red 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.
2128
22-- **Drag and release:** capture a rectangle, clamped to its monitor.
23-- **Click:** capture the monitor; small pointer jitter counts as a click.
24-- **M, then Enter:** select the monitor.
25-- **W, then Enter:** select the current workspace when native workspace metadata is available.
26-- **R:** return to rectangle selection. **G:** toggle full-monitor center and thirds guides.
27-- **1–9:** select that monitor. **Esc:** cancel without creating a capture.
29+| Input | Action |
30+| --- | --- |
31+| Drag | Capture a rectangle |
32+| Click | Capture the monitor |
33+| `W`, then Enter | Capture the current workspace |
34+| `M`, then Enter | Capture the monitor |
35+| `1`–`9` | Pick that monitor |
36+| `R` | Back to rectangle selection |
37+| `G` | Show or hide the thirds guides |
38+| `Tab` | Switch shot ⇄ rec |
39+| `Esc` | Cancel |
2840
29-The selector shows mode keys and the current confirmation action in a two-line legend. Workspace hints appear only when a current workspace is available. Text uses a 1rem base (16 logical pixels), with proportional spacing and controls; the output's fractional scaling determines physical size.
41+A workspace recording follows that workspace, even when you switch to another one. A monitor recording follows whatever the monitor shows.
3042
31-The guides are visible by default: three vertical and three horizontal medium-gray lines, one physical pixel wide, aligned to each monitor's scaling. They stay fixed while dragging. Settings live in `$XDG_CONFIG_HOME/nefercap/config` (default `~/.config/nefercap/config`):
43+## Features
44+
45+- **One shortcut.** Screenshot and recording share one selector; the same key stops a recording.
46+- **Clean video.** The compositor keeps the border and HUD out of the recording.
47+- **Clipboard.** Screenshots can be saved, copied, or both.
48+- **Small footprint.** One capture in flight, reused buffers, no redraw while idle. Allocation tests guard the hot paths.
49+- **Scriptable.** `nefercap screenshot` and `nefercap record` run without the selector.
50+
51+## Configuration
52+
53+`~/.config/nefercap/config` (or `$XDG_CONFIG_HOME/nefercap/config`):
3254
3355 ```ini
3456 selector.grid = on
@@ -37,68 +59,67 @@ screenshot.output = file+clipboard
3759 video.dir = ~/Videos
3860 ```
3961
40-- `selector.grid`: `on` (default) or `off` to hide the guides on startup.
41-- `screenshot.dir`, `video.dir`: an absolute path or `~/…`; relative paths are errors. Absent, the XDG defaults below apply. Before the selector opens, nefercap creates (private) and checks each directory the command can use: both for all-in-one, one for `shot` or `rec`.
42-- `screenshot.output`: `file` (default), `file+clipboard` (save, then copy the same PNG) or `clipboard` (copy only; no file, no path printed).
62+| Key | Values | Default |
63+| --- | --- | --- |
64+| `selector.grid` | `on`, `off` | `on` |
65+| `screenshot.dir` | absolute or `~/` path | `$XDG_PICTURES_DIR/Screenshots` |
66+| `screenshot.output` | `file`, `file+clipboard`, `clipboard` | `file` |
67+| `video.dir` | absolute or `~/` path | `$XDG_VIDEOS_DIR` |
4368
44-Each key may appear once; blank lines and `#` comment lines are allowed; unknown keys, duplicates and invalid values are errors reported before the selector opens. `screenshot.output` and the directories apply to all-in-one, `shot` and `rec`; the scripted `screenshot` and `record` never read them. On `shot`, `-clipboard` alone copies only, `-clipboard -file PATH` saves and copies, and `-file PATH` alone saves only, whatever `screenshot.output` says. **G** changes visibility for the current monitor's overlay without rewriting the config. Selection dimensions are logical pixels; the captured file's dimensions depend on the monitor scaling.
69+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.
4570
46-A screenshot saves immediately. Recording displays a red border around the visible target and a small **REC / Stop** HUD. Both are excluded from nefercap's video. The HUD takes no keyboard focus; clicks outside Stop pass through. Press the recording shortcut again, click Stop, or run `nefercap stop` to finish the file.
71+## Commands
4772
48-Monitor recording follows workspace changes. A workspace recording follows its stable identity and continues when another workspace is displayed. A fixed region stays attached to its monitor. A hidden workspace has no border on the unrelated visible workspace; the recording HUD remains available.
73+```sh
74+nefercap # all-in-one: stop the recording, else open the selector
75+nefercap shot # selector, screenshot only
76+nefercap rec # selector, recording only
77+nefercap stop # stop the active recording
78+nefercap status # print the recording state
79+```
4980
50-Without `screenshot.dir`/`video.dir`, screenshots go to the configured XDG Pictures directory's `Screenshots` subdirectory, and videos to the XDG Videos directory. Names include a nanosecond timestamp. `-file` chooses an explicit destination. Files are private to their owner and are never overwritten. The saved path is printed to stdout, including for scripted commands. Cancelling before any frame is written creates no file and prints no path.
81+Scripted commands never open the selector:
5182
52-`shot -clipboard` copies an `image/png` screenshot using `wl-copy` without creating a capture file or printing a path. Add `-file PATH` to save and copy the same PNG. A successfully saved file is retained and its path printed even if clipboard copying later fails. The clipboard owner intentionally survives nefercap's exit. This CLI-only option also works with scripted `screenshot`; other commands reject it. Install `wl-clipboard` to use it.
83+```sh
84+nefercap outputs
85+nefercap screenshot -output DP-1 -file shot.png
86+nefercap screenshot -output DP-1 -region 0,0,1920x1080 -clipboard
87+nefercap record -output DP-1 -fps 30 -duration 10s -file clip.mp4
88+```
5389
54-`shot` while a recording is active is refused: its overlay is not part of the existing session's authorized controls. A scripted `screenshot` still uses standard capture and includes the active HUD and border.
90+`nefercap -h` lists every flag. Regions use output-local logical coordinates. `-size WxH` sets an even output resolution for odd-sized sources.
5591
5692 ## Requirements
5793
58-- Go 1.27 for development; normal builds use `CGO_ENABLED=0`.
59-- For selection: layer-shell v4, Vulkan, libxkbcommon, linux-dmabuf and linux-drm-syncobj.
60-- For capture: `zwlr_screencopy_manager_v1`.
61-- For recording indicators and workspace targets: NeferWL's native capture-session protocol.
62-- FFmpeg with `libx264` for silent H.264 video in fragmented MP4.
94+- Go 1.27 to build.
95+- A Wayland compositor with `zwlr_layer_shell_v1` v4 and `zwlr_screencopy_manager_v1`.
96+- Vulkan, libxkbcommon, linux-dmabuf and linux-drm-syncobj for the selector.
97+- NeferWL's capture-session protocol to record.
98+- FFmpeg with `libx264` to record.
6399 - `wl-copy` (wl-clipboard) for clipboard screenshots.
64100
65-A standard compositor can support monitor/region screenshots. Recording refuses to start without native session support rather than capture its own controls. Standard capture clients keep their normal behavior and see the HUD and border.
101+Output is SDR, and video is silent H.264 in fragmented MP4. Audio, pause and cursor capture are not supported.
66102
67-## Scripted commands
103+## Install
68104
69105 ```sh
70-./bin/nefercap outputs
71-./bin/nefercap screenshot -output DP-1 -file capture.png
72-./bin/nefercap screenshot -output DP-1 -region 0,0,1920x1080 -file region.png
73-./bin/nefercap record -output DP-1 -fps 30 -duration 10s -file capture.mp4
74-./bin/nefercap rec -size 1920x1080 -file presentation.mp4
106+make bin # builds bin/nefercap
75107 ```
76108
77-Use an output name from `outputs`. Scripted `screenshot` requires `-file` unless `-clipboard` is used; `record` always requires `-file`; omitting `-output` is allowed with exactly one output. Regions use output-local logical coordinates, not desktop-global coordinates. Capture dimensions are physical pixels negotiated with the compositor.
78-
79-`-fps` accepts 1–120, default 30. `-size` requires two even dimensions and changes encoded resolution, not application scaling. Odd source dimensions require an explicit even size; pixels are not silently cropped. `-debug` enables diagnostic logging.
80-
81-Untimed recording stops with the HUD, the control command, Ctrl+C or SIGTERM and finalizes the file. The `stop` command acknowledges the request; finalization finishes in the recorder process, not before the control reply. Timed recording encodes `ceil(duration × fps)` frames. Slow capture can repeat frames; encoder backpressure can extend wall time without adding an unbounded queue.
82-
83-Screenshots and video are opaque SDR. Audio, pause and cursor guarantees are not supported. NeferWL ignores the capture protocol's cursor option.
84-
85-## Architecture and footprint
86-
87-`internal/core` owns capture and selection state and imports only stdlib and `internal/ports`. `internal/adapters` contains Wayland, selection, indicator, control, PNG and FFmpeg integrations. `internal/app` wires them together.
109+Copy `bin/nefercap` to a directory on your `PATH`.
88110
89-One capture is in flight. Writers synchronously consume borrowed, reusable shared-memory storage. Video strips stride padding and handles vertical inversion without a full-frame heap copy. The selector opens one transient layer surface per output; the HUD is one small surface, not a fullscreen GPU buffer. Idle UI does not redraw continuously.
111+## Development
90112
91-The encoder uses `veryfast`, `zerolatency`, two encoding threads and one filter thread. Its separate-process footprint is not the Go heap; lower buffering can produce larger files than slower presets.
113+`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.
92114
93115 ```sh
94116 make check
95117 make race
96118 make mocks-check
97119 staticcheck ./...
98-go test ./... -run '^$' -bench . -benchmem
99120 ```
100121
101-Mockery v3 generates test doubles. Allocation guards cover frame views, selection state, unchanged overlay geometry, HUD refresh, video rows, encoder writes and output lookup. Protocol capture has a measured allocation budget; the application does not claim zero total allocations.
122+Test doubles are generated by Mockery v3.
102123
103124 ## License
104125
@@ -1,34 +1,56 @@
1-# nefercap1+<h1 align="center">nefercap</h1>
2 2
3-Fast Wayland screenshots and silent video recording with a NeferGUI layer-shell selector.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>
4 9
5-## Quick capture10+<p align="center">Screenshots and silent screen recording for Wayland, from one shortcut.</p>
6 11
7-```sh12+> [!WARNING]
8-make bin13+> **Early alpha.** Built for [NeferWL](https://github.com/bnema/neferwl). Other compositors can take screenshots but cannot record. Expect bugs and breaking config changes.
9-./bin/nefercap14+
10-./bin/nefercap shot15+---
11-./bin/nefercap shot -clipboard16+
12-./bin/nefercap shot -clipboard -file capture.png17+## Usage
13-./bin/nefercap rec18+
14-./bin/nefercap stop19+Bind `nefercap` to a key in your compositor. For NeferWL:
15-./bin/nefercap status20+
21+```text
22+bind.cmd+p = spawn nefercap
16 ```23 ```
17 24
18-`nefercap` without a command is all-in-one: it stops an active recording, otherwise opens the selector in shot mode. **Tab** switches shot ⇄ rec and keeps the chosen region, monitor or workspace; Enter or a click confirms in the current mode. It takes no flags except `-debug` and reads its settings from the config file. `shot` and `rec` keep a fixed mode (no Tab) and accept `-file`/`-clipboard` (shot) to override the config per run. A neutral badge at the top left of every overlay always shows the mode: `SHOT` or `REC`.25+Press the key: a selector covers every monitor. Pick what to capture, press **Tab** to switch between screenshot and recording, then confirm. A badge at the top left shows the mode: `SHOT` or `REC`.
19 26
20-The selector covers the connected outputs, up to nine:27+While recording, a red 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.
21 28
22-- **Drag and release:** capture a rectangle, clamped to its monitor.29+| Input | Action |
23-- **Click:** capture the monitor; small pointer jitter counts as a click.30+| --- | --- |
24-- **M, then Enter:** select the monitor.31+| Drag | Capture a rectangle |
25-- **W, then Enter:** select the current workspace when native workspace metadata is available.32+| Click | Capture the monitor |
26-- **R:** return to rectangle selection. **G:** toggle full-monitor center and thirds guides.33+| `W`, then Enter | Capture the current workspace |
27-- **1–9:** select that monitor. **Esc:** cancel without creating a capture.34+| `M`, then Enter | Capture the monitor |
35+| `1`–`9` | Pick that monitor |
36+| `R` | Back to rectangle selection |
37+| `G` | Show or hide the thirds guides |
38+| `Tab` | Switch shot ⇄ rec |
39+| `Esc` | Cancel |
28 40
29-The selector shows mode keys and the current confirmation action in a two-line legend. Workspace hints appear only when a current workspace is available. Text uses a 1rem base (16 logical pixels), with proportional spacing and controls; the output's fractional scaling determines physical size.41+A workspace recording follows that workspace, even when you switch to another one. A monitor recording follows whatever the monitor shows.
30 42
31-The guides are visible by default: three vertical and three horizontal medium-gray lines, one physical pixel wide, aligned to each monitor's scaling. They stay fixed while dragging. Settings live in `$XDG_CONFIG_HOME/nefercap/config` (default `~/.config/nefercap/config`):43+## Features
44+
45+- **One shortcut.** Screenshot and recording share one selector; the same key stops a recording.
46+- **Clean video.** The compositor keeps the border and HUD out of the recording.
47+- **Clipboard.** Screenshots can be saved, copied, or both.
48+- **Small footprint.** One capture in flight, reused buffers, no redraw while idle. Allocation tests guard the hot paths.
49+- **Scriptable.** `nefercap screenshot` and `nefercap record` run without the selector.
50+
51+## Configuration
52+
53+`~/.config/nefercap/config` (or `$XDG_CONFIG_HOME/nefercap/config`):
32 54
33 ```ini55 ```ini
34 selector.grid = on56 selector.grid = on
@@ -37,68 +59,67 @@ screenshot.output = file+clipboard
37 video.dir = ~/Videos59 video.dir = ~/Videos
38 ```60 ```
39 61
40-- `selector.grid`: `on` (default) or `off` to hide the guides on startup.62+| Key | Values | Default |
41-- `screenshot.dir`, `video.dir`: an absolute path or `~/…`; relative paths are errors. Absent, the XDG defaults below apply. Before the selector opens, nefercap creates (private) and checks each directory the command can use: both for all-in-one, one for `shot` or `rec`.63+| --- | --- | --- |
42-- `screenshot.output`: `file` (default), `file+clipboard` (save, then copy the same PNG) or `clipboard` (copy only; no file, no path printed).64+| `selector.grid` | `on`, `off` | `on` |
65+| `screenshot.dir` | absolute or `~/` path | `$XDG_PICTURES_DIR/Screenshots` |
66+| `screenshot.output` | `file`, `file+clipboard`, `clipboard` | `file` |
67+| `video.dir` | absolute or `~/` path | `$XDG_VIDEOS_DIR` |
43 68
44-Each key may appear once; blank lines and `#` comment lines are allowed; unknown keys, duplicates and invalid values are errors reported before the selector opens. `screenshot.output` and the directories apply to all-in-one, `shot` and `rec`; the scripted `screenshot` and `record` never read them. On `shot`, `-clipboard` alone copies only, `-clipboard -file PATH` saves and copies, and `-file PATH` alone saves only, whatever `screenshot.output` says. **G** changes visibility for the current monitor's overlay without rewriting the config. Selection dimensions are logical pixels; the captured file's dimensions depend on the monitor scaling.69+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.
45 70
46-A screenshot saves immediately. Recording displays a red border around the visible target and a small **REC / Stop** HUD. Both are excluded from nefercap's video. The HUD takes no keyboard focus; clicks outside Stop pass through. Press the recording shortcut again, click Stop, or run `nefercap stop` to finish the file.71+## Commands
47 72
48-Monitor recording follows workspace changes. A workspace recording follows its stable identity and continues when another workspace is displayed. A fixed region stays attached to its monitor. A hidden workspace has no border on the unrelated visible workspace; the recording HUD remains available.73+```sh
74+nefercap # all-in-one: stop the recording, else open the selector
75+nefercap shot # selector, screenshot only
76+nefercap rec # selector, recording only
77+nefercap stop # stop the active recording
78+nefercap status # print the recording state
79+```
49 80
50-Without `screenshot.dir`/`video.dir`, screenshots go to the configured XDG Pictures directory's `Screenshots` subdirectory, and videos to the XDG Videos directory. Names include a nanosecond timestamp. `-file` chooses an explicit destination. Files are private to their owner and are never overwritten. The saved path is printed to stdout, including for scripted commands. Cancelling before any frame is written creates no file and prints no path.81+Scripted commands never open the selector:
51 82
52-`shot -clipboard` copies an `image/png` screenshot using `wl-copy` without creating a capture file or printing a path. Add `-file PATH` to save and copy the same PNG. A successfully saved file is retained and its path printed even if clipboard copying later fails. The clipboard owner intentionally survives nefercap's exit. This CLI-only option also works with scripted `screenshot`; other commands reject it. Install `wl-clipboard` to use it.83+```sh
84+nefercap outputs
85+nefercap screenshot -output DP-1 -file shot.png
86+nefercap screenshot -output DP-1 -region 0,0,1920x1080 -clipboard
87+nefercap record -output DP-1 -fps 30 -duration 10s -file clip.mp4
88+```
53 89
54-`shot` while a recording is active is refused: its overlay is not part of the existing session's authorized controls. A scripted `screenshot` still uses standard capture and includes the active HUD and border.90+`nefercap -h` lists every flag. Regions use output-local logical coordinates. `-size WxH` sets an even output resolution for odd-sized sources.
55 91
56 ## Requirements92 ## Requirements
57 93
58-- Go 1.27 for development; normal builds use `CGO_ENABLED=0`.94+- Go 1.27 to build.
59-- For selection: layer-shell v4, Vulkan, libxkbcommon, linux-dmabuf and linux-drm-syncobj.95+- A Wayland compositor with `zwlr_layer_shell_v1` v4 and `zwlr_screencopy_manager_v1`.
60-- For capture: `zwlr_screencopy_manager_v1`.96+- Vulkan, libxkbcommon, linux-dmabuf and linux-drm-syncobj for the selector.
61-- For recording indicators and workspace targets: NeferWL's native capture-session protocol.97+- NeferWL's capture-session protocol to record.
62-- FFmpeg with `libx264` for silent H.264 video in fragmented MP4.98+- FFmpeg with `libx264` to record.
63 - `wl-copy` (wl-clipboard) for clipboard screenshots.99 - `wl-copy` (wl-clipboard) for clipboard screenshots.
64 100
65-A standard compositor can support monitor/region screenshots. Recording refuses to start without native session support rather than capture its own controls. Standard capture clients keep their normal behavior and see the HUD and border.101+Output is SDR, and video is silent H.264 in fragmented MP4. Audio, pause and cursor capture are not supported.
66 102
67-## Scripted commands103+## Install
68 104
69 ```sh105 ```sh
70-./bin/nefercap outputs106+make bin # builds bin/nefercap
71-./bin/nefercap screenshot -output DP-1 -file capture.png
72-./bin/nefercap screenshot -output DP-1 -region 0,0,1920x1080 -file region.png
73-./bin/nefercap record -output DP-1 -fps 30 -duration 10s -file capture.mp4
74-./bin/nefercap rec -size 1920x1080 -file presentation.mp4
75 ```107 ```
76 108
77-Use an output name from `outputs`. Scripted `screenshot` requires `-file` unless `-clipboard` is used; `record` always requires `-file`; omitting `-output` is allowed with exactly one output. Regions use output-local logical coordinates, not desktop-global coordinates. Capture dimensions are physical pixels negotiated with the compositor.109+Copy `bin/nefercap` to a directory on your `PATH`.
78-
79-`-fps` accepts 1–120, default 30. `-size` requires two even dimensions and changes encoded resolution, not application scaling. Odd source dimensions require an explicit even size; pixels are not silently cropped. `-debug` enables diagnostic logging.
80-
81-Untimed recording stops with the HUD, the control command, Ctrl+C or SIGTERM and finalizes the file. The `stop` command acknowledges the request; finalization finishes in the recorder process, not before the control reply. Timed recording encodes `ceil(duration × fps)` frames. Slow capture can repeat frames; encoder backpressure can extend wall time without adding an unbounded queue.
82-
83-Screenshots and video are opaque SDR. Audio, pause and cursor guarantees are not supported. NeferWL ignores the capture protocol's cursor option.
84-
85-## Architecture and footprint
86-
87-`internal/core` owns capture and selection state and imports only stdlib and `internal/ports`. `internal/adapters` contains Wayland, selection, indicator, control, PNG and FFmpeg integrations. `internal/app` wires them together.
88 110
89-One capture is in flight. Writers synchronously consume borrowed, reusable shared-memory storage. Video strips stride padding and handles vertical inversion without a full-frame heap copy. The selector opens one transient layer surface per output; the HUD is one small surface, not a fullscreen GPU buffer. Idle UI does not redraw continuously.111+## Development
90 112
91-The encoder uses `veryfast`, `zerolatency`, two encoding threads and one filter thread. Its separate-process footprint is not the Go heap; lower buffering can produce larger files than slower presets.113+`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.
92 114
93 ```sh115 ```sh
94 make check116 make check
95 make race117 make race
96 make mocks-check118 make mocks-check
97 staticcheck ./...119 staticcheck ./...
98-go test ./... -run '^$' -bench . -benchmem
99 ```120 ```
100 121
101-Mockery v3 generates test doubles. Allocation guards cover frame views, selection state, unchanged overlay geometry, HUD refresh, video rows, encoder writes and output lookup. Protocol capture has a measured allocation budget; the application does not claim zero total allocations.122+Test doubles are generated by Mockery v3.
102 123
103 ## License124 ## License
104 125

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