Running into an issue using the WebBrowserComponent as the GUI for my plugin. Whenever the part of my GUI that is a WebBrowserComponent is in focus, all key events get “swallowed” up. This means that if any controls are moved within the web browser and for instance the user presses spacebar in a DAW, the DAW’s transport doesn’t start. (It does if a non-WebBrowserComponent part of the GUI is in focus). Same idea with any DAW hotkeys that are pressed while the WebBrowser is in focus. Is there any way that this issue can be resolved in JUCE?
Hi jackwcampbell i stumbled accross the same problem. Did you find any solution to this?
Unfortunately nothing in JUCE itself – it would be awesome if JUCE would address this issue because it really makes using the WebBrowserComponent for audio plugins infeasible/clunky in many cases. (@tpoole ?) Users generally expect for instance to be able to start/stop the transport with spacebar regardless of whether a plug GUI is in focus…
Looking around on the web, this is the common way around this issue (usually used with Microsoft WebView2 but works with WkWebView on Mac as well). It would be better if JUCE handled this, because it has knowledge of native windows etc and is unfortunate for the client code to have to handle it…
And FWIW, Microsoft is planning on adding a true key forwarding/detecting callback to a future WebView2. Currently they only support forwarding accelerator keys: WPF Key Forwarding from WebView2 to Host application? · Issue #468 · MicrosoftEdge/WebView2Feedback · GitHub
(So, not to post all the blame on JUCE – but there is a way that JUCE could handle it, it’s just not trivial unfortunately.)
Thanks so much for the detailed answer! Currently working on the windows fix and I have already cobbled together a communication between the plugin and the WebView2 for other purposes so I can send events to the plugin and fake the key input from there.
What I do to get the HWND handle to the DAW window (to which I send all necessary key events) feels even more hacky; when a new Plugin instance is opened I save the response of GetForegroundWindow at the very beginning assuming that the DAW is in the foreground when the user opens a plugin. Would you know if there is a better/more robust way to obtain that handle?
One thing you can try is to focus your plugin’s JUCE window in response and send the input to that, which should put the key event back into the window hook chain (similar to the responder chain on macOS) and then be forwarded to the DAW by the OS. So rather than grabbing the DAW’s HWND, you get the JUCE window HWND using getPeer()->getNativeHandle(). Then you can use the win32 SetFocus on that HWND and use the win32 SendInput() call to inject the JS key events back into the chain (which should end up then being forwarded to the DAW window as well).
If I understood you correctly, that’s what I tried first but here’s the problem: if I send the key event to the JUCE window HWND then it’s consumed by the WebView2 again (essentially creating a feedback loop) or am I missing something?
I think the key is to switch focus to the JUCE window HWND first and then use SendInput, because in that case the WebView2 won’t be in the chain for receiving events (should be skipped, which avoids the feedback loop). Though I’m a little fuzzy in my memory on that… I did run into feedback loop issues trying a similar approach on Mac, but IIRC it wasn’t an issue on Windows.
Just in case someone ever has the same problem: The solution outlined by jack works great on Mac (tested ableton and FL) and on Windows for Ableton. For Windows Fl studio I found with trial and error that I need to take the “grandparent” of the HWND I get with getPeer()->getNativeHandle() (call getParent() on it twice) in order for FL studio to get my spacebar presses to start playback. Thanks again jack for the great help!