VST Plugin Still Not Getting Keystrokes

The code I’ve posted on page 1 works perfectly for us. No complaints from users so far, and having quite a big user base with RTAS/VST/AU, Mac+PC. Only thing is that some special characters are caught by some hosts (the @ for example).

Thanks. I assume you are basically doing the same: A text editor in a new modal window?

By the way, have you tested your solution with Reaper? We have noticed that window popups disappear behind the VST editor due to a “pinned-on-top”-mechanism in Reaper. This messes up the popup menus of comboboxes for instance. Could the same happen with your modal editors?

On Windows if the host is not Sonar: Yes.

On Mac: No, just <grabKeyboardFocus()> does the trick.

We also have these issues on Windows if running Reaper in 64bit and the plugin in 32bit. We have no issues if both are 64bit (or 32bit).

Has anyone tested with the new JUCE 2.0 yet, if it’s finally working out of the box?

Thanks again, Jakob. I will implement something along the lines of what you and Andrew have done. Why is it important to make a special case for Sonar? Does it hurt to do the same there, besides the fact that it isn’t necessary?

I don’t know if that was said but i didn’t like any of those solutions since my plugin changes it’s controls at runtime, it’s like a WYSIWYG for plugins (MIDI plugins). So i had to go all the way and i created a small wrapper code that’s the actual AudioProcessorEditor and your plugin window is actually a normal Desktop window that has all the perks of beeing on the desktop, no more keyboard issues or any issues of any kind. The trick is to keep the wrapper tightly integrated with the window. But it works for me so far and i need a lot of keyboard input in many components.

Hmm. I doesn’t work here, at least not when I try to use your ModalTextEditor as the editor for my custom Label class. No editor shows up. Focus is lost immediately as a side effect of calling addToDesktop(ComponentPeer::windowIsTemporary). How do you create and show your editor from, say, a Label?

In case anyone’s interested I ended up with a solution close to what Andrew showed earlier on this topic. Since we only edit labels using double clicks, it turned out that the easiest fix for us was to customize the Label class only:

#include "juce.h"

class HadronLabel : public Label
{
public:
	HadronLabel(const String& name = String::empty, const String& labelText = String::empty);
	~HadronLabel();

private:
    bool    use_modal_editor_;

    // Override to allow custom text editor
    virtual void mouseDoubleClick(const MouseEvent& e);

    virtual void textEditorReturnKeyPressed(TextEditor& editor);
    virtual void textEditorEscapeKeyPressed(TextEditor& editor);
    virtual void textEditorFocusLost(TextEditor& editor);

    // Hide copy constructor and assignment operator 
    HadronLabel(const HadronLabel&);
	const HadronLabel operator= (const HadronLabel&);
};

#include "HadronLabel.h"

HadronLabel::HadronLabel(const String& name, const String& labelText)
    : Label(name, labelText)
    , use_modal_editor_(false)
{
#if _WIN32
    // Windows need special handling (unless sonar is the host)
    const String hostPath(File::getSpecialLocation(File::hostApplicationPath).getFullPathName());
    const String hostFilename(File(hostPath).getFileName());
    bool is_sonar = hostFilename.containsIgnoreCase("SONAR");
    use_modal_editor_ = !is_sonar;
#endif 
}

HadronLabel::~HadronLabel()
{
}

void HadronLabel::mouseDoubleClick(const MouseEvent& e) 
{
    if (use_modal_editor_) {

        if (isEditableOnDoubleClick() && ! e.mods.isPopupMenu()) {

            ModalComponentManager::Callback* userCallback = 0;
            ScopedPointer<ModalComponentManager::Callback> userCallbackDeleter (userCallback);
            Component::SafePointer<Component> prevFocused (Component::getCurrentlyFocusedComponent());
            Component::SafePointer<Component> prevTopLevel ((prevFocused != 0) ? prevFocused->getTopLevelComponent() : 0);

            ScopedPointer <TextEditor> texteditor = createEditorComponent();
            texteditor->setColour(TextEditor::backgroundColourId, Colours::black);
            texteditor->setWantsKeyboardFocus (true);
            texteditor->setAlwaysOnTop (true);

            // Find screen position
            Rectangle<int> sr (getBounds ());
            sr.setPosition (getScreenX(), getScreenY());
            int fontheight = static_cast<int>(texteditor->getFont().getHeight()) + 4;
            if (sr.getHeight() > fontheight) {
                sr.translate (0, (sr.getHeight() - fontheight)/2);
                sr.setHeight (fontheight);
            }
            texteditor->setBounds(sr);

            texteditor->setText(getText(),false);
            texteditor->setHighlightedRegion (Range <int> (0, getText().length ()));
            texteditor->setVisible (true);
            texteditor->grabKeyboardFocus();
            texteditor->addToDesktop (ComponentPeer::windowIsTemporary, 0);
       
            texteditor->addListener (this);
            texteditor->enterModalState (false);
            texteditor->grabKeyboardFocus();

            texteditor->runModalLoop();

            if (prevTopLevel != 0)
                prevTopLevel->toFront (true);
            if (prevFocused != 0)
                prevFocused->grabKeyboardFocus();
        }
    }
    else {
        Label::mouseDoubleClick(e);
    }
}

void HadronLabel::textEditorReturnKeyPressed(TextEditor& editor)
{
    if (use_modal_editor_) {
        setText(editor.getText(), true);
        editor.exitModalState(0);
    }
    else {
        Label::textEditorReturnKeyPressed(editor);
    }
}

