How to stop Component::grabFocusInternal "virus" spreading


#1

Hi, here's the thing: In JUCE the GUI works basically this way: Whenever you click anything (!) the component that you click either want's keyboard focus, in which case it grabs the focus, or it does not want the focus, in which case it will try all it's children and then it's parent. Parent will try all of it's children and so on. This whole process is spreading like a virus which is a good thing on PC I guess, but it a has some nasty effects on mobile devices. The problem is that every click anywhere always brings in the onscreen keyboard, which makes the application utterly unusable. So the question is: Is there a simple way to redefine this behavior? The only thing I was able to come up with that partially works is to set setMouseClickGrabsKeyboardFocus(false); for every (!) component there. The problem is that I cannot do this for the components I actually need to get focus at somepoint (TextEditor components...). Also I cannot easilly do this for TabbedComponent. It internally uses TabbedButtonBar. Whenever i click any tab, some TextEditor on the displayed page get's focus, which displayes the onscreen keyboard, which is incredibly user-frustrating.

 

So is there some recommended way to explain to all the components to get the focus only if they are clicked directly? No transitive flood...

 

Thanks!


#2

Any idea?


#3

I have to admit that I also always have trouble with getting the grabFocus stuff right, so probably I shouldn't be the one offering advice on this particular topic...

Unfortunately I believe we'll have to wait until Jules is back from NAMM to find a solution.


#4

Thanks Timur, let's wait then.

Basically to simplify the question for Jules: I need for any component to grab focus only when it is directly clicked. Otherwise there is always something that takes the focus whenever you click (touch) anywhere which is a big problem for mobile devices as it always brings in the onscreen keyboard.


#5

If your main component contains e.g. a TextEditor and some other components, then all you'd need to do is to make the top-level component take focus, and then when you click on anything other than the TextEditor, it'd fall back to giving the top-level comp focus.

If you need more control, we have a heap of stuff for controlling this - check out Component::createFocusTraverser(), Component::setExplicitFocusOrder(), Component::setFocusContainer() etc

 


#6

Thanks Jules, this seems to work just fine. I set this for every component that contains any TextEditors:

 

setWantsKeyboardFocus(true);

 

and it does the trick. That's what you meant by "make the top-level component take focus" right?


#7

Yes, that'd work.