Fix drag-out losing audio and FX-container drops losing the capture; re-home ingest under shell/actions

This commit is contained in:
2026-07-29 23:49:53 -04:00
parent a689fb75eb
commit 0800760833
16 changed files with 269 additions and 45 deletions
+23 -12
View File
@@ -20,6 +20,7 @@
#define REAPERAPI_WANT_GetThingFromPoint
#define REAPERAPI_WANT_TrackFX_AddByName
#define REAPERAPI_WANT_TrackFX_Delete
#define REAPERAPI_WANT_TrackFX_GetCount
#define REAPERAPI_WANT_TrackFX_SetPreset
#define REAPERAPI_WANT_Undo_BeginBlock2
#define REAPERAPI_WANT_Undo_EndBlock2
@@ -29,6 +30,9 @@ namespace reasampler {
// Real-namespace-home using-declarations (Q-W6: the namespaces.h shim is retired).
using version::vstPluginName;
using wire::decideDropOutcome;
using wire::DropAttempt;
using wire::DropOutcome;
using wire::infoNamesFxHotspot;
namespace {
@@ -99,25 +103,32 @@ bool loadInstrumentOntoTrack(MediaTrack* track, const std::vector<std::uint8_t>&
// (beta extension <-> beta VST) has no literal to drift.
const std::string fxName = "VST3:" + vstPluginName();
// Negative `instantiate` => always create a NEW instance. recFX = false: a
// normal track FX chain instance, not a record/monitoring FX.
const int fxIndex = TrackFX_AddByName(track, fxName.c_str(), /*recFX=*/false,
/*instantiate=*/-1);
bool ok = fxIndex >= 0;
// An EXPLICIT top-level insertion position (instantiate <= -1000 IS the position, -1000
// = first in chain), not the bare -1. Both always create a new instance; the bare form
// additionally leaves placement to REAPER's ambient FX-chain insert point, which a drop
// onto an FX container/chain-window moves — so the index handed to TrackFX_SetPreset and
// the instance just created stop denoting the same FX and the capture never lands. The
// bare-form retry keeps the reference path alive if the positional form is ever refused.
// recFX = false: a normal track FX chain instance, not a record/monitoring FX.
const int insertPos = TrackFX_GetCount(track);
int fxIndex = TrackFX_AddByName(track, fxName.c_str(), /*recFX=*/false,
/*instantiate=*/-1000 - insertPos);
if (fxIndex < 0)
fxIndex = TrackFX_AddByName(track, fxName.c_str(), /*recFX=*/false, /*instantiate=*/-1);
// u8string() gives UTF-8 bytes on MSVC (not ACP-converted), so a temp dir under
// an accented or CJK user-name is handled correctly by REAPER's path APIs.
if (ok) ok = TrackFX_SetPreset(track, fxIndex, presetPath.u8string().c_str());
DropAttempt attempt;
attempt.addedFxIndex = fxIndex;
if (fxIndex >= 0)
attempt.presetApplied = TrackFX_SetPreset(track, fxIndex, presetPath.u8string().c_str());
std::error_code ec;
std::filesystem::remove(presetPath, ec); // transient regardless of outcome
// All-or-nothing: if the preset apply fails, remove the FX instance we just
// added so the track is left exactly as it was.
if (!ok && fxIndex >= 0) {
TrackFX_Delete(track, fxIndex);
}
return ok;
const DropOutcome outcome = decideDropOutcome(attempt);
if (outcome.rollbackFxIndex >= 0) TrackFX_Delete(track, outcome.rollbackFxIndex);
return outcome.loaded;
}
bool performInstrumentDrop(MediaTrack* track, const std::vector<std::uint8_t>& presetBytes) {