void HadronLabel::textEditorEscapeKeyPressed(TextEditor& editor)
{
    if (use_modal_editor_) {
        editor.exitModalState(0);
    }
    else {
        Label::textEditorEscapeKeyPressed(editor);
    }
}

void HadronLabel::textEditorFocusLost(TextEditor& editor)
{
    if (use_modal_editor_) {
        editor.exitModalState(0);
    }
    else {
        Label::textEditorFocusLost(editor);
    }
}

Guys,

Imho none of these “fixes” or “workarounds” make a lot of sense, this should REALLY be fixed at the level of Juce as far as I’m concerned…
Zamrate’s patch is OK, but it fails for the decimal “.”, so for example if you want to type the value of a parameter (“1.5”) it fails, so it’s not really a solution.
Should we start another thread for a petition Jules to fix this?
It looks like this bug has been around since Cubase 3 and it’s still not fixed, that’s… madness.

  • Bram

+1.

As I think this should belong in JUCE, I made my version of the work-around a patch to juce changing its own Label class. see Work around Cubase and PT not passing keystrokes to plugins in Windows · soundradix/JUCE@554cf7e · GitHub

It’s based on Jakob solution, BUT I found that in Samplitude that solution actually makes the keystrokes stop working! So my patch only does it for Cubase & PT (I’ll have to check what’s up with Nuendo, I suspect it will probably act like Cubase).

I’m reluctant about this because fixing a plugin key-forwarding issue by mutilating an innocent class like Label would just be a horrific hack! The Label class shouldn’t even need to even know whether it’s being used in a plugin, and it certainly shouldn’t be responsible for fixing problems that are caused by something else.

I could possibly be persuaded to create some kind of Label subclass that does this, but there’s really no way that I’ll change the Label class like you’ve done in that diff, it’s just too nasty.

Perhaps something more elegant could be done with the ComponentPeer::textInputRequired() and dismissPendingTextInput() calls…? Those are used for showing a soft-keyboard on mobile devs, so are a good way to find out when key input is needed. Perhaps they could be used to create a temporary 1x1 pixel window that forwards its key events to the normal component?

Perhaps the Label class could stay clean and use LookAndFeel hooks which would allow such workarounds?

Then one would be able to use a CommonAudioPluginLookAndFeelWorkarounds which perhaps could fit in juce with a disclaimer that it’s a horrific hack to work-around DAW problems? :slight_smile:

Hmm… I think it needs a general fix, not something that only applies to certain types of component. That’s why I suggested the textInputRequired() call stuff - if it hooked into that, then it would work for any type of text-entry component, not just for ones that have had special workarounds added.

bump

I just don’t want this one buried down below… When are you getting back to Juce coding, Jules? :slight_smile:

  • bram

Wow! I just had a customer complain that keyboard input to a plugin wasn’t working in Cubase 7 on Win7 (in this case it’s 64 bit). I just tried a build against the current tip, and darned if that customer isn’t correct! None of my editable labels is, um, editable–even though they work fine in other DAWs. I found this thread, which goes back a ways. I ran some old plugs that I made for another company (Juce 1.53 I believe) and they work fine.

Since I’m not much of a Cubase fan, I find it easy to blame them for much of this. But there’s obviously been something in Juce that’s changed as well. In reading back over this thread, I see a number of hacks were recommended (not a big fan of that approach), along with an old suggestion from Jules regarding [color=#0000FF]ComponentPeer::textInputRequired[/color]. Before digging in to figure out just what the heck it does, I’d like to ask if Jules’s solution (or any other) has worked with Cubase 7.

I’m bumping this again too… Jules, this really needs a Juce fix!

  • Bram

[quote=“bdejong”]I’m bumping this again too… Jules, this really needs a Juce fix!

  • Bram[/quote]

Understood, but I have no time to task-switch to this very messy and potentially life-force-sapping area of the code right now… Can anyone summarise the current consensus on what we think is going on?

I have no idea what the cause is, but some of the ideas on page one now also fail for Juce’s current HEAD.

I.e. ssaue’s solution of using an editor that’s addToDesktop’d now results in the complete plugin GUI going grey (i.e. everything disappears) until you close the editor and open it again. Our “modal” text editor (based on another thread’s hack) also stopped working.

This not only happens in Cubase 5 and 7 but also in Ableton live 8 on windows. Plogue Bidule and Audiomulch (my favorite testing apps) work just fine.

A workaround (instead of a fix) would be just fine too as we just want things to work…

If we’d release an update to our plugin with the latest Juce head (like we wanted to) users would no longer be able to register in Cubase/Ableton as none of the text imput works…

  • bram

It’s still a problem here as well. I do observe that the label show its selected color and frame if I click there–it just doesn’t accept any text.

Jules,

I created a test VST effect with a text editor, a label which can be edited and a slider which shows the value of all.
I thought this could be very handy when researching this.

Built with 01ad38a0b4.

Fails in:
64-bit version: Cubase 5.5.3, Cubase 7.0.0
32-bit version: Ableton Live 8.2.7 (32bit).

Works fine in:
Audiomulch (32)
Bidule (32/64)
Reaper (64)

Here’s the package: http://dropbox.samplesumo.com/public/JuceKeyboardInputTestPlugin.zip

  • bram

Did you try ableton 9? I’d need to do this work on a new PC, and there’s no download for ableton 8 any more…