#5176 made ±100% move the edge by max(radius, feather, 2σ smooth), at
least 1 px. Measured in the reference application (a 100 px square,
Radius/Feather/Smooth each varied, Shift Edge -100/-50/+100):
- A hard selection does not move at all, at any Shift Edge.
- On a feathered edge the result is a fixed per-pixel curve, the same at
2, 5 and 10 px feather: the pixel's odds a/(1-a) are multiplied by
49^(shift/100). At -100% a 50% pixel becomes 2%, at -50% 1/8, at
+100% 98%. The fit holds within ±0.05 in log-odds on every sample.
So Shift Edge is now that curve, applied last as before. It needs no
neighbours, so the morphology callback and the halo/spread it added are
gone, with the ignored benchmark that timed it (matting::morph itself
stays for Select › Modify and the mask view).
Tests: a hard edge is unchanged at ±50/±100%; seven measured
before→after coverage pairs; a feathered edge is pulled in; the engine
refine tests now check the hard edge stays and a feathered one moves.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>