Bridged plugins editor window handling?

Not sure if there’s a solution for this, as I already see that other companies just open the window in a new window. So the original plugin can’t just attach to the bridged (new process) window.

Maybe there’s a way to do a quick screenshot of a window that is open somewhere or windows doesn’t have such thing?

Anyway, just wondering. Maybe there’s a new solution lying around. :wink:

In case you don’t know what I’m talking about: I created a 32 bits to 64 bits bridge plugin manager. When you load the 64 bits plugin it creates a new process and call a 32 bits app that will host the desired 32 bits plugin. But now the problem is that the plugin’s editor window is in a separated process from the original 64 bits plugin.

Cheers, WilliamK

One ugly way would be to “record” the window and send to the original plugin. And have a timer do that.

Image snapImage = juce::createSnapshotOfNativeWindow(pluginEditorWindow->theEditor->getWindowHandle());

That seems to work correctly. But now I need to check how I could fake mouse events to the plugin’s window… humm…

Another thing I’m wondering, can I pass a windows handle from the plugin into my external process and have it call

VSTPluginFormat::dispatcher(pluginLoad, 14, 0, 0, windowHandle, 0);

So it opens the Editor but attaches it to the original window. Does Windows allow that? Or since they are separated processes I’m not allowed?

Also, if that’s possible, how do I convert a void* pointer into a value that I can send to my piped process and there how do I convert back to a void*? I never done that. :wink:

Cheers, WilliamK

You can’t share memory like that. It’s much more complicated. The void* you would be sending from another process doesn’t mean the same memory location in another process. But if you need to pass it for some other purpose (not for really using the memory location in the other process), just cast it into a 64 bit integer and back, I guess…?

Regarding the problem of embedding a GUI window from another process, it is possible to do at least on Windows, since Reaper’s Windows version manages to do it with its bit bridge. (With the caveat that if the bridge process crashes or hangs, the main Reaper instance will fault too.) Cockos has not found a way to do it in macOs. Juce itself has no support for that, like you probably already found out. You need to implement it in Windows using the native APIs.

Thank you so much. I just need on Windows for now. On OSX I will do in a different way anyway. I just don’t have a clue on how to void* -> int64 and back…

To do the cast, something like :

uint64_t as_int = (uint64_t)f;

Where f is a void*. Of course, when passing through 32/64 bit process boundaries, attempting to actually use the pointer to directly access anything is completely out of the question. You can only use the 64 bit number as some kind of an identifier. (32 bit processes of course can handle 64 bit integers, but not 64 bit pointers.)

I also found this:

SetParent works perfectly and it is compatible by Windows, as windows handles are 32 bits in size, so all is good. :slight_smile:

I’m getting some weird behavior with SetParent, so I had to ditch the idea for now. Looks like the best option would be to screenshot the original window at X ms and send mouse event commands to it. Just need to figure out the later.

1 Like

Out of curiosity, how are you communicating between the two processes? Pipe, socket, RPC? I’d like to do something like this but am concerned about performance.

NamedPipe. Seems to be ok from what I could tell. :slight_smile:

If you want to see some of my code let me know.

What I decided to do, and seems to work great, is to just screenshot the other process window, and make it move to the front when the mouse is over the bridged plugin. It works great. So when you move the window around or just make the original window go to the back, you still have the screenshot (I take one on every 100ms) of the original window there. Seems almost as it is embedded into the bridged plugin UI. The only drawback is that since I’m using the mouse-move event, the window may overlap some other window. But is still better than just having the window moving around in the back…

Presumably things like metering or animated spectrums feel laggy with this though?

I think what companies like BitWig do is just make the child process show their plugin windows always on top. This might get tricky if you also have a non-bridged plugin open though.

Is your product a plugin that’s hosting other plugins by bridging or simply a host app itself? I’m just trying to visualise how many windows you have to manage and who (plugin or host) owns those windows.


Opening windows as always on top is really bad, as other menus won’t show up. Specially my own menus. :wink: