The changed crop
Turn a bounding box into an image, cropped from the newer frame.
A bounding box tells you that something changed and where. The changed crop gives you the part that changed, as an image, so you can look at it without paying for the whole screen.
eensh session diff "$SID" 1 2 --json --base64 \
--changed-region --changed-padding 20 --changed-format pngWhich frame the crop is taken from
The bounding box describes where the newer frame differs from the older one. So the crop comes from the newer frame — that is where the content you want to see actually is.
The newer frame is retrieved from session history by identity and shared rather than re-captured, so the crop shows the same moment the comparison described. Cropping also allocates no new frame ID: a view is a rendering of a frame that exists, never a new frame.
Two rectangles, reported separately
{
"changed_view": {
"raw_changed_rect": { "x": 150, "y": 100, "width": 100, "height": 60 },
"returned_rect": { "x": 130, "y": 80, "width": 140, "height": 100 },
"padding": 20,
"fell_back_to_overview": false,
"view": { "name": "changed", "kind": "changed_region", ... }
}
}- raw_changed_rect
The factual bounding box, before any padding. This is the honest answer to “where did it change”.
- returned_rect
What was actually returned, after padding and clamping to the source. This is what the image corresponds to.
Keeping them apart is what stops a change at the screen edge from being mistaken for a large one. Padding at an edge can only be applied on the sides that have room, so a 50-pixel request may become a 12-pixel application — and the two rectangles make that visible rather than implied.
The sub-threshold case that looks like a bug
A requested crop is returned even when changed is false. This follows from the box-versus-verdict distinction: the box is a fact about pixels, and changed is a policy judgement about area.
A caller that explicitly asked for the changed region asked about the pixels. So it gets the crop, and the comparison metadata still says the change was not meaningful.
When the change is too large to be worth cropping
A box spanning most of the screen is cheaper and more useful as a resized overview than as a near-full-size crop. A policy may therefore fall back to the whole frame.
The fallback is declared, not silent. On that path the view is renamed to overview — because that is what was actually returned — and fell_back_to_overview is set, while the factual box is still reported. Nothing about the comparison is lost by naming the view honestly.
Every option, with its default
--changed-padding PIXELS— widen the returned rectangle, clamped at the source edges. Default0.--changed-width,--changed-format— the crop’s own image settings.--changed-optional— allow the crop to be dropped to meet a payload budget. Required by default.
Next: the reference tier, starting with every command and flag.