Fix drag-handoff bugs: gate FX re-resolve on outside-panel, cache unresolvable OS-drag verdict, block double FX-add retry
This commit is contained in:
+11
-26
@@ -223,39 +223,26 @@ static void testMixedTallies() {
|
||||
|
||||
// --- OS hand-off ordering -----------------------------------------------------
|
||||
//
|
||||
// The drag-out-lands-without-audio regression: the shell used to wind its internal drag down
|
||||
// The empty-payload teardown regression: the shell used to wind its internal drag down
|
||||
// (release capture, clear drag state) BEFORE checking whether the payload had resolved to any
|
||||
// on-disk file. A payload that resolved to nothing therefore consumed the gesture — the drag
|
||||
// died half-torn-down and the user saw a drop with no audio and dragged again. The two side
|
||||
// effects are one decision; these pin that.
|
||||
// on-disk file. For an unresolvable payload, initiateDragOut is never reached — no OS drop
|
||||
// happens at all — but the teardown ran anyway, so the drag just silently stopped mid-gesture
|
||||
// with no highlight and no drop. The user has to press and start an entirely new drag; retrying
|
||||
// the SAME stale selection resolves to the same empty payload and fails identically. These pin
|
||||
// the fix: the two side effects (teardown, hand-off) are one decision.
|
||||
|
||||
// Nothing draggable -> hand off nothing AND keep the internal drag alive.
|
||||
static void testEmptyPathsHandsOffNothingAndKeepsInternalDrag() {
|
||||
const OsHandoff h = decideOsHandoff({});
|
||||
CHECK(!h.startOsDrag);
|
||||
CHECK(!h.releaseInternalDrag);
|
||||
CHECK(!h.handOffToOs);
|
||||
}
|
||||
|
||||
// A resolvable payload -> release the internal drag, then start the OS drag.
|
||||
// A resolvable payload -> hand off (release the internal drag, then start the OS drag).
|
||||
static void testResolvablePayloadHandsOff() {
|
||||
const OsHandoff one = decideOsHandoff({"C:/proj/bank/a.wav"});
|
||||
CHECK(one.startOsDrag);
|
||||
CHECK(one.releaseInternalDrag);
|
||||
CHECK(one.handOffToOs);
|
||||
const OsHandoff many = decideOsHandoff({"a.wav", "b.wav", "c.wav"});
|
||||
CHECK(many.startOsDrag);
|
||||
CHECK(many.releaseInternalDrag);
|
||||
}
|
||||
|
||||
// The coupling itself: releasing without starting is the defect, so it must be unreachable
|
||||
// for every input the assembler can produce.
|
||||
static void testNeverReleasesWithoutStarting() {
|
||||
const std::vector<std::vector<std::string>> inputs = {
|
||||
{}, {"a.wav"}, {"a.wav", "b.wav"}, {""},
|
||||
};
|
||||
for (const std::vector<std::string>& in : inputs) {
|
||||
const OsHandoff h = decideOsHandoff(in);
|
||||
CHECK(!(h.releaseInternalDrag && !h.startOsDrag));
|
||||
}
|
||||
CHECK(many.handOffToOs);
|
||||
}
|
||||
|
||||
// End to end through the assembler: a selection whose every entry is stale/unresolvable
|
||||
@@ -263,8 +250,7 @@ static void testNeverReleasesWithoutStarting() {
|
||||
static void testAllSkippedSelectionKeepsInternalDrag() {
|
||||
const PathList l = assemblePathList({missing("g1.wav"), unresolved()});
|
||||
const OsHandoff h = decideOsHandoff(l.paths);
|
||||
CHECK(!h.startOsDrag);
|
||||
CHECK(!h.releaseInternalDrag);
|
||||
CHECK(!h.handOffToOs);
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -292,7 +278,6 @@ int main() {
|
||||
|
||||
testEmptyPathsHandsOffNothingAndKeepsInternalDrag();
|
||||
testResolvablePayloadHandsOff();
|
||||
testNeverReleasesWithoutStarting();
|
||||
testAllSkippedSelectionKeepsInternalDrag();
|
||||
|
||||
if (g_fail == 0) std::printf("All tests passed.\n");
|
||||
|
||||
Reference in New Issue
Block a user