Stuck in handleKeyPress loop


#1

VST, Windows 8, Ableton.

After my plugin grabs keyboard focus (by either opening a save/load dialog, or a combobox popupmenu) if I press a QWERTY key the program freezes. It's getting stuck in one of the for loops of the handleKeyPress method:


bool ComponentPeer::handleKeyPress (const int keyCode, const juce_wchar textCharacter)
{
    updateCurrentModifiers();
    bool keyWasUsed = false;
    const KeyPress keyInfo (keyCode,
                            ModifierKeys::getCurrentModifiers().withoutMouseButtons(),
                            textCharacter);
    for (Component* target = getTargetForKeyPress(); target != nullptr; target = target->getParentComponent())
    {
        const WeakReference<Component> deletionChecker (target);
        if (const Array <KeyListener*>* const keyListeners = target->keyListeners)
        {
            for (int i = keyListeners->size(); --i >= 0;)
            {
                keyWasUsed = keyListeners->getUnchecked(i)->keyPressed (keyInfo, target);
                if (keyWasUsed || deletionChecker == nullptr)
                    return keyWasUsed;
                i = jmin (i, keyListeners->size());
            }
        }
        keyWasUsed = target->keyPressed (keyInfo);
        if (keyWasUsed || deletionChecker == nullptr)
            break;
        if (Component* const currentlyFocused = Component::getCurrentlyFocusedComponent())
        {
            const bool isTab      = (keyInfo == KeyPress::tabKey);
            const bool isShiftTab = (keyInfo == KeyPress (KeyPress::tabKey, ModifierKeys::shiftModifier, 0));
            if (isTab || isShiftTab)
            {
                currentlyFocused->moveKeyboardFocusToSibling (isTab);
                keyWasUsed = (currentlyFocused != Component::getCurrentlyFocusedComponent());
                if (keyWasUsed || deletionChecker == nullptr)
                    break;
            }
        }
    }
    return keyWasUsed;
}

The trapping for loop is:


for (Component* target = getTargetForKeyPress(); target != nullptr; target = target->getParentComponent())

 

The target->keyPressed call that occurs halfway through the method isn't implemented in any of my components, so they're always returning false. So as a workaround I've been implementing keyPressed in all of my relevant components and having them return true, which in turn breaks the for loop. While this works, I feel like I'm plugging holes in a leaky boat, when I should be trying to stop the cause of the leaks in the first place (weak metaphor?). Any suggestions?


#2

Huh? It's impossible for that for-loop to get stuck - it'll just go up the component's parent hierarchy, then stop, regardless of what your keyPressed method returns.


#3

Once it freezes, I place a breakpoint in that loop and it stops the debugger. It doesn't matter how long I wait before inserting the breakpoint, it always stops in that loop calling the keyPress method over and over again. I've pressed "continue" in visual over and over and it doesn't leave the loop. And the only way I can get it to stop is by returning true from keyPress. Here's the stack:

 


>    Primer.dll!juce::ComponentPeer::handleKeyPress(int keyCode, unsigned int textCharacter) Line 182    C++
     Primer.dll!juce::HWNDComponentPeer::doKeyChar(int key, const __int64 flags) Line 2022    C++
     Primer.dll!juce::HWNDComponentPeer::peerWindowProc(HWND__ * h, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 2349    C++
     Primer.dll!juce::HWNDComponentPeer::windowProc(HWND__ * h, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 2211    C++
     user32.dll!UserCallWinProcCheckWow()    Unknown
     user32.dll!CallWindowProcW()    Unknown
     Ableton Live 8.exe!0000000001a0d6ad()    Unknown
     Ableton Live 8.exe!0000000001a0fd53()    Unknown
     Ableton Live 8.exe!0000000001a0ff13()    Unknown
     user32.dll!UserCallWinProcCheckWow()    Unknown
     user32.dll!DispatchClientMessage()    Unknown
     user32.dll!__fnINWPARAMDBCSCHAR()    Unknown
     ntdll.dll!KiUserCallbackDispatcherContinue()    Unknown
     user32.dll!NtUserMessageCall()    Unknown
     user32.dll!fnINWPARAMDBCSCHAR()    Unknown
     user32.dll!SendMessageWorker()    Unknown
     user32.dll!SendMessageA()    Unknown
     Primer.dll!`anonymous namespace'::keyboardHookCallback(int nCode, unsigned __int64 wParam, __int64 lParam) Line 228    C++
     user32.dll!DispatchHookA()    Unknown
     user32.dll!CallHookWithSEH()    Unknown
     user32.dll!__fnHkINLPMSG()    Unknown
     ntdll.dll!KiUserCallbackDispatcherContinue()    Unknown
     user32.dll!NtUserPeekMessage()    Unknown
     user32.dll!_PeekMessage()    Unknown
     user32.dll!PeekMessageW()    Unknown
     mfc90u.dll!CWinThread::Run(void)    Unknown
     mfc90u.dll!AfxWinMain(struct HINSTANCE__ *,struct HINSTANCE__ *,wchar_t *,int)    Unknown
     Ableton Live 8.exe!0000000001d6db5e()    Unknown
     kernel32.dll!BaseThreadInitThunk()    Unknown
     ntdll.dll!RtlUserThreadStart()    Unknown


#4

No, you're definitely not interpreting that correctly, the loop can't run forever. More likely something is repeatedly calling that method?


#5

That makes sense. I don't know what would be doing that though. I'm just pressing a key once and it keeps showing the same stack. 


#6

Updated to 2.1.5 (I was 2.1.1, thought I was 2.1.5) and the problem is gone. Weird. But solved.