8284542: [Accessibility] [Win] Missing attribute for toggle state of CheckBox in CheckBoxTreeItem#1088
8284542: [Accessibility] [Win] Missing attribute for toggle state of CheckBox in CheckBoxTreeItem#1088arapte wants to merge 4 commits intoopenjdk:masterfrom
Conversation
|
👋 Welcome back arapte! A progress list of the required criteria for merging this PR into |
Webrevs
|
|
@azuev-java @andy-goryachev-oracle can you take a look at this as well? |
|
/reviewers 2 |
|
@kevinrushforth |
|
@kevinrushforth has indicated that a compatibility and specification (CSR) request is needed for this pull request. @arapte please create a CSR request for issue JDK-8284542 with the correct fix version. This pull request cannot be integrated until the CSR request is approved. |
modules/javafx.graphics/src/main/java/javafx/scene/AccessibleAttribute.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/javafx/scene/AccessibleAttribute.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java
Outdated
Show resolved
Hide resolved
modules/javafx.controls/src/main/java/javafx/scene/control/cell/CheckBoxTreeCell.java
Outdated
Show resolved
Hide resolved
|
Testing with VoiceOver on Mac M1 Ventura 13.3.1(a): undetermined checkbox is pronounced as "mixed checkbox" - is this expected behavior? Also, probably unrelated to this PR: the outlines placed by VoiceOver are shifted to the wrong positions on the secondary monitor, for all nodes in the javafx window. For Chrome, the positioning is correct which makes me believe there might be a problem with FX. Also, the VoiceOver popup (black thing with white outline) inexplicably spans two monitors, though I think it might be a problem with VoiceOver: my setup is: secondary monitor (scale=1) is above the primary (scale=2) |
| } else if (checkBox.isSelected()) { | ||
| state = ToggleState.CHECKED; | ||
| } | ||
| return state; |
There was a problem hiding this comment.
very minor, a question of style. i would avoid double assignment by doing this:
if (checkBox.isIndeterminate()) {
return ToggleState.INDETERMINATE;
} else if (checkBox.isSelected()) {
return ToggleState.CHECKED;
} else {
return ToggleState.UNCHECKED;
}
| AccessibleRole.TABLE_ROW, | ||
| AccessibleRole.TREE_ITEM, | ||
| AccessibleRole.CHECK_BOX_TREE_ITEM, | ||
| AccessibleRole.TREE_TABLE_ROW |
There was a problem hiding this comment.
[question] is the order of elements significant in any way?
There was a problem hiding this comment.
The order does not matter, the roles are accessed by value on the native side code. (initEnum())
| AccessibleRole role = (AccessibleRole) getAttribute(ROLE); | ||
| if (role == AccessibleRole.TREE_ITEM || role == AccessibleRole.TREE_TABLE_ROW) { | ||
| AccessibleRole containerRole = role == AccessibleRole.TREE_ITEM ? AccessibleRole.TREE_VIEW : AccessibleRole.TREE_TABLE_VIEW; | ||
| if (role == AccessibleRole.TREE_ITEM || role == AccessibleRole.CHECK_BOX_TREE_ITEM || role == AccessibleRole.TREE_TABLE_ROW) { |
There was a problem hiding this comment.
could a switch statement be used here instead?
| case INDETERMINATE: { | ||
| if (getAttribute(ROLE) == AccessibleRole.CHECK_BOX) { | ||
| if (getAttribute(ROLE) == AccessibleRole.CHECK_BOX | ||
| || getAttribute(ROLE) == AccessibleRole.CHECK_BOX_TREE_ITEM) { |
There was a problem hiding this comment.
same Q.: could we use a switch statement to avoid double getter call? (I don't know if JVM will optimize that away anyway, but switch makes a cleaner code, in my opinion)
There was a problem hiding this comment.
I think the proposed change is less intrusive than a switch, but I don't mind either way. It might make sense to use a local variable to avoid calling getAttribute twice.
| case SELECTED: { | ||
| Object role = getAttribute(ROLE); | ||
| if (role == AccessibleRole.CHECK_BOX || role == AccessibleRole.TOGGLE_BUTTON) { | ||
| if (role == AccessibleRole.CHECK_BOX || role == AccessibleRole.TOGGLE_BUTTON |
| case LIST_ITEM: return getContainerAccessible(AccessibleRole.LIST_VIEW); | ||
| case TAB_ITEM: return getContainerAccessible(AccessibleRole.TAB_PANE); | ||
| case PAGE_ITEM: return getContainerAccessible(AccessibleRole.PAGINATION); | ||
| case CHECK_BOX_TREE_ITEM: |
There was a problem hiding this comment.
I would recommend reformatting the switch cases here for clarity:
private Accessible getContainer() {
if (isDisposed()) {
return null;
}
AccessibleRole role = (AccessibleRole)getAttribute(ROLE);
if (role != null) {
switch (role) {
case TABLE_ROW:
case TABLE_CELL:
return getContainerAccessible(AccessibleRole.TABLE_VIEW);
case LIST_ITEM:
return getContainerAccessible(AccessibleRole.LIST_VIEW);
case TAB_ITEM:
return getContainerAccessible(AccessibleRole.TAB_PANE);
case PAGE_ITEM:
return getContainerAccessible(AccessibleRole.PAGINATION);
case CHECK_BOX_TREE_ITEM:
case TREE_ITEM:
return getContainerAccessible(AccessibleRole.TREE_VIEW);
case TREE_TABLE_ROW:
case TREE_TABLE_CELL:
return getContainerAccessible(AccessibleRole.TREE_TABLE_VIEW);
}
}
return null;
}
(and below also. but again, this is just my preference)
There was a problem hiding this comment.
I usually prefer to avoid these sort of unrelated changes to minimize the diffs. Either way is fine.
There was a problem hiding this comment.
in this particular case, with many fall-throughs, I think the code would benefit from reformatting.
There was a problem hiding this comment.
Minimal diff eases in tracing regression and in review. May be we can take up the cleanup as a separate issue, there seems to be multiple of such instances. (of switch/replacing if with switch)
modules/javafx.graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/javafx/scene/AccessibleAttribute.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/javafx/scene/AccessibleAttribute.java
Show resolved
Hide resolved
kevinrushforth
left a comment
There was a problem hiding this comment.
The additional changes to add the enum look good to me. I'll test it and review the javadoc.
| case INDETERMINATE: { | ||
| if (getAttribute(ROLE) == AccessibleRole.CHECK_BOX) { | ||
| if (getAttribute(ROLE) == AccessibleRole.CHECK_BOX | ||
| || getAttribute(ROLE) == AccessibleRole.CHECK_BOX_TREE_ITEM) { |
There was a problem hiding this comment.
I think the proposed change is less intrusive than a switch, but I don't mind either way. It might make sense to use a local variable to avoid calling getAttribute twice.
| case SELECTED: { | ||
| Object role = getAttribute(ROLE); | ||
| if (role == AccessibleRole.CHECK_BOX || role == AccessibleRole.TOGGLE_BUTTON) { | ||
| if (role == AccessibleRole.CHECK_BOX || role == AccessibleRole.TOGGLE_BUTTON |
| case LIST_ITEM: return getContainerAccessible(AccessibleRole.LIST_VIEW); | ||
| case TAB_ITEM: return getContainerAccessible(AccessibleRole.TAB_PANE); | ||
| case PAGE_ITEM: return getContainerAccessible(AccessibleRole.PAGINATION); | ||
| case CHECK_BOX_TREE_ITEM: |
There was a problem hiding this comment.
I usually prefer to avoid these sort of unrelated changes to minimize the diffs. Either way is fine.
modules/javafx.graphics/src/main/java/javafx/scene/AccessibleAttribute.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/javafx/scene/AccessibleAttribute.java
Show resolved
Hide resolved
This is a Windows-only fix, so the behavior should be unchanged on Mac from before this fix. The only change on Mac is to react to the new AccessibleRole value (to do what it would have done before). |
|
it looks like the behavior on Mac is unchanged. |
|
I can't find anything like VoiceOver on Windows 11. Do you need JAWS or similar to test? |
kevinrushforth
left a comment
There was a problem hiding this comment.
Testing looks (and sounds) good to me. I'll reapprove if you make the suggested formatting or doc changes. Go ahead and update the CSR when ready.
You can use Windows Narrator. |
Definitely unrelated, but it should be filed as a bug. I remember seeing this before, but I don't see a bug for it. |
On Windows 10/11 it is called Narrator and is in Start->All Apps->Accessibility->Narrator |
andy-goryachev-oracle
left a comment
There was a problem hiding this comment.
looks and sounds good.
|
Is JDK-8087651 a duplicate of this issue? or related? |
created JDK-8308191 |
|
@arapte This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 5 new commits pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the ➡️ To integrate this PR with the above commit message to the |
|
/integrate |
|
Going to push as commit bdadcb2.
Your commit was automatically rebased without conflicts. |

Issue:
CheckBoxTreeItem extends TreeItem and adds a CheckBox.
The state of this CheckBox is not visible to an accessibility client application.
If we analyze a simple program that contains a CheckBoxTreeItem using a windows application "Accessibility Insights for Window", we can notice that toggle state of CheckBox is not exposed.
Fix:
Include the Toggle Control Pattern in Accessibility information of a CheckBoxTreeItem in addition to the patterns that are used for a TreeItem.
Verification:
On Windows: Do the following with and without the fix.
Progress
Issues
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1088/head:pull/1088$ git checkout pull/1088Update a local copy of the PR:
$ git checkout pull/1088$ git pull https://git.openjdk.org/jfx.git pull/1088/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1088View PR using the GUI difftool:
$ git pr show -t 1088Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1088.diff
Webrev
Link to Webrev Comment