Globally intercepting space key?


I’d like the space key to be globally intercepted in my application, even when a component that reacts to it (such as TextEditor) has focus (this is acceptable for me because my TextEditor components will only accept numbers anyway). Indeed, I’d like the space key to ALWAYS trigger a play/pause transport command for audio playback.

I tried to create a TextEditor subclass and override the keyPressed method to no avail. When doing that, even though I call the base class for all other key events, text input does not work anymore. Furthermore, I would have to do that for every component that acts on a spacekey press, such as buttons…

Is there a way to globally intercept (and stop) key events at the DocumentWindow (or application) level ?

Thanks a lot


Have you looked at the Desktop’s global key listener stuff?

Thanks, I wasn’t aware of the capabilities of the Desktop class.

However, I see it contains global mouse listeners, but no global key listeners. Is there something I’m missing ?

Sorry, I’m losing my mind. There’s no such thing in the Desktop class.

Hmm. Bit tricky then, there’s no way to intercept events globally like that.

OK. In that case, do you know of a way to do hook events in every component by overriding them (TextEditor for instance) or adding a KeyListener to it ?

Well you can certainly add a keylistener to any component, and I think that’ll be able to intercept events.

I’m 7 years late to the party, but…

I was hoping to do something similar, and I don’t believe the keyListener would help for a TextEditor for a spacebar key event, at least not on all platforms. On the Mac at least the interepretKeyEvents is called on the JuceNSViewClass::keyDown() and this results in JuceNSViewClass::insertText() being called, which then sets the owner’s textWasInserted to true. This results in the owner->redirectKeyDown() not being called.

Still haven’t figured out a way to do this without a massive hack. Maybe it’s one of those “you just shouldn’t be doing that” things.

Just in case anyone else cares I was able to hack this by adding:
virtual bool TextInputTarget::canInsertTextAtCaret(const String& textToInsert) const { return true; }

Then in the JuceNSViewClass’s insertText() I do this:

                auto str = nsStringToJuce (newText);
                if(target->canInsertTextAtCaret(str)) {
                    target->insertTextAtCaret (str);
                    owner->textWasInserted = true;

Now in my code I am able to subclass TextEdit and override canInsertTextAtCaret() as desired. When I return false the text ends up getting passed to the keyPress() and I can handle it there. Not sure if this is an elegant change but it was minimally invasive and worked for me.