RFR: 8090456: Focus Management
Andy Goryachev
angorya at openjdk.org
Wed Sep 11 15:09:12 UTC 2024
On Wed, 11 Sep 2024 01:05:33 GMT, Michael Strauß <mstrauss at openjdk.org> wrote:
>> Public APIs for focus traversal and the focus traversal policy:
>>
>> https://github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal.md
>>
>> This work is loosely based on the patch
>> https://cr.openjdk.org/~jgiles/8061673/
>
> By its own admission, this proposal basically promotes an internal implementation to public API (albeit with some refactoring). This may or may not be a good idea, so I'd like to take a step back and look at the problem we're trying to solve.
>
> Looking at several of the linked JBS issues, a missing feature of JavaFX is the ability to customize the focus traversal logic of a custom control (or a container of nodes in the widest sense of the word). Any proposed solution should support complex scenarios like toolbars with overflow, or [radio groups](https://www.w3.org/TR/2009/WD-wai-aria-practices-20090224/#radiobutton).
>
> I think there are two distinct modes of focus traversal: logical ("tabbing") and directional (arrow keys). Both modes are independent axes of the problem at hand, and should be customizable independently from each other.
>
> The current implementation provides a single `Algorithm` (or `TraversalPolicy` after the refactoring) for both traversal modes. I've played around with the code for a while, and while in theory I can provide my own `TraversalPolicy`, it can be quite a lot of code and it's not as easy as it could be. Additionally, it is hard to customize the traversal policies of the substructure of skinnable controls.
>
> I question whether we need custom traversal policies at all, as the ways in which focus can move from one node to the next are quite limited:
> 1. **Permeable edges**: The next node in a container is selected until an edge is reached, then the input focus leaves the container.
> 2. **Confined to container**: The next node in a container is selected until the end of the container is reached; then the input focus doesn't move on.
> 3. **Cyclic in container**: Like confined, but at the end of the container, the input focus wraps around to the first element.
> 4. **Single focused node in container**: When the input focus enters a container, it moves to the node that was most recently selected (or to the first node in the container if none of the nodes was selected before); after that the input focus leaves the container.
>
> Having two traversal toggles (logical and directional), each with four possible modes, already solves most of the problem. The advantage of this over a custom policy implementation is that these properties can be modelled with an enumeration and easily be set by control and application developers, and they can also be set via CSS. This allows developers to customize the focus traversal behavior of existing skinnable cont...
Thank you @mstr2 for a detailed writeup!
I fully agree with you that the majority of use cases can be handled with the existing policies.
The default one seems to be geometry-based ("directional") _where supported_, and the other being a "logical" one which is not explicitly accessible. The question, therefore, is do we need a static getter for that kind of a policy? (I'd say no since the logical order depends on a particular control).
A couple of points:
1. setting via CSS is not a goal (I probably should mention this in the JEP)
2. the 4-item enumeration is not complete. For example, application may specify some other, or even dynamic, order of traversal, which would require a custom policy.
Another question is whether there exists a policy that cannot be implemented by the new APIs provided by this PR.
What do you think?
-------------
PR Comment: https://git.openjdk.org/jfx/pull/1555#issuecomment-2343940594
More information about the openjfx-dev
mailing list