RFR: 8340852: ScrollPane should not consume navigation keys when it doesn't have direct focus

John Hendrikx jhendrikx at openjdk.org
Thu Oct 3 13:06:43 UTC 2024


On Wed, 2 Oct 2024 21:00:55 GMT, Martin Fox <mfox at openjdk.org> wrote:

> > > 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.
> > 
> > 
> > this seems to be incorrect: unless you set `mouseTransparent`, ScrollPane can be focused with a mouse click, even when `focusTraversable` is false.
> 
> I didn't say that a ScrollPane couldn't take focus, just that it normally doesn't. And if focus lies with a node inside the ScrollPane we can't expect a user to move focus to the ScrollPane to get PgUp and PgDn working.
> 
> > > I can’t think of an instance where a ScrollPane receives focus.
> > 
> > 
> > when there is a non-interactive content inside (such as image or a label). they you _do_ want to handle arrow keys to scroll.
> 
> Unless that would make the ScrollPane a traversal dead-end.
> 
> It's a conundrum. There are cases where the arrows should scroll particularly for top-level content (I can use them to scroll through a web page in Safari). But from what I can tell this is not the default behavior in the macOS toolkit probably because it interferes with traversal.

It makes sense to not make something that doesn't apply in all situations the default behavior.   A browser is mostly a read-only affair, and consuming directional keys for scrolling makes a lot of sense.  They don't allow directional navigation for focusable controls, except in very specific cases (like an embedded toolbar) so they are not dealing with this conundrum at all.

The toolkit browsers are built on however do allow directional navigation (their toolbars and other native controls support it), but it was a **choice** to not to do this on the web page itself (the nested application).  It was also a choice there to not be able to escape the nested application easily (when tabbing through things on the web page, you wouldn't want to accidentally tab to the back button or address bar, that would break the immersion of the nested application).  Instead browsers provide special short cuts to "escape" the web page (F6 to focus the address bar for example).

FX is similar to most other toolkits.  It provides directional navigation as that makes sense for productivity applications.  It however sets up its scroll pane's default behavior to act like a web browser would.  It is taking away the choice here, as you can't disable this easily without making a new skin for `ScrollPane`.  It would have been better to not set such an opiniated default that can't be overridden easily.  In the opposite situation, users can easily install handlers to make the scroll pane act the way they want (and deal with the consequences of their actions by consuming certain keys before they bubble up).  So to sum up there are two options:

- ScrollPane aggressively consumes navigational and other keys **[current]**
  - To prevent this, must create a new skin for ScrollPane to get rid of its default behavior; possibly this can be improved with a behavior or input map proposal, but the main point stands: why have such an opiniated default that doesn't apply in all situations?
  - Or alternatively: have all embedded controls handle such keys before they reach the scroll pane (what FX does with the controls it provides in order to get the expected result of navigation before scrolling).

- ScrollPane by default remains impassive when not focused **[proposed]**
  - To get the existing behavior, just install an event handler on ScrollPane (a choice the user makes that will block directional navigation in favor of scrolling)
  - If you want to allow directional navigation first, then the handler should be installed on Scene.  Any left over keys can then be converted into actions for a specific scroll pane (probably a top level one, browser style)
  - If you want to have exact control over the scrolls a scroll pane should do, then consider handling those at the embedded control that is aware of how its content is best represented (like ListView, TableView) -- this is how pgup/pgdown/home/end should be handled -- a scroll pane is not smart enough to make such keys behave sensibly in all situations

> BTW, I'm not optimistic that we can find some combination of modifiers + arrow keys to use. The behavior of Shift is already defined and many of the other modifier + arrow combinations are used by one OS or another.

Yeah, I think we definitely should not do this as part of this problem.  A scroll pane is too generic; it makes much more sense to leave this up to the specific implementation instead (ie. TableView, ListView).  There is little sense to provide something out of the box that for any realistic control probably needs to be overridden to do what the user expects.

-------------

PR Comment: https://git.openjdk.org/jfx/pull/1582#issuecomment-2391370612


More information about the openjfx-dev mailing list