Skip to content

8384483: Create implementation of NSAccessibilityTable protocol - #2217

Open
azuev-java wants to merge 5 commits into
openjdk:masterfrom
azuev-java:JDK-8384483
Open

8384483: Create implementation of NSAccessibilityTable protocol#2217
azuev-java wants to merge 5 commits into
openjdk:masterfrom
azuev-java:JDK-8384483

Conversation

@azuev-java

@azuev-java azuev-java commented Jul 16, 2026

Copy link
Copy Markdown
Member
  • To preserve functionality the separate native peers for tables and lists are created;
  • The list peer for now reports its role as a table for backward compatibility, that can be changed later;
  • Fixed the long existed bug where table reported incorrectly currently selected rows;
  • Added accessibilityFocusedUIElement to AccessibleBase;
  • Added functionality for array attribute count and array attribute values retrieval to AccessibleBase;


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change requires a CSR request matching fixVersion jfx28 to be approved (needs to be created)
  • Change must be properly reviewed (2 reviews required, with at least 1 Reviewer, 1 Author)

Issue

  • JDK-8384483: Create implementation of NSAccessibilityTable protocol (Enhancement - P3)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/2217/head:pull/2217
$ git checkout pull/2217

Update a local copy of the PR:
$ git checkout pull/2217
$ git pull https://git.openjdk.org/jfx.git pull/2217/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 2217

View PR using the GUI difftool:
$ git pr show -t 2217

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/2217.diff

Using Webrev

Link to Webrev Comment

azuev-java and others added 3 commits July 13, 2026 15:24
- Create first implementation;
- Fix incorrect verbosity level when navigating to the table from other component;
…lectedRowsAttribute. We should select a set of rows, not a set of cells because that confuses VoiceOver and it falls back to reporting as first row is selected.
…ive accessibility peer for Lists;

- Expose the focused item trough the corresponding function in AccessibleBase;
- Resolve issue with incorrect row selection in MacAccessible;
@bridgekeeper

bridgekeeper Bot commented Jul 16, 2026

Copy link
Copy Markdown

👋 Welcome back kizune! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk

openjdk Bot commented Jul 16, 2026

Copy link
Copy Markdown

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk Bot added the rfr Ready for review label Jul 16, 2026
@openjdk

openjdk Bot commented Jul 16, 2026

Copy link
Copy Markdown

The total number of required reviews for this PR has been set to 2 based on the presence of this label: rfr. This can be overridden with the /reviewers command.

@mlbridge

mlbridge Bot commented Jul 16, 2026

Copy link
Copy Markdown

Webrevs

@kevinrushforth

Copy link
Copy Markdown
Member

Reviewers: @arapte @andy-goryachev-oracle

@andy-goryachev-oracle andy-goryachev-oracle left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • opened monkey tester
  • selected table view page
  • chose Items: 500,000 rows
  • enabled voice over

and it locked up with the beach ball. are you rendering all the rows somehow? I see it iterating in TableViewSkin:152 with rowIndex 143390 which isn't right.

MacAccessible:1152 iterates over the whole table (maxCount=500000).

edit: this looks like something this PR introduced, as it's not reproducible in master.

@andy-goryachev-oracle

Copy link
Copy Markdown
Contributor

Just FYI, there seems to be multiple accessibility issues in TableView (present in master, so they are separate, pre-existing issues):

  1. command-A to select all, the accessibility rectangle goes outside of the visible area (i.e. when the table width exceeds the scroll pane view port). tried to create a screenshot, but mac does not screenshot the accessibility decorations.

  2. select a table cell, then click on the scroll bar with the mouse to show next/previous page. the accessibility focus rectangle remains in the same place, now selecting some other cell, while the logical selection remains unchanged it seems. using control-option-arrow keys, the viewport jumps to the previously selected cell. also, the accessibility focus rectangle might go outside of the view port area if the table width is larger than the scroll pane viewport.

  3. unexpectedly, using accessibility navigation control-option-arrow keys, the menu is selected on all key released (because of the option key release).

- Always return the NSArray of the appropriate size, otherwice VO reports the table size incorrectly;
- To avoid querying of the entire content of the control fill in only visible rows +/- additional 10 to avoid incorrect reporting due to the VO caching when navigating with VO controls beyond the visible range;
- To request the visible range from the control's skin a new a11y attribute added - VISIBLE_ITEM_RANGE. Since outside of the MacOS it is not used that will not create any problems on other platforms;
@azuev-java

