On Sat, 9 Nov 2024 01:28:53 GMT, Michael Strauß <mstra...@openjdk.org> wrote:

> Implementation of [focus 
> delegation](https://gist.github.com/mstr2/44d94f0bd5b5c030e26a47103063aa29).

This looks really good.  I'm wondering if this could be simplified further.  
Specifically, I think the `hoistFocus` flag and manual management of the focus 
delegate may not be needed.

It seems to me that a Control could share some similarities with a Scene, in 
that Control has properties that track a focus owner (similar to focus 
delegate). In effect, a Control is a focus root similar to scene.  When a Scene 
receives focus, it determines the best Node to "delegate" focus to; similarly, 
when a Control receives focus, it determines which skin control should be 
focused.  The normal focus rules should do the right thing here and for example 
select the TextField of a Spinner as the delegate automatically (some children 
may need to be marked as not focusable to guide the auto selection, but this is 
an already existing standard mechanism).

When determining where to send events, if the target is a focus root, it 
queries its focus owner (or focus delegate) and extends the event to that 
target.  If that target is also a focus root, the process repeats.

The request focus function should operate differently as well.  It should look 
for the closest focus root (a Control or Scene) and call the appropriate 
request focus function on the root it finds.  If that root is Scene, everything 
works as usual.  If it is another focus root like a Control, Control can 
determine the best way to focus one of its child nodes (likely you can just 
apply a normal search for an eligible focusable control for this).

Perhaps the focus root functionality can be captured in an interface that both 
Scene and Control implement.  I think it would need to specify a `requestFocus` 
method and `focusOwnerProperty`.  This interface would then replace the 
`focusScope` flag.

> > It works quite well to say that a `Scene` delegates focus to a `Node`. It 
> > doesn't seem to work quite as well (linguistically) to say that a 
> > `TextField` is the focus owner of a `ComboBox` (the `ComboBox` is also 
> > focused, why would the `TextField` be its focus owner?).
> 
> For what it's worth I am not a fan of using the term focus owner to refer to 
> a focus delegate. The focusOwner of a Scene is the target of key events. The 
> focus delegate of a ComboBox is the _second_ target of key events. Key events 
> are sent to the ComboBox first and the delegate only receives the events that 
> it doesn't consume. To me that's an important distinction.

I don't think the distinction quite holds.  Scene does not delegate all key 
events.  Menu shortcuts for example are consumed and never dispatched, and I 
think the same goes for mnemonics.  Navigation keys are dispatched, and only 
acted upon by Scene when bubbled back up.

However, I now think that "focus delegate" is indeed the better name for this.
 
> Presumably we would need a way of telling the focus scope node which sub-node 
> hoisted the focus so it could select the correct delegate. But it's difficult 
> to imagine a control that's trying to pass itself off as a monolithic entity 
> having two internal TextFields. Wouldn't that require enabling keyboard 
> traversal inside a monolithic control? What does that mean? I don't think 
> this is a scenario we need to solve.

See my example in my reply to Michael, I think it may be worth having a few 
thoughts about.

Keep open IMHO.

-------------

PR Comment: https://git.openjdk.org/jfx/pull/1632#issuecomment-2569018506
PR Comment: https://git.openjdk.org/jfx/pull/1632#issuecomment-2646636802
PR Comment: https://git.openjdk.org/jfx/pull/1632#issuecomment-3027816893

Reply via email to