Exempt ReaSampler 9000's own editor from the plugin OS drag hand-off

A dragged bank card over our own instrument's editor was OLE-dropping like a third-party plugin. Classify our channel's own .vst3 module as Instrument, not Plugin, so it keeps the normal instrument-drop outcome.
This commit is contained in:
2026-09-25 13:57:11 -04:00
parent 0484599408
commit fee941a83d
7 changed files with 83 additions and 9 deletions
+35
View File
@@ -23,6 +23,14 @@ static WindowFacts inModule(const std::string& path, bool host = false) {
return f;
}
static WindowFacts ownModule(const std::string& path) {
WindowFacts f;
f.procResolved = true;
f.modulePath = path;
f.ownModule = true;
return f;
}
// --- classifyWindowCode --------------------------------------------------------
// REAPER's own chrome and containers: the class procedure lives in the executable.
@@ -103,6 +111,17 @@ static void testMissingSystemRootNeverYieldsPlugin() {
CHECK(classifyWindowCode(inModule("C:\\REAPER\\reaper.exe", true), "") == WindowCode::Host);
}
// Our own ReaSampler 9000 module — stable or beta, whichever the shell set ownModule for — is
// Instrument, not Plugin: FX chrome we own, so a drag over it must not hand off to the OS.
static void testOwnModuleIsInstrument() {
CHECK(classifyWindowCode(
ownModule("C:\\Program Files\\Common Files\\VST3\\reasampler_9000.vst3"), kWinDir) ==
WindowCode::Instrument);
CHECK(classifyWindowCode(
ownModule("C:\\Program Files\\Common Files\\VST3\\reasampler_9000_beta.vst3"),
kWinDir) == WindowCode::Instrument);
}
// --- isPluginEditorChain -------------------------------------------------------
// Pointer on REAPER's FX-window chrome: a standard control or a REAPER container, under the
@@ -134,6 +153,19 @@ static void testBridgedEmbeddedEditorIsPlugin() {
WindowCode::System}));
}
// A pointer over our own instrument's editor — Instrument code, not Plugin — is not hand-off
// proof: it stays REAPER's FX chrome, unlike a genuine plugin editor (testPluginWindowChainIsPlugin).
static void testOwnInstrumentChainIsNotPlugin() {
CHECK(!isPluginEditorChain({WindowCode::Instrument, WindowCode::Host, WindowCode::System}));
}
// Another plugin's editor sitting alongside our own instrument in the same chain is still proof —
// only OUR module is exempted, nobody else's.
static void testOtherPluginBesideOwnInstrumentIsStillPlugin() {
CHECK(isPluginEditorChain(
{WindowCode::Plugin, WindowCode::Instrument, WindowCode::Host, WindowCode::System}));
}
// Unknown anywhere, and nothing else, is not proof; an empty chain (no window at all) is not.
static void testUnknownAndEmptyChainsAreNotPlugin() {
CHECK(!isPluginEditorChain({WindowCode::Unknown, WindowCode::Host, WindowCode::System}));
@@ -150,11 +182,14 @@ int main() {
testOtherProcessIsPluginRegardlessOfModule();
testUnresolvedProcIsUnknown();
testMissingSystemRootNeverYieldsPlugin();
testOwnModuleIsInstrument();
testChromeChainIsNotPlugin();
testPluginWindowChainIsPlugin();
testStandardControlInsidePluginIsPlugin();
testBridgedEmbeddedEditorIsPlugin();
testOwnInstrumentChainIsNotPlugin();
testOtherPluginBesideOwnInstrumentIsStillPlugin();
testUnknownAndEmptyChainsAreNotPlugin();
if (g_fail == 0) std::printf("All tests passed.\n");