Weird KeyPress & keyCode quirks in Windows and Linux

While making some keyboard mappings and keyboard shortcuts in my program, I noticed two weird quirks with the KeyPress handling, one in Windows and one in Linux

In Windows the function isKeyCurrentlyDown() ignores the key state of ‘=’ and ‘\’. Normally the obvious workaround would be to just use ‘+’ and ‘|’, respectively, but I use the integer value of those characters for the rest of my function (a 2.5 octave computer key to midi map in the style of Pro/Fast/Impulse tracker) so I need to check those if the keys for those specific characters are down

I was able to create a workaround by modifying the source code of isKeyCurrentlyDown() in juce_Windowing_windows.cpp to this:

bool KeyPress::isKeyCurrentlyDown (const int keyCode)
{
    auto k = (SHORT) keyCode;

    if ((keyCode & extendedKeyModifier) == 0)
    {
        if (k >= (SHORT) 'a' && k <= (SHORT) 'z')
            k += (SHORT) 'A' - (SHORT) 'a';

        // Only translate if extendedKeyModifier flag is not set
        const SHORT translatedValues[] = { (SHORT) ',', VK_OEM_COMMA,
                                           (SHORT) '+', VK_OEM_PLUS,
                                           (SHORT) '=', VK_OEM_PLUS,
                                           (SHORT) '-', VK_OEM_MINUS,
                                           (SHORT) '.', VK_OEM_PERIOD,
                                           (SHORT) ';', VK_OEM_1,
                                           (SHORT) ':', VK_OEM_1,
                                           (SHORT) '/', VK_OEM_2,
                                           (SHORT) '?', VK_OEM_2,
                                           (SHORT) '[', VK_OEM_4,
                                           (SHORT) ']', VK_OEM_6 };

        for (int i = 0; i < numElementsInArray (translatedValues); i += 2)
            if (k == translatedValues[i])
                k = translatedValues[i + 1];

        /* US keyboards use VK_OEM_5, non-US 102-key keyboards use VK_OEM_102 */
        if (k == (SHORT) '\\') k = VkKeyScanA(k);
    }

    return HWNDComponentPeer::isKeyDown (k);
}

But I wanted to check and see if there’s a better workaround so I don’t have to overwrite this file or recopy the modified code every time I update JUCE, or if this is the only way to actually get around it while still using those characters

This bug isn’t present in Linux but while writing keyboard shortcuts for the numpad in Ubuntu 20.04, I discovered that getKeyCode() for the numpad doesn’t return a KeyPress::numberPad# value but rather returns the same char value as its respective number in the number row. Haven’t found a workaround for this one yet but if anyone knows of one, that’d be greatly appreciated :pray:

I don’t have a keyboard with a numpad to test but I will procur one and see if I can repro!

Okay never mind about the numpad turns out I’m just dumb lol I thought getKeyCode() would return the juce::numberPad# value whenever the number pad is pressed. Just figured out that it only returns the numberPad value when Num Lock is turned off. If Num Lock is on, it returns the value of the corresponding number row. Happens in Windows too

I wonder if there’s a way to check for numpad keypresses without triggering number row values regardless of Num Lock

Couldn’t figure out a fix in the source but I made this workaround for my program at least. Basically just wanted to be able to use the numpad to switch between the first ten samples of my sampler plugin (numbered 1-10 for the user, 0-9 internally) without it affecting the number row char values since they’re mapped to MIDI noteOn triggers.

bool AmiAudioProcessorEditor::switchSamples(const juce::KeyPress& k)
{
    const int num = k.getKeyCode() & ~'0';

    if (num < 0 || num > 15) return false;

    if (!juce::KeyPress::isKeyCurrentlyDown(juce::KeyPress::numberPad0 + num)) return false;

    currentSample = num < 10 ? num > 0 ? num - 1 : 10 - 1 : currentSample;
    audioProcessor.setCurrentSample(currentSample);

    repaint(sampleArea.getBounds());

    return true;
}

I have this before my mapping function in my keyPressed() function so that if it returns true I can exit out of the keypress before the number keys are passed to my map

Also turns out with numlock off, the numpad keys are returning their corresponding extended keys value (0 returns Insert, 9 returns Page Up), so I’m just not able to get it to return a numpad value at all :sweat_smile: