mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-25 09:40:10 +00:00
8341311: [Accessibility,macOS,VoiceOver] VoiceOver announces incorrect number of items in submenu of JPopupMenu
Reviewed-by: asemenov, kizune
This commit is contained in:
parent
6f9e1175a9
commit
e33eeeea04
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2025, 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
|
||||
@ -60,9 +60,11 @@ import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
@ -856,6 +858,34 @@ class CAccessibility implements PropertyChangeListener {
|
||||
}, c);
|
||||
}
|
||||
|
||||
private static Accessible getCurrentAccessiblePopupMenu(Accessible a, Component c) {
|
||||
if (a == null) return null;
|
||||
|
||||
return invokeAndWait(new Callable<Accessible>() {
|
||||
@Override
|
||||
public Accessible call() throws Exception {
|
||||
return traversePopupMenu(a);
|
||||
}
|
||||
}, c);
|
||||
}
|
||||
|
||||
private static Accessible traversePopupMenu(Accessible a) {
|
||||
// a is root level popupmenu
|
||||
AccessibleContext ac = a.getAccessibleContext();
|
||||
if (ac != null) {
|
||||
for (int i = 0; i < ac.getAccessibleChildrenCount(); i++) {
|
||||
Accessible child = ac.getAccessibleChild(i);
|
||||
if (child instanceof JMenu subMenu) {
|
||||
JPopupMenu popup = subMenu.getPopupMenu();
|
||||
if (popup.isVisible()) {
|
||||
return traversePopupMenu((Accessible) popup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
@Native private static final int JAVA_AX_ROWS = 1;
|
||||
@Native private static final int JAVA_AX_COLS = 2;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2025, 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
|
||||
@ -24,6 +24,10 @@
|
||||
*/
|
||||
|
||||
#import "MenuAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
/*
|
||||
* Implementing a protocol that represents menus both as submenu and as a
|
||||
@ -51,4 +55,31 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return all non-ignored children.
|
||||
*/
|
||||
- (NSArray *)accessibilityChildren {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(sjm_getCurrentAccessiblePopupMenu, sjc_CAccessibility,
|
||||
"getCurrentAccessiblePopupMenu",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;", nil);
|
||||
jobject axComponent = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility,
|
||||
sjm_getCurrentAccessiblePopupMenu,
|
||||
fAccessible, fComponent);
|
||||
|
||||
CommonComponentAccessibility *currentElement = [CommonComponentAccessibility createWithAccessible:axComponent
|
||||
withEnv:env withView:self->fView isCurrent:YES];
|
||||
|
||||
NSArray *children = [CommonComponentAccessibility childrenOfParent:currentElement
|
||||
withEnv:env
|
||||
withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN
|
||||
allowIgnored:NO];
|
||||
|
||||
if ([children count] == 0) {
|
||||
return nil;
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
109
test/jdk/javax/accessibility/TestPopupMenuChildCount.java
Normal file
109
test/jdk/javax/accessibility/TestPopupMenuChildCount.java
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8341311
|
||||
* @summary Verifies that VoiceOver announces correct number of child for PopupMenu on macOS
|
||||
* @requires os.family == "mac"
|
||||
* @library /java/awt/regtesthelpers
|
||||
* @build PassFailJFrame
|
||||
* @run main/manual TestPopupMenuChildCount
|
||||
*/
|
||||
|
||||
public class TestPopupMenuChildCount {
|
||||
public static void main(String[] args) throws Exception {
|
||||
String INSTRUCTIONS = """
|
||||
This test is applicable only on macOS.
|
||||
|
||||
Test UI contains an empty JFrame. On press of left/right mouse button,
|
||||
a PopupMenu will be visible.
|
||||
|
||||
Follow these steps to test the behaviour:
|
||||
|
||||
1. Start the VoiceOver (Press Command + F5) application
|
||||
2. Press Left/Right mouse button inside test frame window to open
|
||||
the PopupMenu
|
||||
3. VO should announce "Menu" with number of child items of the Popupmenu
|
||||
4. Press Up/Down arrow to traverse popupmenu child items
|
||||
5. Press Right arrow key to open submenu
|
||||
6. VO should announce "Menu" with correct number of child items
|
||||
for the submenu (For e.g. When Submenu-1 is open, VO should announce
|
||||
"Menu 4 items")
|
||||
7. Repeat the process for other submenus
|
||||
8. Press Pass if you are able to hear correct announcements
|
||||
else Fail""";
|
||||
|
||||
PassFailJFrame.builder()
|
||||
.instructions(INSTRUCTIONS)
|
||||
.columns(45)
|
||||
.testUI(TestPopupMenuChildCount::createUI)
|
||||
.build()
|
||||
.awaitAndCheck();
|
||||
}
|
||||
|
||||
private static JFrame createUI() {
|
||||
JFrame frame = new JFrame("Test Frame");
|
||||
|
||||
JPopupMenu popupmenu = new JPopupMenu();
|
||||
JMenuItem mi1 = new JMenuItem("MenuItem-1");
|
||||
JMenuItem mi2 = new JMenuItem("MenuItem-2");
|
||||
JMenuItem mi3 = new JMenuItem("MenuItem-3");
|
||||
popupmenu.add(mi1);
|
||||
popupmenu.add(mi2);
|
||||
popupmenu.add(mi3);
|
||||
|
||||
JMenu submenu1 = new JMenu("Submenu-1");
|
||||
submenu1.add("subOne");
|
||||
submenu1.add("subTwo");
|
||||
submenu1.add("subThree");
|
||||
|
||||
JMenu submenu2 = new JMenu("Submenu-2");
|
||||
submenu2.add("subOne");
|
||||
submenu2.add("subTwo");
|
||||
|
||||
JMenu submenu3 = new JMenu ("Submenu-3");
|
||||
submenu3.add("subOne");
|
||||
submenu1.add(submenu3);
|
||||
|
||||
popupmenu.add(submenu1);
|
||||
popupmenu.add(submenu2);
|
||||
|
||||
frame.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
popupmenu.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
});
|
||||
frame.setSize(300, 300);
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user