modifierKeysChanged() with setWantsKeyboardFocus(false)

Our plugins setWantsKeyboardFocus(false) but would like to receive modifier key changes for mouseEvents. Though the state of a modifier key at the time of a mouse event is transmitted together with the mouse event - a dynamic modifier key change is not received by modifierKeysChanged() until any of our components actually did receive a mouseDown() (which probably brings the focus the plugin).
How can our plugins receive modifierKeysChanged() without having to request setWantsKeyboardFocus(true) (in this case the modifier keys are mouse modifier keys and not keyboard input)?

Even with setWantsKeyboardFocus(true) modifierKeysChanged() is not triggered until the mouse clicked onto the plugin already in focus.

If you want to track the dynamic state of the modifier keys while the mouse is down, you can start a timer in the mouseDown method, and stop the timer in the mouseUp method. Alternatively, if you want to track the modifier keys when the mouse is over the component you can manage the timer from the mouseEnter/mouseExit routines.

In the timerCallback() you can use ModifierKeys::getCurrentModifiersRealtime() to get the current state of the modifier keys.

Thanks for the suggestion, but once the mouse has been pressed, the plugin will receive modifierKeysChanged() anyways. The problem is receiving the indication before that.

Therefor one could setup a timer, but wouldn’t it be easier to fix the framework?
For our purpose getting notified about a state change will only result in a graphical indication about a functional change of a GUI control. Thus I would prefer having the plugin receiving an indication over polling the state…

But maybe ROLI knows some workaround…, and can confirm it as a bug or feature? Would that be possible?!

It works as expected here -when the component has the focus, it gets notified. I think the problem might be getting the focus in the first place. I use ComponentMovementWatcher to make a component try to get the focus when it’s made visible:

class FocusGrabber : public ComponentMovementWatcher
{
public:
    FocusGrabber (Component* c) : ComponentMovementWatcher{ c }
    {
        c->setWantsKeyboardFocus (true);
    }
    void componentVisibilityChanged() override
    {
        auto c{ getComponent() };
        if (c->isShowing()) c->grabKeyboardFocus();
    }
    void componentPeerChanged() override {}
    void componentMovedOrResized (bool, bool) override {}
};

class SomeComponent : public Component
{
    FocusGrabber grabber{ this };
};

It’s not that simple with plugins though. If the host gets the focus and doesn’t pass the notifications down, you won’t get them. This is a typical problem -sometimes you expect a plugin to get a key and nothing happens, or something else happens in the host, because the focus moved to it. You could check the modifiers in focusGained and focusLost, and update your state accordingly.