Keystroke input compatibility listing for plugin hosts

Hey all,

I noticed that there are many threads regarding keyboard input problems especially under Windows when the juce framework is used in plugins. For example the Label or TextEditor do receive keystrokes or not depending on the host and the OS.

For this reason I’d like to set up a listing, where everybody can post which solution worked for him/her for a combination of juce Component, plugin-host and OS.

This could help to share some knowledge, so that the wheel has not be reinvented over and over again.

Let me start…


Component:Label
OS:Windows
tested Hosts: Samplitude, Cubase/Nuendo, Live, Minihost, VstHost
notes: Sonar under Windows only works with the Standard juce::Label and not with the suggested solution for the other hosts!

EDIT 2010.01.02:
OS:OSX 10.5 (just remove the “#if JUCE_WIN32”)
tested Hosts: Logic 8

Implementation: subclass from juce::Label and implement the following functions of juce::Label in your subclass.

void YourLabel::editorShown (TextEditor* editorComponent)
{
	#if JUCE_WIN32
		originalParent = getParentComponent();
		originalX = getX();
		originalY = getY();
		addToDesktop(ComponentPeer::windowIsTemporary);
	#endif
}

void YourLabel::editorAboutToBeHidden (TextEditor* editorComponent)
{
	#if JUCE_WIN32
		originalParent->addChildComponent(this);
		setBounds(originalX, originalY, getWidth(), getHeight());
	#endif
}

Component:TextEditor
OS:Windows
tested Hosts: Samplitude, Cubase/Nuendo, Live, Minihost, VstHost
notes: Sonar under Windows only works with the Standard juce::TextEditor and not with the suggested solution for the other hosts!

EDIT 2010.01.02:
OS:OSX 10.5 (just remove the “#if JUCE_WIN32”)
tested Hosts: Logic 8

Implementation: subclass from TextEditor and implement the following functions:

void YourTextEditor::focusGained (FocusChangeType cause)
{
	#if JUCE_WIN32
		if(!isOnDesktop() && !isReadOnly())
		{
			originalParent = getParentComponent();
			originalX = getX();
			originalY = getY();
			addToDesktop(ComponentPeer::windowIsTemporary);
			setAlwaysOnTop(true);
			TextEditor::focusGained(cause);
			grabKeyboardFocus();
		}
	#endif
	TextEditor::focusGained(cause);
}

void YourTextEditor::focusLost (FocusChangeType cause)
{
	#if JUCE_WIN32
		if(isOnDesktop())
		{
			originalParent->addChildComponent(this);
			setBounds(originalX, originalY, getWidth(), getHeight());
			setAlwaysOnTop(false);
			TextEditor::focusLost(cause);
		}
	#endif
	TextEditor::focusLost(cause);
}

If you have improvements or problems with the posted solutions, please let me know.
Everybody is invited to post other solutions for Components, hosts and OSs.

@yfede:
In this post http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=4330 you said, you’re checking at runtime what’s the parent host of your plugin. How do you do that? I need something like this to fix the Sonar problem, so that I don’t add the Components to the Desktop if Sonar is the host.

Edit: As suggesetd, I’ve tried to collect the posts regarding this issue - this is an uncomplete collection. I will add new ones when I remeber where I read them.

http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=4330&highlight=keystroke


http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=1662&highlight=keystroke


http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=4330


http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=312&highlight=keystroke


http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=4357&highlight=keyboard


http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=3999&highlight=keyboard


http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=3817&highlight=keyboard


http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=1770&highlight=keyboard

Might be an idea to link to the other threads you mention, so we have them all referenced from this one thread? 2 cents, Pete

done.

Ok, I found the code of yfede to detect the parent host. For completeness here it is.

yfede:

// can't include windows.h before juce, thus
// can't rely on JUCE_WIN32 to be defined
// to know if we're under windows or not

#if (defined (_WIN32) || defined (_WIN64))
#include <windows.h>
#endif

#include <juce.h>

// For mac it is safe to include these headers
// after juce, so we can safely use JUCE_MAC here

#if JUCE_MAC
#include <sys/param.h>
#include <mach-o/dyld.h>
#endif


#if JUCE_WIN32

String getCurrentExecutableName()
{
    WCHAR buf[MAX_PATH] = { '\0' };

    if ( !GetModuleFileNameW( NULL, buf, MAX_PATH ))
    {
        return String::empty;    // Error
    }
    return String(buf);
}

#elif JUCE_MAC

String getCurrentExecutableName() throw()
{
    char str[2*MAXPATHLEN] = {'\0'};

    unsigned int size = 2*MAXPATHLEN;
    if ( _NSGetExecutablePath( str, &size ))
    {
       return String::empty;    // Error
    }

    return String(str, size);
}

#else
#error unsupported OS
#endif 

Nice work friscokid :slight_smile:

Thanks for the excellent summary!

This has been on my to-do-list for a while, but it’ll involve me dedicating at least a day for it, and I’ve too many demands on my time right now… I promise to do it asap!

Excellent!!

Hey,

while for all the hosts I’ve tested on Windows, key input for Label and Texteditor works either with the standard version or by adding them to Desktop, the situation on Mac is currently pretty annoying.

With the latest juce version (all tips since at least 1.50) it is not possible to get these Components working for any AU host I’ve tested:

Logic 8 is the worst one:
It does not get key input for Labels (juce version) and passes all the keystrokes to the host. If you add the Label to Desktop, it receives a keystroke, but only when it is no defined command key of Logic because these are always passed to the host no matter which settings you use.
Texteditor doesn’t work at all because the Component never gets focusGained() or focusLost() callbacks and therefore you don’t get reliable information when to put it on Desktop or remove it. Needless to say that the non Desktop standard version doesn’t work, too.
I think the whole focus handling thing of many juce Components doesn’t work as it is supposed to with logic right now.

AU lab is not as bad as logic but a bit more weird:
Label and TextEditor work as they are implemented by Jules… as long as no AlertWindow or something like this was opened. After such a Component was opened (and closed again, modalLoop exited, deleted…) no instance of this Plugin will receive keystrokes for Labels and TextEditors and Components using them, again. No matter if the Plugin instance was the parent of the AlertWindow or not. Even closing and reopening the Editor won’t work, you have to restart the host.

I don’t know if this is because of the Carbon/Cocoa adjustments to the juce framework but the way it is right now, a whole bunch of fine Components have become moreless unusable. I really tried but with the way juce is setup in it’s current version I couldn’t find any workaround.

It would be nice if you could have a look at this, Jules.

Thanks

EDIT: Ableton Live 7 is fine. No problems at all.

Logic 9:
Key input working.

Key input in Logic 8 and AU Lab works correctly, when using the adjustments described in this post:
http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?p=24594#24594

Thank you friscokid for the good work!

Still, I was not able to get the standard juce TextEditor to work with Sonar 8. Does it works out of the box for you? Sonar seems to pass keystrokes to the plugin, but only after handling them and hence eats most of them, which renders the TextEditor unusable. As you mentionned, adding to desktop does not work either.

I’ve noticed that the standard juce TextEditors in AlertWindows do work fine in all PC hosts that I’ve tried lately, even in Sonar, is it because the AlertWindow has its own modalLoop ?

For me the juce::TextEditor works out of the box with Sonar 8 on Windows XP, Vista, 7 (32 bit and 64 bit versions).
You don’t have to tweak anything when using Sonar.

On my 32 bits windows 7, it does work when the TextEditor is a direct child of the audio editor but Sonar eats the keystrokes when the TextEditor is embedded into a component:

[code]class MyPanel : public Component
{
public:
MyPanel() : edt(0)
{
addAndMakeVisible(edt = new TextEditor(T("")));
setSize(200, 200);
}

		~MyPanel() 
		{
			deleteAndZero(edt);
		}

		void resized()
		{
			edt->setBoundsInset(BorderSize(1));
		}

private:
	TextEditor *edt;
};

BasicPluginAudioProcessorEditor::BasicPluginAudioProcessorEditor (BasicPluginAudioProcessor* ownerFilter)
: AudioProcessorEditor (ownerFilter),
ed(0)
{
addAndMakeVisible(ed = new MyPanel());
setSize (400, 300);
}
[/code]

I’m a little stretched at the moment so I haven’t really looked into this, but shouldn’t we get the same behaviour in the two situations?

That does seem a little odd, but I think some of the VST code might look at the top-level plugin component to see whether it wants key focus. So doing a setWantsKeyboardFocus (true) on the top-level comp might kick it into life…

I’ve actually tried this already but it didn’t seem to change anything.

I’m still stuck on this one. Do you have any other idea on this issue jules before I start digging into the code? Thanks!

Sorry, no flashes of inspiration on that one…