Copy link
Copy Markdown
Member Author
  • opened monkey tester
  • selected table view page
  • chose Items: 500,000 rows
  • enabled voice over

and it locked up with the beach ball. are you rendering all the rows somehow? I see it iterating in TableViewSkin:152 with rowIndex 143390 which isn't right.

MacAccessible:1152 iterates over the whole table (maxCount=500000).

edit: this looks like something this PR introduced, as it's not reproducible in master.

I have fixed it in the latest commit, should be working now.

@azuev-java

Copy link
Copy Markdown
Member Author

Just FYI, there seems to be multiple accessibility issues in TableView (present in master, so they are separate, pre-existing issues):

  1. command-A to select all, the accessibility rectangle goes outside of the visible area (i.e. when the table width exceeds the scroll pane view port). tried to create a screenshot, but mac does not screenshot the accessibility decorations.
  2. select a table cell, then click on the scroll bar with the mouse to show next/previous page. the accessibility focus rectangle remains in the same place, now selecting some other cell, while the logical selection remains unchanged it seems. using control-option-arrow keys, the viewport jumps to the previously selected cell. also, the accessibility focus rectangle might go outside of the view port area if the table width is larger than the scroll pane viewport.
  3. unexpectedly, using accessibility navigation control-option-arrow keys, the menu is selected on all key released (because of the option key release).

I will try to address these issues with the implementation for the table rows, if i will not be able to - i will create a separate bug to tackle it later.

@andy-goryachev-oracle

Copy link
Copy Markdown
Contributor

How do I trigger VISIBLE_ITEM_RANGE code path?

@andy-goryachev-oracle

Copy link
Copy Markdown
Contributor

Noted a weird thing (though pre-existing in master): after a cell in the ListView is edited, it cannot receive accessibility focus rectangle and the content of it does not announce:

Screenshot 2026-08-11 at 10 13 16

also, the tooltip shows edit to 'update' to commit the change which is confusing and makes little sense.

@andy-goryachev-oracle andy-goryachev-oracle left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basically works identically to the master branch.

two questions:

  1. accessibility cursor sort of breaks after editing a cell in both ListView and TableView
  2. question about updating visible range in case of mouse scrolling

return new int[] { 0, 0 };
}
int firstIndex = firstVisibleCell.getIndex();
return new int[] { firstIndex, lastVisibleCell.getIndex() - firstIndex + 1 };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code is not being hit when scrolling with the mouse.

should the change in the viewport origin result in VISIBLE_ITEM_RANGE being updated?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code is not being hit when scrolling with the mouse.

should the change in the viewport origin result in VISIBLE_ITEM_RANGE being updated?

Not until the VO requests the data. Which happens when it detects change in the selected row or when we enter/exit the table or list with VO selection shortcuts.

* <li>Parameters: </li>
* </ul>
*/
VISIBLE_ITEM_RANGE(int[].class),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. this is a new attribute, so this PR needs as CSR, correct?
  2. would it make more sense to use a more descriptive record instead of int[]?

minor: the values in this enum are not sorted alphabetically - should they? do we care?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. this is a new attribute, so this PR needs as CSR, correct?

I have no idea. If that would be a change in the public API i would definitely say yes, for the attribute - since we add it and not changing the meaning of the existing attribute - may be? Gray area for me honestly. @kevinrushforth Any comments?

  1. would it make more sense to use a more descriptive record instead of int[]?

That would require more processing on the native side so i would just leave it as is. It is a technical attribute that is required to pass information from the skin level to the native a11y helper - it is not supposed to be available for any other purposes.

minor: the values in this enum are not sorted alphabetically - should they? do we care?

Not really. Changing the existing code just to sort the enum - i would hate to do so, i prefer to keep the history cleaner, it's an old code, technical binding of the parameters to the native bound variables, nobody really looks at it except the compiler.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AccessibleAttribute is public API. The new attribute also needs @since 28.
CSR is needed.

