Juce Window doesn't receive keyboard input

gui

#1

Hi, I’m doing my first juce standalone app on OS X, and the app is not receiving keyboard input.
Not only it doesn’t respond to my key presses, it seems to be completely ignored by the computer:
the key presses go to whatever app is on the background. I’m sure there’s something simple that I’m missing.
I’m using CMake as a biul system and here’s my juceAPP, my MainWindow and my MainComponent files:

#include <memory>
#include <string>
#include <GUI/MainWindow.hpp>
#include <juce_events/juce_events.h>
#include <GUI/CommandManager.hpp>

using namespace std::string_literals;

class App : public juce::JUCEApplication {

    std::unique_ptr<VT::MainWindow> window;

    public:
    const juce::String getApplicationName() override       { return "VTDaw"s; }
    const juce::String getApplicationVersion() override    { return "0.0.1"s; }
    bool moreThanOneInstanceAllowed() override       { return false; }

    void initialise (const juce::String& commandLine) override {
	window = std::make_unique<VT::MainWindow>(getApplicationName().toStdString());
    }

    void shutdown() override {}

};

START_JUCE_APPLICATION(App)


#include <GUI/MainComponent.hpp>

using namespace juce;
using namespace VT;

MainComponent::MainComponent(int x, int y) {
    addAndMakeVisible(centerPanel);
    setSize(x, y);
    setWantsKeyboardFocus(true);
}

void MainComponent::paint(Graphics & g) {
    g.setColour(Colours::black);
    g.fillAll();
}

void MainComponent::resized() {
    auto r = getLocalBounds();
    centerPanel.setBounds(r);
}


#include <cstdlib>
#include <GUI/MainWindow.hpp>
#include <GUI/CommandManager.hpp>

using namespace juce;
using namespace VT;

MainWindow::MainWindow(std::string name) : DocumentWindow (name,
					Colours::lightgrey,
					DocumentWindow::allButtons,
					true) {
    content = std::make_unique<MainComponent>(800, 500);
    setContentNonOwned(content.get(), true);
    setResizable(true, true);
    setUsingNativeTitleBar(true);
    setWantsKeyboardFocus(true);
    centreWithSize (getWidth(), getHeight());
    setVisible(true);
    auto m = getManager();
    m->getKeyMappings()->resetToDefaultMappings();
    addKeyListener(m->getKeyMappings());
}

void MainWindow::closeButtonPressed() {
    std::exit(0);
}

#2

I tried your code - and with a few modifications to get it to compile (what’s up with getManager()) - it all works fine for me.

I think this is probably related to your non-standard setup with cmake (and including module headers directly etc.). Maybe you are missing some juce cpp files which contain some important static initialisers?

Here’s the modified code that I tested:

#include "../JuceLibraryCode/JuceHeader.h"
#include <memory>
#include <string>

class MainComponent : public Component
{
public:
	MainComponent(int x, int y) {
		setSize(x, y);
		setWantsKeyboardFocus(true);
	}

	void paint(Graphics & g) {
		g.setColour(Colours::black);
		g.fillAll();
	}

	void resized() {
	}
};

class MyKeyListener : public KeyListener
{
public:
	bool keyPressed (const KeyPress& key,
					 Component* originatingComponent) override
	{
		DBG ("hey ho!");

		return false;
	}
};

class MainWindow : DocumentWindow
{
public:
	MainWindow(std::string name)
		: DocumentWindow (name,
						  Colours::lightgrey,
						  DocumentWindow::allButtons,
						   true) {
		content = std::make_unique<MainComponent>(800, 500);
		setContentNonOwned(content.get(), true);
		setResizable(true, true);
		setUsingNativeTitleBar(true);
		setWantsKeyboardFocus(true);
		centreWithSize (getWidth(), getHeight());
		setVisible(true);
		addKeyListener(&keyListener);
	}

	void closeButtonPressed() {
		std::exit(0);
	}

	private:
	MyKeyListener keyListener;
	std::unique_ptr<MainComponent> content;
};


class App : public juce::JUCEApplication {

	std::unique_ptr<MainWindow> window;

public:
	const String getApplicationName() override       { return "VTDaw"; }
	const String getApplicationVersion() override    { return "0.0.1"; }
	bool moreThanOneInstanceAllowed() override       { return false; }

	void initialise (const juce::String& commandLine) override {
		window = std::make_unique<MainWindow>(getApplicationName().toStdString());
	}

	void shutdown() override {}

};





START_JUCE_APPLICATION(App)

#3

Hi Fabian,
getManager() gets a pointer to my ApplicationCommandManager, which is declared as a global variable in
another .cpp file (I didn’t include the whole code because it’s too big and I’ve removed most of the other files
for testing). I’ve removed the other files from my build and compiled the code you sent having the same result.
The Juce Application never seems to gain focus completly (I’m starting to wonder if it’s a bug on my computer…) as you can see here

My cmake build is based on Kiwi’s one https://github.com/Musicoll/Kiwi and they don’t experience a similar issue.
I’m starting to wonder if the bug is related to my computer somehow


#4

Obviously, when you are debugging your app, the debugger usually steals the initial focus request. But if you run the app without the debugger (i.e. launching it from the Finder or explorer) it should work fine. Alternatively, put the app in the background and bring it to the foreground again.


#5

Sorry, I was not being that good a programmer, I was doing “printf” debugging.
I changed my cmake file to make an OS X .app bundle which… fixed the problem.
I’ll never understand the witchcraft that goes on with .app bundles, but I guess I’ve learned my lesson
regarding always making one to have things working fine on OS X…

Thanks a lot for your help, Fabian!