A native Wayland screenshot and annotation overlay designed for Omarchy and Hyprland. It captures the focused monitor before mapping an exclusive layer-shell surface, so the editor never appears in its own screenshot. The editor retains annotations as movable, resizable vector layers and preserves the monitor's native pixels on scaled displays.
- Freeform region, window, and full-monitor capture modes.
- A pointer-side readout that turns any drag into a ruler: the pointer position while the crosshair is idle, then the frame size in native export pixels while a region, a hovered window, or a crop handle is being sized.
- Window capture is a crop of the focused-monitor frame. Overlapping windows stay visible; there is no second clean-window recapture.
- Select/move/resize layers, mouse-wheel scaling, and eight external recropping handles.
- Arrows, straight lines, smoothed freehand strokes, translucent highlighter strokes, hollow or filled rectangles (optionally rounded) and ellipses, numbered markers, editable Neucha text (on a readability pill), and secure redaction with opaque or randomized non-spatial mosaic output.
- Per-layer preset or custom colors (including highlighter ink), undo/redo history, one-click whole-image OCR, mesh-gradient backdrops, and rendered drop shadows.
- Cut tool: drag across a band of the image to remove it and collapse the gap, with a live preview and dashed seam marker while dragging; annotations shift to follow.
- Pin a finished capture as a bottom-right always-on-top layer surface, launched
from the same
omasnapexecutable and visible on every workspace. - Crash-resistant working documents under
/run/user/<UID>/omasnap/(falling back to a private/tmp/omasnap-<UID>/): the original source image plus a sidecar JSON operation log. Undo still works after a crash or--filereopen. Saving and copying write a normal flattened PNG to the clipboard or~/Pictures/Screenshots. - Verified PNG clipboard output through
wl-copy/wl-paste, plus timestamped files under~/Pictures/Screenshotsby default. - Open an image already on the clipboard directly in the annotation editor.
- Correct native-pixel export on fractional or integer-scaled monitors.
The supported target is Wayland + Hyprland, with Omarchy as the primary integration.
The renderer, layer surface, clipboard, and monitor capture use Wayland protocols;
monitor/window discovery currently calls hyprctl. The focused output is captured
in-process through ext-image-copy-capture before the layer maps. Selection displays
that captured frame, while the annotation editor uses
a translucent layer scrim over the live desktop and draws only the selected capture.
Another Wayland compositor could support the application after supplying equivalent
monitor and window discovery; generic Wayland support is not claimed by 1.0.
Runtime commands used by the application:
hyprctlwl-copyandwl-pastetesseractomarchy-notification-sendwhen available; saved captures include a thumbnail and reopen in Omasnap when clicked. Notification failure does not invalidate output.
Clone the repository and run the Omarchy installer:
git clone https://github.com/tobi/omasnap.git
cd omasnap
./install-omarchyThe installer uses Omarchy's package helper for missing dependencies, builds in
~/.cache/omasnap, and installs under ~/.local. It does not modify
Hyprland configuration.
Paste this into a Lua config loaded after require("default.hypr.omarchy"):
hl.unbind("PRINT")
hl.unbind("F12")
hl.unbind("ALT + SHIFT + 4")
o.bind("PRINT", "Screenshot", "omasnap")
o.bind("F12", "Screenshot", "omasnap")
o.bind("ALT + SHIFT + 4", "Screenshot", "omasnap")
hl.layer_rule({
match = { namespace = "^omasnap$" },
no_anim = true,
animation = "none",
no_screen_share = true,
})Each of these keys toggles: the first press opens the overlay, the next press dismisses it.
Apply and verify:
hyprctl reload
hyprctl configerrors
hyprctl binds -j | jq -c \
'[.[] | select(.description == "Screenshot") | {modmask,key,description}]'omarchy plugin add is intentionally not used. Omarchy plugins are Quickshell QML
extensions; they do not install native executables or system packages.
Set OMASNAP_PREFIX before running install-omarchy to use a prefix other than
~/.local.
Install the complete build/runtime dependency set:
sudo pacman -S --needed \
base-devel cmake ninja pkgconf qt6-base layer-shell-qt \
wayland wayland-protocols hyprland wl-clipboard \
tesseract tesseract-data-engBuild and install:
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$HOME/.local"
cmake --build build --parallel
cmake --install buildThe install step places:
~/.local/bin/omasnap~/.local/share/applications/omasnap.desktop~/.local/share/licenses/omasnap/Neucha-OFL.txt
Ensure ~/.local/bin is on PATH, then verify the installed CLI:
omasnap --version
omasnap --helpRunning without arguments opens freeform region selection:
omasnapExplicit starting modes:
omasnap --capture-region
omasnap --capture-window
omasnap --capture-fullscreenCompatibility positional names are also accepted:
omasnap region
omasnap windows
omasnap fullscreen
omasnap smart # maps to region selectionThese options choose what is initially selected; the editor still controls whether the result is copied, saved, or both.
Quick output skips the annotation editor. Add --copy to copy only, --save to save
only, or both flags to copy and save. Region and window captures output after selection;
fullscreen captures output immediately. Quick output cannot be combined with --file,
--clipboard, or --pin.
Only one capture overlay runs at a time, guarded by a lock file in the runtime snapshot
directory. Starting omasnap while an overlay is open sends the running instance SIGTERM,
which it handles with a clean Qt shutdown; the new process then exits without capturing.
Pressing PRINT therefore opens the overlay and pressing it again dismisses it.
Every capture invocation dismisses this way, quick output included: --copy/--save
while an overlay is open closes the overlay and outputs nothing, rather than screenshotting
the overlay that is still on screen.
Editing an existing image is never cancelled this way: --file, --clipboard, or an
image path stops the running instance, waits up to two seconds for the lock, and opens the
editor on that image. That is how a pin's Edit button and a notification click always land
in the editor.
A lock left behind by a crashed instance is removed and reclaimed. A lock file that cannot be read or written at all is reported on stderr instead of being mistaken for a running instance.
Exit codes:
| Code | Meaning |
|---|---|
0 |
Success, including dismissing a running overlay |
1 |
Capture, image, or single-instance lock failure |
2 |
Usage error |
Point omasnap at any readable image and it opens straight into the annotation editor with the whole image selected, skipping the screen-capture step:
omasnap ~/Pictures/Screenshots/screenshot-2026-08-11_10-00-00.png
# or
omasnap --file /path/to/capture.pngTo open the image currently on the Wayland clipboard:
omasnap --clipboardThe clipboard must offer readable image data. Text-only clipboard contents return an error instead of opening an empty editor.
File URLs are accepted too. A saved capture notification's "Click to edit" action launches
omasnap on the finished screenshot, so it can be reopened and re-annotated. Captures copied
without saving are not retained on disk and therefore have no delayed edit action.
Environment overrides:
OMASNAP_SCREENSHOT_DIR="$HOME/Pictures/Captures" omasnap
OMASNAP_OCR_LANGS="eng+deu" omasnap
# Thai plus English:
OMASNAP_OCR_LANGS="tha+eng" omasnapInstall the corresponding Tesseract language data before adding a language to
OMASNAP_OCR_LANGS. When unset, omasnap falls back to Omarchy's
OMARCHY_OCR_LANGS (which commonly includes the user's script, e.g.
tha+eng), then to eng.
| Input | Action |
|---|---|
| Drag | Select a region, with its native pixel size shown at the pointer |
Space |
Toggle region/window selection |
SUPER + Arrow |
Move among windows in window mode |
Enter |
Capture the highlighted window |
Ctrl+A |
Select the full focused monitor |
Esc, Esc |
Dismiss |
| Input | Action |
|---|---|
V |
Select/move/resize layers; drag empty canvas for a marquee; wheel scales the selected layer |
A |
Arrow |
S |
Spotlight/loupe; press again to cycle ellipse, rectangle, rounded |
L |
Straight line |
F |
Freehand stroke |
I |
Eyedropper in the color popover · sample the image as the custom color |
C |
Numbered marker |
R |
Rectangle; hover the shape button for rectangle, ellipse, and fill controls; Alt+wheel rounds corners |
E |
Ellipse; shares the shape submenu and filled/hollow toggle |
D |
Redact; press again to toggle randomized pixelation or solid redaction |
X |
Cut out a band; drag to preview the crossed-out strip, then release to remove and collapse it |
T |
Neucha text on a cream readability pill; Enter adds a line, clicking away keeps the text; press T again to toggle the pill |
O |
Recognize and copy all text in the current image |
B |
Cycle backdrop |
1–8 |
Set annotation color; 7 is black and 8 is white |
| Wheel | Scale selected layer, magnify the spotlight under the cursor, or change active tool size (Alt+wheel: rectangle corner radius or spotlight border); while just viewing a zoomed capture, scroll it like a document |
Shift+wheel |
Scroll a zoomed capture sideways (a wide stitch); never changes the zoom |
Ctrl+wheel · middle-drag |
Zoom about the cursor · pan by dragging |
+ / - / 0 (also with Ctrl) |
Zoom in / out / fit |
Hold Shift while dragging |
Make rectangles, ellipses, and spotlights 1:1; snap lines and arrows to 45°; while dragging a selected layer's handle, keep a rectangle, redaction or spotlight's aspect ratio (lines and arrows: 45°) |
Hold Alt while dragging |
Center rectangles, ellipses, and spotlights on the press point; add Shift for a centered square/circle |
← ↑ → ↓ |
Nudge the selected layer 1 px; hold Shift for 10 px (a held key is one undo step). With nothing selected, pan a zoomed capture |
| Double-click text | Reopen text editing |
Delete |
Delete selected layer |
Alt+D |
Duplicate selected layer (offset down-left, or away from a nearby edge); the copy becomes the selection |
Ctrl+Z |
Undo |
Ctrl+Shift+Z, Ctrl+Y |
Redo |
Ctrl+C |
Copy PNG only |
Ctrl+S |
Save PNG only |
Enter |
Copy and save |
P |
Pin the capture on screen and close the editor |
Esc |
Return to Select; press again to close |
| Right-click | Return to Select; cancel active drawing |
P renders the current capture, writes it to a pin-<pid>-<n>-<random>.png under
the runtime snapshot directory, and launches the same omasnap executable in
detached pin mode. Active pins stack from the bottom-right and can be dragged
by the image background. The layer stays visible on every workspace without
compositor window rules. It preserves the image
aspect ratio, with a maximum width of one third of the screen and a maximum height of one
half.
Pinning neither touches the clipboard nor writes to the screenshot directory; it is a
fourth output alongside copy, save, and copy-and-save. P closes the editor and releases
the single-instance lock immediately. Pins from separate captures accumulate as independent
processes.
Hover the pin to reveal its controls:
| Input on a pin | Action |
|---|---|
| Edit button | Reopen the full-resolution PNG in Omasnap and replace the pin |
| Link button | Copy the source file path |
Copy button, Ctrl+C |
Copy the full-resolution PNG |
| Double-wide top-left drag handle | Drag the PNG into a file-capable drop target |
| Wheel | Resize within the screen caps, preserving aspect ratio |
Close button, Esc, middle-click |
Close |
Image and path copying use wl-copy rather than QClipboard, so clipboard data remains
available after the pin is closed. No font-based symbol set or compositor-specific window
rule is required; the controls use the same vector icon renderer as the annotation toolbar.
Creation tools return to Select after one placement without selecting the new layer. In Select mode, arrows and lines show only their two endpoint handles; other layers show a selection boundary. The eight blue/white handles outside the image recrop its corners or edges.
make checkThe smoke executable exercises region/window/fullscreen startup modes, capture selection, working-document persistence (source plus op-log JSON), annotation tools, undo/redo replay, vector movement and scaling, text editing, OCR, native-DPI output, endpoint-only line selection, external crop handles, and the native-pixel measurement readout on a scaled monitor.
.github/workflows/build-linux.yml runs the same make check build, interaction smoke,
and available static-analysis checks in an Arch Linux container, stages the CMake installation, and uploads a versioned Linux
artifact. A v* tag also attaches that artifact to the corresponding GitHub release.
The capture and annotation workflow is inspired by three excellent screenshot tools:
- Shottr — fast region/window capture, OCR, and polished backdrops.
- Satty — a focused, Wayland-native annotation workflow.
- Flameshot — selection-first capture and an approachable annotation toolbar.
Thanks to their authors and contributors for establishing the interaction patterns that made this project possible. Omasnap is an independent implementation and is not affiliated with those projects.
This standalone repository was extracted with git filter-repo from the original Omarchy
system-customization repository. The former omasnap/ directory was promoted to
the repository root while retaining its relevant commit history.
The bundled Neucha font is distributed under the SIL Open Font License; its license is in
assets/OFL.txt and is installed with the application.
