fix: close round-2 review findings — Critical silent-note bug plus majors/minors

Fixes the 2-point spline-EG early-free bug causing silent fade-ins, the pitch/filter enable-toggle Trigger-forcing hole, the contour-node/marker pixel shadow, missing deck-residue test coverage, and stale comments in knob_deck and spline_edit.
This commit is contained in:
2026-07-31 23:12:08 -04:00
parent d8ffd860d1
commit c3d67bc3da
12 changed files with 150 additions and 30 deletions
+26
View File
@@ -565,6 +565,31 @@ static void testNoFaceLeavesSlackWhereItsDroppedControlsWere() {
}
}
// Every shipped face's reserve divides its present-cell count evenly (see
// testNoFaceLeavesSlackWhereItsDroppedControlsWere), so none of them exercises the
// "residue lands in symmetric end margins" rule knob_deck.cpp documents — only that the
// leftover is small, not where it goes. A synthetic 7-slot reserve with 5 present (336/5,
// remainder 1) forces a real residue and pins it split across BOTH ends.
static void testASyntheticIndivisibleReserveSplitsItsResidueAcrossBothEnds() {
const DeckGroupDesc g{0, 78, {}, {100, 44}, {}, {20, 21, 22, 23, 24, -1, -1}, {}};
const std::vector<DeckGroupDesc> gs{g};
const DeckLayout dl = layoutDeck(gs, 0, 0, kAvailAtMinWidth);
const DeckGroupLayout& lay = dl.groups[0];
CHECK(lay.cells.size() == 5);
const int run = 7 * kDeckCellW;
const int cellW = run / 5; // the same integer division layoutGroup uses
const int residue = run - cellW * 5; // 1: nonzero, unlike every shipped face's reserve
CHECK(residue > 0);
const int covered = lay.cells.back().cell.right() - lay.cells.front().cell.x;
CHECK(run - covered == residue);
const int leadPad = lay.cells.front().cell.x - (lay.box.x + kDeckGroupPadX);
const int trailPad = (lay.box.right() - kDeckGroupPadX) - lay.cells.back().cell.right();
CHECK(leadPad == residue / 2);
CHECK(trailPad == residue - leadPad); // both ends share it, not one cell absorbing it
}
// Gate is the common face and it already packs correctly: pin its group widths and row
// assignment at the floor so a later edit anywhere in the deck cannot reflow it silently.
// (Measured from the shipped descriptors, not copied out of a failing run.)
@@ -666,6 +691,7 @@ int main() {
testWrappedDeckHeightAtTheEditorFloorWidth();
testDeckFitsInsideTheEnforcedMinimumWindow();
testNoFaceLeavesSlackWhereItsDroppedControlsWere();
testASyntheticIndivisibleReserveSplitsItsResidueAcrossBothEnds();
testGateModeWidthsAndRowAssignmentAreUnchanged();
testGateSplineGateRoundTripsToTheSameLayout();
testHitTestResolvesTheNewFilterControls();