On Fri, 11 Jul 2025 16:30:14 GMT, Martin Fox <m...@openjdk.org> wrote:
> > Does `resolveFocusDelegate` do what you need? > > 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. Alright, so a method to get the current delegate would really help there, and I think that information should be available easily enough. > 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. I think the variant with a parameter has a different intent, and so I think we should not attempt to combine the two. > > For example, for keyboard traversal, I don't see why this wouldn't work > > with multiple delegates (as its similar to having a Skin that has multiple > > focusable controls)? > > The existing traversal machinery is designed to update a Scene's focusOwner > not which delegate is active within the current focusOwner. > > 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. Tab would definitely be the most intuitive model, and that's also what I would expect (and how this has worked for such controls since ages past). So what I think is missing here is that in order to do correct navigation, Scene must be able to query the delegate of its current focus owner. I think this could be done transparently: - This PR already directs events to the current delegate, including events that are interpreted as navigation events - Events targeted at a delegate already bubble up in the usual way, eventually reaching Scene - Scene, when it wants to act on such an event for navigation, can ask its current focus owner to find out the actual control that received the event (the delegate). This could be a parameterless `getFocusDelegate` or some such or a property. - Scene then initiates the navigation logic from the delegate node (let's say it is in a field of a composed DateEntryControl -- the normal logic would find a next/previous field, or if there is none, a next unrelated node). Navigation in FX works like this everywhere, where the child order determines navigation order, and I think we should keep that. - A new Node now has been found that should receive focus. If this node was a node external to the DateEntryControl, it won't have hoist focus set; proceed as normal as make it the focus owner. - If the new Node does have hoist focus set, then find out its parent, and inform it that the delegate changed; this parent (whether it is the same or different) becomes or already is the new focus owner -- the focus owner may not have changed at all if the navigation only changed the active delegate -- which is probably a good thing For input methods then I think the missing piece is to find out the delegate chain, but as Scene would need to know this for correct navigation (and so we don't have to build a navigation override system on a per Node basis) I think it could use the same mechanism. > 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 would really not want to see custom traversal mechanisms, because on top of what you said I think it would be unintuitive as well. I think relying on child order is more than sufficient. Any custom mechanism is I think more likely to be unintuitive for the user as there is IMHO only one way to navigate intuitively through a UI -- tab/shift tab to focus the next **logical** component (defined by child order and UI hierarchy), and arrow keys go to the visually best next component -- this is what Scene does already, and allowing controls to deviate here further is just not something that is a requirement ever. Controls already have more than sufficient leeway to define the next "logical" node, even to the point that it would be unintuitive for users... ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1632#discussion_r2202486786