On Mon, 14 Jul 2025 18:59:49 GMT, John Hendrikx <jhendr...@openjdk.org> wrote:
>> Yeah, I'm sure traversal is solvable, I just wanted to spend some cycles >> figuring it out. For example, would you set focusTraversable on the >> date/time control AND it's delegates? My guess is just the delegates but >> this is the sort of thing one would want to prototype. >> >> To be clear I'm not trying to solve traversal in this round. I just want to >> make sure we have mapped out the path forward so the API will accommodate >> traversal eventually. > > When I have a few moments, I'll see if I can create the date entry control, > and see how it works with this solution. I can then override Scene code to > see if navigation is a quick fix or a huge issue. > Currently we turn on input method processing at the platform level if and > only if there's any control in the focus chain that is set up to receive > input method events and respond to input method requests. That could be any > focusOwner in any focused Scene or any one of the focusOwners' delegates. So > I need to see the entire delegate chain. > > If we don't expect the focus delegate to change while a focus scope node has > focus then all I need is getFocusDelegate with no parameters. If we expect > the focus delegate to change dynamically it should become a property. The focus delegate can change while a focus scope has focus, but only due to a focus request (i.e. navigation or calling `Node.requestFocus()`). I'm reasonably certain that we don't need or want the delegate to be a property. As of now, the delegate chain is simply re-evaluated in response to a focus request. However, there's currently no easy way for `Scene` to know when the delegate chain has changed. > The existing traversal machinery is designed to update a Scene's focusOwner > not which delegate is active within the current focusOwner. Focus traversal is not aware of what a delegate is, nor should it be. This means that focus traversal _will_ update the delegate chain if you traverse into a node that hoists focus. I think it's important to point out that the primary use case of focus delegation is the creation of black-box controls, but focus delegation is not the same level of abstraction as black-box controls. It's better to think of focus delegation as a basic building block, and black-box controls as a higher-level abstraction. At the `Node` level (where controls are not a thing yet), it is more approriate to picture focus delegation as a kind of openly visible multi-level focus. In this model, focus traversal doesn't differentiate between nodes based on how they came into being (e.g. as part of a skin), it simply applies the traversal algorithm on the scene graph as it is, being completely unaware of the logical grouping that is established by controls. > In the Date/Time control you give as an example how would the user move focus > between the various delegates? What would be the most intuitive model for the > user? Personally I prefer the one used in macOS Calendar where Tab is used to > move between the month, day, and year (or hour and minute). But that creates > a conflict with using Tab to move focus into and out of the Date/Time control > as a whole. I don't know what it would mean to move focus into and out of a control as a whole. You can only meaningfully move focus into a composite control if it has at least one sub-node that can be focused. If there is no such node, then you trivially can't use focus delegation. If, on the other hand, you have a focusable sub-node, then "moving into" the composite control just means focusing the sub-node. And "moving out" of the composite control means focusing the next logically focusable node in the scene graph. I don't see any conflict here. > In any case the question is whether a monolithic control with multiple > delegates is expected to roll its own internal traversal mechanism or if we > need to extend the existing mechanism to include delegates. Having each > control roll its own internal traversal would hide it from the accessibility > frameworks. And if we expect the existing traversal keys (like Tab) to work > internally we should extend the existing traversal machinery to work with > delegates. I haven't extensively tested this yet with custom composite controls, but I think the existing traversal logic will just work as it is. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1632#discussion_r2212343939