A smart, edge-detection-based screen ruler for Linux desktops.
Move your mouse cursor over any UI element and instantly read the width and height of the space between the nearest edges — buttons, panels, windows, icons — with no clicking or dragging required.
At launch, screen-ruler captures a one-time screenshot and builds a binary edge map using Canny edge detection (with an OpenCV Gaussian pre-blur to suppress font anti-aliasing and wallpaper noise). A transparent overlay is then shown over all monitors. Each frame, four rays are cast North / South / East / West from the mouse cursor until they hit an edge pixel or the screen boundary. The total East+West distance is reported as W and North+South as H, live in a small label next to the cursor.
| Package | Minimum version |
|---|---|
| PyQt6 | 6.2 |
| NumPy | 1.21 |
| opencv-python-headless | 4.5 |
Install all dependencies at once:
pip install -r requirements.txtpython screen_ruler.py [--threshold-low N] [--threshold-high N] [--debug-edge-overlay]| Option | Default | Description |
|---|---|---|
--threshold-low N |
29 | Lower hysteresis threshold for the Canny edge detector |
--threshold-high N |
101 | Upper hysteresis threshold for the Canny edge detector |
--debug-edge-overlay |
off | Keep the captured Canny edge map visible (base opacity) for debugging; slider changes also trigger a transient edge preview |
Controls
| Input | Action |
|---|---|
1 / 2 / 3 / 4 / 5 |
Switch measurement mode |
Tab |
Toggle session mode (persistent annotation workspace) |
Ctrl+C |
Copy current measurement to clipboard, then quit (quick mode) |
Enter |
Copy drag/shrink selection to clipboard, then quit (quick mode) |
? or H |
Toggle the shortcut help overlay |
Escape |
Exit session mode (or quit when not in session mode) |
Q |
Quit |
| Left click | Copy current measurement and quit (crosshair/container/color), or confirm drag/shrink selection |
Top Sensitivity slider |
Recompute edge detection live (debounced) and show the edge-map preview briefly (hold then fade) |
Color mode Average (px) slider |
Increase circular weighted sampling radius (0 = single pixel) |
| Mouse wheel | Adjust active mode control (sensitivity / snap distance / color averaging) |
Session mode controls (active after pressing Tab)
| Input | Action |
|---|---|
| Left click | Place persistent annotation at cursor position |
Ctrl+C |
Copy all annotations as a Markdown list |
Ctrl+Z or Z |
Undo last annotation |
Ctrl+Shift+Z |
Redo last undone annotation |
Ctrl+Shift+C |
Enter composite export mode, then drag a region to copy a screenshot with annotations (works from any annotation mode) |
Session mode also shows MD and IMG buttons next to the SESSION badge for these two export actions.
On launch, a lightweight shortcut overlay is shown briefly and fades automatically; press ? or H any time to bring it back.
If you don't want to install a Python environment, you can build a single self-contained binary with PyInstaller:
pip install -r requirements.txt -r requirements-build.txt
pyinstaller screen_ruler.specThe binary is written to dist/screen-ruler. Copy it anywhere and run it directly — no Python or library installation needed on the target machine.
Note: the executable bundles all dependencies and is therefore ~100 MB. This is expected for an application that ships PyQt6, NumPy, and OpenCV.
Screen Ruler is designed to be ephemeral — capture, measure, quit. A global keyboard shortcut lets you summon it instantly without a persistent daemon.
After building the binary, run the install script:
./install-linux.sh # installs to the current directory
./install-linux.sh -d ~/bin # or specify a directoryThe script copies the binary, installs a .desktop entry, and automatically registers a Super+Shift+R shortcut for the detected desktop environment (GNOME, KDE Plasma, Hyprland, Sway).
After building the binary, run the install script:
./install-macos.sh # installs to the current directory
./install-macos.sh -d ~/bin # or specify a directoryThe script copies the binary and creates an Automator Quick Action ("Launch Screen Ruler"). Then bind a shortcut (e.g. ⌘⇧R) in System Settings → Keyboard → Keyboard Shortcuts → Services.
After building the executable, run the install script in PowerShell:
.\install-windows.ps1 # installs to the current directory
.\install-windows.ps1 -InstallDir "$env:LOCALAPPDATA\screen-ruler" # or specify a directoryThe script copies the binary, adds it to the user PATH, and creates a Start Menu shortcut with a Ctrl+Shift+R hotkey.
For manual setup on any platform, see docs/manual-shortcut-setup.md.
On some X11 window managers, frameless utility windows are constrained to the desktop work area (excluding panels/docks). screen-ruler uses Qt.X11BypassWindowManagerHint on X11 so the overlay matches full virtual-desktop coordinates used for capture and measurement.
Because bypass windows may have less predictable focus behavior, the app also installs an application-level Escape/Q key fallback.
On some GNOME/X11 systems Qt may print this warning during startup while probing desktop theme services over DBus. In most cases it is harmless and does not affect ruler behavior.
If it appears repeatedly, check that your session DBus and portal services are healthy (dbus-daemon, xdg-desktop-portal).
- Install the dev dependencies (same as the runtime ones, plus
pytest):pip install -r requirements-dev.txt
- Run the test suite from the repository root:
pytest tests/
- The pure-logic helpers (
trace_ray,compute_edge_map) are module-level functions specifically so they can be tested without a display. Keep new logic in the same style when possible. - The QML overlay (
screen_ruler.qml) and screen-capture code require a running Qt application and are not covered by the unit tests.
This project is licensed under the MIT License. See the LICENSE file for details.