8377936: VoiceOver Reads Button Incorrectly

Reviewed-by: prr, kizune
This commit is contained in:
Jeremy Wood 2026-04-17 20:53:42 +00:00 committed by Phil Race
parent 804ecc14dc
commit 0dd0108c1a
2 changed files with 112 additions and 17 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -188,10 +188,6 @@ final class CAccessible extends CFRetainedResource implements Accessible {
// Do send check box state changes to native side
if (thisRole == AccessibleRole.CHECK_BOX) {
if (!Objects.equals(newValue, oldValue)) {
valueChanged(ptr);
}
// Notify native side to handle check box style menuitem
if (parentRole == AccessibleRole.POPUP_MENU && newValue != null
&& ((AccessibleState)newValue) == AccessibleState.FOCUSED) {
@ -201,23 +197,12 @@ final class CAccessible extends CFRetainedResource implements Accessible {
// Do send radio button state changes to native side
if (thisRole == AccessibleRole.RADIO_BUTTON) {
if (newValue != null && !newValue.equals(oldValue)) {
valueChanged(ptr);
}
// Notify native side to handle radio button style menuitem
if (parentRole == AccessibleRole.POPUP_MENU && newValue != null
&& ((AccessibleState)newValue) == AccessibleState.FOCUSED) {
menuItemSelected(ptr);
}
}
// Do send toggle button state changes to native side
if (thisRole == AccessibleRole.TOGGLE_BUTTON) {
if (!Objects.equals(newValue, oldValue)) {
valueChanged(ptr);
}
}
} else if (name.equals(ACCESSIBLE_NAME_PROPERTY)) {
//for now trigger only for JTabbedPane.
if (e.getSource() instanceof JTabbedPane) {
@ -227,7 +212,10 @@ final class CAccessible extends CFRetainedResource implements Accessible {
AccessibleRole thisRole = accessible.getAccessibleContext()
.getAccessibleRole();
if (thisRole == AccessibleRole.SLIDER ||
thisRole == AccessibleRole.PROGRESS_BAR) {
thisRole == AccessibleRole.PROGRESS_BAR ||
thisRole == AccessibleRole.CHECK_BOX ||
thisRole == AccessibleRole.RADIO_BUTTON ||
thisRole == AccessibleRole.TOGGLE_BUTTON ) {
valueChanged(ptr);
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.FlowLayout;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
/*
* @test
* @key headful
* @bug 8377936
* @summary manual test for VoiceOver reading button names and states
* @requires os.family == "mac"
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual VoiceOverNamesAndStates
*/
public class VoiceOverNamesAndStates {
public static void main(String[] args) throws Exception {
String INSTRUCTIONS = """
INSTRUCTIONS:
Part A:
1. Open VoiceOver
2. Move the VoiceOver cursor to the leftmost button.
3. Press CTRL + ALT + RIGHT to move to the rightmost button.
Expected behavior: VoiceOver should announce rightmost button.
(It should NOT announce the leftmost button.)
Part B (Regression for 8061359, 8348936, 8309733):
1. Open VoiceOver
2. Move the VoiceOver cursor to the leftmost button.
3. Press SPACE to trigger Swing's default KeyListeners.
4. Repeat step 3 to untoggle button.
5. Press CTRL + ALT + SPACE to trigger VO's listeners.
6. Repeat step 5 to untoggle button
Expected behavior: VoiceOver should announce the change in the
button state in steps 3-6. (When you use VoiceOver to toggle
the button you should hear a small chirp as the button
toggles.)
Part C (Regression for 8345728, 8283400):
1. Turn on Screen Magnifier
(See System Settings -> Accessibility -> Hover Text)
2. Press CMD key and hover mouse over leftmost button
3. Click the button
4. Release the CMD key
Expected behavior: both the button and the "hover text" window
repaint to show a selected button.
5. Repeat steps 2-4 to untoggle the button
Expected behavior: both the button and the "hover text" window
repaint to show a deselected button.
""";
PassFailJFrame.builder()
.title("VoiceOverNamesAndStates Instruction")
.instructions(INSTRUCTIONS)
.columns(40)
.testUI(VoiceOverNamesAndStates::createUI)
.build()
.awaitAndCheck();
}
private static JFrame createUI() {
JFrame f = new JFrame();
f.getContentPane().setLayout(new FlowLayout());
AbstractButton button1 = new JCheckBox("chess");
AbstractButton button2 = new JButton("backgammon");
f.getContentPane().add(button1);
f.getContentPane().add(button2);
f.pack();
f.setVisible(true);
return f;
}
}