RFR: 8340852: ScrollPane should not consume navigation keys when it doesn't have direct focus
Martin Fox
mfox at openjdk.org
Wed Oct 2 18:15:42 UTC 2024
On Thu, 26 Sep 2024 21:17:55 GMT, John Hendrikx <jhendrikx at openjdk.org> wrote:
> This change modifies `ScrollPaneBehavior` to only consume keys that are targetted at it. As `KeyEvent`s are in almost all cases only intended for the targetted node (as visually that's where the user expects the keyboard input to go, as per normal UI rules) consuming key events that bubble up is simply incorrect. When the `ScrollPane` is focused directly (it has the focused border) then it is fine for it to respond to all kinds of keys.
>
> In FX controls normally there is no need to check if a `Control` is focused (although they probably should **all** do this) as they do not have children that could have received the Key Events involved, and Key Events are always sent to the focused Node. When `ScrollPane` was developed this was not taken into account, leading to it consuming keys not intended for it.
>
> This fixes several unexpected problems for custom control builders. A custom control normally benefits from standard navigation out of the box (TAB/shift+TAB) and directional keys. However, this breaks down as soon as this custom control is positioned within a `ScrollPane`, which is very surprising behavior and not at all expected. This makes it harder than needed for custom control developers to get the standard navigation for the directional keys, as they would have to specifically capture those keys before they reach the `ScrollPane` and trigger the correct navigation action themselves (for which as of this writing there is no public API).
>
> The same goes for all the other keys captured by `ScrollPane` when it does not have focus, although not as critical as the UP/DOWN/LEFT/RIGHT keys.
I agree that the current ScrollPane implementation is wrong. Traversal is an accessibility issue so it’s imperative that we don’t block the traversal keys. We can’t expect custom controls to work around the ScrollPane's faulty behavior.
I don’t agree with the idea that a ScrollPane should only process key events when it has the focus largely because I can’t think of an instance where a ScrollPane receives focus. Focus either lies on the node that owns the ScrollPane (like a TableView) or one of the nodes inside the ScrollPane but not on the ScrollPane itself.
In any case there are instances in any UI toolkit where key event handling is split between a control and non-focused containers further up the tree (for example, I just verified that on macOS the NSScrollView implements PgUp and PgDn but never has focus). I haven’t dug into JavaFX controls in depth but I would be surprised if there weren’t similar instances. It’s a pretty common occurrence.
If we remove the existing PgUp, PgDn, and Home behavior folks will notice and accessibility will take a hit. I’m not entirely sure anyone will notice if we remove the arrow key behavior since the other Controls work so hard to hide them from the ScrollPane to begin with. I do agree that these bindings need to be removed OR completely re-implemented so they don’t block traversal (e.g. they could try to traverse and scroll if traversal isn't possible).
TL;DR Don’t try to filter events based on whether the ScrollPane has focus. Remove the ScrollPane bindings that block the traversal keys. Leave the rest.
-------------
PR Comment: https://git.openjdk.org/jfx/pull/1582#issuecomment-2389354901
More information about the openjfx-dev
mailing list