Multi-Monitor Screenshots: The Mixed-DPI Trap Nobody Warns You About
You capture the whole desktop, paste it into a ticket, and the text on the laptop half is soft and slightly too large. The external monitor's half is sharp. Nobody touched a compression setting.
That is not your capture tool misbehaving. Your two displays run at different scale factors, and a single-bitmap capture across both has to pick one density and resample everything that doesn't match.
What the OS does when your monitors disagree on DPI
Two pixel concepts matter here. Physical pixels are what the panel actually has. Logical pixels are the coordinate system apps draw into, which the OS multiplies by a scale factor before it hits the glass. A 4K panel at 200% scaling is 3840x2160 physical, 1920x1080 logical.
Your desktop is one coordinate space. The primary display's top-left corner is the origin. Every other monitor sits at an offset inside that space: 1920 pixels to the right, or 2560 to the left, or 400 down. A full-desktop capture asks for one bitmap covering the bounding rectangle of all of it.
One rectangle, one density. So at least one region gets scaled.
On Windows the damage often happens before the screenshot. Apps that aren't per-monitor DPI aware get bitmap-stretched by the OS when they land on a scaled display. What you see on screen is already blurry, and the screenshot records that blur faithfully. The capture is accurate; the rendering was not.
On macOS the mechanism differs. A Retina panel writes 2x pixels, a 1080p external writes 1x. Combine them into one image and you have two densities baked into a single file, with one of them resampled to match the other.
Dead space and negative coordinates
Put a 27-inch 1440p monitor next to a laptop, align them however feels natural, and the bounding rectangle has to contain both. Wherever neither panel reaches, the capture has nothing to record and you get black.
The more expensive geometry trap is negative coordinates. If a monitor sits to the left of your primary display, its origin is at negative X. A monitor placed above sits at negative Y. So a perfectly ordinary two-monitor setup can have half its pixels living at coordinates below zero.
This breaks scripts that assume the desktop starts at (0,0). Crop maths clamps to the origin and grabs a region shifted right by however far negative you were, so you get part of the primary display and a black band where the left monitor should have been. Region-capture flags that take an x,y origin will happily accept -2560 on some tools and reject it on others. Some third-party libraries return an empty rect instead of an error, which means your script writes a zero-byte or all-black file and keeps going.
The quick sanity check: make the leftmost display primary for a moment and see whether the script starts working. If it does, negative offsets were the problem.
Check whether your captures are already wrong
Thirty seconds, once per display arrangement.
Note each display's native resolution and its scale setting. Take one capture per display. Then look at the pixel dimensions of the resulting files in Finder's Get Info, Explorer's Details pane, or any image viewer.
If a 3840x2160 display produced a 1920x1080 file, you're capturing logical pixels. It will look acceptable at 100% and fall apart the moment anyone zooms in to read a stack trace.
If a 1920x1080 display produced a 3840x2160 file, something upscaled it. Bigger file, no extra detail.
Mixing densities in one document
This is where the problem escapes the screenshot and lands in your docs. You grab one image from the Retina laptop and one from the 1080p external, drop both into the same Markdown ticket, and they render at wildly different sizes. Markdown has no way to say "this one is 2x", so most renderers lay the image out at its natural pixel width. The Retina capture comes out roughly twice the size of the other, and a reader reasonably concludes that one of those dialogs really is much larger than the other.
Fix it before embedding, not after. Pick one target width that matches your documentation's content column, something in the region of 1200 to 1600 pixels for a typical wide layout, and downsample every image to it. Downsampling the 2x capture is fine, it has pixels to spare. Upsampling the 1x one is not; leave it narrower and let it sit smaller on the page rather than smearing it.
The fix: one display at a time
Almost nothing you send a colleague needs both monitors in one frame. What they need is the window with the problem plus enough surrounding context to place it: the tab bar, the sidebar, enough of the URL to know which environment you were on.
Per-display and per-window captures keep native density, produce no dead space, and give smaller files. The whole class of problem goes away rather than getting managed.
There is a real exception. A dialog that spans the monitor boundary, or a bug that only manifests when a window crosses displays (dropdown renders on the wrong screen, video freezes on the secondary panel) genuinely needs the full desktop. Capture it, and say so in the caption, because otherwise the reviewer spends a minute wondering why half the image is black.
macOS
Cmd+Shift+3 already writes one file per display. People expect a single image and are surprised to find three on the desktop. That default is the right one.
Cmd+Shift+5 gives you a toolbar with a display picker; click the screen you want.
For scripting, screencapture is the tool:
screencapture -D 2 out.pngcaptures display 2.screencapture -R 100,200,800,600 out.pngcaptures a rect in virtual-desktop coordinates, which is where the negative-offset problem bites.screencapture -l <windowid> out.pngcaptures one window.-xsuppresses the shutter sound,-oomits the window shadow. Both worth having in any docs pipeline, since drop shadows on a light doc background look like smudges.
Windows
What each shortcut grabs, with one version caveat that trips people up:
PrtScnon Windows 10 copies the entire virtual desktop to the clipboard. On current Windows 11 builds it opens the Snipping Tool overlay instead. If you want the old clipboard behaviour back, it's Settings > Accessibility > Keyboard > "Use the Print screen key to open Snipping Tool", toggled off.Alt+PrtScncopies the active window.Win+Shift+Sopens the Snipping Tool overlay across every screen.Win+PrtScnsaves the full desktop toPictures\Screenshots.
Make window capture your default for bug reports. It avoids the cross-monitor scaling path entirely.
For scripted per-monitor grabs, ffmpeg with gdigrab takes an explicit region:
ffmpeg -f gdigrab -offset_x 1920 -offset_y 0 -video_size 2560x1440 -i desktop -frames:v 1 out.png
Those offsets are measured from the primary display's top-left, so a monitor sitting to the left needs a negative -offset_x. If your build refuses the negative value or hands back a black frame, the reliable workarounds are to make that monitor primary for the duration of the capture, or to capture the window rather than the region.
One practical caveat: if the app itself is legacy and not per-monitor DPI aware, it will look blurry on a scaled display no matter which capture tool you use. You can sometimes force better rendering from the app side. Right-click the executable, Properties > Compatibility > Change high DPI settings, tick "Override high DPI scaling behaviour" and try "System (Enhanced)". Some apps sharpen up considerably; some ignore it. Worth thirty seconds before you accept a fuzzy screenshot.
Linux: X11 and Wayland
Under X11, get per-output geometry from xrandr --listmonitors, which prints each output's size and offset in the form 2560/597x1440/336+1920+0. Feed that to maim -g 2560x1440+1920+0, or use slop for an interactive region, or ImageMagick's import with an explicit crop.
Wayland has no equivalent of X11's global screen access. A client cannot simply ask for the contents of the screen, and what replaces that depends on your compositor. On GNOME and KDE, screenshots go through xdg-desktop-portal: the compositor prompts, then hands back the image. On wlroots compositors such as Sway and river, there is also the wlr-screencopy protocol, which grim talks to directly. That's why grim -o DP-1 works there and sidesteps the display-index problem entirely, since you're naming the output rather than counting it.
If a screenshot tool that worked fine on X11 returns a black frame or nothing at all under Wayland, the usual cause is the tool reaching for X11 APIs through XWayland instead of using the compositor's Wayland path. The tool isn't broken; it's asking the wrong layer.
Why your scripted capture suddenly grabs the wrong screen
Display indices are assigned in enumeration order. They are not bound to a physical panel.
Undock and redock, change which display is primary, or plug the same two cables into swapped ports, and index 2 becomes index 1. Your nightly capture script keeps running, exits zero, and saves a picture of the wrong monitor. Nobody notices until someone reviews the artefacts.
Three mitigations, in order of preference. Resolve displays by name or serial where the tool supports it (grim -o, or matching on output name from xrandr). Capture by window rather than by display, so identity comes from the app. Or assert on expected dimensions in the script and fail loudly rather than writing a plausible-looking wrong file.
Recording has the same problem, louder
A full-desktop recording across mismatched displays carries the oversized frame and the dead space in every single frame. Upload that to a ticket and the viewer sees a letterboxed postage stamp with unreadable text.
Pick a single display or window as the source, and set output resolution to match that source rather than the virtual desktop.
There's also a cursor problem specific to multi-monitor recording. Reach for something on the other screen and the pointer leaves frame, so the viewer watches a mysterious pause while you do something invisible. If your demo needs both monitors, either script the movements or narrate them.
Checklist
- Capture the window, not the desktop.
- If you need surrounding context, one display per file.
- Check pixel dimensions once after any display change, dock, or scaling tweak.
- Resize to a common width before putting two captures side by side in a doc.
- Annotate before sharing so the reader knows which screen they're looking at.
- If you must span monitors, say why in the caption.
Most of this is habit rather than tooling, which is why it survives switching machines.