> The TextField of a ComboBox or Spinner is not just an artifact of its skin. 
> They are both explicitly composite controls that contains a TextField inside. 
> It’s part of the API. And if you were to install some filters on the Scene to 
> track Key and InputMethod events you could easily conclude that that 
> TextField is the focus owner (it walks like the focus owner, it quacks like 
> the focus owner).
>
> I believe the implementation of Spinner predates focusWithin and 
> focusVisible. I think the natural way to drive the focus indicators these 
> days would be to use focused for the TextEdit and focus-within for the 
> Spinner. In any case I think it’s a good idea to somehow separate these out 
> and not force all of these flags to be set in unison across the entire 
> delegate chain.
>
> If we were to make the Spinner’s TextEdit the focus owner input methods would 
> work, the focused and focus-within pseudo-classes would sort themselves out 
> in a natural way, and the double firing of KeyEvents would go away. The 
> downside is that you would create an information deficit during event 
> processing; the event target would be the TextEdit and not the logical 
> control. But that’s an existing problem that also affects mouse click events. 
> Perhaps we should focus on closing that information gap instead.

I think you might be onto something here:

Let's close down the "Node.setFocused" loophole, no more tampering
with the focused flag. This entails fixing TableView and other
controls that misuse this flag. With this improvement, there's only
ever going to be a single focused node in the scene graph, and
"focused == input focus" is always true.

Then we would need to redefine "Node.requestFocus()" to allow a
control to delegate the focus request to one of its descendants
instead. This means:
1. If a control accepts requestFocus(), the focusWithin flag will
_always_ be set on the control.
2. It _might_ also have the focused flag, but this is
implementation-specific and should not be relied upon.
3. Scene.focusOwner might not point to the control, but to one of its
descendants.

As a consequence, controls that now use the focused style class to
adjust their appearance (with a focus ring) should use focusWithin
instead. The same is true for user code: you should always use
focusWithin on controls, and only use focused if you're sure that you
are interested in the actual input focus owner.

Additionally, there should be an additional Event.originalTarget
property. This property will always correspond to the node that fired
the event, in the case of Spinner this would be the TextField. The
Event.target property, on the other hand, would correspond to the
logical target that an observer would expect, in our example the
Spinner.

I think this approach would still allow us to clean up the skin
implementations, remove the duplicate events, and have logically
consistent events.

Reply via email to