How to get pixel coordinates on macOS, Windows, and Linux
Every OS has a built-in way to read a coordinate — they're below, and for a one-off they're all you need. The part that bites is that modern screens have two coordinate systems: physical pixels (the screenshot's own grid) and logical points (what many click APIs use). On a 2× Retina display, the pixel at (1624, 880) in a screenshot is the point (812, 440) to a click API — mix them up and every click lands in the wrong quadrant. Whatever tool you use, know which space its number lives in.
macOS
Built in: press Cmd+Shift+4. The screenshot crosshair follows your cursor with live coordinates (logical points); press Esc to cancel without taking a screenshot. That's the fastest one-off answer on a Mac.
The pitfall: screenshots on Retina are captured in physical pixels at 2× the crosshair numbers, so a coordinate read from a screenshot in an editor won't match. For coordinates that survive — saved, labeled, converted per display — freeze the screen instead:
pixelcoords # freeze, mark the spot, S saves
pixelcoords emit --session <dir> --format cliclick # logical points
pixelcoords emit --session <dir> --format pyautogui # logical on macOSmacOS asks for Screen Recording permission on first run; the session records each monitor's scale so conversions are per-display, correct on mixed-DPI setups.
Windows
Built in: PowerToys' Mouse Utilities and Screen Ruler give quick on-screen numbers — genuinely good for a fast read (full comparison).
The pitfall: per-monitor DPI scaling. A 150% display makes physical and logical disagree by half again, and every monitor can differ. pixelcoords records each monitor's true scale factor in session.json (it declares per-monitor DPI awareness before capturing, so the number is exact, not virtualized):
pixelcoords
pixelcoords emit --session <dir> --format pyautogui # physical px on WindowsHonesty note from the tool's own docs: the pyautogui-on-Windows convention follows its documented DPI-aware behavior and has not yet been verified on hardware.
Linux
Built in on X11: xdotool getmouselocation prints the live cursor position in physical pixels — the classic answer, still the right one for a one-off.
The pitfall is Wayland: its security design withholds global coordinates and window geometry from applications, so live trackers can't exist there. A frozen-snapshot overlay is the model Wayland permits — pixelcoords freezes through the desktop portal, and --pick marks a single window with window-relative coordinates:
pixelcoords # X11: everything works, incl. --target
pixelcoords --pick # Wayland: mark one picked window
pixelcoords emit --session <dir> --format xdotool # physical pxWhen a number isn't enough
A coordinate you read once answers today's question. If the same spot matters tomorrow — in a script, a test, an agent — you want it saved with its context: which monitor, what scale, what the region looked like. That's the pixelcoords session: mark once, then assert verifies points with exit codes, and find re-locates regions after the UI drifts. The front page shows the whole loop in sixty seconds.
Questions people actually ask
Why don’t my screenshot coordinates match my click coordinates on a Retina display?
HiDPI screens have two coordinate systems: physical pixels (the screenshot’s grid) and logical points (what most click APIs use on macOS). On a 2× Retina display a screenshot pixel at (1624, 880) is the logical point (812, 440). Divide by the display’s scale factor — or use a tool that records the scale per monitor and converts for you.
How do I get the pixel coordinates of my mouse on macOS?
Press Cmd+Shift+4 — the screenshot crosshair shows live cursor coordinates in logical points; press Esc to cancel without capturing. For coordinates you can save, verify, and hand to a script, freeze the screen with pixelcoords and mark the spot.
How do I get screen pixel coordinates on Wayland?
Wayland’s security design withholds global coordinates and window geometry from applications, so live trackers can’t work. A frozen-snapshot overlay is the model Wayland permits: pixelcoords freezes via the desktop portal, and --pick marks a single window with window-relative coordinates.
How do I get coordinates in the right format for pyautogui?
pyautogui speaks logical points on macOS and physical pixels on Windows and X11. pixelcoords emit --format pyautogui applies the right convention per monitor from the recorded DPI scale. The Windows pyautogui convention follows its documented behavior and has not yet been verified on hardware.
How can a script verify a point is inside a screen region?
Mark the region once, then run pixelcoords assert --session <dir> --point X,Y --label name. The exit code is the API: 0 hit, 1 miss, 2 malformed question — CI and computer-use agents can gate on it.
Two ways in
cargo install pixelcoordsOr skip the toolchain: prebuilt binaries for macOS, Windows, and Linux — download, unpack, run.
Rust 1.88+ for the cargo route. On Linux, build dependencies first:
sudo apt-get install -y libxcb1-dev libxcb-randr0-dev libpipewire-0.3-dev \
libclang-dev libegl1-mesa-dev libgbm-dev pkg-configmacOS asks for Screen Recording permission on first run.