Design View: no undo block may open over the reclaim span, and a reapply closes none

Every opener ends the span first, so a tag fired mid-drain no longer hijacks the
switch's point. One stated criterion governs both lane sites; no-op actions discard.
This commit is contained in:
2026-08-07 15:13:52 -04:00
parent 39529a5ac4
commit b2f6b3f1d0
9 changed files with 210 additions and 76 deletions
+13 -7
View File
@@ -93,11 +93,16 @@ extern const int kViewUndoMask;
// Returns whether it wrote.
bool writeIfChanged(MediaTrack* tr, const char* parm, double value);
// What one parkTrack call did. `wrote` is any project write at all — a flag write
// or a record write — and feeds the apply's undo-point fold. `exposed` is true iff
// this call handed the track back visible instead of parking or adopting it; the
// caller (view.cpp) collects exposed tracks across the whole apply for the one
// batched console report.
// What one parkTrack call did. `wrote` is a REAPER write — a driven flag moved —
// and nothing else: storing the snapshot is a MODEL move, and the model reaches disk
// outside every undo block, so counting it would mint a point carrying none of it
// (ModeApplyResult, view.h). The two readings part company on exactly one path — a
// RE-PARK whose restore had already handed the flags back at park-shaped values, which
// stores a fresh snapshot and writes no flag — and the REAPER reading is the one that
// wants: nothing in the project moved, so nothing is there for a point to hold.
// `exposed` is true iff this call handed the track back visible instead of parking or
// adopting it; the caller (view.cpp) collects exposed tracks across the whole apply for
// the one batched console report.
struct TrackParkResult {
bool wrote = false;
bool exposed = false;
@@ -170,8 +175,9 @@ inline bool shouldReport(bool sameOwnerAsLast, const std::vector<std::string>& l
void reportExposedTracks(ReaProject* proj, const std::vector<std::string>& trackNames);
// Restores one returning leaf from its record and spends the record's flag half.
// Always true: the record is consumed here, so this apply changed state and is not
// repeatable, which is exactly what its one reader (the undo-point decision) asks.
// Returns whether a FLAG actually moved — the same REAPER-writes-only reading
// TrackParkResult::wrote carries, and for the same reason: spending the record is a
// model move no undo point can hold.
bool restoreTrack(ViewModeModel& model, const std::string& guid, MediaTrack* tr,
const std::vector<TrackFlagOp>& flags);