Win/PT modifier fixes in JUCE 4.1

Firstly - there are good reasons I’m not on the current version of JUCE - surround formats being one of them.

So, I’ve attempted to recreate your recent AAX modifier fixes in my copy of JUCE 4.1.
It seems to work for me but other users are reporting intermittent failures for the ALT key.
I saw it “let go” once or twice myself but for the most part it correctly senses the ALT ket down.

Can you think of any reason this new fix would be incompatible with older JUCE code?
Is there some other fix I should have also applied?

The changes are working fine in JUCE 4.0 as I wrote here:

Rail

Please test the experimental/multibus - we’ve taken all the feedback on board and any surround issues should be fixed. We will merge the experimental/multibus to develop soon, so getting your feedback now would be really valuable.

Thanks, I’d love to try out the multi-bus again stuff but I’m too close to a stable build risk so many fundamental changes.

But I do have a bug with the Windows AAX ALT modifiers.

ALT held by itself is detected correctly.
SHIFT-ALT (pressed in that order) is detected correctly as long as it’s held.
ALT-SHIFT (in that order) is broken - the ALT status is detected for the first ~0.5sec then it “lets go”.
ALT-CTRL = same issue as with ALT-SHIFT

RIGHT-ALT in AAX plugins will behave like ALT-CTRL (in that order) so it always “lets go” and reverts to CTRL after a brief moment. I know the RIGHT ALT topic has been discussed here before but I thought this might provide another lead to follow.

As a comparison: None of these issues are present in REAPER with the VST3 version of my plugin. Even RIGHT ALT performs like the LEFT ALT.

Rail - did you notice this also?

EDIT:
I should add that I’m talking about the user doing a MODIFIER-CLICK-AND-DRAG on an object, and I do the work in the mouse callbacks (e.g…mouseDrag)

Can someone please point me to the changes related to the ALT key behaviour on Windows.
I am using JUCE 4.2.3 and having trouble detecting ALT-click combination in PT 12.5.1.

I am currently not in the situation to be able to test experimental /multibus branch, so any suggestion how to fix it would be greatly appreciated.

Thx!

This is the commit:

@justinwebster: I’ll have a look at the modifier key issues you are seeing.

That PT needs to tamper with the native GetKeyState Win32 call so that it returns invalid modifiers will always remain a mystery to me. :rage:

Yeah, I don’t get it.
You saw that post from AVID on the AAX forum?

Yes we are using the suggested workarounds. Still investigating…

OK this would be a really ugly bug to workaround. Can you try using:

ModifierKeys mods = ModifierKeys::getCurrentModifiersRealtime();

It works for me!

nope, getCurrentModifiersRealtime() doesn’t work for ALT in Pro Tools 12.4 on windows 10.
ALT is completely ignored during drag operations but seems to be detectable during double-clicks.
works in other hosts and other mods work in PT.

Best result I have had so far is using the MouseEvent passed to the drag method.
The user needs to press the buttons in the right order but it is possible to get the job done.
Can’t wait for all the support emails on this one…

Hmmm I need to test this again. However, getCurrentModifiersRealtime() did work for me for the alt key in Windows 10 in the mouseDown method.

@fabian - you tested in Pro Tools? Which version?
I have no trouble outside of PT, and no trouble with other modifiers at all.

Yes I tested this in PT.

Wait - you said the mouseDown method?
It’s the drag method that has trouble. I can see ALT during clicks, it’s just testing it during drags which is failing.

Even looking at the event modifiers it is possible to see the ALT key held, but it lets go during the drag operation.

Has this been fixed?

I have attempted to extend fabian’s fix to also work for the drag method.

It involves adding an extra update of the key modifiers to the doMouseMove() method in HWNDComponentPeer, so the implementation now looks like this:

void doMouseMove (Point<float> position, bool isMouseDownEvent)
{
    // this will be handled by WM_TOUCH
    if (isTouchEvent())
        return;

    if (! isMouseOver)
    {
        isMouseOver = true;

        // This avoids a rare stuck-button problem when focus is lost unexpectedly, but must
        // not be called as part of a move, in case it's actually a mouse-drag from another
        // app which ends up here when we get focus before the mouse is released..
        if (isMouseDownEvent)
            ModifierKeys::getCurrentModifiersRealtime();

        updateKeyModifiers();

       #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client
        if (modProvider != nullptr)
            currentModifiers = currentModifiers.withFlags(modProvider->getWin32Modifiers());
       #endif

        TRACKMOUSEEVENT tme;
        tme.cbSize = sizeof (tme);
        tme.dwFlags = TME_LEAVE;
        tme.hwndTrack = hwnd;
        tme.dwHoverTime = 0;

        if (! TrackMouseEvent (&tme))
            jassertfalse;

        Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate();
    }
    else if (! isDragging)
    {
        if (! contains (position.roundToInt(), false))
            return;
    }

    if (isMouseOver && isDragging)
    {
        updateKeyModifiers();

       #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client
        if (modProvider != nullptr)
            currentModifiers = currentModifiers.withFlags(modProvider->getWin32Modifiers());
       #endif
    }

    static uint32 lastMouseTime = 0;
    static int minTimeBetweenMouses = getMinTimeBetweenMouseMoves();
    const uint32 now = Time::getMillisecondCounter();

    if (now >= lastMouseTime + minTimeBetweenMouses)
    {
        lastMouseTime = now;
        doMouseEvent (position, MouseInputSource::invalidPressure);
    }
}

This mostly fixes the problem, however to ensure that the release of the Alt modifier is received consistently, the static current modifiers must also be updated in the handleMouseEvent() in ComponentPeer like this:

void ComponentPeer::handleMouseEvent (int touchIndex, Point<float> pos, ModifierKeys newMods, float newPressure, int64 time)
{
    ModifierKeys::updateCurrentModifiers();

    if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex))
        MouseInputSource (*mouse).handleEvent (*this, pos, time, newMods, newPressure);
}

This seems to work fine, although I am interested to know if anyone can think of any reasons why this would cause problems, or can think of a better solution.

this still appears to be a thing, even in juce7 and latest AAX SDK.
I appreciate that AAX SDK has a role to play, but it would be great if juce could have a fix for this.
Key modifiers are pretty important…

and FTR, the fix above seems to work pretty well, minus the add to ComponentPeer::handleMouseEvent, since ModifierKeys ::updateCurrentModifiers() doesn’t seem to exist any more.