Caliper
Freeze the screen, measure any gap, sample any pixel, and copy the colour or the distance without leaving your work.
Press the hotkey and the desktop stops. From that moment you are working on a still image: a crosshair that snaps to edges, a magnifier showing individual pixels, and a drag that measures. Escape puts everything back.
Why freezing matters
A measuring tool that works on the live screen has to fight the compositor for input, and anything under the pointer can move while you are reading it. Caliper takes one capture, shows it fullscreen, and measures that. Nothing moves while you work, and the interaction is simple enough to be exact.
Sharp freeze, sensible numbers
The capture is taken at native resolution, so the frozen desktop is pixel-sharp and a sampled colour is the true colour on screen rather than a resampled approximation of it.
Positions and measurements are reported in logical pixels, which is the unit you would write in a stylesheet. On a fractionally scaled display a 24px gap reads as 24, and the device-pixel figure is shown alongside it so nothing is hidden from you.
Capturing at logical scale instead was tried, and it makes the whole frozen desktop visibly soft: a 2880-wide capture drawn onto a 3840-wide panel. Sample in device pixels and convert for display; do not capture small.
Edge snapping
The crosshair looks up to six pixels around the pointer for a luminance step and
lands on the nearest one. Placing a measurement by eye is a pixel or two out
every time, and a pixel or two is the whole difference between 24 and 26. The
nearest strong edge wins rather than the strongest in range, so the boundary you
are pointing at beats a harder edge further away. Press s to turn it off.
Colour
The readout is the exact captured pixel, not an interpolation: hex, RGB, and
position. Press p on one colour and then hover another to get their WCAG
contrast ratio and whether it passes AA or AAA, which is the number an
accessibility review will actually ask for.
Keys
| Key | Action |
|---|---|
| drag | measure a distance; the readout shows width, height and diagonal |
c |
copy the colour as hex |
r |
copy the colour as RGB |
m |
copy the current measurement |
p |
pin the current colour as the contrast reference |
s |
toggle edge snapping |
space |
clear the measurement |
esc or right click |
close |
Install
omarchy plugin add https://github.com/angus-mcritchie/omarchy-caliper.git --enable
Remove it again with:
omarchy plugin disable angus.caliper # keep it installed, stop loading it
omarchy plugin remove angus.caliper # delete it
Then bind it. In ~/.config/hypr/bindings.lua:
o.bind("SUPER + SHIFT + I", "Caliper (measure & pick)", "omarchy-shell angus.caliper toggle")
SHIFT + I mirrors the inspect shortcut in browser devtools, and is unbound in
stock Omarchy. Any spare combination works; the command is what matters:
omarchy-shell angus.caliper toggle
Requirements
grim for the capture, ImageMagick for the pixel plane, jq, and wl-copy for
the clipboard. All but ImageMagick already ship with Omarchy.
How pixels are read, and one thing to know if you fork this
The capture is written twice: a PNG for display, and a raw RGB plane at the same native resolution. Reading a pixel is a seek into that plane, which costs about two milliseconds; decoding the PNG per sample cost sixty-seven. A 13x13 block around the cursor is read when the pointer settles, and it serves both the colour readout and the edge search. The crosshair and the magnifier are pure transforms, so they stay live while the numbers settle.
The obvious approach, a QML Canvas with getImageData, is the wrong tool here
and fails quietly. A Canvas carries the monitor's device-pixel-ratio, so
drawImage lands the capture in device pixels while getImageData reads logical
ones. On a fractionally scaled display the two disagree: readings near the origin
come back exact and everything further out is silently wrong. It is worth knowing
before you spend an afternoon on it.
Licence
MIT.