BubbleComponent and hasKeyboardFocus


#1

if a bubbleComponent disappears, the underlying window (or the component in it, which the Component belongs to) hasKeyboardFocus() is false, but that’s not true it has keyboard focus. The behaviour on Windows is correct, not on Mac.


#2

Have you checked that with the very latest build? I tweaked some mac focus things last week, which are probably related to this.


#3

yes, its still there, i use hasKeyboardFocus(true) on a DocumentWindow (the main window of my app)


#4

ok, here is the demo, after 5 seconds, the bubble is closed, hasKeyboardFocus(true) is false (wrong) , but the Window still receives keyPresses (which is right)
btw (hasKeyboardFocus should also return true when the Bubble is open), this is a main issue in my app, because if hasKeyboardFocus returns the wrong status, i can’t update the GUI with the correct status…
the behavior on windows is right

[code]
#include “…/JuceLibraryCode/JuceHeader.h”

class myDoc : public DocumentWindow, public Timer
{
public:
myDoc() : DocumentWindow(“White”,Colours::white,DocumentWindow::allButtons,true)
{
time=0;
l=new Label();
b=new BubbleMessageComponent();
b->addToDesktop(0);
b->setVisible(true);

	startTimer(1000);
	setBounds(100,100,300,500);
	
	setContentNonOwned(l,false);
	
};

~myDoc(){};


void timerCallback()
{
	
	
	
	
	if (hasKeyboardFocus(true))
	{
		l->setText("has Keyboard Focus",false);
	} else
	{
		l->setText("no Keyboard Focus",false);
	};
	
	time++;
	if (time==3)
	{
		b->showAt (l,"Bubble", 5000,false);
		l->setText("openBubble",false);
	};
};

bool keyPressed (const KeyPress& key)
{
	l->setText("received Keypress",false);
	return true;
};

private:
ScopedPointer l;
ScopedPointer b;
int time;

};

//==============================================================================
class KeyboardFocusProbApplication : public JUCEApplication
{
public:
//==============================================================================
KeyboardFocusProbApplication()
{
}

~KeyboardFocusProbApplication()
{
}

//==============================================================================
void initialise (const String& commandLine)
{
    // Do your application's initialisation code here..
    doc.setVisible(true);
}

void shutdown()
{
    // Do your application's shutdown code here..
    
}

//==============================================================================
void systemRequestedQuit()
{
    quit();
}

//==============================================================================
const String getApplicationName()
{
    return "KeyboardFocusProb";
}

const String getApplicationVersion()
{
    return ProjectInfo::versionString;
}

bool moreThanOneInstanceAllowed()
{
    return true;
}

void anotherInstanceStarted (const String& commandLine)
{
    
}

private:

myDoc doc;

};

//==============================================================================
// This macro generates the main() routine that starts the app.
START_JUCE_APPLICATION(KeyboardFocusProbApplication)[/code]


#5

Looks like it’s just because the proxy component used in fading-out the bubble is temporarily grabbing key focus. Easy enough to fix, thanks!


#6

Thanks! But it seems there is a second issue, under certain conditions (when setVisiblity is done later, not in the constructor) you will get this hasKeyboardFocus/getting KeyPresses inconsistency too.
I changed the Demo to reconstruct the issue.

[code]/*

This file was auto-generated by the Jucer!

It contains the basic startup code for a Juce application.

==============================================================================
*/

#include “…/JuceLibraryCode/JuceHeader.h”

class myDoc : public DocumentWindow, public Timer
{
public:
myDoc() : DocumentWindow(“White”,Colours::white,DocumentWindow::allButtons,true)
{
time=0;
l=new Label();
b=new BubbleMessageComponent();
b->addToDesktop(0);
// b->setVisible(true); if i do this in the constructor correct behavior

	startTimer(1000);
	setBounds(100,100,300,500);
	
	setContentNonOwned(l,false);
	
};

~myDoc()
{
	if (b!=0)
	{
		b->removeFromDesktop();
	};
};


void timerCallback()
{
	
	
	
	
	if (hasKeyboardFocus(true))
	{
		l->setText("has Keyboard Focus",false);
	} else
	{
		l->setText("no Keyboard Focus",false);
	};
	
	time++;
	if (time==3)
	{
		l->setText("openBubble",false);
		
		b->setVisible(true);		//wrong behavior
		b->showAt (100+getScreenX(),100+getScreenY(),"Bubble", 0,false,false);
		b->toFront(false);
		
	};
};

bool keyPressed (const KeyPress& key)
{
	l->setText("received Keypress",false);
	return true;
};

void closeButtonPressed()
{
	JUCEApplication::quit();
};

private:
ScopedPointer l;
ScopedPointer b;
int time;

};

//==============================================================================
class KeyboardFocusProbApplication : public JUCEApplication
{
public:
//==============================================================================
KeyboardFocusProbApplication()
{
}

~KeyboardFocusProbApplication()
{
}

//==============================================================================
void initialise (const String& commandLine)
{
    // Do your application's initialisation code here..
    doc.setVisible(true);
}

void shutdown()
{
    // Do your application's shutdown code here..
    
}

//==============================================================================
void systemRequestedQuit()
{
    quit();
}

//==============================================================================
const String getApplicationName()
{
    return "KeyboardFocusProb";
}

const String getApplicationVersion()
{
    return ProjectInfo::versionString;
}

bool moreThanOneInstanceAllowed()
{
    return true;
}

void anotherInstanceStarted (const String& commandLine)
{
    
}

private:

myDoc doc;

};

//==============================================================================
// This macro generates the main() routine that starts the app.
START_JUCE_APPLICATION(KeyboardFocusProbApplication)
[/code]


#7

btw the issue is when the bubble is visible


#8

If you don’t want your bubble to get keyboard focus, then when you call addToDesktop, you’d need to set the ComponentPeer::windowIgnoresKeyPresses flag.


#9

jules, the issue is not that something is grabbing the focus, the issue is that the DocumentWindow gets all KeyPresses (right, so it has Keyboard-Focus) but at the same time hasKeyboardFocus(true) is false, and this behaviour is only on Mac not on Windows.

Also the behavior change when i move setVisible from the constructor into the callback… (this can’t be normal)


#10

If it’s already on the desktop as a hidden window, and then you show it, it’ll grab the focus - that’s not a big surprise. Use the flag I told you about to avoid that happening.

What’s happening is that when the bubble has focus in this way, it’ll receive all the keypresses, but because the component itself doesn’t want them, they’ll be forwarded to the last focused object.

The fix is to set the flag like I said - although you could argue that in fact, the flag should be automatically set for components like the bubble, which don’t want keyboard focus.


#11

ok thanks i try it that way :smiley: