Session::execute catches a command's panic and returns an ordinary Err (the
last-resort guard in jobs.rs), so the unwind never reached panic_hunt's own
catch_unwind and a panicking command counted as a pass.
The harness now installs a panic hook that counts every panic in the process,
including on rayon workers, and a run fails if the count moved. Runs are
serialised so a panic is charged to the run that caused it. No production
code changes.
Test: contained_panics_count_and_graceful_errors_do_not. A contained panic
fails the run and a graceful Err passes; the first assertion fails without
the hook. The full --ignored fuzz stays green, so no command panics today.
Co-authored-by: prekabreki <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* Keep the Color panel selected when switching themes (#3371)
* Scope Camera Raw color checks to its settings panel (#3371)
---------
Co-authored-by: prekabreki <[email protected]>
composite_area already honours lock transparency, but paint_gradient and
bucket_fill(_src) always passed false, and paint.bucket / paint.gradient
dropped the flag target_surface returns. Thread it through, as Edit > Fill
and the brushes already do.
Co-authored-by: prekabreki <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
The single-layer path removed the layer with no guard, leaving a document
with no layers and no active layer. It now refuses with the same error as
the multi-select path; the edit is discarded, so nothing changes and no
history step is recorded.
Co-authored-by: prekabreki <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* Clear, Cut and Image > Adjustments refuse a pixel-locked layer (#1103)
clear_area, destructive_adjust and auto_adjust took the layer's surface
directly. They now go through commands::paint_surface, which refuses a
pixel- or fully-locked layer with the same message painting uses.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* edit.cut: refuse a pixel-locked layer before filling the clipboard
copy() ran before clear_selected noticed the lock, so a refused Cut still
replaced the clipboard. Check the lock first (check_pixels_unlocked, shared
with paint_surface) and assert the clipboard is unchanged in the test.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: prekabreki <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
* Filters refuse a pixel-locked layer (#1102)
run_filter never consulted layer locks. It now refuses a pixel- or
fully-locked layer with the same message painting uses. Channel, Quick
Mask and mask targets are unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Filters keep alpha under lock transparency; render filters and Fill Path refuse a pixel-locked layer (#1102)
- run_filter puts the layer's alpha back in the tiles a filter changed when
transparency is locked (the same tile walk as restrict_to_color).
- Flame / Tree / Picture Frame take the surface through paint_surface.
- path.fill refuses a pixel- or fully-locked layer.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: prekabreki <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* Toolbar: the header chevron switches between one and two columns (#1197)
The Pro theme's chevron was painted with a hover-only sense, so clicking it
did nothing. It now toggles Panels::toolbar_double (serde default, so older
state still loads); the toolbar is two columns when that is on or when one
column doesn't fit, and the chevron points left while two are shown.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Toolbar: the Pro two-column toolbar fills every row (#1197)
Rows were cut per tool group, so a group with an odd number of tools left
a half-empty row (Move, Eyedropper). Pro draws no group dividers, so its
two columns now flow across groups; the other themes keep their per-group
rows between dividers.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: prekabreki <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>