# JUCE flaw in plugin hosting applications

**URL:** <https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921>\
**Category:** General JUCE discussion\
**Created:** [September 18, 2023, 8:52am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921 "2023-09-18T08:52:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 18, 2023, 8:52am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/1 "2023-09-18T08:52:12Z")

</div>

I’m raising my concern about a small detail regarding how JUCE handles keyboard focus/input when you’re using JUCE to build you own VST/AU plugin hosting applications, such as a DAW. This tiny detail basically renders JUCE unusable in DAW types of applications:

Clicking the hosted VST/AU plugin’s GUI grabs the keyboard focus completely from the main JUCE application, which sound like a logical thing to happen at first glance. However, plugins are meant to be used in DAW applications, which most often use the spacebar key to start/stop the song playback and other key combinations to quckly save your project, etc. Now if there is no way for the main JUCE application to receive any keyboard events while the user is tweaking the plugin GUI elements (knobs/sliders/etc.), the JUCE application cannot start/stop playback, or save the project, before the user clicks the main JUCE application area itself, outside the plugin’s GUI.

This almost defeats the whole point of having VST/AU plugin hosting support in JUCE, since DAWs are the main thing which host such plugins. And if you can’t perform standard DAW functions while having plugins on screen, the users get frustrated and/or confused why the JUCE application isn’t reacting as expected.

Is there an easy way to hack my way around this limitation?

---

<div class="post-metadata">

**Author:** ![eyalamir](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/eyalamir/32/2978_2.png) [@eyalamir](https://forum.juce.com/u/eyalamir)\
**Post date:** [September 18, 2023, 10:02am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/2 "2023-09-18T10:02:01Z")

</div>

> [@Kraku](#):
>
> This tiny detail basically renders JUCE unusable in DAW types of applications:

1. Have you tested that this is actually a bug in JUCE (and not some bug in your code)?  
For example, I’ve just opened Waveform 11 (a DAW made with JUCE) and I was able to be focused on the plugin while clicking spacebar to trigger play/stop/etc.

2. From the plugin makers point of view, you get a shot at the key with KeyPressed(). If you return `false` from that event that will pass that event to the host. For example we only process spacebar if we’re on standalone mode, but otherwise we give it back to the host.

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 18, 2023, 10:29am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/3 "2023-09-18T10:29:28Z")

</div>

Here’s a small test project, which hosts plugins and writes on screen changing key press counter whenever a key has been pressed. Compile and run it to see how it works on your computer. Just right click with mouse to select/load a VST/AU plugin. Then click the plugin’s GUI area and start pressing computer keyboard keys. Let me know if it works on your computer. On mine I get no keyboard presses until I click outside the plugin GUI area.

[VST\_Host\_Bugs.zip](https://forum.juce.com/uploads/short-url/heB50QgEISWyxLshatNhdYbrUkb.zip) (11.3 KB)

All the keyboard handling happens in the MainComponent.cpp, if you’re interested in checking out what’s happening there.

Reuk said in another thread ([VST3/AU plugin hosting bugs - demonstration project](https://forum.juce.com/t/vst3-au-plugin-hosting-bugs-demonstration-project/57462)) :

> I think that this is by design. If the plugin is focused, it gets to respond to key events first, and only unhandled key events should be passed up to the host.
> 
> Perhaps there’s scope for a new addGlobalKeyboardListener feature on juce::Desktop to mirror the existing addGlobalMouseListener - however, this would not be trivial to add and would require a lot of testing. I don’t see this happening in the near future as we’re currently focusing on other major features.

---

<div class="post-metadata">

**Author:** ![eyalamir](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/eyalamir/32/2978_2.png) [@eyalamir](https://forum.juce.com/u/eyalamir)\
**Post date:** [September 18, 2023, 10:59am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/4 "2023-09-18T10:59:18Z")

</div>

From what I see in your testing code, the problem is you’ve added the editor directly as a child to MainComponent with `addAndMakeVisible(*mp_editor);`

Usually the way it’s done in most hosts (JUCE and non-JUCE) is to add the plugin into its own window. I think doing that will greatly simplify what you’re doing and solve problems like that.

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 18, 2023, 11:03am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/5 "2023-09-18T11:03:21Z")

</div>

Using the ready made window fixes the issue only if I wouldn’t need to add my own Components into the same window next to the plugin GUI. (Namely audio routing and modulation/automation related parameters) For this I need to have a separate parent Component inside the window which contains the plugin GUI and my extra Components next to it. This in turn raises the current issue demonstrated in this thread.

---

<div class="post-metadata">

**Author:** ![eyalamir](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/eyalamir/32/2978_2.png) [@eyalamir](https://forum.juce.com/u/eyalamir)\
**Post date:** [September 18, 2023, 11:26am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/6 "2023-09-18T11:26:36Z")

</div>

> [@Kraku](#):
>
> For this I need to have a separate parent Component inside the window which contains the plugin GUI and my extra Components next to it.

You can still add other Components to the external window, this shouldn’t cause a conflict with spacebar and other keyboard shortcuts that should probably be processed by the main host window and not the plugin window.

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 18, 2023, 11:51am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/7 "2023-09-18T11:51:08Z")

</div>

I have to make a small test application to test this. The application I’m developing presents this issue though.

---

<div class="post-metadata">

**Author:** ![eyalamir](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/eyalamir/32/2978_2.png) [@eyalamir](https://forum.juce.com/u/eyalamir)\
**Post date:** [September 18, 2023, 12:03pm UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/8 "2023-09-18T12:03:43Z")

</div>

You can just compare the behavior against other DAWs (JUCE and non-JUCE).

For example Waveform 11 also adds custom Components to the plugin window (see image) but the spacebar gets correctly passed to the host window even in focus.

 ![Screenshot 2023-09-18 at 3.02.26 PM](https://us1.discourse-cdn.com/flex026/uploads/juce/original/3X/4/f/4f0933b381f17350e6b71b1f674d893c8ff79d18.jpeg)

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [September 18, 2023, 4:13pm UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/9 "2023-09-18T16:13:10Z")

</div>

You can also derive your plugin Window from KeyListener if you need to handle keystrokes yourself. I do this for my plugin which hosts 3rd party plugins but needs to handle the spacebar in Standalone.

Also check the JucePlugin\_EditorRequiresKeyboardFocus setting.

Rail

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 19, 2023, 8:53am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/10 "2023-09-19T08:53:42Z")

</div>

What is that “JucePlugin\_EditorRequiresKeyboardFocus” setting? Where can it be found? I couldn’t find any reference to it from the documentation nor by Googling.

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 19, 2023, 10:58am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/11 "2023-09-19T10:58:11Z")

</div>

Doesn’t seem to work on Windows. On Mac using AU/VST3 plugins things work OK, but on Windows the keyboard events don’t get received by the KeyListener, after you’ve tweaked the plugin’s GUI knobs/etc…

Here’s my short PluginWindow class derived from DocumentWindow and KeyListener:

```auto
class PluginWindow : public juce::DocumentWindow,
                     public juce::KeyListener
{
public:
    PluginWindow(const juce::String& name,
                 juce::Component* p_plugin_editor
        : juce::DocumentWindow(name, juce::Colour(0xFF000000), DocumentWindow::TitleBarButtons::closeButton)
    {
        setUsingNativeTitleBar(true);
        setVisible(true);
        setAlwaysOnTop(true);

        p_plugin_editor->addKeyListener(this);
        setContentComponentSize(p_plugin_editor->getWidth(), p_plugin_editor->getHeight());
        setContentNonOwned(p_plugin_editor, true);
    }

    void closeButtonPressed() override
    {
        clearContentComponent();
        delete this;
    }

    bool keyPressed(const KeyPress& key) override
    {
        // Windows VST3 doesn't end up here when you tweak knobs and press computer's keys!
        return false;
    }

    bool keyStateChanged(bool isKeyDown) override
    {
        // Windows VST3 doesn't end up here when you tweak knobs and press computer's keys!
        return false;
    }

    bool keyPressed(const KeyPress& key, Component* originatingComponent) override
    {
        // Windows VST3 doesn't end up here when you tweak knobs and press computer's keys!
        return false;
    }

    bool keyStateChanged(bool isKeyDown, Component* originatingComponent) override
    {
        // Windows VST3 doesn't end up here when you tweak knobs and press computer's keys!
        return false;
    }

private:
    juce::TooltipWindow m_tool_tip_window { this, 500 };

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginWindow)
};

```

The p\_plugin\_editor I give to the constructor is a juce::Component, which has some of my own Components and also the VST3 plugin GUI as child Components.

---

<div class="post-metadata">

**Author:** ![eyalamir](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/eyalamir/32/2978_2.png) [@eyalamir](https://forum.juce.com/u/eyalamir)\
**Post date:** [September 19, 2023, 11:35am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/12 "2023-09-19T11:35:21Z")

</div>

You can place a breakpoint in `ComponentPeer::handleKeyPress` and see which Component captured the event.

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 19, 2023, 12:42pm UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/14 "2023-09-19T12:42:37Z")

</div>

There are two of those methods in JUCE:

bool ComponentPeer::handleKeyPress (const int keyCode, const juce\_wchar textCharacter)  
bool ComponentPeer::handleKeyPress (const KeyPress& keyInfo)

On Windows, neither one of those methods gets called when the issue happens.

---

<div class="post-metadata">

**Author:** ![eyalamir](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/eyalamir/32/2978_2.png) [@eyalamir](https://forum.juce.com/u/eyalamir)\
**Post date:** [September 19, 2023, 1:13pm UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/15 "2023-09-19T13:13:56Z")

</div>

> [@Kraku](#):
>
> On Windows, neither one of those methods gets called when the issue happens.

That means the native plugin window has consumed the event. I’m guessing that’s what you will also experience in other DAWs, and is probably the ‘correct’ behavior.

The plugin needs to report it doesn’t consume the event for it to be passed to the host.

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 19, 2023, 1:45pm UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/17 "2023-09-19T13:45:08Z")

</div>

That cannot be the case, that it would happen in other DAWs also. The plugins that are misbehaving are all of Native Instruments / U-he plugins. In any DAW it’s possible to successfully press spacebar once you’ve tweaked any of NI / U-he plugin GUI elements.

Is there a way to steal the keyboard event information before it is given to the plugin?

---

<div class="post-metadata">

**Author:** ![eyalamir](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/eyalamir/32/2978_2.png) [@eyalamir](https://forum.juce.com/u/eyalamir)\
**Post date:** [September 19, 2023, 1:51pm UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/18 "2023-09-19T13:51:58Z")

</div>

> [@Kraku](#):
>
> That cannot be the case, that it would happen in other DAWs also.

That’s not what I’m experiencing here with my hosting app.

I can focus on my plugin (that has intentionally not consumed spacebar), and clicking spacebar will trigger `ComponentPeer::handleKeyPress` in the host.

However, clicking another button (not spacebar) that my plugin does consume will not be called by my host.

I would start by debugging AudioPluginHost or Tracktion Engine’s examples to see if it’s something that you’ve done in your test that is different.

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 20, 2023, 7:41am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/19 "2023-09-20T07:41:54Z")

</div>

Hmm, weird. Are you testing this on Windows + VST3 plugins?

Also, just in case:  
Do you have the plugin added to DocumentWindow, with  
setContentNonOwned() ?

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 20, 2023, 8:24am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/20 "2023-09-20T08:24:02Z")

</div>

AudioPluginHost is also buggy on Windows. So it has the very same issue I’m describing here. I.e. `ComponentPeer::handleKeyPress` doesn’t get called at all when you have been tweaking VST plugin’s knobs right before you press some key.

Can you confirm that AudioPluginHost, on your Windows computer, calls `ComponentPeer::handleKeyPress` when you have tweaked GUI elements (knobs/sliders) of a VST3 plugin with mouse and then press some key on computer’s keyboard?

---

<div class="post-metadata">

**Author:** ![eyalamir](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/eyalamir/32/2978_2.png) [@eyalamir](https://forum.juce.com/u/eyalamir)\
**Post date:** [September 20, 2023, 8:50am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/21 "2023-09-20T08:50:45Z")

</div>

> [@Kraku](#):
>
> Can you confirm that AudioPluginHost, on your Windows computer, calls `ComponentPeer::handleKeyPress` when you have tweaked GUI elements (knobs/sliders) of a VST3 plugin with mouse and then press some key on computer’s keyboard?

Yes, I’ve just compiled APH from source on Windows and it works correctly with the VST3 plugin I’ve tested, which is a commercial plugin of ours that consumes some keys but not spacebar.

But just to make sure - it only works correctly if the plugin didn’t consume the event. If the plugin consumes the event, I don’t get `handleKeyPress` in the host, which I suspect is what will happen in most hosts to avoid a key command doing 2 things at the same time.

You should really compare/debug other DAWs and plugins to see what’s the expected behavior is.

---

<div class="post-metadata">

**Author:** ![Kraku](https://avatars.discourse-cdn.com/v4/letter/k/74df32/32.png) [@Kraku](https://forum.juce.com/u/Kraku)\
**Post date:** [September 20, 2023, 9:22am UTC](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921/22 "2023-09-20T09:22:59Z")

</div>

From the tests I’ve already done as described above, here are my observations on Windows:

1. Ableton Live reacts happily to any keyboard presses (Spacebar for example) after VST3 plugin’s knobs have been touched with mouse.

2. AudioPluginHost, nor my own application, does not react at all to any keyboard presses after VST3 plugin’s knobs have been touched with mouse.

I can only check the ComponentPeer::handleKeyPress issue on AudioPluginHost and my own app, since they are the only ones I can debug. And as I already mentioned, that method won’t get called.

I’m not sure if there is much else that can be debugged this way?

Which version of JUCE are you using?

[Next page](https://forum.juce.com/t/juce-flaw-in-plugin-hosting-applications/57921.md?page=2)
