Skip to content

Heal & Scratch tool enhancements: exclusivity, overlay alignment, tool menus, suspend/restore#458

Merged
marcinz606 merged 2 commits into
marcinz606:mainfrom
linkmodo:feature/heal-scratch-enhancements
Jul 12, 2026
Merged

Heal & Scratch tool enhancements: exclusivity, overlay alignment, tool menus, suspend/restore#458
marcinz606 merged 2 commits into
marcinz606:mainfrom
linkmodo:feature/heal-scratch-enhancements

Conversation

@linkmodo

Copy link
Copy Markdown
Contributor

Summary

A set of fixes and workflow enhancements for the Heal and Scratch tools, aimed at making retouching self-contained on the canvas instead of round-tripping to the sidebar for every correction.

Fixes

  • Heal/Scratch buttons are now mutually exclusive. Activating one while the other was on left both highlighted: the tool-sync pass never refreshed the retouch sidebar, so the stale button kept its checked state. The colour sidebar's WB picker had the same latent bug — also synced now.
  • Placed-heal overlays now sit exactly where the user clicked/drew. The raw→screen inverse uv-grid lookup snapped to the centres of a ~100-bucket decimated grid (up to half a bucket off — several to tens of pixels depending on preview size, magnified by zoom), while the heal itself used the exact forward lookup. A full-resolution refinement pass over the winning bucket's neighbourhood pins outlines to sub-pixel at any zoom, HQ or not (measured worst case: 1.9px on a 3000px-wide zoomed view over a rotated + cropped HQ grid, ~23px before). The dodge/burn mask overlay and the new heal hit-test share the same lookup and benefit equally.
  • Manual heals/scratches now light the Finish tab's edited dotmanual_heal_strokes (where both tools commit) was missing from the Retouch section's modified count.
  • Tool placements are left-click only, so right-click no longer drops a stray scratch point or heal on its way to the context menu.

Enhancements

  • Tab-away suspend/restore: navigating off the tab hosting Retouch suspends an active heal/scratch tool (canvas clicks stop placing heals while the controls are out of sight); returning restores the suspended tool and its overlay. Nothing is restored if no tool was active when leaving, or if another tool was picked up meanwhile.
  • Pen-nib cursor while the scratch tool is active (rotated to read like a pointer, hotspot on the tip), so click-points line-drawing mode is visible at a glance.
  • Tool-specific context menus replace the general settings menu while a heal tool is live. Heal: Undo Last Heal, Clear All Heals. Scratch adds Confirm Scratch (same as double-click/Enter) and Undo Last Point. Right-clicking a placed heal offers Delete This Heal — a bad patch can be picked off directly instead of unwinding newer heals step by step.
  • Backspace steps back one click-point of the in-progress scratch polyline.
  • Context-sensitive Ctrl+Z: while a heal tool is active it removes the last placed heal; outside the tools it stays the normal edit undo.
  • Clear All Heals asks for confirmation (sidebar button and menus) — unlike single-heal undo it is not step-recoverable.
  • Tooltips updated to surface the new interactions (right-click to delete, Backspace for points).

Testing

Verified in-app on Windows (tool switching, tab suspend/restore, overlay alignment at multiple zooms with HQ on/off, context menus, Backspace/Ctrl+Z, delete-heal hit-testing). Headless checks cover the raw→screen round-trip precision (≤2px on a rotated/cropped HQ grid), heal hit-testing, and scratch point undo. Targeted suites pass (test_retouch_logic, test_desktop_session, test_compare_baseline — 70 tests); ruff + compile clean.

linkmodo added 2 commits July 11, 2026 18:36
…itches

Activating the Heal tool while the Scratch tool was on (or vice versa) left
both buttons highlighted: the tool-sync pass never refreshed the retouch
sidebar, so the stale button kept its checked state even though only one tool
was live. Sync the retouch (and colour, same latent WB-picker bug) sidebars on
tool change.

Navigating away from the tab hosting the Retouch section now suspends an
active heal/scratch tool — canvas clicks stop placing heals while the tool's
controls are out of sight — and returning to the tab restores the suspended
tool and its overlay. Nothing is restored if no tool was active when leaving,
or if another tool was picked up in the meantime.
Working the heal/scratch tools previously meant round-tripping to the sidebar
for every correction. Make the tools self-contained on the canvas:

- The scratch tool shows a pen-nib cursor (rotated to read like a pointer,
  nib tip up-left, hotspot on the tip) so click-points line-drawing mode is
  visible at a glance.
- Right-click opens a tool menu instead of the general settings menu. Heal:
  Undo Last Heal, Clear All Heals. Scratch adds Confirm Scratch (same as
  double-click/Enter) and Undo Last Point. Right-clicking a placed heal offers
  Delete This Heal, so a bad patch can be picked off directly instead of
  unwinding newer heals step by step (hit-test over the stroke band / spot
  radius the overlay draws).
- Backspace steps back one click-point of the in-progress scratch polyline.
- Ctrl+Z while a heal tool is active undoes the last placed heal; outside the
  tools it stays the normal edit undo.
- Clear All Heals (sidebar button and menus) asks for confirmation — unlike
  single-heal undo it is not step-recoverable.
- Tool placements are now left-click only, so right-click no longer drops a
  stray scratch point or heal on its way to the context menu.
- Manual heals/scratches now count toward the Retouch section's modified
  badge, so the Finish tab's edited dot lights for healed images
  (manual_heal_strokes was missing from the count — both tools commit there;
  manual_dust_spots is the legacy list).

Also fix the placed-heal overlay drawing offset from where the user actually
clicked/drew: the raw->screen inverse uv-grid lookup snapped to the centres of
a ~100-bucket decimated grid (up to half a bucket off — several to tens of
pixels depending on preview size, magnified by zoom), while the heal itself
used the exact forward lookup. A full-resolution refinement pass over the
winning bucket's neighbourhood pins the outline to sub-pixel of the healed
spot at any zoom, HQ or not.
@marcinz606 marcinz606 merged commit 05b8763 into marcinz606:main Jul 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants