diff --git a/native_bridge/src/FxGuiServer.cpp b/native_bridge/src/FxGuiServer.cpp index ee8b602..2282769 100644 --- a/native_bridge/src/FxGuiServer.cpp +++ b/native_bridge/src/FxGuiServer.cpp @@ -269,6 +269,18 @@ uint64_t frameHash(HWND hwnd) { return h; } +// Lift the window above the foreground app without making it TOPMOST (the +// foreground-lock would otherwise swallow real clicks). Attaching to the +// foreground thread is required to steal foreground from another process. +static void bringToTop(HWND hwnd) { + DWORD fgTid = GetWindowThreadProcessId(GetForegroundWindow(), nullptr); + DWORD myTid = GetCurrentThreadId(); + if (fgTid && fgTid != myTid) AttachThreadInput(fgTid, myTid, TRUE); + SetForegroundWindow(hwnd); + BringWindowToTop(hwnd); + if (fgTid && fgTid != myTid) AttachThreadInput(fgTid, myTid, FALSE); +} + void danceStart(HWND hwnd, HWND target, int x, int y) { // Real-input fallback (only entered when synthetic PostMessage was probed // as rejected — iZotope/JUCE editors): hardware input needs the plugin @@ -291,6 +303,7 @@ void danceStart(HWND hwnd, HWND target, int x, int y) { } SetWindowPos(hwnd, HWND_TOP, g_embedRect.left, g_embedRect.top, cw, ch, SWP_NOACTIVATE | SWP_SHOWWINDOW); + bringToTop(hwnd); // plugin must sit above the foreground app (e.g. browser) or real clicks land there fxGuiRequestResize(hwnd, cw, ch); Sleep(60); // let the compositor repaint so the editor sees itself active g_dance = true; diff --git a/src-tauri/binaries/fx_vst_bridge.exe b/src-tauri/binaries/fx_vst_bridge.exe index dd8de9e..4bbf749 100644 Binary files a/src-tauri/binaries/fx_vst_bridge.exe and b/src-tauri/binaries/fx_vst_bridge.exe differ