Files
reasampler/src/core/ui/window_origin.cpp
T
daniel fe1aec5925 Hand a card dragged onto a plugin's own editor to the OS as a file drop; withdraw the OLE drag when the pointer returns to REAPER
A code-ownership proof (window class procedure's module, via the pure window_origin) plus REAPER's FX-surface token routes a plugin editor to OLE; FX chrome keeps the instrument drop. The OLE loop re-asks the law each turn, so passing a plugin editor stays reversible.
2026-09-25 13:39:39 -04:00

49 lines
1.8 KiB
C++

// window_origin — pure implementation. See window_origin.h.
#include "core/ui/window_origin.h"
#include <algorithm>
namespace reasampler::ui {
namespace {
// Case-folded (ASCII only — Windows' own directory names are ASCII), separator-unified, with the
// "\\?\" long-path prefix GetModuleFileName may report dropped, so the same directory compares
// equal however each API chose to spell it.
std::string normalizePath(const std::string& p) {
std::string s = p.rfind("\\\\?\\", 0) == 0 ? p.substr(4) : p;
for (char& c : s) {
if (c == '/') c = '\\';
else if (c >= 'A' && c <= 'Z') c = static_cast<char>(c - 'A' + 'a');
}
while (!s.empty() && s.back() == '\\') s.pop_back();
return s;
}
// Directory containment, not string prefix: C:\Windows must not claim C:\WindowsApps.
bool isBeneath(const std::string& path, const std::string& dir) {
const std::string p = normalizePath(path);
const std::string d = normalizePath(dir);
return !d.empty() && p.size() > d.size() && p.compare(0, d.size(), d) == 0 &&
p[d.size()] == '\\';
}
} // namespace
WindowCode classifyWindowCode(const WindowFacts& facts, const std::string& systemRoot) {
// Another process's procedure address means nothing in ours; the process boundary is itself
// the proof. Inside an FX window that is the bridged plugin's editor.
if (facts.otherProcess) return WindowCode::Plugin;
if (!facts.procResolved) return WindowCode::Unknown;
if (facts.hostModule) return WindowCode::Host;
if (normalizePath(systemRoot).empty()) return WindowCode::Unknown;
return isBeneath(facts.modulePath, systemRoot) ? WindowCode::System : WindowCode::Plugin;
}
bool isPluginEditorChain(const std::vector<WindowCode>& chain) {
return std::find(chain.begin(), chain.end(), WindowCode::Plugin) != chain.end();
}
} // namespace reasampler::ui