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:
@@ -98,7 +98,9 @@ L7 sub-pass, 2026-07-27):
|
||||
hand off over any extension window docked in REAPER, so this route also REQUIRES the
|
||||
FX-surface token; within an FX window the proof is what separates the plugin's editor
|
||||
(OS hand-off — the plugin takes the files as it would from Explorer) from REAPER's
|
||||
chrome (instrument drop, unchanged).
|
||||
chrome (instrument drop, unchanged). Our own ReaSampler 9000 editor is exempted from
|
||||
this proof (`WindowCode::Instrument`) — it is FX chrome we own, so a drop on it is the
|
||||
instrument-drop outcome like any other REAPER chrome, never the OS hand-off.
|
||||
|
||||
Once handed off, the law keeps running: on Windows the OS drag loop re-asks it every
|
||||
turn (`decideOsDragTurn`) and WITHDRAWS the moment it stops answering `OsHandoff`,
|
||||
@@ -116,7 +118,7 @@ L7 sub-pass, 2026-07-27):
|
||||
- `tab_strip` — REAPER-free scrollable tab-strip layout + hit-test for the named-banks strip.
|
||||
- `prune_button` — pure layout/hit-test for the `bank_panel` footer Prune button.
|
||||
- `drag_out` — the pure drag-out gesture law plus path-list assembly. Owns the `ReaperSurface` vocabulary (TrackPanel / FxSurface / FxEmbed / Arrange / Other — `core/wire/instrument_drop` classifies REAPER's info token INTO it; there is deliberately no off-REAPER member, since no token can carry that fact), `decideDropClass` (surface × single-vs-multi payload → Internal / InstrumentDrop / ArrangeInsert / Refuse / OsHandoff / None), and `cueForDropClass`. `OsHandoff` is reachable ONLY through the two proof members of `DropContext` — `pointerOffHost` (`drag_out_win::pointerOverHostWindow`) where REAPER's hit-test named nothing (`Other`, no track), and `pointerOverPluginEditor` (`drag_out_win::pointerOverPluginEditor`) where it named `FxSurface` — both gated ahead of the surface switch, so no evidence source can give a live drag away to OLE on its own (the invariant above states why each pairing). Also owns `decideOsDragTurn`, the OS drag loop's per-turn Continue / Drop / Cancel / Withdraw / WithdrawAtRelease verdict. **No `DropClass` means "nothing happens"**: a surface with no defined outcome for the payload resolves to `Refuse`, which the shell shows as a cursor, so "no silent no-op release" is a property of the enumeration rather than of any call site.
|
||||
- `window_origin` — whose code implements a window (Host / System / Plugin / Unknown, from the owning process and the module holding the window CLASS's procedure) and `isPluginEditorChain`, the rule behind `pointerOverPluginEditor`: any Plugin window from the hit window up to its root. Unknown is never proof, and without the OS directory every non-host module degrades to Unknown — both keep the failure direction toward REAPER's own outcome, never toward the modal hand-off. The shell reads the facts; the known misses are listed at `drag_out_win.h`'s `pointerOverPluginEditor`.
|
||||
- `window_origin` — whose code implements a window (Host / System / Plugin / Instrument / Unknown, from the owning process and the module holding the window CLASS's procedure) and `isPluginEditorChain`, the rule behind `pointerOverPluginEditor`: any Plugin window from the hit window up to its root. Unknown is never proof, and without the OS directory every non-host module degrades to Unknown — both keep the failure direction toward REAPER's own outcome, never toward the modal hand-off. `Instrument` is the one deliberate exemption: our own ReaSampler 9000 module (`WindowFacts::ownModule`, a basename match against this channel's `app_version::vstOutputName() + ".vst3"` — stable and beta each recognise only their own binary) is FX chrome we own, not a hand-off-worthy plugin editor, so it is never `Plugin` and never counts as `isPluginEditorChain` proof — a drag over our own editor stays the instrument-drop outcome. Every other plugin's module is unaffected. The shell reads the facts; the known misses are listed at `drag_out_win.h`'s `pointerOverPluginEditor`.
|
||||
- `theme` — pure palette module: role→color mapping, REAPER-grey neutral ladder + the pastel accent system, the keyboard strip's spectral ramp, WCAG contrast-floor helpers + `compositeOver` (the effective color of a translucent fill, so alpha overlays are testable). Only the ramp's MID stop is its own constant; lo/hi are still aliases of `accent/primary`/`accent/tertiary`, so a categorical accent move CAN still reorder the ramp — `testSpectralRampLuminanceIsMonotonic` is the build-time catch, not the structure.
|
||||
- `component_geometry` — pure button/slider/list-row geometry + hover hit-test helpers.
|
||||
- `action_bar` — pure task-grouped action-bar layout/hit-test: clusters (Capture / Placement / Maintenance / Tagging / Switching).
|
||||
|
||||
@@ -37,6 +37,7 @@ WindowCode classifyWindowCode(const WindowFacts& facts, const std::string& syste
|
||||
if (facts.otherProcess) return WindowCode::Plugin;
|
||||
if (!facts.procResolved) return WindowCode::Unknown;
|
||||
if (facts.hostModule) return WindowCode::Host;
|
||||
if (facts.ownModule) return WindowCode::Instrument;
|
||||
if (normalizePath(systemRoot).empty()) return WindowCode::Unknown;
|
||||
return isBeneath(facts.modulePath, systemRoot) ? WindowCode::System : WindowCode::Plugin;
|
||||
}
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
namespace reasampler::ui {
|
||||
|
||||
enum class WindowCode {
|
||||
Host, // the host executable itself — REAPER's own chrome and containers
|
||||
System, // an OS module (standard controls, dialog class): says nothing about who placed it
|
||||
Plugin, // any other code — a plugin binary, or a window of another process (bridged plugin)
|
||||
Unknown, // the procedure resolved to no loaded module — no evidence either way
|
||||
Host, // the host executable itself — REAPER's own chrome and containers
|
||||
System, // an OS module (standard controls, dialog class): says nothing about who placed it
|
||||
Plugin, // any other code — a plugin binary, or a window of another process (bridged plugin)
|
||||
Instrument, // our own ReaSampler 9000 module: FX chrome, not a hand-off-worthy plugin editor
|
||||
Unknown, // the procedure resolved to no loaded module — no evidence either way
|
||||
};
|
||||
|
||||
// What the shell observed about ONE window. The CLASS procedure, not the instance one, because an
|
||||
@@ -23,6 +24,11 @@ struct WindowFacts {
|
||||
bool otherProcess = false; // the window belongs to a process other than the host's
|
||||
bool procResolved = false; // the class procedure lies inside a loaded module
|
||||
bool hostModule = false; // ...and that module is the host executable
|
||||
// ...and that module is THIS channel's ReaSampler 9000 .vst3 (basename match, set by the
|
||||
// shell against app_version::vstOutputName() + ".vst3" — stable and beta each recognise only
|
||||
// their own binary, never the other channel's). A drag over our own instrument's editor is
|
||||
// the load-bearing-principle instrument-drop outcome, not the OS hand-off other plugins get.
|
||||
bool ownModule = false;
|
||||
std::string modulePath; // that module's file path, UTF-8
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user