fix(instrument_drop): narrow FX hotspot to tcp.fx/mcp.fx, not bare tcp/mcp (S-VIEW-BUG-1)

This commit is contained in:
2026-07-27 13:34:40 -04:00
parent fef595be91
commit 5870b18362
4 changed files with 48 additions and 37 deletions
+22 -16
View File
@@ -109,23 +109,25 @@ static void testBase64DecodeRejectsMalformed() {
//
// THE BUG: dropping a capture onto a track's FX button (in the TCP) never armed the
// instrument drop, because the old predicate matched only "fx_" — which the SDK reserves for
// the FX CHAIN / FLOATING-FX windows. A track-panel hit (where the FX button lives) reports a
// string beginning with "tcp"/"mcp". These tests fix the classifier at the boundary the shell
// consumes: each would FAIL under the old "fx_"-only rule for the tcp/mcp cases.
// the FX CHAIN / FLOATING-FX windows. A track-panel FX-button hit reports "tcp.fx"/"mcp.fx"
// (SDK §GetThingFromPoint: "string will begin with 'tcp' or 'mcp' or 'tcp.mute' etc").
//
// THE FIX: narrow to two documented FX-bearing surfaces:
// * "tcp.fx" / "mcp.fx" — the TCP/MCP FX button (exact token, NOT bare tcp/mcp)
// * "fx_*" — the FX-chain / floating-FX windows (prefix, as before)
// Bare "tcp"/"mcp" and any other "tcp.*"/"mcp.*" sub-element (e.g. "tcp.mute", "tcp.vol")
// are non-FX track-panel regions — an instrument drop must NOT fire there.
// The regression case: the TCP FX-button surface reports "tcp*" and MUST classify as an FX
// hotspot. Under the pre-fix "fx_"-only predicate these all returned false — the exact miss
// that produced the "drops as audio to arrange" symptom.
static void testTcpMcpPanelIsHotspot() {
CHECK(infoNamesFxHotspot("tcp")); // bare track control panel
CHECK(infoNamesFxHotspot("tcp.fx")); // the TCP FX-button WALTER element
CHECK(infoNamesFxHotspot("tcp.mute")); // any tcp.* sub-element resolves to the track
CHECK(infoNamesFxHotspot("mcp")); // mixer control panel
CHECK(infoNamesFxHotspot("mcp.fx")); // the MCP FX area
// The TCP/MCP FX button specifically — the surface that arms an instrument drop (S-VIEW-BUG-1
// fix). Under the old "fx_"-only predicate these returned false — the exact miss that produced
// the "drops as audio to arrange" symptom on the FX button.
static void testTcpMcpFxButtonIsHotspot() {
CHECK(infoNamesFxHotspot("tcp.fx")); // TCP FX button (SDK token)
CHECK(infoNamesFxHotspot("mcp.fx")); // MCP FX area (SDK token)
}
// The FX chain / floating-FX windows (the surfaces the ORIGINAL predicate matched) still
// classify as hotspots — the fix widens the rule, it does not regress the "fx_" surface.
// classify as hotspots — the fix does not regress the "fx_" surface.
static void testFxWindowStillHotspot() {
CHECK(infoNamesFxHotspot("fx_chain")); // FX chain window
CHECK(infoNamesFxHotspot("fx_0")); // first FX, floating
@@ -133,9 +135,13 @@ static void testFxWindowStillHotspot() {
}
// Non-FX surfaces are NOT hotspots — a drop here is not an instrument drop (it would fall
// through to the OS drag / no-op). Guards against over-broad matching (e.g. "spacer_0" must
// not match despite living near the tracks; "arrange" is the audio-import surface).
// through to the OS drag / no-op). This includes the bare TCP/MCP tokens and all non-FX
// "tcp.*"/"mcp.*" sub-elements (e.g. mute button, volume fader, track name, meter).
static void testNonFxSurfacesAreNotHotspot() {
CHECK(!infoNamesFxHotspot("tcp")); // bare track control panel — NOT an FX hotspot
CHECK(!infoNamesFxHotspot("mcp")); // bare mixer control panel — NOT an FX hotspot
CHECK(!infoNamesFxHotspot("tcp.mute")); // mute button — track panel, not FX
CHECK(!infoNamesFxHotspot("tcp.vol")); // volume fader — track panel, not FX
CHECK(!infoNamesFxHotspot("arrange"));
CHECK(!infoNamesFxHotspot("spacer_0"));
CHECK(!infoNamesFxHotspot("")); // pointer over nothing REAPER classifies
@@ -152,7 +158,7 @@ int main() {
testBase64RoundTripAllBytes();
testBase64DecodeRejectsMalformed();
testTcpMcpPanelIsHotspot();
testTcpMcpFxButtonIsHotspot();
testFxWindowStillHotspot();
testNonFxSurfacesAreNotHotspot();