(it's fine to keep it an int[])

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AccessibleAttribute is public API. The new attribute also needs @since 28. CSR is needed.

Oh well. Time to learn how to create CSR for JavaFX. Yaaaaay.... [/sarcasm off]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. this is a new attribute, so this PR needs as CSR, correct?

I have no idea. If that would be a change in the public API i would definitely say yes, for the attribute - since we add it and not changing the meaning of the existing attribute - may be? Gray area for me honestly. @kevinrushforth Any comments?

It's new API, so yes, a CSR is in order.

minor: the values in this enum are not sorted alphabetically - should they? do we care?

Not really. Changing the existing code just to sort the enum - i would hate to do so, i prefer to keep the history cleaner, it's an old code, technical binding of the parameters to the native bound variables, nobody really looks at it except the compiler.

Yeah, let's not do this. In addition to creating diff churn for no good reason, this would techincally be an incompatible change, since it would change the result of the "ordinal()" method. In practice I can't imagine that wouldn't matter, but ...

AccessibleAttribute is public API. The new attribute also needs @since 28. CSR is needed.

Oh well. Time to learn how to create CSR for JavaFX. Yaaaaay.... [/sarcasm off]

Same way as you would for the JDK. :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, let's not do this. In addition to creating diff churn for no good reason, this would techincally be an incompatible change, since it would change the result of the "ordinal()" method. In practice I can't imagine that wouldn't matter, but ...

Although, I see that we've inserted enums in the middle before, and this does too, so nm about the compatibility point.

Still, let's not have the churn.

@azuev-java

Copy link
Copy Markdown
Member Author

How do I trigger VISIBLE_ITEM_RANGE code path?

It is being called from the a11y code to query the currently visible rows range when VO requests all rows. So just create a large list or table (like 100000 rows), put focus on one of the first rows and start VoiceOver. Then using mouse scroll somewhere far away from the currently focussed row and click on any element within the row. The VO should re-request the list of the rows and it should correctly narrate the newly selected element. If this query fails the VO will narrate "Empty row" instead of the actual content of the selected row or cell.

@azuev-java

Copy link
Copy Markdown
Member Author

Noted a weird thing (though pre-existing in master): after a cell in the ListView is edited, it cannot receive accessibility focus rectangle and the content of it does not announce:

Screenshot 2026-08-11 at 10 13 16 also, the tooltip shows `edit to 'update' to commit the change` which is confusing and makes little sense.

Thats... interesting. Seems like another thing i might need to address while working on the row a11y peer. Totally unexpected. Where on earth did it get data for that that tooltip?

@andy-goryachev-oracle

Copy link
Copy Markdown
Contributor

edit to 'update' to commit the change

oh sorry, this tooltip comes from the monkey tester...

@andy-goryachev-oracle

Copy link
Copy Markdown
Contributor

/csr

@openjdk openjdk Bot added the csr Need approved CSR to integrate pull request label Aug 11, 2026
@openjdk

openjdk Bot commented Aug 11, 2026

Copy link
Copy Markdown

@andy-goryachev-oracle has indicated that a compatibility and specification (CSR) request is needed for this pull request.

@azuev-java please create a CSR request for issue JDK-8384483 with the correct fix version. This pull request cannot be integrated until the CSR request is approved.

@andy-goryachev-oracle

Copy link
Copy Markdown
Contributor

Re: scrolling.

In theory, there is Node.notifyAccessibleAttributeChanged().
It's typically called in an invalidated() method when a11y-related properties change.

@andy-goryachev-oracle

andy-goryachev-oracle commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Another issue:

  1. choose a large model (500,000 rows)
  2. enable VoiceOver
  3. select all (command-A)

locks up both ListView and TableView. This is pre-existing, as it also locks up in master.

This is not a big issue for ListView since it is not intended for large models, but it may be a problem for the TableView.

@andy-goryachev-oracle

Copy link
Copy Markdown
Contributor

Created https://bugs.openjdk.org/browse/JDK-8390342 for VoiceOver lockup after select-all with large models.

* <li>Needs notify: no </li>
* <li>Return Type: {@code int[]} containing the first item index and the
* number of visible items </li>
* <li>Parameters: </li>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameters: should describe the structure (see BOUNDS_FOR_RANGE for example)

* <ul>
* <li>Used by: ListView and TableView </li>
* <li>Needs notify: no </li>
* <li>Return Type: {@code int[]} containing the first item index and the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please specify how it encodes a no-range case.

it looks like the code returns [0,0], but is this right?
should it return an empty array or null instead?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The {0, 0} is the valid range, we should not return empty array or null in any case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

csr Need approved CSR to integrate pull request rfr Ready for review

Development

Successfully merging this pull request may close these issues.

3 participants