Where a change to the crop would place existing local work outside the visible frame, say so before the change is committed.
Why
This is the entire counter-argument to cropping early, and the reason the sources are genuinely split on crop-first-versus-crop-last.
Mask geometry is stored in normalised source coordinates, so re-cropping tighter does not destroy the work — it makes it invisible, which is worse, because nothing announces it. A warning turns a silent loss into a decision, and lets DarkRoom keep the crop-early default that the histogram argument supports.
Acceptance
Reported at commit, not during the drag — a crop handle passing over a mask mid-gesture is not an event.
Names how many layers are affected, and offers to keep the crop anyway. Never blocks it.
Reversed by undo along with the crop, as one step.
Silent when no layer is affected — no dialog on the common path.
Sequencing
Cheap, but only matters once masks are worth losing. Do it after range masks and mask composition.
Part of the Develop Ergonomics spec (FR-DEV series proposal), 2026-09-05.
Where a change to the crop would place existing local work outside the visible frame, say so **before the change is committed.**
## Why
This is the entire counter-argument to cropping early, and the reason the sources are genuinely split on crop-first-versus-crop-last.
Mask geometry is stored in normalised source coordinates, so re-cropping tighter does not *destroy* the work — it makes it **invisible**, which is worse, because nothing announces it. A warning turns a silent loss into a decision, and lets DarkRoom keep the crop-early default that the histogram argument supports.
## Acceptance
- [ ] Reported at commit, not during the drag — a crop handle passing over a mask mid-gesture is not an event.
- [ ] Names how many layers are affected, and offers to keep the crop anyway. **Never blocks it.**
- [ ] Reversed by undo along with the crop, as one step.
- [ ] Silent when no layer is affected — no dialog on the common path.
## Sequencing
Cheap, but only matters once masks are worth losing. Do it after range masks and mask composition.
---
Part of the Develop Ergonomics spec (FR-DEV series proposal), 2026-09-05.
Merged to master: 9772785, fc0ea88, c3d1f83. The clause is now in requirements.md as FR-DEV-17, the ID this issue reserved.
core/dr-pipeline/src/orphan.rs: hidden_by_crop samples each layer on a 64×64 lattice with the mask shader's geometry, folds parts with their joins (through Join::apply, so intersect counts too) and inversions, maps the samples through crop and turns, and reports a layer when less than 10% of its coverage is left in the frame and it was not already that low. Ranges and region selections are never reported.
UI: when a crop drag is let go, or a ratio is picked, a notice at the top of the canvas reads "This crop leaves N mask(s) outside the frame: ", with Undo crop and Keep crop. The notice is tied to the crop's history step, so one undo takes both back.
All four acceptance items are met, with tests: reported on release not during the drag; names the layers and never blocks; undone as one step; silent when nothing is affected. Also checked in the app.
Judgement calls: the 10% threshold (HIDDEN_SHARE), and feather and morphology are left out of the estimate on purpose. The auto-crop after a straighten is not checked; it has no "before" rect and only trims slivers.
Merged to master: 9772785, fc0ea88, c3d1f83. The clause is now in requirements.md as **FR-DEV-17**, the ID this issue reserved.
- `core/dr-pipeline/src/orphan.rs`: `hidden_by_crop` samples each layer on a 64×64 lattice with the mask shader's geometry, folds parts with their joins (through `Join::apply`, so intersect counts too) and inversions, maps the samples through crop and turns, and reports a layer when less than 10% of its coverage is left in the frame and it was not already that low. Ranges and region selections are never reported.
- UI: when a crop drag is let go, or a ratio is picked, a notice at the top of the canvas reads "This crop leaves N mask(s) outside the frame: <names>", with **Undo crop** and **Keep crop**. The notice is tied to the crop's history step, so one undo takes both back.
All four acceptance items are met, with tests: reported on release not during the drag; names the layers and never blocks; undone as one step; silent when nothing is affected. Also checked in the app.
Judgement calls: the 10% threshold (`HIDDEN_SHARE`), and feather and morphology are left out of the estimate on purpose. The auto-crop after a straighten is not checked; it has no "before" rect and only trims slivers.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Where a change to the crop would place existing local work outside the visible frame, say so before the change is committed.
Why
This is the entire counter-argument to cropping early, and the reason the sources are genuinely split on crop-first-versus-crop-last.
Mask geometry is stored in normalised source coordinates, so re-cropping tighter does not destroy the work — it makes it invisible, which is worse, because nothing announces it. A warning turns a silent loss into a decision, and lets DarkRoom keep the crop-early default that the histogram argument supports.
Acceptance
Sequencing
Cheap, but only matters once masks are worth losing. Do it after range masks and mask composition.
Part of the Develop Ergonomics spec (FR-DEV series proposal), 2026-09-05.
Sequence after #7 and #9 — cheap, but only matters once masks are worth losing.
Merged to master:
9772785,fc0ea88,c3d1f83. The clause is now in requirements.md as FR-DEV-17, the ID this issue reserved.core/dr-pipeline/src/orphan.rs:hidden_by_cropsamples each layer on a 64×64 lattice with the mask shader's geometry, folds parts with their joins (throughJoin::apply, so intersect counts too) and inversions, maps the samples through crop and turns, and reports a layer when less than 10% of its coverage is left in the frame and it was not already that low. Ranges and region selections are never reported.All four acceptance items are met, with tests: reported on release not during the drag; names the layers and never blocks; undone as one step; silent when nothing is affected. Also checked in the app.
Judgement calls: the 10% threshold (
HIDDEN_SHARE), and feather and morphology are left out of the estimate on purpose. The auto-crop after a straighten is not checked; it has no "before" rect and only trims slivers.