mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-26 03:09:41 +01:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdbb6f02b8 | ||
|
|
6743f36c32 | ||
|
|
f706b93717 | ||
|
|
6f046e9f68 | ||
|
|
bac641fe77 | ||
|
|
8dfcb3fd5a | ||
|
|
ef651ca1bb | ||
|
|
3092ca0461 | ||
|
|
3caa06a639 | ||
|
|
6c50ed6690 | ||
|
|
805a5b4f75 | ||
|
|
efabfd0370 | ||
|
|
f757a39090 | ||
|
|
1039653b97 | ||
|
|
65fa801231 | ||
|
|
3d9ae4dbe8 | ||
|
|
ef8e01b0d4 | ||
|
|
eaa9c1618e | ||
|
|
ee3c7edd84 | ||
|
|
8a19c38728 | ||
|
|
4fcd80acf0 | ||
|
|
6f5dd836de | ||
|
|
2ff21b425e |
26
README.md
26
README.md
@@ -16,6 +16,7 @@ It includes a number enhancements in font rendering, HiDPI support, ligatures, p
|
||||
- [Ubuntu Linux](#ubuntu-linux)
|
||||
- [Windows](#build-windows)
|
||||
- [macOS](#macos)
|
||||
- [Developing](#developing)
|
||||
- [Contributing](#contributing)
|
||||
- [Resources](#resources)
|
||||
|
||||
@@ -130,6 +131,31 @@ $ make images
|
||||
```
|
||||
This will build the release configuration under `./build/macosx-x86_64-server-release/`.
|
||||
|
||||
## Developing
|
||||
You can use [CLion](https://www.jetbrains.com/clion/) to develop native parts of the JetBrains Runtime and
|
||||
[IntelliJ IDEA](https://www.jetbrains.com/idea/) for the parts written in Java.
|
||||
Both require projects to be created.
|
||||
|
||||
### CLion
|
||||
Run
|
||||
```
|
||||
$ make compile-commands
|
||||
```
|
||||
in the git root and open the resulting `build/.../compile_commands.json` file as a project.
|
||||
Then use `Tools | Compilation Database | Change Project Root` to point to git root of this repository.
|
||||
|
||||
See also this detailed step-by-step tutorial for all platforms:
|
||||
[How to develop OpenJDK with CLion](https://blog.jetbrains.com/clion/2020/03/openjdk-with-clion/).
|
||||
|
||||
### IDEA
|
||||
Run
|
||||
```
|
||||
$ sh ./bin/idea.sh
|
||||
```
|
||||
in the git root to generate project files (add `--help` for options). If you have multiple
|
||||
configurations (for example, `release` and `fastdebug`), supply the `--conf <conf_name>` argument.
|
||||
Then open the git root directory as a project in IDEA.
|
||||
|
||||
## Contributing
|
||||
We are happy to receive your pull requests!
|
||||
Before you submit one, please sign our [Contributor License Agreement (CLA)](https://www.jetbrains.com/agreements/cla/).
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "jvm_md.h"
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
@@ -220,6 +221,39 @@ ContainsLibJVM(const char *env) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
HaveGLibCCompatLibrary(struct dl_phdr_info* info, size_t size, void* data)
|
||||
{
|
||||
static const char * const GLIBC_COMPAT_LIBRARY_NAME = "libgcompat.so";
|
||||
|
||||
const char * const so_pathname = info->dlpi_name;
|
||||
if (so_pathname != NULL && so_pathname[0] != 0) {
|
||||
const char * const last_slash = JLI_StrRChr(so_pathname, '/');
|
||||
const char * const so_basename = (last_slash != NULL) ? last_slash + 1 : so_pathname;
|
||||
if (JLI_StrNCmp(so_basename, GLIBC_COMPAT_LIBRARY_NAME, JLI_StrLen(GLIBC_COMPAT_LIBRARY_NAME)) == 0) {
|
||||
return JNI_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* also means continue to iterate */
|
||||
}
|
||||
|
||||
static jboolean
|
||||
UsingMusl(void) {
|
||||
const jlong start = CurrentTimeMicros();
|
||||
|
||||
const int found_gcompat = dl_iterate_phdr(HaveGLibCCompatLibrary, NULL);
|
||||
|
||||
if (JLI_IsTraceLauncher()) {
|
||||
const jlong end = CurrentTimeMicros();
|
||||
JLI_TraceLauncher("%ld micro seconds to check for the musl compatibility layer for glibc\n",
|
||||
(long)(end - start));
|
||||
}
|
||||
|
||||
return (found_gcompat != 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test whether the environment variable needs to be set, see flowchart.
|
||||
*/
|
||||
@@ -243,6 +277,10 @@ RequiresSetenv(const char *jvmpath) {
|
||||
return JNI_TRUE;
|
||||
#endif
|
||||
|
||||
if (UsingMusl()) {
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
llp = getenv("LD_LIBRARY_PATH");
|
||||
/* no environment variable is a good environment variable */
|
||||
if (llp == NULL && dmllp == NULL) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.awt.geom.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import sun.lwawt.macosx.CThreading;
|
||||
import static sun.awt.SunHints.*;
|
||||
|
||||
public final class CStrike extends PhysicalStrike {
|
||||
|
||||
@@ -205,7 +206,15 @@ public final class CStrike extends PhysicalStrike {
|
||||
return;
|
||||
}
|
||||
|
||||
result.setRect(floatRect.x + pt.x, floatRect.y + pt.y, floatRect.width, floatRect.height);
|
||||
boolean subpixel = desc.aaHint == INTVAL_TEXT_ANTIALIAS_ON &&
|
||||
desc.fmHint == INTVAL_FRACTIONALMETRICS_ON;
|
||||
float subpixelResolutionX = subpixel ? FontUtilities.subpixelResolution.width : 1;
|
||||
float subpixelResolutionY = subpixel ? FontUtilities.subpixelResolution.height : 1;
|
||||
// Before rendering, glyph positions are offset by 0.5 pixels, take into consideration
|
||||
float x = ((int) (pt.x * subpixelResolutionX + 0.5f)) / subpixelResolutionX;
|
||||
float y = ((int) (pt.y * subpixelResolutionY + 0.5f)) / subpixelResolutionY;
|
||||
|
||||
result.setRect(floatRect.x + x, floatRect.y + y, floatRect.width, floatRect.height);
|
||||
}
|
||||
|
||||
private void getGlyphImageBounds(int glyphCode, float x, float y, Rectangle2D.Float floatRect) {
|
||||
|
||||
@@ -291,6 +291,10 @@ public class LWWindowPeer
|
||||
updateFocusableWindowState();
|
||||
super.setVisibleImpl(visible);
|
||||
// TODO: update graphicsConfig, see 4868278
|
||||
if (visible) {
|
||||
// Set correct background for a window before making it visible
|
||||
platformWindow.setOpaque(!isTranslucent());
|
||||
}
|
||||
platformWindow.setVisible(visible);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,12 +35,14 @@ import java.awt.EventQueue;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.annotation.Native;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.accessibility.Accessible;
|
||||
import javax.accessibility.AccessibleAction;
|
||||
@@ -59,6 +61,8 @@ import javax.swing.JEditorPane;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
@@ -128,7 +132,7 @@ class CAccessibility implements PropertyChangeListener {
|
||||
static <T> T invokeAndWait(final Callable<T> callable, final Component c) {
|
||||
if (c != null) {
|
||||
try {
|
||||
return EventQueue.isDispatchThread() ? callable.call() : LWCToolkit.invokeAndWait(callable, c);
|
||||
return EventQueue.isDispatchThread() ? callable.call() : invokeAndWait(callable, c, (T)null);
|
||||
} catch (final Exception e) { e.printStackTrace(); }
|
||||
}
|
||||
return null;
|
||||
@@ -561,6 +565,10 @@ class CAccessibility implements PropertyChangeListener {
|
||||
if (pac == null) return;
|
||||
AccessibleSelection as = pac.getAccessibleSelection();
|
||||
if (as == null) return;
|
||||
if (parent instanceof JList) {
|
||||
((JList) parent).setSelectedIndex(i);
|
||||
return;
|
||||
}
|
||||
as.addAccessibleSelection(i);
|
||||
}
|
||||
}, c);
|
||||
@@ -661,77 +669,148 @@ class CAccessibility implements PropertyChangeListener {
|
||||
|
||||
// Duplicated from JavaComponentAccessibility
|
||||
// Note that values >=0 are indexes into the child array
|
||||
static final int JAVA_AX_ALL_CHILDREN = -1;
|
||||
static final int JAVA_AX_SELECTED_CHILDREN = -2;
|
||||
static final int JAVA_AX_VISIBLE_CHILDREN = -3;
|
||||
@Native static final int JAVA_AX_ALL_CHILDREN = -1;
|
||||
@Native static final int JAVA_AX_SELECTED_CHILDREN = -2;
|
||||
@Native static final int JAVA_AX_VISIBLE_CHILDREN = -3;
|
||||
|
||||
// Each child takes up two entries in the array: one for itself and one for its role
|
||||
public static Object[] getChildrenAndRoles(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored) {
|
||||
if (a == null) return null;
|
||||
return invokeAndWait(new Callable<Object[]>() {
|
||||
public Object[] call() throws Exception {
|
||||
ArrayList<Object> childrenAndRoles = new ArrayList<Object>();
|
||||
_addChildren(a, whichChildren, allowIgnored, childrenAndRoles);
|
||||
|
||||
/* In the case of fetching a selection, need to check to see if
|
||||
* the active descendant is at the beginning of the list. If it
|
||||
* is not it needs to be moved to the beginning of the list so
|
||||
* VoiceOver will annouce it correctly. The list returned
|
||||
* from Java is always in order from top to bottom, but when shift
|
||||
* selecting downward (extending the list) or multi-selecting using
|
||||
* the VO keys control+option+command+return the active descendant
|
||||
* is not at the top of the list in the shift select down case and
|
||||
* may not be in the multi select case.
|
||||
*/
|
||||
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
|
||||
if (!childrenAndRoles.isEmpty()) {
|
||||
AccessibleContext activeDescendantAC =
|
||||
CAccessible.getActiveDescendant(a);
|
||||
if (activeDescendantAC != null) {
|
||||
String activeDescendantName =
|
||||
activeDescendantAC.getAccessibleName();
|
||||
AccessibleRole activeDescendantRole =
|
||||
activeDescendantAC.getAccessibleRole();
|
||||
// Move active descendant to front of list.
|
||||
// List contains pairs of each selected item's
|
||||
// Accessible and AccessibleRole.
|
||||
ArrayList<Object> newArray = new ArrayList<Object>();
|
||||
int count = childrenAndRoles.size();
|
||||
Accessible currentAccessible = null;
|
||||
AccessibleContext currentAC = null;
|
||||
String currentName = null;
|
||||
AccessibleRole currentRole = null;
|
||||
for (int i = 0; i < count; i+=2) {
|
||||
// Is this the active descendant?
|
||||
currentAccessible = (Accessible)childrenAndRoles.get(i);
|
||||
currentAC = currentAccessible.getAccessibleContext();
|
||||
currentName = currentAC.getAccessibleName();
|
||||
currentRole = (AccessibleRole)childrenAndRoles.get(i+1);
|
||||
if (currentName != null && currentName.equals(activeDescendantName) &&
|
||||
currentRole.equals(activeDescendantRole) ) {
|
||||
newArray.add(0, currentAccessible);
|
||||
newArray.add(1, currentRole);
|
||||
} else {
|
||||
newArray.add(currentAccessible);
|
||||
newArray.add(currentRole);
|
||||
}
|
||||
}
|
||||
childrenAndRoles = newArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((whichChildren < 0) || (whichChildren * 2 >= childrenAndRoles.size())) {
|
||||
return childrenAndRoles.toArray();
|
||||
}
|
||||
|
||||
return new Object[] { childrenAndRoles.get(whichChildren * 2), childrenAndRoles.get((whichChildren * 2) + 1) };
|
||||
return getChildrenAndRolesImpl(a, c, whichChildren, allowIgnored);
|
||||
}
|
||||
}, c);
|
||||
}
|
||||
|
||||
private static final int JAVA_AX_ROWS = 1;
|
||||
private static final int JAVA_AX_COLS = 2;
|
||||
private static Object[] getChildrenAndRolesImpl(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored) {
|
||||
if (a == null) return null;
|
||||
|
||||
ArrayList<Object> childrenAndRoles = new ArrayList<Object>();
|
||||
_addChildren(a, whichChildren, allowIgnored, childrenAndRoles);
|
||||
|
||||
/* In case of fetching a selection, we need to check if
|
||||
* the active descendant is at the beginning of the list, or
|
||||
* otherwise move it, so that VoiceOver announces it correctly.
|
||||
* The java list is always in order from top to bottom, but when
|
||||
* (1) shift-selecting downward (extending the list) or (2) multi-selecting with
|
||||
* the VO keys (CTRL+ALT+CMD+RETURN) the active descendant
|
||||
* is not at the top of the list in the 1st case and may not be in the 2nd.
|
||||
*/
|
||||
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
|
||||
if (!childrenAndRoles.isEmpty()) {
|
||||
AccessibleContext activeDescendantAC =
|
||||
CAccessible.getActiveDescendant(a);
|
||||
if (activeDescendantAC != null) {
|
||||
String activeDescendantName =
|
||||
activeDescendantAC.getAccessibleName();
|
||||
AccessibleRole activeDescendantRole =
|
||||
activeDescendantAC.getAccessibleRole();
|
||||
// Move active descendant to front of list.
|
||||
// List contains pairs of each selected item's
|
||||
// Accessible and AccessibleRole.
|
||||
ArrayList<Object> newArray = new ArrayList<Object>();
|
||||
int count = childrenAndRoles.size();
|
||||
Accessible currentAccessible = null;
|
||||
AccessibleContext currentAC = null;
|
||||
String currentName = null;
|
||||
AccessibleRole currentRole = null;
|
||||
for (int i = 0; i < count; i += 2) {
|
||||
// Is this the active descendant?
|
||||
currentAccessible = (Accessible) childrenAndRoles.get(i);
|
||||
currentAC = currentAccessible.getAccessibleContext();
|
||||
currentName = currentAC.getAccessibleName();
|
||||
currentRole = (AccessibleRole) childrenAndRoles.get(i + 1);
|
||||
if (currentName != null && currentName.equals(activeDescendantName) &&
|
||||
currentRole.equals(activeDescendantRole)) {
|
||||
newArray.add(0, currentAccessible);
|
||||
newArray.add(1, currentRole);
|
||||
} else {
|
||||
newArray.add(currentAccessible);
|
||||
newArray.add(currentRole);
|
||||
}
|
||||
}
|
||||
childrenAndRoles = newArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((whichChildren < 0) || (whichChildren * 2 >= childrenAndRoles.size())) {
|
||||
return childrenAndRoles.toArray();
|
||||
}
|
||||
|
||||
return new Object[]{childrenAndRoles.get(whichChildren * 2), childrenAndRoles.get((whichChildren * 2) + 1)};
|
||||
}
|
||||
|
||||
// This method is called from the native
|
||||
// Each child takes up three entries in the array: one for itself, one for its role, and one for the recursion level
|
||||
private static Object[] getChildrenAndRolesRecursive(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored, final int level) {
|
||||
if (a == null) return null;
|
||||
return invokeAndWait(new Callable<Object[]>() {
|
||||
public Object[] call() throws Exception {
|
||||
ArrayList<Object> currentLevelChildren = new ArrayList<Object>();
|
||||
ArrayList<Object> allChildren = new ArrayList<Object>();
|
||||
ArrayList<Accessible> parentStack = new ArrayList<Accessible>();
|
||||
parentStack.add(a);
|
||||
ArrayList<Integer> indexses = new ArrayList<Integer>();
|
||||
Integer index = 0;
|
||||
int currentLevel = level;
|
||||
while (!parentStack.isEmpty()) {
|
||||
Accessible p = parentStack.get(parentStack.size() - 1);
|
||||
|
||||
currentLevelChildren.addAll(Arrays.asList(getChildrenAndRolesImpl(p, c, JAVA_AX_ALL_CHILDREN, allowIgnored)));
|
||||
if ((currentLevelChildren.size() == 0) || (index >= currentLevelChildren.size())) {
|
||||
if (!parentStack.isEmpty()) parentStack.remove(parentStack.size() - 1);
|
||||
if (!indexses.isEmpty()) index = indexses.remove(indexses.size() - 1);
|
||||
currentLevel -= 1;
|
||||
currentLevelChildren.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
Accessible ca = null;
|
||||
Object obj = currentLevelChildren.get(index);
|
||||
if (!(obj instanceof Accessible)) {
|
||||
index += 2;
|
||||
currentLevelChildren.clear();
|
||||
continue;
|
||||
}
|
||||
ca = (Accessible) obj;
|
||||
Object role = currentLevelChildren.get(index + 1);
|
||||
currentLevelChildren.clear();
|
||||
|
||||
AccessibleContext cac = ca.getAccessibleContext();
|
||||
if (cac == null) {
|
||||
index += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((cac.getAccessibleStateSet().contains(AccessibleState.SELECTED) && (whichChildren == JAVA_AX_SELECTED_CHILDREN)) ||
|
||||
(cac.getAccessibleStateSet().contains(AccessibleState.VISIBLE) && (whichChildren == JAVA_AX_VISIBLE_CHILDREN)) ||
|
||||
(whichChildren == JAVA_AX_ALL_CHILDREN)) {
|
||||
allChildren.add(ca);
|
||||
allChildren.add(role);
|
||||
allChildren.add(String.valueOf(currentLevel));
|
||||
}
|
||||
|
||||
index += 2;
|
||||
|
||||
if (cac.getAccessibleStateSet().contains(AccessibleState.EXPANDED)) {
|
||||
parentStack.add(ca);
|
||||
indexses.add(index);
|
||||
index = 0;
|
||||
currentLevel += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return allChildren.toArray();
|
||||
}
|
||||
}, c);
|
||||
}
|
||||
|
||||
@Native private static final int JAVA_AX_ROWS = 1;
|
||||
@Native private static final int JAVA_AX_COLS = 2;
|
||||
|
||||
public static int getTableInfo(final Accessible a, final Component c,
|
||||
final int info) {
|
||||
@@ -750,6 +829,23 @@ class CAccessibility implements PropertyChangeListener {
|
||||
}, c);
|
||||
}
|
||||
|
||||
private static int[] getTableSelectedInfo(final Accessible a, final Component c,
|
||||
final int info) {
|
||||
if (a == null) return null;
|
||||
return invokeAndWait(() -> {
|
||||
AccessibleContext ac = a.getAccessibleContext();
|
||||
AccessibleTable table = ac.getAccessibleTable();
|
||||
if (table != null) {
|
||||
if (info == JAVA_AX_COLS) {
|
||||
return table.getSelectedAccessibleColumns();
|
||||
} else if (info == JAVA_AX_ROWS) {
|
||||
return table.getSelectedAccessibleRows();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}, c);
|
||||
}
|
||||
|
||||
private static AccessibleRole getAccessibleRoleForLabel(JLabel l, AccessibleRole fallback) {
|
||||
String text = l.getText();
|
||||
if (text != null && text.length() > 0) {
|
||||
@@ -868,4 +964,18 @@ class CAccessibility implements PropertyChangeListener {
|
||||
}
|
||||
}, (Component)ax);
|
||||
}
|
||||
|
||||
private static boolean isTreeRootVisible(Accessible a, Component c) {
|
||||
if (a == null) return false;
|
||||
|
||||
return invokeAndWait(new Callable<Boolean>() {
|
||||
public Boolean call() throws Exception {
|
||||
Accessible sa = CAccessible.getSwingAccessible(a);
|
||||
if (sa instanceof JTree) {
|
||||
return ((JTree) sa).isRootVisible();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,7 @@ import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.accessibility.Accessible;
|
||||
import javax.accessibility.AccessibleContext;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import static javax.accessibility.AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY;
|
||||
import static javax.accessibility.AccessibleContext.ACCESSIBLE_CARET_PROPERTY;
|
||||
@@ -75,6 +71,8 @@ class CAccessible extends CFRetainedResource implements Accessible {
|
||||
private static native void menuOpened(long ptr);
|
||||
private static native void menuClosed(long ptr);
|
||||
private static native void menuItemSelected(long ptr);
|
||||
private static native void treeNodeExpanded(long ptr);
|
||||
private static native void treeNodeCollapsed(long ptr);
|
||||
|
||||
private Accessible accessible;
|
||||
|
||||
@@ -137,6 +135,13 @@ class CAccessible extends CFRetainedResource implements Accessible {
|
||||
if (parentAccessible != null) {
|
||||
parentRole = parentAccessible.getAccessibleContext().getAccessibleRole();
|
||||
}
|
||||
|
||||
if (newValue == AccessibleState.EXPANDED) {
|
||||
treeNodeExpanded(ptr);
|
||||
} else if (newValue == AccessibleState.COLLAPSED) {
|
||||
treeNodeCollapsed(ptr);
|
||||
}
|
||||
|
||||
// At least for now don't handle combo box menu state changes.
|
||||
// This may change when later fixing issues which currently
|
||||
// exist for combo boxes, but for now the following is only
|
||||
|
||||
@@ -422,15 +422,15 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
|
||||
protected int getInitialStyleBits() {
|
||||
// defaults style bits
|
||||
int styleBits = DECORATED | HAS_SHADOW | CLOSEABLE | MINIMIZABLE | ZOOMABLE | RESIZABLE | TITLE_VISIBLE;
|
||||
int styleBits = DECORATED | HAS_SHADOW | CLOSEABLE | ZOOMABLE | RESIZABLE | TITLE_VISIBLE;
|
||||
|
||||
styleBits |= getFocusableStyleBits();
|
||||
|
||||
final boolean isFrame = (target instanceof Frame);
|
||||
final boolean isDialog = (target instanceof Dialog);
|
||||
final boolean isPopup = (target.getType() == Window.Type.POPUP);
|
||||
if (isDialog) {
|
||||
styleBits = SET(styleBits, MINIMIZABLE, false);
|
||||
if (isFrame) {
|
||||
styleBits = SET(styleBits, MINIMIZABLE, true);
|
||||
}
|
||||
|
||||
// Either java.awt.Frame or java.awt.Dialog can be undecorated, however java.awt.Window always is undecorated.
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
#import "CGLGraphicsConfig.h"
|
||||
#import "AWTView.h"
|
||||
#import "AWTWindow.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
#import "JavaTextAccessibility.h"
|
||||
#import "a11y/CommonComponentAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "GeomUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
@@ -698,42 +697,29 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
- (id)getAxData:(JNIEnv*)env
|
||||
{
|
||||
jobject jcomponent = [self awtComponent:env];
|
||||
id ax = [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease];
|
||||
id ax = [[[CommonComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease];
|
||||
(*env)->DeleteLocalRef(env, jcomponent);
|
||||
return ax;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityAttributeNames
|
||||
{
|
||||
return [[super accessibilityAttributeNames] arrayByAddingObject:NSAccessibilityChildrenAttribute];
|
||||
}
|
||||
|
||||
// NSAccessibility messages
|
||||
// attribute methods
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
- (id)accessibilityChildren
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
(*env)->PushLocalFrame(env, 4);
|
||||
|
||||
(*env)->PushLocalFrame(env, 4);
|
||||
id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]);
|
||||
|
||||
id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]);
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
|
||||
- (BOOL)isAccessibilityElement
|
||||
{
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (id)accessibilityHitTest:(NSPoint)point
|
||||
@@ -743,7 +729,7 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
|
||||
(*env)->PushLocalFrame(env, 4);
|
||||
|
||||
id result = [[self getAxData:env] accessibilityHitTest:point withEnv:env];
|
||||
id result = [[self getAxData:env] accessibilityHitTest:point];
|
||||
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
|
||||
@@ -768,17 +754,24 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
// --- Services menu support for lightweights ---
|
||||
|
||||
// finds the focused accessible element, and if it is a text element, obtains the text from it
|
||||
- (NSString *)accessibleSelectedText
|
||||
- (NSString *)accessibilitySelectedText
|
||||
{
|
||||
id focused = [self accessibilityFocusedUIElement];
|
||||
if (![focused isKindOfClass:[JavaTextAccessibility class]]) return nil;
|
||||
return [(JavaTextAccessibility *)focused accessibilitySelectedTextAttribute];
|
||||
if (![focused respondsToSelector:@selector(accessibilitySelectedText)]) return nil;
|
||||
return [focused accessibilitySelectedText];
|
||||
}
|
||||
|
||||
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText {
|
||||
id focused = [self accessibilityFocusedUIElement];
|
||||
if ([focused respondsToSelector:@selector(setAccessibilitySelectedText:)]) {
|
||||
[focused setAccessibilitySelectedText:accessibilitySelectedText];
|
||||
}
|
||||
}
|
||||
|
||||
// same as above, but converts to RTFD
|
||||
- (NSData *)accessibleSelectedTextAsRTFD
|
||||
{
|
||||
NSString *selectedText = [self accessibleSelectedText];
|
||||
NSString *selectedText = [self accessibilitySelectedText];
|
||||
NSAttributedString *styledText = [[NSAttributedString alloc] initWithString:selectedText];
|
||||
NSData *rtfdData = [styledText RTFDFromRange:NSMakeRange(0, [styledText length])
|
||||
documentAttributes:
|
||||
@@ -791,8 +784,8 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
- (BOOL)replaceAccessibleTextSelection:(NSString *)text
|
||||
{
|
||||
id focused = [self accessibilityFocusedUIElement];
|
||||
if (![focused isKindOfClass:[JavaTextAccessibility class]]) return NO;
|
||||
[(JavaTextAccessibility *)focused accessibilitySetSelectedTextAttribute:text];
|
||||
if (![focused respondsToSelector:@selector(setAccessibilitySelectedText)]) return NO;
|
||||
[focused setAccessibilitySelectedText:text];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -802,7 +795,7 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
if ([[self window] firstResponder] != self) return nil; // let AWT components handle themselves
|
||||
|
||||
if ([sendType isEqual:NSStringPboardType] || [returnType isEqual:NSStringPboardType]) {
|
||||
NSString *selectedText = [self accessibleSelectedText];
|
||||
NSString *selectedText = [self accessibilitySelectedText];
|
||||
if (selectedText) return self;
|
||||
}
|
||||
|
||||
@@ -815,7 +808,7 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
if ([types containsObject:NSStringPboardType])
|
||||
{
|
||||
[pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||
return [pboard setString:[self accessibleSelectedText] forType:NSStringPboardType];
|
||||
return [pboard setString:[self accessibilitySelectedText] forType:NSStringPboardType];
|
||||
}
|
||||
|
||||
if ([types containsObject:NSRTFDPboardType])
|
||||
|
||||
@@ -635,6 +635,7 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
DECLARE_CLASS(jc_CCursorManager, "sun/lwawt/macosx/CCursorManager");
|
||||
DECLARE_STATIC_METHOD(sjm_resetCurrentCursor, jc_CCursorManager, "resetCurrentCursor", "()V");
|
||||
(*env)->CallStaticVoidMethod(env, jc_CCursorManager, sjm_resetCurrentCursor);
|
||||
CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
- (BOOL) canBecomeMainWindow {
|
||||
|
||||
@@ -129,6 +129,7 @@ JNI_COCOA_ENTER(env);
|
||||
JNI_COCOA_ENTER(blockEnv);
|
||||
// call the user's runnable
|
||||
(*blockEnv)->CallVoidMethod(blockEnv, runnableRef, jm_run);
|
||||
CHECK_EXCEPTION_IN_ENV(blockEnv);
|
||||
(*blockEnv)->DeleteGlobalRef(blockEnv, runnableRef);
|
||||
JNI_COCOA_EXIT(blockEnv);
|
||||
});
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <jni.h>
|
||||
|
||||
extern NSMutableDictionary *sActions;
|
||||
extern NSMutableDictionary *sActionSelectors;
|
||||
extern NSMutableArray *sAllActionSelectors;
|
||||
void initializeActions();
|
||||
|
||||
@protocol JavaAccessibilityAction
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
NSMutableDictionary *sActions = nil;
|
||||
NSMutableDictionary *sActionSelectors = nil;
|
||||
NSMutableArray *sAllActionSelectors = nil;
|
||||
void initializeActions();
|
||||
|
||||
@implementation JavaAxAction
|
||||
|
||||
@@ -148,3 +152,31 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void initializeActions() {
|
||||
int actionsCount = 5;
|
||||
|
||||
sActions = [[NSMutableDictionary alloc] initWithCapacity:actionsCount];
|
||||
|
||||
[sActions setObject:NSAccessibilityPressAction forKey:@"click"];
|
||||
[sActions setObject:NSAccessibilityIncrementAction forKey:@"increment"];
|
||||
[sActions setObject:NSAccessibilityDecrementAction forKey:@"decrement"];
|
||||
[sActions setObject:NSAccessibilityShowMenuAction forKey:@"togglePopup"];
|
||||
[sActions setObject:NSAccessibilityPressAction forKey:@"toggleExpand"];
|
||||
|
||||
sActionSelectors = [[NSMutableDictionary alloc] initWithCapacity:actionsCount];
|
||||
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformPress)) forKey:NSAccessibilityPressAction];
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformShowMenu)) forKey:NSAccessibilityShowMenuAction];
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformDecrement)) forKey:NSAccessibilityDecrementAction];
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformIncrement)) forKey:NSAccessibilityIncrementAction];
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformPick)) forKey:NSAccessibilityPickAction];
|
||||
|
||||
sAllActionSelectors = [[NSMutableArray alloc] initWithCapacity:actionsCount];
|
||||
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformPick))];
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformIncrement))];
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformDecrement))];
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformShowMenu))];
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformPress))];
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ BOOL isVertical(JNIEnv *env, jobject axContext, jobject component);
|
||||
BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component);
|
||||
BOOL isShowing(JNIEnv *env, jobject axContext, jobject component);
|
||||
BOOL isSelectable(JNIEnv *env, jobject axContext, jobject component);
|
||||
BOOL isExpanded(JNIEnv *env, jobject axContext, jobject component);
|
||||
NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component);
|
||||
jint getAxTextCharCount(JNIEnv *env, jobject axText, jobject component);
|
||||
|
||||
@@ -60,3 +61,6 @@ void JavaAccessibilitySetAttributeValue(id element, NSString *attribute, id valu
|
||||
void JavaAccessibilityRaiseSetAttributeToIllegalTypeException(const char *functionName, id element, NSString *attribute, id value);
|
||||
void JavaAccessibilityRaiseUnimplementedAttributeException(const char *functionName, id element, NSString *attribute);
|
||||
void JavaAccessibilityRaiseIllegalParameterTypeException(const char *functionName, id element, NSString *attribute, id parameter);
|
||||
BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
NSNumber* JavaNumberToNSNumber(JNIEnv *env, jobject jnumber);
|
||||
NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
static BOOL JavaAccessibilityIsSupportedAttribute(id element, NSString *attribute);
|
||||
static void JavaAccessibilityLogError(NSString *message);
|
||||
@@ -199,6 +200,20 @@ BOOL isSelectable(JNIEnv *env, jobject axContext, jobject component)
|
||||
return selectable;
|
||||
}
|
||||
|
||||
BOOL isExpanded(JNIEnv *env, jobject axContext, jobject component)
|
||||
{
|
||||
GET_ACCESSIBLESTATE_CLASS_RETURN(NO);
|
||||
DECLARE_STATIC_FIELD_RETURN(jm_EXPANDED,
|
||||
sjc_AccessibleState,
|
||||
"EXPANDED",
|
||||
"Ljavax/accessibility/AccessibleState;", NO );
|
||||
jobject axExpandedState = (*env)->GetStaticObjectField(env, sjc_AccessibleState, jm_EXPANDED);
|
||||
CHECK_EXCEPTION_NULL_RETURN(axExpandedState, NO);
|
||||
BOOL expanded = containsAxState(env, axContext, axExpandedState, component);
|
||||
(*env)->DeleteLocalRef(env, axExpandedState);
|
||||
return expanded;
|
||||
}
|
||||
|
||||
NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)
|
||||
{
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(NSZeroPoint);
|
||||
@@ -348,6 +363,75 @@ static void JavaAccessibilityLogError(NSString *message)
|
||||
NSLog(@"!!! %@", message);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns Object.equals for the two items
|
||||
* This may use LWCToolkit.invokeAndWait(); don't call while holding fLock
|
||||
* and try to pass a component so the event happens on the correct thread.
|
||||
*/
|
||||
BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component)
|
||||
{
|
||||
DECLARE_CLASS_RETURN(sjc_Object, "java/lang/Object", NO);
|
||||
DECLARE_METHOD_RETURN(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z", NO);
|
||||
|
||||
if ((a == NULL) && (b == NULL)) return YES;
|
||||
if ((a == NULL) || (b == NULL)) return NO;
|
||||
|
||||
if (pthread_main_np() != 0) {
|
||||
// If we are on the AppKit thread
|
||||
DECLARE_CLASS_RETURN(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit", NO);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_doEquals, sjc_LWCToolkit, "doEquals",
|
||||
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z", NO);
|
||||
return (*env)->CallStaticBooleanMethod(env, sjc_LWCToolkit, jm_doEquals, a, b, component);
|
||||
CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
jboolean jb = (*env)->CallBooleanMethod(env, a, jm_equals, b);
|
||||
CHECK_EXCEPTION();
|
||||
return jb;
|
||||
}
|
||||
|
||||
/*
|
||||
* The java/lang/Number concrete class could be for any of the Java primitive
|
||||
* numerical types or some other subclass.
|
||||
* All existing A11Y code uses Integer so that is what we look for first
|
||||
* But all must be able to return a double and NSNumber accepts a double,
|
||||
* so that's the fall back.
|
||||
*/
|
||||
NSNumber* JavaNumberToNSNumber(JNIEnv *env, jobject jnumber) {
|
||||
if (jnumber == NULL) {
|
||||
return nil;
|
||||
}
|
||||
DECLARE_CLASS_RETURN(jnumber_Class, "java/lang/Number", nil);
|
||||
DECLARE_CLASS_RETURN(jinteger_Class, "java/lang/Integer", nil);
|
||||
DECLARE_METHOD_RETURN(jm_intValue, jnumber_Class, "intValue", "()I", nil);
|
||||
DECLARE_METHOD_RETURN(jm_doubleValue, jnumber_Class, "doubleValue", "()D", nil);
|
||||
if ((*env)->IsInstanceOf(env, jnumber, jinteger_Class)) {
|
||||
jint i = (*env)->CallIntMethod(env, jnumber, jm_intValue);
|
||||
CHECK_EXCEPTION();
|
||||
return [NSNumber numberWithInteger:i];
|
||||
} else {
|
||||
jdouble d = (*env)->CallDoubleMethod(env, jnumber, jm_doubleValue);
|
||||
CHECK_EXCEPTION();
|
||||
return [NSNumber numberWithDouble:d];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts an int array to an NSRange wrapped inside an NSValue
|
||||
* takes [start, end] values and returns [start, end - start]
|
||||
*/
|
||||
NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
|
||||
jint *values = (*env)->GetIntArrayElements(env, array, 0);
|
||||
if (values == NULL) {
|
||||
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
|
||||
NSLog(@"%s failed calling GetIntArrayElements", __FUNCTION__);
|
||||
return nil;
|
||||
};
|
||||
NSValue *value = [NSValue valueWithRange:NSMakeRange(values[0], values[1] - values[0])];
|
||||
(*env)->ReleaseIntArrayElements(env, array, values, 0);
|
||||
return value;
|
||||
}
|
||||
|
||||
// end appKit copies
|
||||
|
||||
/*
|
||||
@@ -417,13 +501,13 @@ void initializeRoles()
|
||||
[sRoles setObject:NSAccessibilitySplitGroupRole forKey:@"splitpane"];
|
||||
[sRoles setObject:NSAccessibilityValueIndicatorRole forKey:@"statusbar"];
|
||||
[sRoles setObject:NSAccessibilityGroupRole forKey:@"swingcomponent"];
|
||||
[sRoles setObject:NSAccessibilityGridRole forKey:@"table"];
|
||||
[sRoles setObject:NSAccessibilityTableRole forKey:@"table"];
|
||||
[sRoles setObject:NSAccessibilityTextFieldRole forKey:@"text"];
|
||||
[sRoles setObject:NSAccessibilityTextAreaRole forKey:@"textarea"]; // supports top/bottom of document notifications: CAccessability.getAccessibleRole()
|
||||
[sRoles setObject:NSAccessibilityCheckBoxRole forKey:@"togglebutton"];
|
||||
[sRoles setObject:NSAccessibilityToolbarRole forKey:@"toolbar"];
|
||||
[sRoles setObject:JavaAccessibilityIgnore forKey:@"tooltip"];
|
||||
[sRoles setObject:NSAccessibilityBrowserRole forKey:@"tree"];
|
||||
[sRoles setObject:NSAccessibilityOutlineRole forKey:@"tree"];
|
||||
[sRoles setObject:NSAccessibilityUnknownRole forKey:@"unknown"];
|
||||
[sRoles setObject:JavaAccessibilityIgnore forKey:@"viewport"];
|
||||
[sRoles setObject:JavaAccessibilityIgnore forKey:@"window"];
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
// <https://www.ibm.com/able/guidelines/java/snsjavagjfc.html>
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
#import "a11y/CommonComponentAccessibility.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
@@ -45,6 +44,12 @@
|
||||
#import "JNIUtilities.h"
|
||||
#import "AWTView.h"
|
||||
|
||||
// these constants are duplicated in CAccessibility.java
|
||||
#define JAVA_AX_ALL_CHILDREN (-1)
|
||||
#define JAVA_AX_SELECTED_CHILDREN (-2)
|
||||
#define JAVA_AX_VISIBLE_CHILDREN (-3)
|
||||
// If the value is >=0, it's an index
|
||||
|
||||
// GET* macros defined in JavaAccessibilityUtilities.h, so they can be shared.
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
@@ -82,7 +87,7 @@ static jclass sjc_CAccessible = NULL;
|
||||
static NSMutableDictionary *sAttributeNamesForRoleCache = nil;
|
||||
static NSObject *sAttributeNamesLOCK = nil;
|
||||
|
||||
@interface TabGroupAccessibility : JavaComponentAccessibility {
|
||||
@interface TabGroupLegacyAccessibility : JavaComponentAccessibility {
|
||||
NSInteger _numTabs;
|
||||
}
|
||||
|
||||
@@ -112,7 +117,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
- (id)accessibilityValueAttribute;
|
||||
@end
|
||||
|
||||
@interface TableAccessibility : JavaComponentAccessibility {
|
||||
@interface TableLegacyAccessibility : JavaComponentAccessibility {
|
||||
|
||||
}
|
||||
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
|
||||
@@ -362,21 +367,18 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
|
||||
// otherwise, create a new instance
|
||||
JavaComponentAccessibility *newChild = nil;
|
||||
newChild = [CommonComponentAccessibility getComponentAccessibility:javaRole];
|
||||
if (newChild == nil) {
|
||||
if ([javaRole isEqualToString:@"pagetablist"]) {
|
||||
newChild = [TabGroupAccessibility alloc];
|
||||
} else if ([javaRole isEqualToString:@"table"]) {
|
||||
newChild = [TableAccessibility alloc];
|
||||
if ([javaRole isEqualToString:@"pagetablist"]) {
|
||||
newChild = [TabGroupLegacyAccessibility alloc];
|
||||
} else if ([javaRole isEqualToString:@"table"]) {
|
||||
newChild = [TableLegacyAccessibility alloc];
|
||||
} else {
|
||||
NSString *nsRole = [sRoles objectForKey:javaRole];
|
||||
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole] ||
|
||||
[nsRole isEqualToString:NSAccessibilityTextAreaRole] ||
|
||||
[nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
|
||||
newChild = [JavaTextAccessibility alloc];
|
||||
} else {
|
||||
NSString *nsRole = [sRoles objectForKey:javaRole];
|
||||
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole] ||
|
||||
[nsRole isEqualToString:NSAccessibilityTextAreaRole] ||
|
||||
[nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
|
||||
newChild = [JavaTextAccessibility alloc];
|
||||
} else {
|
||||
newChild = [JavaComponentAccessibility alloc];
|
||||
}
|
||||
newChild = [JavaComponentAccessibility alloc];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,7 +389,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
// This is the only way to know if the menu is opening; visible state change
|
||||
// can't be caught because the listeners are not set up in time.
|
||||
if ( [javaRole isEqualToString:@"popupmenu"] &&
|
||||
![[parent javaRole] isEqualToString:@"combobox"] ) {
|
||||
![[parent javaRole] isEqualToString:@"combobox"] ) {
|
||||
[newChild postMenuOpened];
|
||||
}
|
||||
|
||||
@@ -904,32 +906,6 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* The java/lang/Number concrete class could be for any of the Java primitive
|
||||
* numerical types or some other subclass.
|
||||
* All existing A11Y code uses Integer so that is what we look for first
|
||||
* But all must be able to return a double and NSNumber accepts a double,
|
||||
* so that's the fall back.
|
||||
*/
|
||||
static NSNumber* JavaNumberToNSNumber(JNIEnv *env, jobject jnumber) {
|
||||
if (jnumber == NULL) {
|
||||
return nil;
|
||||
}
|
||||
DECLARE_CLASS_RETURN(jnumber_Class, "java/lang/Number", nil);
|
||||
DECLARE_CLASS_RETURN(jinteger_Class, "java/lang/Integer", nil);
|
||||
DECLARE_METHOD_RETURN(jm_intValue, jnumber_Class, "intValue", "()I", nil);
|
||||
DECLARE_METHOD_RETURN(jm_doubleValue, jnumber_Class, "doubleValue", "()D", nil);
|
||||
if ((*env)->IsInstanceOf(env, jnumber, jinteger_Class)) {
|
||||
jint i = (*env)->CallIntMethod(env, jnumber, jm_intValue);
|
||||
CHECK_EXCEPTION();
|
||||
return [NSNumber numberWithInteger:i];
|
||||
} else {
|
||||
jdouble d = (*env)->CallDoubleMethod(env, jnumber, jm_doubleValue);
|
||||
CHECK_EXCEPTION();
|
||||
return [NSNumber numberWithDouble:d];
|
||||
}
|
||||
}
|
||||
|
||||
// Element's maximum value (id)
|
||||
- (id)accessibilityMaxValueAttribute
|
||||
{
|
||||
@@ -1600,7 +1576,7 @@ JNI_COCOA_ENTER(env);
|
||||
JNI_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
@implementation TabGroupAccessibility
|
||||
@implementation TabGroupLegacyAccessibility
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
{
|
||||
@@ -1802,9 +1778,6 @@ JNI_COCOA_EXIT(env);
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
|
||||
@implementation TabGroupControlAccessibility
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
@@ -1873,7 +1846,7 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
#define JAVA_AX_ROWS (1)
|
||||
#define JAVA_AX_COLS (2)
|
||||
|
||||
@implementation TableAccessibility
|
||||
@implementation TableLegacyAccessibility
|
||||
|
||||
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
|
||||
{
|
||||
@@ -1907,30 +1880,3 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
return [self getTableInfo:JAVA_AX_COLS];
|
||||
}
|
||||
@end
|
||||
|
||||
/*
|
||||
* Returns Object.equals for the two items
|
||||
* This may use LWCToolkit.invokeAndWait(); don't call while holding fLock
|
||||
* and try to pass a component so the event happens on the correct thread.
|
||||
*/
|
||||
static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component)
|
||||
{
|
||||
DECLARE_CLASS_RETURN(sjc_Object, "java/lang/Object", NO);
|
||||
DECLARE_METHOD_RETURN(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z", NO);
|
||||
|
||||
if ((a == NULL) && (b == NULL)) return YES;
|
||||
if ((a == NULL) || (b == NULL)) return NO;
|
||||
|
||||
if (pthread_main_np() != 0) {
|
||||
// If we are on the AppKit thread
|
||||
DECLARE_CLASS_RETURN(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit", NO);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_doEquals, sjc_LWCToolkit, "doEquals",
|
||||
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z", NO);
|
||||
return (*env)->CallStaticBooleanMethod(env, sjc_LWCToolkit, jm_doEquals, a, b, component);
|
||||
CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
jboolean jb = (*env)->CallBooleanMethod(env, a, jm_equals, b);
|
||||
CHECK_EXCEPTION();
|
||||
return jb;
|
||||
}
|
||||
|
||||
@@ -53,23 +53,6 @@ static jmethodID sjm_getAccessibleEditableText = NULL;
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;", ret);
|
||||
|
||||
|
||||
/*
|
||||
* Converts an int array to an NSRange wrapped inside an NSValue
|
||||
* takes [start, end] values and returns [start, end - start]
|
||||
*/
|
||||
NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
|
||||
jint *values = (*env)->GetIntArrayElements(env, array, 0);
|
||||
if (values == NULL) {
|
||||
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
|
||||
NSLog(@"%s failed calling GetIntArrayElements", __FUNCTION__);
|
||||
return nil;
|
||||
};
|
||||
NSValue *value = [NSValue valueWithRange:NSMakeRange(values[0], values[1] - values[0])];
|
||||
(*env)->ReleaseIntArrayElements(env, array, values, 0);
|
||||
return value;
|
||||
}
|
||||
|
||||
@implementation JavaTextAccessibility
|
||||
|
||||
// based strongly upon NSTextViewAccessibility:accessibilityAttributeNames
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
- (NSString * _Nullable)accessibilityLabel
|
||||
{
|
||||
return [self accessibilityTitleAttribute];
|
||||
return [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformPress
|
||||
@@ -44,4 +44,14 @@
|
||||
return [self performAccessibleAction:0];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface CellAccessibility : CommonComponentAccessibility
|
||||
@end
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CellAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "TableAccessibility.h"
|
||||
|
||||
@implementation CellAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityCellRole;;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
NSString *javaRole = [self javaRole];
|
||||
CommonComponentAccessibility *newChild = [CommonComponentAccessibility createWithParent:self
|
||||
accessible:self->fAccessible
|
||||
role:javaRole
|
||||
index:self->fIndex
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withView:self->fView
|
||||
isWrapped:NO];
|
||||
return [NSArray arrayWithObject:newChild];
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRowIndexRange {
|
||||
NSInteger location = -1;
|
||||
if ([[(CommonComponentAccessibility *)fParent accessibilityParent] isKindOfClass:[TableAccessibility class]]) {
|
||||
TableAccessibility *table = [(CommonComponentAccessibility *)fParent accessibilityParent];
|
||||
location = [table accessibleRowAtIndex:fIndex];
|
||||
}
|
||||
|
||||
return NSMakeRange(location, 1);
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityColumnIndexRange {
|
||||
NSInteger location = -1;
|
||||
if ([[(CommonComponentAccessibility *)fParent accessibilityParent] isKindOfClass:[TableAccessibility class]]) {
|
||||
TableAccessibility *table = [(CommonComponentAccessibility *)fParent accessibilityParent];
|
||||
location = [table accessibleColumnAtIndex:fIndex];
|
||||
}
|
||||
|
||||
return NSMakeRange(location, 1);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -39,7 +39,7 @@
|
||||
- (id _Nonnull) accessibilityValue
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
return [self accessibilityValueAttribute];
|
||||
return [super accessibilityValue];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface ColumnAccessibility : CommonComponentAccessibility
|
||||
|
||||
@property(readonly) NSUInteger columnNumberInTable;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "CellAccessibility.h"
|
||||
#import "ColumnAccessibility.h"
|
||||
#import "TableAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID jm_getChildrenAndRoles = NULL;
|
||||
#define GET_CHILDRENANDROLES_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles",\
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;", ret);
|
||||
|
||||
@implementation ColumnAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityColumnRole;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
CommonComponentAccessibility *parent = [self accessibilityParent];
|
||||
if (parent->fAccessible == NULL) return nil;
|
||||
GET_CHILDRENANDROLES_METHOD_RETURN(nil);
|
||||
jobjectArray jchildrenAndRoles = (jobjectArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getChildrenAndRoles,
|
||||
parent->fAccessible, parent->fComponent, sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN, NO);
|
||||
CHECK_EXCEPTION();
|
||||
if (jchildrenAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
|
||||
NSMutableArray *childrenCells = [NSMutableArray arrayWithCapacity:arrayLen/2];
|
||||
|
||||
NSUInteger childIndex = fIndex;
|
||||
|
||||
int inc = [(TableAccessibility *)[self accessibilityParent] accessibilityRowCount] * 2;
|
||||
NSInteger i = childIndex * 2;
|
||||
for(i; i < arrayLen; i += inc)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
NSString *childJavaRole = nil;
|
||||
if (jchildJavaRole != NULL) {
|
||||
DECLARE_CLASS_RETURN(sjc_AccessibleRole, "javax/accessibility/AccessibleRole", nil);
|
||||
DECLARE_FIELD_RETURN(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;", nil);
|
||||
jobject jkey = (*env)->GetObjectField(env, jchildJavaRole, sjf_key);
|
||||
CHECK_EXCEPTION();
|
||||
childJavaRole = JavaStringToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
}
|
||||
|
||||
CellAccessibility *child = [[CellAccessibility alloc] initWithParent:self
|
||||
withEnv:env
|
||||
withAccessible:jchild
|
||||
withIndex:childIndex
|
||||
withView:self->fView
|
||||
withJavaRole:childJavaRole];
|
||||
[childrenCells addObject:[[child retain] autorelease]];
|
||||
|
||||
(*env)->DeleteLocalRef(env, jchild);
|
||||
(*env)->DeleteLocalRef(env, jchildJavaRole);
|
||||
|
||||
childIndex += (inc / 2);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
|
||||
return childrenCells;
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex
|
||||
{
|
||||
return fIndex;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface ComboBoxAccessibility : CommonComponentAccessibility
|
||||
@end
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "ComboBoxAccessibility.h"
|
||||
#import "../JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID sjm_getAccessibleName = NULL;
|
||||
#define GET_ACCESSIBLENAME_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", ret);
|
||||
|
||||
@implementation ComboBoxAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (id)accessibilityValue {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
if (axContext == NULL) return nil;
|
||||
jclass axContextClass = (*env)->GetObjectClass(env, axContext);
|
||||
DECLARE_METHOD_RETURN(jm_getAccessibleSelection, axContextClass, "getAccessibleSelection", "(I)Ljavax/accessibility/Accessible;", nil);
|
||||
jobject axSelectedChild = (*env)->CallObjectMethod(env, axContext, jm_getAccessibleSelection, 0);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
if (axSelectedChild == NULL) {
|
||||
return nil;
|
||||
}
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(nil);
|
||||
GET_ACCESSIBLENAME_METHOD_RETURN(nil);
|
||||
jobject childName = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, sjm_getAccessibleName, axSelectedChild, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (childName == NULL) {
|
||||
(*env)->DeleteLocalRef(env, axSelectedChild);
|
||||
return nil;
|
||||
}
|
||||
NSString *selectedText = JavaStringToNSString(env, childName);
|
||||
(*env)->DeleteLocalRef(env, axSelectedChild);
|
||||
(*env)->DeleteLocalRef(env, childName);
|
||||
return selectedText;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -26,23 +26,83 @@
|
||||
#ifndef JAVA_COMPONENT_ACCESSIBILITY
|
||||
#define JAVA_COMPONENT_ACCESSIBILITY
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
#include "jni.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
|
||||
// these constants are duplicated in CAccessibility.java
|
||||
#define JAVA_AX_ALL_CHILDREN (-1)
|
||||
#define JAVA_AX_SELECTED_CHILDREN (-2)
|
||||
#define JAVA_AX_VISIBLE_CHILDREN (-3)
|
||||
// If the value is >=0, it's an index
|
||||
@interface CommonComponentAccessibility : NSAccessibilityElement {
|
||||
NSView *fView;
|
||||
NSObject *fParent;
|
||||
|
||||
@interface CommonComponentAccessibility : JavaComponentAccessibility <NSAccessibilityElement> {
|
||||
NSString *fNSRole;
|
||||
NSString *fJavaRole;
|
||||
|
||||
jint fIndex;
|
||||
jobject fAccessible;
|
||||
jobject fComponent;
|
||||
|
||||
NSMutableDictionary *fActions;
|
||||
NSMutableArray *fActionSelectors;
|
||||
NSObject *fActionsLOCK;
|
||||
}
|
||||
|
||||
@property(nonnull, readonly) NSArray *actionSelectors;
|
||||
|
||||
- (id _Nonnull)initWithParent:(NSObject* _Nonnull)parent withEnv:(JNIEnv _Nonnull * _Nonnull)env withAccessible:(jobject _Nullable)accessible withIndex:(jint)index withView:(NSView* _Nonnull)view withJavaRole:(NSString* _Nullable)javaRole;
|
||||
- (void)unregisterFromCocoaAXSystem;
|
||||
- (void)postValueChanged;
|
||||
- (void)postSelectedTextChanged;
|
||||
- (void)postSelectionChanged;
|
||||
- (void)postTitleChanged;
|
||||
- (void)postTreeNodeExpanded;
|
||||
- (void)postTreeNodeCollapsed;
|
||||
- (BOOL)isEqual:(nonnull id)anObject;
|
||||
- (BOOL)isAccessibleWithEnv:(JNIEnv _Nonnull * _Nonnull)env forAccessible:(nonnull jobject)accessible;
|
||||
|
||||
+ (void)postFocusChanged:(nullable id)message;
|
||||
|
||||
+ (void) initializeRolesMap;
|
||||
+ (JavaComponentAccessibility * _Nullable) getComponentAccessibility:(NSString * _Nonnull)role;
|
||||
|
||||
+ (CommonComponentAccessibility* _Nullable) getComponentAccessibility:(NSString* _Nonnull)role;
|
||||
+ (CommonComponentAccessibility * _Nullable) getComponentAccessibility:(NSString * _Nonnull)role andParent:(CommonComponentAccessibility * _Nonnull)parent;
|
||||
|
||||
+ (NSArray* _Nullable)childrenOfParent:(CommonComponentAccessibility* _Nonnull)parent withEnv:(JNIEnv _Nonnull * _Nonnull)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored;
|
||||
+ (NSArray* _Nullable)childrenOfParent:(CommonComponentAccessibility* _Nonnull)parent withEnv:(JNIEnv _Nonnull * _Nonnull)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored recursive:(BOOL)recursive;
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithParent:(CommonComponentAccessibility* _Nullable)parent accessible:(jobject _Nonnull)jaccessible role:(NSString* _Nonnull)javaRole index:(jint)index withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view;
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithAccessible:(jobject _Nonnull)jaccessible role:(NSString* _Nonnull)role index:(jint)index withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view;
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithAccessible:(jobject _Nonnull)jaccessible withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view;
|
||||
|
||||
// If the isWraped parameter is true, then the object passed as a parent was created based on the same java component,
|
||||
// but performs a different NSAccessibilityRole of a table cell, or a list row, or tree row,
|
||||
// and we need to create an element whose role corresponds to the role in Java.
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithParent:(CommonComponentAccessibility* _Nullable)parent accessible:(jobject _Nonnull)jaccessible role:(NSString* _Nonnull)javaRole index:(jint)index withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view isWrapped:(BOOL)wrapped;
|
||||
|
||||
// The current parameter is used to bypass the check for an item's index on the parent so that the item is created. This is necessary,
|
||||
// for example, for AccessibleJTreeNode, whose currentComponent has index -1
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithAccessible:(jobject _Nonnull)jaccessible withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view isCurrent:(BOOL)current;
|
||||
|
||||
- (jobject _Nullable)axContextWithEnv:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (NSView* _Nonnull)view;
|
||||
- (NSWindow* _Nonnull)window;
|
||||
- (id _Nonnull)parent;
|
||||
- (NSString* _Nonnull)javaRole;
|
||||
|
||||
- (BOOL)isMenu;
|
||||
- (BOOL)isSelected:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (BOOL)isSelectable:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (BOOL)isVisible:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
|
||||
- (NSArray* _Nullable)accessibleChildrenWithChildCode:(NSInteger)childCode;
|
||||
|
||||
- (NSDictionary* _Nullable)getActions:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (void)getActionsWithEnv:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (BOOL)accessiblePerformAction:(NSAccessibilityActionName _Nonnull)actionName;
|
||||
|
||||
- (BOOL)performAccessibleAction:(int)index;
|
||||
|
||||
- (NSRect)accessibilityFrame;
|
||||
- (id _Nullable)accessibilityParent;
|
||||
- (BOOL)performAccessibleAction:(int)index;
|
||||
- (BOOL)isAccessibilityElement;
|
||||
@end
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,7 +70,7 @@ static NSRange javaIntArrayToNSRange(JNIEnv* env, jintArray array) {
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", nil);
|
||||
if ([[self accessibilityRoleAttribute] isEqualToString:NSAccessibilityStaticTextRole]) {
|
||||
if ([[self accessibilityRole] isEqualToString:NSAccessibilityStaticTextRole]) {
|
||||
jobject axName = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility,
|
||||
sjm_getAccessibleName, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#import "GroupAccessibility.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
/*
|
||||
* This is the protocol for the components that contain children.
|
||||
* Basic logic of accessibilityChildren might be overridden in the specific implementing
|
||||
@@ -43,9 +44,9 @@
|
||||
- (NSArray *)accessibilityChildren {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self
|
||||
NSArray *children = [CommonComponentAccessibility childrenOfParent:self
|
||||
withEnv:env
|
||||
withChildrenCode:JAVA_AX_ALL_CHILDREN
|
||||
withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN
|
||||
allowIgnored:NO];
|
||||
|
||||
if ([children count] == 0) {
|
||||
@@ -55,4 +56,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -36,7 +36,17 @@
|
||||
|
||||
- (NSString * _Nullable)accessibilityLabel
|
||||
{
|
||||
return [self accessibilityTitleAttribute];
|
||||
return [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface ListAccessibility : CommonComponentAccessibility <NSAccessibilityList>
|
||||
@end
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "ListAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
@implementation ListAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityRows
|
||||
{
|
||||
return [self accessibilityChildren];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedRows
|
||||
{
|
||||
return [self accessibilitySelectedChildren];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
return [super accessibilityLabel] == NULL ? @"list" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
// to avoid warning (why?): method in protocol 'NSAccessibilityElement' not implemented
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
// to avoid warning (why?): method in protocol 'NSAccessibilityElement' not implemented
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface ListRowAccessibility : CommonComponentAccessibility <NSAccessibilityRow>
|
||||
@end
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#import "ListRowAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ListAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
@implementation ListRowAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityRowRole;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
|
||||
// Since the row element has already been created, we should no create it again, but just retrieve it by a pointer, that's why isWrapped is set to YES.
|
||||
CommonComponentAccessibility *newChild = [CommonComponentAccessibility createWithParent:self
|
||||
accessible:self->fAccessible
|
||||
role:self->fJavaRole
|
||||
index:self->fIndex
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withView:self->fView
|
||||
isWrapped:YES];
|
||||
return [NSArray arrayWithObject:newChild];
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex
|
||||
{
|
||||
return [[self accessibilityParent] accessibilityIndexOfChild:self];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface NavigableTextAccessibility : CommonComponentAccessibility <NSAccessibilityNavigableStaticText>
|
||||
|
||||
@property(readonly) BOOL accessibleIsPasswordText;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "NavigableTextAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
#define GET_CACCESSIBLITY_CLASS() \
|
||||
GET_CLASS(sjc_CAccessibility, "sun/lwawt/macosx/CAccessibility");
|
||||
#define GET_CACCESSIBLITY_CLASS_RETURN(ret) \
|
||||
GET_CLASS_RETURN(sjc_CAccessibility, "sun/lwawt/macosx/CAccessibility", ret);
|
||||
|
||||
static jmethodID sjm_getAccessibleText = NULL;
|
||||
#define GET_ACCESSIBLETEXT_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBLITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleText, sjc_CAccessibility, "getAccessibleText", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleText;", ret);
|
||||
|
||||
static jclass sjc_CAccessibleText = NULL;
|
||||
#define GET_CACCESSIBLETEXT_CLASS() \
|
||||
GET_CLASS(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText");
|
||||
#define GET_CACCESSIBLETEXT_CLASS_RETURN(ret) \
|
||||
GET_CLASS_RETURN(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText", ret);
|
||||
|
||||
static jmethodID sjm_getAccessibleEditableText = NULL;
|
||||
#define GET_ACCESSIBLEEDITABLETEXT_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;", ret);
|
||||
|
||||
|
||||
@implementation NavigableTextAccessibility
|
||||
|
||||
- (BOOL)accessibleIsPasswordText {
|
||||
return [fJavaRole isEqualToString:@"passwordtext"];
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSRect)accessibilityFrameForRange:(NSRange)range
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSMakeRect(0, 0, 0, 0));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D", NSMakeRect(0, 0, 0, 0));
|
||||
jdoubleArray axBounds = (jdoubleArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getBoundsForRange,
|
||||
fAccessible, fComponent, range.location, range.length);
|
||||
CHECK_EXCEPTION();
|
||||
if (axBounds == NULL) return NSMakeRect(0, 0, 0, 0);
|
||||
|
||||
// We cheat because we know that the array is 4 elements long (x, y, width, height)
|
||||
jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0);
|
||||
CHECK_EXCEPTION();
|
||||
|
||||
NSRect bounds;
|
||||
bounds.origin.x = values[0];
|
||||
bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping
|
||||
bounds.size.width = values[2];
|
||||
bounds.size.height = values[3];
|
||||
(*env)->ReleaseDoubleArrayElements(env, axBounds, values, 0);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityLineForIndex:(NSInteger)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(-1);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I", -1);
|
||||
jint row = (*env)->CallStaticIntMethod(env, sjc_CAccessibleText, jm_getLineNumberForIndex,
|
||||
fAccessible, fComponent, index);
|
||||
CHECK_EXCEPTION();
|
||||
if (row < 0) return -1;
|
||||
return row;
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRangeForLine:(NSInteger)line
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSRangeFromString(@""));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I", NSRangeFromString(@""));
|
||||
jintArray axTextRange = (jintArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibleText,
|
||||
jm_getRangeForLine, fAccessible, fComponent, line);
|
||||
CHECK_EXCEPTION();
|
||||
if (axTextRange == NULL) return NSRangeFromString(@"");
|
||||
|
||||
NSRange range = [javaIntArrayToNSRangeValue(env,axTextRange) rangeValue];
|
||||
(*env)->DeleteLocalRef(env, axTextRange);
|
||||
return range;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityStringForRange:(NSRange)range
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;", nil);
|
||||
jstring jstringForRange = (jstring)(*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getStringForRange,
|
||||
fAccessible, fComponent, range.location, range.length);
|
||||
CHECK_EXCEPTION();
|
||||
if (jstringForRange == NULL) return @"";
|
||||
NSString* str = JavaStringToNSString(env, jstringForRange);
|
||||
(*env)->DeleteLocalRef(env, jstringForRange);
|
||||
return str;
|
||||
}
|
||||
|
||||
- (id)accessibilityValue
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLITY_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", nil);
|
||||
// cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
|
||||
GET_ACCESSIBLETEXT_METHOD_RETURN(@"");
|
||||
jobject axText = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility,
|
||||
sjm_getAccessibleText, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (axText == NULL) return nil;
|
||||
(*env)->DeleteLocalRef(env, axText);
|
||||
|
||||
GET_ACCESSIBLEEDITABLETEXT_METHOD_RETURN(nil);
|
||||
jobject axEditableText = (*env)->CallStaticObjectMethod(env, sjc_CAccessibleText,
|
||||
sjm_getAccessibleEditableText, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (axEditableText == NULL) return nil;
|
||||
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getTextRange, sjc_CAccessibleText, "getTextRange",
|
||||
"(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;", nil);
|
||||
jobject jrange = (*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getTextRange,
|
||||
axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
NSString *string = JavaStringToNSString(env, jrange);
|
||||
|
||||
(*env)->DeleteLocalRef(env, jrange);
|
||||
(*env)->DeleteLocalRef(env, axEditableText);
|
||||
|
||||
if (string == nil) string = @"";
|
||||
return string;
|
||||
}
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole {
|
||||
if ([self accessibleIsPasswordText]) {
|
||||
return NSAccessibilitySecureTextFieldSubrole;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRangeForIndex:(NSInteger)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSRangeFromString(@""));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I", NSRangeFromString(@""));
|
||||
jintArray axTextRange = (jintArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getRangeForIndex,
|
||||
fAccessible, fComponent, index);
|
||||
CHECK_EXCEPTION();
|
||||
if (axTextRange == NULL) return NSRangeFromString(@"");
|
||||
|
||||
return [javaIntArrayToNSRangeValue(env, axTextRange) rangeValue];
|
||||
}
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole {
|
||||
return [sRoles objectForKey:self.javaRole];
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRangeForPosition:(NSPoint)point
|
||||
{
|
||||
point.y = [[[[self view] window] screen] frame].size.height - point.y; // flip into java screen coords (0 is at upper-left corner of screen)
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSRangeFromString(@""));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getCharacterIndexAtPosition, sjc_CAccessibleText, "getCharacterIndexAtPosition",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)I", NSRangeFromString(@""));
|
||||
jint charIndex = (*env)->CallStaticIntMethod(env, sjc_CAccessibleText, jm_getCharacterIndexAtPosition,
|
||||
fAccessible, fComponent, point.x, point.y);
|
||||
CHECK_EXCEPTION();
|
||||
if (charIndex == -1) return NSRangeFromString(@"");
|
||||
|
||||
// AccessibleText.getIndexAtPoint returns -1 for an invalid point
|
||||
NSRange range = NSMakeRange(charIndex, 1); //range's length is 1 - one-character range
|
||||
return range;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilitySelectedText
|
||||
{
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", nil);
|
||||
jobject axText = (*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getSelectedText,
|
||||
fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (axText == NULL) return @"";
|
||||
NSString* str = JavaStringToNSString(env, axText);
|
||||
(*env)->DeleteLocalRef(env, axText);
|
||||
return str;
|
||||
}
|
||||
|
||||
- (NSRange)accessibilitySelectedTextRange
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSRangeFromString(@""));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getSelectedTextRange, sjc_CAccessibleText, "getSelectedTextRange",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I", NSRangeFromString(@""));
|
||||
jintArray axTextRange = (*env)->CallStaticObjectMethod(env, sjc_CAccessibleText,
|
||||
jm_getSelectedTextRange, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (axTextRange == NULL) return NSRangeFromString(@"");
|
||||
|
||||
return [javaIntArrayToNSRangeValue(env, axTextRange) rangeValue];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityNumberOfCharacters
|
||||
{
|
||||
// cmcnote: should coalesce these two calls - radr://3951923
|
||||
// also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_ACCESSIBLETEXT_METHOD_RETURN(0);
|
||||
jobject axText = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility,
|
||||
sjm_getAccessibleText, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
NSInteger num = getAxTextCharCount(env, axText, fComponent);
|
||||
(*env)->DeleteLocalRef(env, axText);
|
||||
return num;
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityInsertionPointLineNumber
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(0);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText,
|
||||
"getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I", 0);
|
||||
jint row = (*env)->CallStaticIntMethod(env, sjc_CAccessibleText,
|
||||
jm_getLineNumberForInsertionPoint, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
return row >= 0 ? row : 0;
|
||||
}
|
||||
|
||||
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jstring jstringValue = NSStringToJavaString(env, accessibilitySelectedText);
|
||||
GET_CACCESSIBLETEXT_CLASS();
|
||||
DECLARE_STATIC_METHOD(jm_setSelectedText, sjc_CAccessibleText, "setSelectedText",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;Ljava/lang/String;)V");
|
||||
(*env)->CallStaticVoidMethod(env, sjc_CAccessibleText, jm_setSelectedText,
|
||||
fAccessible, fComponent, jstringValue);
|
||||
CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
- (void)setAccessibilitySelectedTextRange:(NSRange)accessibilitySelectedTextRange
|
||||
{
|
||||
jint startIndex = accessibilitySelectedTextRange.location;
|
||||
jint endIndex = startIndex + accessibilitySelectedTextRange.length;
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS();
|
||||
DECLARE_STATIC_METHOD(jm_setSelectedTextRange, sjc_CAccessibleText, "setSelectedTextRange",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)V");
|
||||
(*env)->CallStaticVoidMethod(env, sjc_CAccessibleText, jm_setSelectedTextRange,
|
||||
fAccessible, fComponent, startIndex, endIndex);
|
||||
CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityEdited {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityEnabled {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
/*
|
||||
* Other text methods
|
||||
- (NSRange)accessibilitySharedCharacterRange;
|
||||
- (NSArray *)accessibilitySharedTextUIElements;
|
||||
- (NSData *)accessibilityRTFForRange:(NSRange)range;
|
||||
- (NSRange)accessibilityStyleRangeForIndex:(NSInteger)index;
|
||||
*/
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "ListAccessibility.h"
|
||||
|
||||
// This is a tree representation. See: https://developer.apple.com/documentation/appkit/nsoutlineview
|
||||
|
||||
@interface OutlineAccessibility : ListAccessibility <NSAccessibilityOutline>
|
||||
|
||||
@property(readonly) BOOL isTreeRootVisible;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "OutlineAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID sjm_isTreeRootVisible = NULL;
|
||||
#define GET_ISTREEROOTVISIBLE_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_isTreeRootVisible, sjc_CAccessibility, "isTreeRootVisible", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Z", ret);
|
||||
|
||||
@implementation OutlineAccessibility
|
||||
|
||||
- (BOOL)isTreeRootVisible
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_ISTREEROOTVISIBLE_METHOD_RETURN(NO);
|
||||
bool isTreeRootVisible = (*env)->CallStaticBooleanMethod(env, sjc_CAccessibility, sjm_isTreeRootVisible, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
return isTreeRootVisible;
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
return [[super accessibilityLabel] isEqualToString:@"list"] ? @"tree" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "ListRowAccessibility.h"
|
||||
|
||||
@interface OutlineRowAccessibility : ListRowAccessibility
|
||||
|
||||
@property(readwrite) int accessibleLevel;
|
||||
|
||||
- (jobject)currentAccessibleWithENV:(JNIEnv *)env;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#import "OutlineRowAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "OutlineAccessibility.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessible = NULL;
|
||||
#define GET_CACCESSIBLE_CLASS_RETURN(ret) \
|
||||
GET_CLASS_RETURN(sjc_CAccessible, "sun/lwawt/macosx/CAccessible", ret);
|
||||
|
||||
@implementation OutlineRowAccessibility
|
||||
|
||||
@synthesize accessibleLevel;
|
||||
|
||||
- (jobject)currentAccessibleWithENV:(JNIEnv *)env
|
||||
{
|
||||
jobject jAxContext = getAxContext(env, fAccessible, fComponent);
|
||||
if (jAxContext == NULL) return NULL;
|
||||
jclass axContextClass = (*env)->GetObjectClass(env, jAxContext);
|
||||
DECLARE_METHOD_RETURN(jm_getCurrentComponent, axContextClass, "getCurrentComponent", "()Ljava/awt/Component;", NULL);
|
||||
jobject newComponent = (*env)->CallObjectMethod(env, jAxContext, jm_getCurrentComponent);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, jAxContext);
|
||||
if (newComponent != NULL) {
|
||||
GET_CACCESSIBLE_CLASS_RETURN(NULL);
|
||||
DECLARE_STATIC_METHOD_RETURN(sjm_getCAccessible, sjc_CAccessible, "getCAccessible", "(Ljavax/accessibility/Accessible;)Lsun/lwawt/macosx/CAccessible;", NULL);
|
||||
jobject currentAccessible = (*env)->CallStaticObjectMethod(env, sjc_CAccessible, sjm_getCAccessible, newComponent);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, newComponent);
|
||||
return currentAccessible;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject currentAccessible = [self currentAccessibleWithENV:env];
|
||||
if (currentAccessible != NULL) {
|
||||
CommonComponentAccessibility *currentElement = [CommonComponentAccessibility createWithAccessible:currentAccessible withEnv:env withView:self->fView isCurrent:YES];
|
||||
NSArray *children = [CommonComponentAccessibility childrenOfParent:currentElement withEnv:env withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
if ([children count] != 0) {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
return [NSArray arrayWithObject:[CommonComponentAccessibility createWithParent:self
|
||||
accessible:self->fAccessible
|
||||
role:self->fJavaRole
|
||||
index:self->fIndex
|
||||
withEnv:env
|
||||
withView:self->fView
|
||||
isWrapped:YES]];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityDisclosureLevel
|
||||
{
|
||||
int level = [self accessibleLevel];
|
||||
return [(OutlineAccessibility *)[self accessibilityParent] isTreeRootVisible] ? level - 1 : level;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityDisclosed
|
||||
{
|
||||
return isExpanded([ThreadUtilities getJNIEnv], [self axContextWithEnv:[ThreadUtilities getJNIEnv]], self->fComponent);
|
||||
}
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole
|
||||
{
|
||||
return NSAccessibilityOutlineRowSubrole;;
|
||||
}
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityRowRole;;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilitySelected
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -39,7 +39,7 @@
|
||||
- (id _Nonnull) accessibilityValue
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
return [self accessibilityValueAttribute];
|
||||
return [super accessibilityValue];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#import "ScrollAreaAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
/*
|
||||
* Implementation of the accessibility peer for the ScrollArea role
|
||||
@@ -35,16 +36,16 @@
|
||||
- (NSArray * _Nullable)accessibilityContentsAttribute
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
NSArray *children = [CommonComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
|
||||
if ([children count] <= 0) return nil;
|
||||
NSArray *contents = [NSMutableArray arrayWithCapacity:[children count]];
|
||||
|
||||
// The scroll bars are in the children. children less the scroll bars is the contents
|
||||
NSEnumerator *enumerator = [children objectEnumerator];
|
||||
JavaComponentAccessibility *aElement;
|
||||
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
|
||||
if (![[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
CommonComponentAccessibility *aElement;
|
||||
while ((aElement = (CommonComponentAccessibility *)[enumerator nextObject])) {
|
||||
if (![[aElement accessibilityRole] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
// no scroll bars in contents
|
||||
[(NSMutableArray *)contents addObject:aElement];
|
||||
}
|
||||
@@ -56,14 +57,14 @@
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
NSArray *children = [CommonComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
if ([children count] <= 0) return nil;
|
||||
|
||||
// The scroll bars are in the children.
|
||||
JavaComponentAccessibility *aElement;
|
||||
CommonComponentAccessibility *aElement;
|
||||
NSEnumerator *enumerator = [children objectEnumerator];
|
||||
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
|
||||
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
while ((aElement = (CommonComponentAccessibility *)[enumerator nextObject])) {
|
||||
if ([[aElement accessibilityRole] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
jobject elementAxContext = [aElement axContextWithEnv:env];
|
||||
if (orientation == NSAccessibilityOrientationHorizontal) {
|
||||
if (isHorizontal(env, elementAxContext, fComponent)) {
|
||||
|
||||
@@ -39,12 +39,12 @@
|
||||
|
||||
- (NSString * _Nullable)accessibilityLabel
|
||||
{
|
||||
return [self accessibilityTitleAttribute];
|
||||
return [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (id _Nullable)accessibilityValue
|
||||
{
|
||||
return [self accessibilityValueAttribute];
|
||||
return [super accessibilityValue];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformIncrement
|
||||
@@ -57,4 +57,14 @@
|
||||
return [self performAccessibleAction:DECREMENT];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -39,12 +39,12 @@
|
||||
|
||||
- (NSString * _Nullable)accessibilityLabel
|
||||
{
|
||||
return [self accessibilityTitleAttribute];
|
||||
return [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (id _Nullable)accessibilityValue
|
||||
{
|
||||
return [self accessibilityValueAttribute];
|
||||
return [super accessibilityValue];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformIncrement
|
||||
@@ -58,4 +58,14 @@
|
||||
return [self performAccessibleAction:DECREMENT];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -47,4 +47,14 @@
|
||||
return [self accessibilityVisibleCharacterRangeAttribute];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface TabButtonAccessibility : CommonComponentAccessibility {
|
||||
jobject fTabGroupAxContext;
|
||||
}
|
||||
|
||||
@property(readonly) jobject tabGroup;
|
||||
|
||||
// from TabGroup controller
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole;
|
||||
- (void)performPressAction;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "TabButtonAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
@implementation TabButtonAccessibility
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
{
|
||||
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
|
||||
if (self) {
|
||||
if (tabGroup != NULL) {
|
||||
fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroup);
|
||||
CHECK_EXCEPTION();
|
||||
} else {
|
||||
fTabGroupAxContext = NULL;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
|
||||
|
||||
if (fTabGroupAxContext != NULL) {
|
||||
(*env)->DeleteWeakGlobalRef(env, fTabGroupAxContext);
|
||||
fTabGroupAxContext = NULL;
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (jobject)tabGroup
|
||||
{
|
||||
if (fTabGroupAxContext == NULL) {
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
jobject tabGroupAxContext = [(CommonComponentAccessibility *)[self parent] axContextWithEnv:env];
|
||||
fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroupAxContext);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, tabGroupAxContext);
|
||||
}
|
||||
return fTabGroupAxContext;
|
||||
}
|
||||
|
||||
- (void)performPressAction {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
TabGroupAction *action = [[TabGroupAction alloc] initWithEnv:env withTabGroup:[self tabGroup] withIndex:fIndex withComponent:fComponent];
|
||||
[action perform];
|
||||
[action release];
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole
|
||||
{
|
||||
if (@available(macOS 10.13, *)) {
|
||||
return NSAccessibilityTabButtonSubrole;
|
||||
}
|
||||
return NSAccessibilityUnknownSubrole;
|
||||
}
|
||||
|
||||
- (id)accessibilityValue
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent);
|
||||
|
||||
// Returns the current selection of the page tab list
|
||||
id val = [NSNumber numberWithBool:ObjectEquals(env, axContext, selAccessible, fComponent)];
|
||||
|
||||
(*env)->DeleteLocalRef(env, selAccessible);
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return val;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformPress {
|
||||
[self performPressAction];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface TabGroupAccessibility : CommonComponentAccessibility {
|
||||
NSInteger _numTabs;
|
||||
}
|
||||
|
||||
@property(readonly) NSInteger numTabs;
|
||||
|
||||
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext;
|
||||
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
|
||||
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "TabGroupAccessibility.h"
|
||||
#import "TabButtonAccessibility.h"
|
||||
#import "../JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID jm_getChildrenAndRoles = NULL;
|
||||
#define GET_CHILDRENANDROLES_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles",\
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;", ret);
|
||||
|
||||
@implementation TabGroupAccessibility
|
||||
|
||||
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext
|
||||
{
|
||||
NSArray *tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:NO];
|
||||
|
||||
// Looking at the JTabbedPane sources, there is always one AccessibleSelection.
|
||||
jobject selAccessible = getAxContextSelection(env, axContext, 0, fComponent);
|
||||
if (selAccessible == NULL) return nil;
|
||||
|
||||
// Go through the tabs and find selAccessible
|
||||
_numTabs = [tabs count];
|
||||
CommonComponentAccessibility *aTab;
|
||||
NSInteger i;
|
||||
for (i = 0; i < _numTabs; i++) {
|
||||
aTab = (CommonComponentAccessibility *)[tabs objectAtIndex:i];
|
||||
if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
|
||||
(*env)->DeleteLocalRef(env, selAccessible);
|
||||
return aTab;
|
||||
}
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, selAccessible);
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
|
||||
{
|
||||
GET_CHILDRENANDROLES_METHOD_RETURN(nil);
|
||||
jobjectArray jtabsAndRoles = (jobjectArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getChildrenAndRoles,
|
||||
fAccessible, fComponent, whichTabs, allowIgnored);
|
||||
CHECK_EXCEPTION();
|
||||
if(jtabsAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles);
|
||||
if (arrayLen == 0) {
|
||||
(*env)->DeleteLocalRef(env, jtabsAndRoles);
|
||||
return nil;
|
||||
}
|
||||
NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)];
|
||||
|
||||
// all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs
|
||||
jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1.
|
||||
if (jtabJavaRole == NULL) {
|
||||
(*env)->DeleteLocalRef(env, jtabsAndRoles);
|
||||
return nil;
|
||||
}
|
||||
DECLARE_CLASS_RETURN(sjc_AccessibleRole, "javax/accessibility/AccessibleRole", nil);
|
||||
DECLARE_FIELD_RETURN(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;", nil);
|
||||
jobject jkey = (*env)->GetObjectField(env, jtabJavaRole, sjf_key);
|
||||
CHECK_EXCEPTION();
|
||||
NSString *tabJavaRole = JavaStringToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
|
||||
NSInteger i;
|
||||
NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly
|
||||
for(i = 0; i < arrayLen; i+=2) {
|
||||
jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i);
|
||||
CommonComponentAccessibility *tab = [[[TabButtonAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
|
||||
(*env)->DeleteLocalRef(env, jtab);
|
||||
[tabs addObject:tab];
|
||||
tabIndex++;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jtabsAndRoles);
|
||||
return tabs;
|
||||
}
|
||||
|
||||
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
|
||||
{
|
||||
// Contents are the children of the selected tab.
|
||||
id currentTab = [self currentTabWithEnv:env withAxContext:axContext];
|
||||
if (currentTab == nil) return nil;
|
||||
|
||||
NSArray *contents = [CommonComponentAccessibility childrenOfParent:currentTab withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
|
||||
if ([contents count] <= 0) return nil;
|
||||
return contents;
|
||||
}
|
||||
|
||||
- (NSInteger)numTabs
|
||||
{
|
||||
if (_numTabs == -1) {
|
||||
_numTabs = [[self accessibilityTabsAttribute] count];
|
||||
}
|
||||
return _numTabs;
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSArray *)accessibilityTabs
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
id tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:NO];
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return tabs;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityContents
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:NO];
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return cont;
|
||||
}
|
||||
|
||||
- (id)accessibilityValue
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
id val = [self currentTabWithEnv:env withAxContext:axContext];
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return val;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
//children = AXTabs + AXContents
|
||||
NSArray *tabs = [self accessibilityTabs];
|
||||
NSArray *contents = [self accessibilityContents];
|
||||
|
||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[tabs count] + [contents count]];
|
||||
[children addObjectsFromArray:tabs];
|
||||
[children addObjectsFromArray:contents];
|
||||
|
||||
return (NSArray *)children;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityArrayAttributeValues:(NSAccessibilityAttributeName)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount
|
||||
{
|
||||
NSArray *result = nil;
|
||||
if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
// Children codes for ALL, SELECTED, VISIBLE are <0. If the code is >=0, we treat it as an index to a single child
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
|
||||
//children = AXTabs + AXContents
|
||||
NSArray *children = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:index allowIgnored:NO]; // first look at the tabs
|
||||
if ([children count] > 0) {
|
||||
result = children;
|
||||
} else {
|
||||
children= [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:(index-[self numTabs]) allowIgnored:NO];
|
||||
if ([children count] > 0) {
|
||||
result = children;
|
||||
}
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
} else {
|
||||
result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setAccessibilityValue:(id)accessibilityValue
|
||||
{
|
||||
// set the current tab
|
||||
NSNumber *number = (NSNumber *)accessibilityValue;
|
||||
if (![number boolValue]) return;
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
setAxContextSelection(env, axContext, fIndex, fComponent);
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface TableAccessibility : CommonComponentAccessibility <NSAccessibilityTable>
|
||||
|
||||
- (BOOL)isAccessibleChildSelectedFromIndex:(int)index;
|
||||
- (int) accessibleRowAtIndex:(int)index;
|
||||
- (int) accessibleColumnAtIndex:(int)index;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#import "TableRowAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "TableAccessibility.h"
|
||||
#import "CellAccessibility.h"
|
||||
#import "ColumnAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "CellAccessibility.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID sjm_getAccessibleName = NULL;
|
||||
#define GET_ACCESSIBLENAME_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", ret);
|
||||
|
||||
@implementation TableAccessibility
|
||||
|
||||
- (id)getTableInfo:(jint)info
|
||||
{
|
||||
if (fAccessible == NULL) return 0;
|
||||
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getTableInfo, sjc_CAccessibility, "getTableInfo",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I", nil);
|
||||
jint count = (*env)->CallStaticIntMethod(env, sjc_CAccessibility, jm_getTableInfo, fAccessible,
|
||||
fComponent, info);
|
||||
CHECK_EXCEPTION();
|
||||
NSNumber *index = [NSNumber numberWithInt:count];
|
||||
return index;
|
||||
}
|
||||
|
||||
- (NSArray<NSNumber *> *)getTableSelectedInfo:(jint)info
|
||||
{
|
||||
if (fAccessible == NULL) return 0;
|
||||
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getTableSelectedInfo, sjc_CAccessibility, "getTableSelectedInfo",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I", nil);
|
||||
jintArray selected = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getTableSelectedInfo, fAccessible,
|
||||
fComponent, info);
|
||||
CHECK_EXCEPTION();
|
||||
if (selected == NULL) {
|
||||
return nil;
|
||||
}
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, selected);
|
||||
jint *indexsis = (*env)->GetIntArrayElements(env, selected, 0);
|
||||
NSMutableArray<NSNumber *> *nsArraySelected = [NSMutableArray<NSNumber *> arrayWithCapacity:arrayLen];
|
||||
for (int i = 0; i < arrayLen; i++) {
|
||||
[nsArraySelected addObject:[NSNumber numberWithInt:indexsis[i]]];
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, selected);
|
||||
return [NSArray<NSNumber *> arrayWithArray:nsArraySelected];
|
||||
}
|
||||
|
||||
- (int)accessibleRowAtIndex:(int)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
if (axContext == NULL) return 0;
|
||||
jclass clsInfo = (*env)->GetObjectClass(env, axContext);
|
||||
DECLARE_METHOD_RETURN(jm_getAccessibleRowAtIndex, clsInfo, "getAccessibleRowAtIndex", "(I)I", -1);
|
||||
jint rowAtIndex = (*env)->CallIntMethod(env, axContext, jm_getAccessibleRowAtIndex, (jint)index);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return (int)rowAtIndex;
|
||||
}
|
||||
|
||||
- (int)accessibleColumnAtIndex:(int)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
if (axContext == NULL) return 0;
|
||||
jclass clsInfo = (*env)->GetObjectClass(env, axContext);
|
||||
DECLARE_METHOD_RETURN(jm_getAccessibleColumnAtIndex, clsInfo, "getAccessibleColumnAtIndex", "(I)I", -1);
|
||||
jint columnAtIndex = (*env)->CallIntMethod(env, axContext, jm_getAccessibleColumnAtIndex, (jint)index);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return (int)columnAtIndex;
|
||||
}
|
||||
|
||||
- (BOOL) isAccessibleChildSelectedFromIndex:(int)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
if (axContext == NULL) return NO;
|
||||
jclass clsInfo = (*env)->GetObjectClass(env, axContext);
|
||||
DECLARE_METHOD_RETURN(jm_isAccessibleChildSelected, clsInfo, "isAccessibleChildSelected", "(I)Z", NO);
|
||||
jboolean isAccessibleChildSelected = (*env)->CallIntMethod(env, axContext, jm_isAccessibleChildSelected, (jint)index);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return isAccessibleChildSelected;
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
return [self accessibilityRows];
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilitySelectedChildren
|
||||
{
|
||||
return [self accessibilitySelectedRows];
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityRows
|
||||
{
|
||||
int rowCount = [self accessibilityRowCount];
|
||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:rowCount];
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
[children addObject:[[TableRowAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i
|
||||
withView:[self view]
|
||||
withJavaRole:JavaAccessibilityIgnore]];
|
||||
}
|
||||
return [NSArray arrayWithArray:children];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedRows
|
||||
{
|
||||
NSArray<NSNumber *> *selectedRowIndexses = [self getTableSelectedInfo:sun_lwawt_macosx_CAccessibility_JAVA_AX_ROWS];
|
||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[selectedRowIndexses count]];
|
||||
for (NSNumber *index in selectedRowIndexses) {
|
||||
[children addObject:[[TableRowAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:index.unsignedIntValue
|
||||
withView:[self view]
|
||||
withJavaRole:JavaAccessibilityIgnore]];
|
||||
}
|
||||
return [NSArray arrayWithArray:children];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
return [super accessibilityLabel] == NULL ? @"table" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilityColumns
|
||||
{
|
||||
int colCount = [self accessibilityColumnCount];
|
||||
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:colCount];
|
||||
for (int i = 0; i < colCount; i++) {
|
||||
[columns addObject:[[ColumnAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i
|
||||
withView:self->fView
|
||||
withJavaRole:JavaAccessibilityIgnore]];
|
||||
}
|
||||
return [NSArray arrayWithArray:columns];
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilitySelectedColumns
|
||||
{
|
||||
NSArray<NSNumber *> *indexes = [self getTableSelectedInfo:sun_lwawt_macosx_CAccessibility_JAVA_AX_COLS];
|
||||
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:[indexes count]];
|
||||
for (NSNumber *i in indexes) {
|
||||
[columns addObject:[[ColumnAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i.unsignedIntValue
|
||||
withView:self->fView
|
||||
withJavaRole:JavaAccessibilityIgnore]];
|
||||
}
|
||||
return [NSArray arrayWithArray:columns];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityRowCount
|
||||
{
|
||||
return [[self getTableInfo:sun_lwawt_macosx_CAccessibility_JAVA_AX_ROWS] integerValue];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityColumnCount
|
||||
{
|
||||
return [[self getTableInfo:sun_lwawt_macosx_CAccessibility_JAVA_AX_COLS] integerValue];
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilitySelectedCells
|
||||
{
|
||||
NSArray *children = [super accessibilitySelectedChildren];
|
||||
NSMutableArray *cells = [NSMutableArray arrayWithCapacity:[children count]];
|
||||
for (CommonComponentAccessibility *child in children) {
|
||||
[cells addObject:[[CellAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:child->fAccessible
|
||||
withIndex:child->fIndex
|
||||
withView:fView
|
||||
withJavaRole:child->fJavaRole]];
|
||||
}
|
||||
return [NSArray arrayWithArray:cells];
|
||||
}
|
||||
|
||||
- (id)accessibilityCellForColumn:(NSInteger)column row:(NSInteger)row {
|
||||
return [[(TableRowAccessibility *)[[self accessibilityRows] objectAtIndex:row] accessibilityChildren] objectAtIndex:column];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "CommonComponentAccessibility.h"
|
||||
|
||||
@interface TableRowAccessibility : CommonComponentAccessibility <NSAccessibilityRow>
|
||||
|
||||
@property(readonly) NSUInteger rowNumberInTable;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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 "TableRowAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "TableAccessibility.h"
|
||||
#import "CellAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID jm_getChildrenAndRoles = NULL;
|
||||
#define GET_CHILDRENANDROLES_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles",\
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;", ret);
|
||||
|
||||
@implementation TableRowAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityRowRole;
|
||||
}
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole
|
||||
{
|
||||
return NSAccessibilityTableRowSubrole;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == nil) {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
CommonComponentAccessibility *parent = [self accessibilityParent];
|
||||
if (parent->fAccessible == NULL) return nil;
|
||||
GET_CHILDRENANDROLES_METHOD_RETURN(nil);
|
||||
jobjectArray jchildrenAndRoles = (jobjectArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getChildrenAndRoles,
|
||||
parent->fAccessible, parent->fComponent, sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN, NO);
|
||||
CHECK_EXCEPTION();
|
||||
if (jchildrenAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
|
||||
NSMutableArray *childrenCells = [NSMutableArray arrayWithCapacity:arrayLen/2];
|
||||
|
||||
NSUInteger childIndex = fIndex * [(TableAccessibility *)parent accessibilityColumnCount];
|
||||
NSInteger i = childIndex * 2;
|
||||
NSInteger n = (fIndex + 1) * [(TableAccessibility *)parent accessibilityColumnCount] * 2;
|
||||
for(i; i < n; i+=2)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
NSString *childJavaRole = nil;
|
||||
if (jchildJavaRole != NULL) {
|
||||
DECLARE_CLASS_RETURN(sjc_AccessibleRole, "javax/accessibility/AccessibleRole", nil);
|
||||
DECLARE_FIELD_RETURN(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;", nil);
|
||||
jobject jkey = (*env)->GetObjectField(env, jchildJavaRole, sjf_key);
|
||||
CHECK_EXCEPTION();
|
||||
childJavaRole = JavaStringToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
}
|
||||
|
||||
CellAccessibility *child = [[CellAccessibility alloc] initWithParent:self
|
||||
withEnv:env
|
||||
withAccessible:jchild
|
||||
withIndex:childIndex
|
||||
withView:self->fView
|
||||
withJavaRole:childJavaRole];
|
||||
[childrenCells addObject:[[child retain] autorelease]];
|
||||
|
||||
(*env)->DeleteLocalRef(env, jchild);
|
||||
(*env)->DeleteLocalRef(env, jchildJavaRole);
|
||||
|
||||
childIndex++;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
|
||||
return childrenCells;
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex
|
||||
{
|
||||
return self->fIndex;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
NSString *accessibilityName = @"";
|
||||
NSArray *children = [self accessibilityChildren];
|
||||
for (id cell in children) {
|
||||
if ([accessibilityName isEqualToString:@""]) {
|
||||
accessibilityName = [cell accessibilityLabel];
|
||||
} else {
|
||||
accessibilityName = [accessibilityName stringByAppendingFormat:@", %@", [cell accessibilityLabel]];
|
||||
}
|
||||
}
|
||||
return accessibilityName;
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
int height = [[[self accessibilityChildren] objectAtIndex:0] accessibilityFrame].size.height;
|
||||
int width = 0;
|
||||
NSPoint point = [[[self accessibilityChildren] objectAtIndex:0] accessibilityFrame].origin;
|
||||
for (id cell in [self accessibilityChildren]) {
|
||||
width += [cell accessibilityFrame].size.width;
|
||||
}
|
||||
return NSMakeRect(point.x, point.y, width, height);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -183,23 +183,25 @@
|
||||
* or maybe a way for the app to continue running depending on the exact
|
||||
* nature of the problem that has been detected and how survivable it is.
|
||||
*/
|
||||
#define CHECK_EXCEPTION() \
|
||||
if ((*env)->ExceptionOccurred(env) != NULL) { \
|
||||
#define CHECK_EXCEPTION_IN_ENV(env) \
|
||||
if ((*(env))->ExceptionOccurred(env) != NULL) { \
|
||||
if ([NSThread isMainThread] == YES) { \
|
||||
if (getenv("JNU_APPKIT_TRACE")) { \
|
||||
(*env)->ExceptionDescribe(env); \
|
||||
(*(env))->ExceptionDescribe(env); \
|
||||
NSLog(@"%@",[NSThread callStackSymbols]); \
|
||||
} else { \
|
||||
(*env)->ExceptionClear(env); \
|
||||
(*(env))->ExceptionClear(env); \
|
||||
} \
|
||||
} \
|
||||
if (getenv("JNU_NO_COCOA_EXCEPTION") == NULL) { \
|
||||
[NSException raise:NSGenericException format:@"Java Exception"]; \
|
||||
} else { \
|
||||
(*env)->ExceptionClear(env); \
|
||||
(*(env))->ExceptionClear(env); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define CHECK_EXCEPTION() CHECK_EXCEPTION_IN_ENV(env)
|
||||
|
||||
#define CHECK_EXCEPTION_NULL_RETURN(x, y) \
|
||||
CHECK_EXCEPTION(); \
|
||||
if ((x) == NULL) { \
|
||||
|
||||
@@ -122,6 +122,8 @@ module java.desktop {
|
||||
exports sun.awt.dnd to jdk.unsupported.desktop;
|
||||
exports sun.swing to jdk.unsupported.desktop;
|
||||
|
||||
exports sun.font to jetbrains.api.impl;
|
||||
|
||||
opens javax.swing.plaf.basic to
|
||||
jdk.jconsole;
|
||||
|
||||
|
||||
@@ -235,15 +235,38 @@ public abstract class SunToolkit extends Toolkit
|
||||
private static final ReentrantLock AWT_LOCK = new ReentrantLock();
|
||||
private static final Condition AWT_LOCK_COND = AWT_LOCK.newCondition();
|
||||
|
||||
public interface AwtLockListener {
|
||||
void afterAwtLocked();
|
||||
void beforeAwtUnlocked();
|
||||
}
|
||||
|
||||
private static java.util.List<AwtLockListener> awtLockListeners;
|
||||
public static synchronized void addAwtLockListener(AwtLockListener l) {
|
||||
if (awtLockListeners == null) {
|
||||
awtLockListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
}
|
||||
awtLockListeners.add(l);
|
||||
}
|
||||
|
||||
public static final void awtLock() {
|
||||
AWT_LOCK.lock();
|
||||
if (awtLockListeners != null) {
|
||||
awtLockListeners.forEach(AwtLockListener::afterAwtLocked);
|
||||
}
|
||||
}
|
||||
|
||||
public static final boolean awtTryLock() {
|
||||
return AWT_LOCK.tryLock();
|
||||
final boolean wasLocked = AWT_LOCK.tryLock();
|
||||
if (wasLocked && awtLockListeners != null) {
|
||||
awtLockListeners.forEach(AwtLockListener::afterAwtLocked);
|
||||
}
|
||||
return wasLocked;
|
||||
}
|
||||
|
||||
public static final void awtUnlock() {
|
||||
if (awtLockListeners != null) {
|
||||
awtLockListeners.forEach(AwtLockListener::beforeAwtUnlocked);
|
||||
}
|
||||
AWT_LOCK.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,12 @@
|
||||
|
||||
#include "fontscaler.h"
|
||||
|
||||
#define CHECK_EXCEPTION(env, describe) \
|
||||
if ((*(env))->ExceptionCheck(env)) { \
|
||||
if (describe) (*(env))->ExceptionDescribe(env);\
|
||||
else (*(env))->ExceptionClear(env); \
|
||||
}
|
||||
|
||||
#define ftFixed1 (FT_Fixed) (1 << 16)
|
||||
#define FloatToFTFixed(f) (FT_Fixed)((f) * (float)(ftFixed1))
|
||||
#define FTFixedToFloat(x) ((x) / (float)(ftFixed1))
|
||||
@@ -164,6 +170,7 @@ static jclass tkClass;
|
||||
static jmethodID getScreenResolutionMID;
|
||||
static jfieldID platNameFID;
|
||||
static jfieldID familyNameFID;
|
||||
static jboolean debugFonts; // Stores the value of FontUtilities.debugFonts()
|
||||
|
||||
#ifndef DISABLE_FONTCONFIG
|
||||
typedef FcBool (*FcPatternAddPtrType) (FcPattern *p, const char *object, FcValue value, FcBool append);
|
||||
@@ -253,6 +260,11 @@ Java_sun_font_FreetypeFontScaler_initIDs(
|
||||
|
||||
invalidateScalerMID =
|
||||
(*env)->GetMethodID(env, FFSClass, "invalidateScaler", "()V");
|
||||
|
||||
jboolean ignoreException;
|
||||
debugFonts = JNU_CallStaticMethodByName(env, &ignoreException,
|
||||
"sun/font/FontUtilities",
|
||||
"debugFonts", "()Z").z;
|
||||
getDefaultToolkitMID =
|
||||
(*env)->GetStaticMethodID(env, TKClass, "getDefaultToolkit",
|
||||
"()Ljava/awt/Toolkit;");
|
||||
@@ -337,6 +349,11 @@ static int getScreenResolution(JNIEnv *env) {
|
||||
jthrowable exc;
|
||||
jclass tk = (*env)->CallStaticObjectMethod(
|
||||
env, tkClass, getDefaultToolkitMID);
|
||||
exc = (*env)->ExceptionOccurred(env);
|
||||
if (exc) {
|
||||
(*env)->ExceptionClear(env);
|
||||
return DEFAULT_DPI;
|
||||
}
|
||||
int dpi = (*env)->CallIntMethod(env, tk, getScreenResolutionMID);
|
||||
|
||||
/* Test if there is no exception here (can get java.awt.HeadlessException)
|
||||
@@ -396,6 +413,9 @@ static void invalidateJavaScaler(JNIEnv *env,
|
||||
FTScalerInfo* scalerInfo) {
|
||||
freeNativeResources(env, scalerInfo);
|
||||
(*env)->CallVoidMethod(env, scaler, invalidateScalerMID);
|
||||
// NB: Exceptions must not be cleared (and therefore no JNI calls
|
||||
// performed) after calling this method because it intentionally
|
||||
// leaves an exception pending.
|
||||
}
|
||||
|
||||
/******************* I/O handlers ***************************/
|
||||
@@ -446,6 +466,7 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
|
||||
scalerInfo->font2D,
|
||||
sunFontIDs.ttReadBlockMID,
|
||||
bBuffer, offset, numBytes);
|
||||
CHECK_EXCEPTION(env, debugFonts);
|
||||
if (bread < 0) {
|
||||
return 0;
|
||||
} else {
|
||||
@@ -465,7 +486,8 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
|
||||
(*env)->CallObjectMethod(env, scalerInfo->font2D,
|
||||
sunFontIDs.ttReadBytesMID,
|
||||
offset, numBytes);
|
||||
/* If there's an OutofMemoryError then byteArray will be null */
|
||||
CHECK_EXCEPTION(env, debugFonts);
|
||||
/* If there's an OutOfMemoryError then byteArray will be null */
|
||||
if (byteArray == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
@@ -498,6 +520,7 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
|
||||
sunFontIDs.ttReadBlockMID,
|
||||
bBuffer, offset,
|
||||
scalerInfo->fontDataLength);
|
||||
CHECK_EXCEPTION(env, debugFonts);
|
||||
if (bread <= 0) {
|
||||
return 0;
|
||||
} else if ((unsigned long)bread < numBytes) {
|
||||
|
||||
@@ -168,8 +168,6 @@ public class XBaseWindow {
|
||||
|
||||
// Set WM_CLIENT_LEADER property
|
||||
initClientLeader();
|
||||
|
||||
initUserTimeWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -441,13 +439,6 @@ public class XBaseWindow {
|
||||
}
|
||||
}
|
||||
|
||||
private void initUserTimeWindow() {
|
||||
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
|
||||
if (netProtocol != null ) {
|
||||
netProtocol.setupUserTimeWindow(this);
|
||||
}
|
||||
}
|
||||
|
||||
static XRootWindow getXAWTRootWindow() {
|
||||
return XRootWindow.getInstance();
|
||||
}
|
||||
@@ -1314,12 +1305,18 @@ public class XBaseWindow {
|
||||
}
|
||||
|
||||
protected void setUserTime(long time, boolean updateGlobalTime) {
|
||||
setUserTime(time, updateGlobalTime, true);
|
||||
}
|
||||
|
||||
protected void setUserTime(long time, boolean updateGlobalTime, boolean updateWindowProperty) {
|
||||
if (updateGlobalTime && (int)time - (int)globalUserTime > 0 /* accounting for wrap-around */) {
|
||||
globalUserTime = time;
|
||||
}
|
||||
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
|
||||
if (netProtocol != null) {
|
||||
netProtocol.setUserTime(this, time);
|
||||
if (updateWindowProperty) {
|
||||
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
|
||||
if (netProtocol != null) {
|
||||
netProtocol.setUserTime(this, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.awt.event.WindowEvent;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import sun.awt.IconInfo;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
@@ -340,7 +341,19 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
|| ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom())
|
||||
{
|
||||
if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
|
||||
getWMSetInsets(XAtom.get(ev.get_atom()));
|
||||
if (getMWMDecorTitleProperty().isPresent()) {
|
||||
// Insets might have changed "in-flight" if that property
|
||||
// is present, so we need to get the actual values of
|
||||
// insets from the WM and propagate them through all the
|
||||
// proper channels.
|
||||
wm_set_insets = null;
|
||||
Insets in = getWMSetInsets(XAtom.get(ev.get_atom()));
|
||||
if (in != null && !in.equals(dimensions.getInsets())) {
|
||||
handleCorrectInsets(in);
|
||||
}
|
||||
} else {
|
||||
getWMSetInsets(XAtom.get(ev.get_atom()));
|
||||
}
|
||||
} else {
|
||||
if (!isReparented()) {
|
||||
return;
|
||||
@@ -1059,10 +1072,13 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
XClientMessageEvent cl = xev.get_xclient();
|
||||
if ((wm_protocols != null) && (cl.get_message_type() == wm_protocols.getAtom())) {
|
||||
long timestamp = getTimeStampFromClientMessage(cl);
|
||||
// we should treat WM_TAKE_FOCUS and WM_DELETE_WINDOW messages as user interaction, as they can originate
|
||||
// We should treat WM_TAKE_FOCUS and WM_DELETE_WINDOW messages as user interaction, as they can originate
|
||||
// e.g. from user clicking on window title bar and window close button correspondingly
|
||||
// (there will be no ButtonPress/ButtonRelease events in those cases)
|
||||
setUserTime(timestamp, true);
|
||||
// (there will be no ButtonPress/ButtonRelease events in those cases).
|
||||
// The received timestamp will be used to set _NET_WM_USER_TIME on newly opened windows to ensure their
|
||||
// correct focusing/positioning, but we don't set it on current window to avoid race conditions (when e.g.
|
||||
// WM_TAKE_FOCUS arrives around the time of new window opening).
|
||||
setUserTime(timestamp, true, false);
|
||||
|
||||
if (cl.get_data(0) == wm_delete_window.getAtom()) {
|
||||
handleQuit();
|
||||
@@ -1319,4 +1335,24 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
}
|
||||
super.handleWindowFocusOut(oppositeWindow, serial);
|
||||
}
|
||||
|
||||
public static final String MWM_DECOR_TITLE_PROPERTY_NAME = "xawt.mwm_decor_title";
|
||||
|
||||
public final Optional<Boolean> getMWMDecorTitleProperty() {
|
||||
Optional<Boolean> res = Optional.empty();
|
||||
|
||||
if (SunToolkit.isInstanceOf(target, "javax.swing.RootPaneContainer")) {
|
||||
javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer) target).getRootPane();
|
||||
Object prop = rootpane.getClientProperty(MWM_DECOR_TITLE_PROPERTY_NAME);
|
||||
if (prop != null) {
|
||||
res = Optional.of(Boolean.parseBoolean(prop.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public final boolean getWindowTitleVisible() {
|
||||
return getMWMDecorTitleProperty().orElse(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,4 +155,25 @@ class XDialogPeer extends XDecoratedPeer implements DialogPeer {
|
||||
}
|
||||
return super.isFocusedWindowModalBlocker();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUnmapNotifyEvent(XEvent xev) {
|
||||
super.handleUnmapNotifyEvent(xev);
|
||||
if (visible && ((Dialog)target).isModal() && XWM.getWMID() == XWM.KDE2_WM) {
|
||||
// the case of modal dialog window being minimized (iconified) on KDE
|
||||
// (other WMs don't seem to allow minimizing)
|
||||
Vector<XWindowPeer> windowPeers = collectJavaToplevels();
|
||||
for (XWindowPeer peer : windowPeers) {
|
||||
if (peer.modalBlocker == target) {
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
XlibWrapper.XIconifyWindow(XToolkit.getDisplay(), peer.getWindow(), peer.getScreenNumber());
|
||||
}
|
||||
finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.awt.Insets;
|
||||
import java.awt.MenuBar;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.peer.FramePeer;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
import sun.awt.AWTAccessor;
|
||||
|
||||
@@ -66,11 +67,7 @@ class XFramePeer extends XDecoratedPeer implements FramePeer {
|
||||
state = 0;
|
||||
undecorated = Boolean.valueOf(target.isUndecorated());
|
||||
winAttr.nativeDecor = !target.isUndecorated();
|
||||
if (winAttr.nativeDecor) {
|
||||
winAttr.decorations = XWindowAttributesData.AWT_DECOR_ALL;
|
||||
} else {
|
||||
winAttr.decorations = XWindowAttributesData.AWT_DECOR_NONE;
|
||||
}
|
||||
winAttr.decorations = getWindowDecorationBits();
|
||||
winAttr.functions = MWMConstants.MWM_FUNC_ALL;
|
||||
winAttr.isResizable = true; // target.isResizable();
|
||||
winAttr.title = target.getTitle();
|
||||
@@ -80,6 +77,38 @@ class XFramePeer extends XDecoratedPeer implements FramePeer {
|
||||
Integer.valueOf(winAttr.decorations), Boolean.valueOf(winAttr.initialResizability),
|
||||
Boolean.valueOf(!winAttr.nativeDecor), Integer.valueOf(winAttr.initialState));
|
||||
}
|
||||
|
||||
registerWindowDecorationChangeListener();
|
||||
}
|
||||
|
||||
private void registerWindowDecorationChangeListener() {
|
||||
if (SunToolkit.isInstanceOf(target, "javax.swing.RootPaneContainer")) { // avoid unnecessary class loading
|
||||
javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer) target).getRootPane();
|
||||
rootpane.addPropertyChangeListener(MWM_DECOR_TITLE_PROPERTY_NAME, e -> winAttr.decorations = getWindowDecorationBits() );
|
||||
}
|
||||
}
|
||||
|
||||
private int getWindowDecorationBits() {
|
||||
int decorations = XWindowAttributesData.AWT_DECOR_NONE;
|
||||
final Frame target = (Frame)(this.target);
|
||||
final boolean useNativeDecor = !target.isUndecorated();
|
||||
if (useNativeDecor) {
|
||||
decorations = XWindowAttributesData.AWT_DECOR_ALL;
|
||||
|
||||
if (!getWindowTitleVisible()) {
|
||||
// NB: the window must be [re-]mapped to make this change effective. Also, window insets will probably
|
||||
// change and that'll be caught by one of the subsequent property change events in XDecoratedPeer
|
||||
// (not necessarily the very next event, though).
|
||||
decorations = XWindowAttributesData.AWT_DECOR_BORDER;
|
||||
}
|
||||
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
log.fine("Frame''s initial decorations affected by the client property {0}={1}",
|
||||
MWM_DECOR_TITLE_PROPERTY_NAME, getMWMDecorTitleProperty());
|
||||
}
|
||||
}
|
||||
|
||||
return decorations;
|
||||
}
|
||||
|
||||
void postInit(XCreateWindowParams params) {
|
||||
|
||||
@@ -293,7 +293,6 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
|
||||
XAtom XA_NET_WM_WINDOW_OPACITY = XAtom.get("_NET_WM_WINDOW_OPACITY");
|
||||
|
||||
XAtom XA_NET_WM_USER_TIME = XAtom.get("_NET_WM_USER_TIME");
|
||||
XAtom XA_NET_WM_USER_TIME_WINDOW = XAtom.get("_NET_WM_USER_TIME_WINDOW");
|
||||
|
||||
/* For _NET_WM_STATE ClientMessage requests */
|
||||
static final int _NET_WM_STATE_REMOVE =0; /* remove/unset property */
|
||||
@@ -466,20 +465,9 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
|
||||
return (state != null && state.size() != 0 && state.contains(XA_NET_WM_STATE_HIDDEN));
|
||||
}
|
||||
|
||||
private boolean isUserTimeWindowSupported() {
|
||||
return checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_USER_TIME_WINDOW);
|
||||
}
|
||||
|
||||
void setupUserTimeWindow(XBaseWindow window) {
|
||||
if (active() && isUserTimeWindowSupported()) {
|
||||
XA_NET_WM_USER_TIME_WINDOW.setWindowProperty(window, XRootWindow.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
void setUserTime(XBaseWindow window, long time) {
|
||||
if (active()) {
|
||||
XBaseWindow target = isUserTimeWindowSupported() ? XRootWindow.getInstance() : window;
|
||||
XA_NET_WM_USER_TIME.setCard32Property(target, time);
|
||||
XA_NET_WM_USER_TIME.setCard32Property(window, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,11 +111,15 @@ import java.awt.peer.TextFieldPeer;
|
||||
import java.awt.peer.TrayIconPeer;
|
||||
import java.awt.peer.WindowPeer;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
@@ -125,6 +129,12 @@ import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Deque;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
@@ -159,6 +169,282 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
private static final PlatformLogger keyEventLog = PlatformLogger.getLogger("sun.awt.X11.kye.XToolkit");
|
||||
private static final PlatformLogger backingStoreLog = PlatformLogger.getLogger("sun.awt.X11.backingStore.XToolkit");
|
||||
|
||||
public static final class Tracer {
|
||||
private static int flags; // what to trace (see TRACE... below)
|
||||
private static String fileName; // where to trace to (file or stderr if null)
|
||||
private static String pattern; // limit tracing to method names containing this pattern (ignore case)
|
||||
private static PrintStream outStream; // stream to trace to
|
||||
private static long threshold = 0; // minimum time delta to record the event
|
||||
private static boolean verbose = false; // verbose tracing
|
||||
|
||||
private static final int TRACELOG = 1;
|
||||
private static final int TRACETIMESTAMP = 1 << 1;
|
||||
private static final int TRACESTATS = 1 << 2;
|
||||
|
||||
private static void showTraceUsage() {
|
||||
System.err.println("usage: -Dsun.awt.x11.trace=" +
|
||||
"[log[,timestamp]],[stats],[name:<substr pattern>]," +
|
||||
"[out:<filename>],[td=<threshold>],[help],[verbose]");
|
||||
}
|
||||
|
||||
static {
|
||||
final GetPropertyAction gpa = new GetPropertyAction("sun.awt.x11.trace");
|
||||
@SuppressWarnings("removal")
|
||||
final String trace = AccessController.doPrivileged(gpa);
|
||||
if (trace != null) {
|
||||
int traceFlags = 0;
|
||||
final StringTokenizer st = new StringTokenizer(trace, ",");
|
||||
while (st.hasMoreTokens()) {
|
||||
final String tok = st.nextToken();
|
||||
if (tok.equalsIgnoreCase("stats")) {
|
||||
traceFlags |= TRACESTATS;
|
||||
} else if (tok.equalsIgnoreCase("log")) {
|
||||
traceFlags |= TRACELOG;
|
||||
} else if (tok.equalsIgnoreCase("timestamp")) {
|
||||
traceFlags |= TRACETIMESTAMP;
|
||||
} else if (tok.regionMatches(true, 0, "name:", 0, 5)) {
|
||||
pattern = tok.substring(5).toUpperCase();
|
||||
} else if (tok.equalsIgnoreCase("verbose")) {
|
||||
verbose = true;
|
||||
} else if (tok.regionMatches(true, 0, "out:", 0, 4)) {
|
||||
fileName = tok.substring(4);
|
||||
} else if (tok.regionMatches(true, 0, "td=", 0, 3)) {
|
||||
try {
|
||||
threshold = Long.max(Long.parseLong(tok.substring(3)), 0);
|
||||
} catch (NumberFormatException e) {
|
||||
showTraceUsage();
|
||||
}
|
||||
} else {
|
||||
if (!tok.equalsIgnoreCase("help")) {
|
||||
System.err.println("unrecognized token: " + tok);
|
||||
}
|
||||
showTraceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
System.err.print("XToolkit logging ");
|
||||
if ((traceFlags & TRACELOG) != 0) {
|
||||
System.err.println("enabled");
|
||||
System.err.print("XToolkit timestamps ");
|
||||
if ((traceFlags & TRACETIMESTAMP) != 0) {
|
||||
System.err.println("enabled");
|
||||
} else {
|
||||
System.err.println("disabled");
|
||||
}
|
||||
} else {
|
||||
System.err.println("[and timestamps] disabled");
|
||||
}
|
||||
System.err.print("XToolkit invocation statistics at exit ");
|
||||
if ((traceFlags & TRACESTATS) != 0) {
|
||||
System.err.println("enabled");
|
||||
} else {
|
||||
System.err.println("disabled");
|
||||
}
|
||||
System.err.print("XToolkit trace output to ");
|
||||
if (fileName == null) {
|
||||
System.err.println("System.err");
|
||||
} else {
|
||||
System.err.println("file '" + fileName + "'");
|
||||
}
|
||||
if (pattern != null) {
|
||||
System.err.println("XToolkit trace limited to " + pattern);
|
||||
}
|
||||
}
|
||||
|
||||
Tracer.flags = traceFlags;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean tracingEnabled() {
|
||||
return (flags != 0);
|
||||
}
|
||||
|
||||
private static synchronized PrintStream getTraceOutputFile() {
|
||||
if (outStream == null) {
|
||||
outStream = System.err;
|
||||
if (fileName != null) {
|
||||
try {
|
||||
outStream = new PrintStream(new FileOutputStream(fileName), true);
|
||||
} catch (FileNotFoundException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return outStream;
|
||||
}
|
||||
|
||||
private static long lastTimeMs = System.currentTimeMillis();
|
||||
|
||||
private static synchronized void outputTraceLine(String prefix, String line) {
|
||||
final StringBuilder outStr = new StringBuilder(prefix);
|
||||
outStr.append(' ');
|
||||
if ((flags & TRACETIMESTAMP) != 0) {
|
||||
final long curTimeMs = System.currentTimeMillis();
|
||||
outStr.append(String.format("+ %1$03dms ", curTimeMs - lastTimeMs));
|
||||
lastTimeMs = curTimeMs;
|
||||
}
|
||||
outStr.append(line);
|
||||
getTraceOutputFile().println(outStr);
|
||||
}
|
||||
|
||||
public static void traceRawLine(String line) {
|
||||
getTraceOutputFile().println(line);
|
||||
}
|
||||
|
||||
public static void traceLine(String line) {
|
||||
outputTraceLine("[LOG] ", line);
|
||||
}
|
||||
|
||||
public static void traceError(String msg) {
|
||||
outputTraceLine("[ERR] ", msg);
|
||||
}
|
||||
|
||||
private static boolean isInterestedInMethod(String mname) {
|
||||
return (pattern == null || mname.toUpperCase().contains(pattern));
|
||||
}
|
||||
|
||||
private static final class AwtLockerDescriptor {
|
||||
public long startTimeMs; // when the locking has occurred
|
||||
public StackWalker.StackFrame frame; // the frame that called awtLock()
|
||||
|
||||
public AwtLockerDescriptor(StackWalker.StackFrame frame, long start) {
|
||||
this.startTimeMs = start;
|
||||
this.frame = frame;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Deque<AwtLockerDescriptor> awtLockersStack = new ArrayDeque<>();
|
||||
|
||||
private static void pushAwtLockCaller(StackWalker.StackFrame frame, long startTimeMs) {
|
||||
// accessed under AWT lock so no need for additional synchronization
|
||||
awtLockersStack.push(new AwtLockerDescriptor(frame, startTimeMs));
|
||||
}
|
||||
|
||||
private static long popAwtLockCaller(StackWalker.StackFrame frame, long finishTimeMs) {
|
||||
// accessed under AWT lock so no need for additional synchronization
|
||||
try {
|
||||
final AwtLockerDescriptor descr = awtLockersStack.pop();
|
||||
if (descr.frame.getMethodName().compareTo(frame.getMethodName()) != 0) {
|
||||
// Note: this often happens with XToolkit.waitForEvents()/XToolkit.run().
|
||||
// traceError("Mismatching awtLock()/awtUnlock(): locked by " + descr.frame + ", unlocked by " + frame);
|
||||
}
|
||||
return finishTimeMs - descr.startTimeMs;
|
||||
} catch(NoSuchElementException e) {
|
||||
traceError("No matching awtLock() for awtUnlock(): " + frame);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static class AwtLockTracer implements SunToolkit.AwtLockListener {
|
||||
private static final Set<String> awtLockerMethods = Set.of("awtLock", "awtUnlock", "awtTryLock");
|
||||
|
||||
private static StackWalker.StackFrame getLockCallerFrame() {
|
||||
Optional<StackWalker.StackFrame> frame = StackWalker.getInstance().walk(
|
||||
s -> s.dropWhile(stackFrame -> !awtLockerMethods.contains(stackFrame.getMethodName()))
|
||||
.dropWhile(stackFrame -> awtLockerMethods.contains( stackFrame.getMethodName()))
|
||||
.findFirst() );
|
||||
|
||||
return frame.orElse(null);
|
||||
}
|
||||
|
||||
public void afterAwtLocked() {
|
||||
final StackWalker.StackFrame awtLockerFrame = getLockCallerFrame();
|
||||
if (awtLockerFrame != null) {
|
||||
final String mname = awtLockerFrame.getMethodName();
|
||||
if (isInterestedInMethod(mname)) {
|
||||
pushAwtLockCaller(awtLockerFrame, System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void beforeAwtUnlocked() {
|
||||
final StackWalker.StackFrame awtLockerFrame = getLockCallerFrame();
|
||||
if (awtLockerFrame != null) {
|
||||
final String mname = awtLockerFrame.getMethodName();
|
||||
if (isInterestedInMethod(mname)) {
|
||||
final long timeSpentMs = popAwtLockCaller(awtLockerFrame, System.currentTimeMillis());
|
||||
if (timeSpentMs >= threshold) {
|
||||
updateStatistics(awtLockerFrame.toString(), timeSpentMs);
|
||||
traceLine(String.format("%s held AWT lock for %dms", awtLockerFrame, timeSpentMs));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MethodStats implements Comparable<MethodStats> {
|
||||
public long minTimeMs;
|
||||
public long maxTimeMs;
|
||||
public long count;
|
||||
private long totalTimeMs;
|
||||
|
||||
MethodStats() {
|
||||
this.minTimeMs = Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
public void update(long timeSpentMs) {
|
||||
count++;
|
||||
minTimeMs = Math.min(minTimeMs, timeSpentMs);
|
||||
maxTimeMs = Math.max(maxTimeMs, timeSpentMs);
|
||||
totalTimeMs += timeSpentMs;
|
||||
}
|
||||
|
||||
public long averageTimeMs() {
|
||||
return (long)((double)totalTimeMs / count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MethodStats other) {
|
||||
return Long.compare(other.averageTimeMs(), this.averageTimeMs());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%dms (%dx[%d-%d]ms)", averageTimeMs(), count, minTimeMs, maxTimeMs);
|
||||
}
|
||||
}
|
||||
|
||||
private static HashMap<String, MethodStats> methodTimingTable;
|
||||
|
||||
private static synchronized void updateStatistics(String mname, long timeSpentMs) {
|
||||
if ((flags & TRACESTATS) != 0) {
|
||||
if (methodTimingTable == null) {
|
||||
methodTimingTable = new HashMap<>(1024);
|
||||
TraceReporter.setShutdownHook();
|
||||
}
|
||||
|
||||
final MethodStats descr = methodTimingTable.computeIfAbsent(mname, k -> new MethodStats());
|
||||
descr.update(timeSpentMs);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TraceReporter implements Runnable {
|
||||
public static void setShutdownHook() {
|
||||
final Tracer.TraceReporter t = new Tracer.TraceReporter();
|
||||
final Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), t,
|
||||
"XToolkit TraceReporter", 0, false);
|
||||
thread.setContextClassLoader(null);
|
||||
Runtime.getRuntime().addShutdownHook(thread);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
traceRawLine("");
|
||||
traceRawLine("AWT Lock usage statistics");
|
||||
traceRawLine("=========================");
|
||||
final ArrayList<AbstractMap.SimpleImmutableEntry<String, MethodStats>> l;
|
||||
synchronized(Tracer.class) { // in order to avoid methodTimingTable modifications during the traversal
|
||||
l = new ArrayList<>(methodTimingTable.size());
|
||||
methodTimingTable.forEach((fname, fdescr)
|
||||
-> l.add(new AbstractMap.SimpleImmutableEntry<>(fname, fdescr)));
|
||||
}
|
||||
l.sort(Map.Entry.comparingByValue());
|
||||
l.forEach(item -> traceRawLine(item.getValue() + " --- " + item.getKey()));
|
||||
traceRawLine("Legend: <avg time> ( <times called> x [ <fastest time> - <slowest time> ] ms) --- <caller of XToolkit.awtUnlock()>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//There is 400 ms is set by default on Windows and 500 by default on KDE and GNOME.
|
||||
//We use the same hardcoded constant.
|
||||
private static final int AWT_MULTICLICK_DEFAULT_TIME = 500;
|
||||
@@ -361,9 +647,15 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
try {
|
||||
((X11GraphicsEnvironment)GraphicsEnvironment.
|
||||
getLocalGraphicsEnvironment()).rebuildDevices();
|
||||
if (useCachedInsets) resetScreenInsetsCache();
|
||||
} finally {
|
||||
awtLock();
|
||||
}
|
||||
} else if (useCachedInsets) {
|
||||
final XAtom XA_NET_WORKAREA = XAtom.get("_NET_WORKAREA");
|
||||
final boolean rootWindowWorkareaResized = (ev.get_type() == XConstants.PropertyNotify
|
||||
&& ev.get_xproperty().get_atom() == XA_NET_WORKAREA.getAtom());
|
||||
if (rootWindowWorkareaResized) resetScreenInsetsCache();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -419,6 +711,10 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
PerformanceLogger.setTime("XToolkit construction");
|
||||
}
|
||||
|
||||
if (Tracer.tracingEnabled()) {
|
||||
addAwtLockListener(new Tracer.AwtLockTracer());
|
||||
}
|
||||
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
String mainClassName = null;
|
||||
|
||||
@@ -866,8 +1162,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
* When two screens overlap and the first contains a dock(*****), then
|
||||
* _NET_WORKAREA may start at point x1,y1 and end at point x2,y2.
|
||||
*/
|
||||
@Override
|
||||
public Insets getScreenInsets(final GraphicsConfiguration gc) {
|
||||
private Insets getScreenInsetsImpl(final GraphicsConfiguration gc) {
|
||||
GraphicsDevice gd = gc.getDevice();
|
||||
XNETProtocol np = XWM.getWM().getNETProtocol();
|
||||
if (np == null || !(gd instanceof X11GraphicsDevice) || !np.active()) {
|
||||
@@ -895,6 +1190,20 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private final Hashtable<GraphicsConfiguration, Insets> cachedInsets = new Hashtable<>();
|
||||
private void resetScreenInsetsCache() {
|
||||
cachedInsets.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getScreenInsets(final GraphicsConfiguration gc) {
|
||||
if (useCachedInsets) {
|
||||
return cachedInsets.computeIfAbsent(gc, this::getScreenInsetsImpl);
|
||||
} else {
|
||||
return getScreenInsetsImpl(gc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The current implementation of disabling background erasing for
|
||||
* canvases is that we don't set any native background color
|
||||
@@ -2619,4 +2928,8 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
public static boolean getSunAwtDisableGrab() {
|
||||
return AccessController.doPrivileged(new GetBooleanAction("sun.awt.disablegrab"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static final boolean useCachedInsets = Boolean.parseBoolean(AccessController.doPrivileged(
|
||||
new GetPropertyAction("x11.cache.screen.insets", "true")));
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
import sun.awt.util.ThreadGroupUtils;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
@@ -136,7 +137,7 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
return Region.clipRound(x / (double)getScaleFactor());
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
private Rectangle getBoundsImpl() {
|
||||
Rectangle rect = pGetBounds(getScreen());
|
||||
if (getScaleFactor() != 1) {
|
||||
rect.x = scaleDown(rect.x);
|
||||
@@ -147,6 +148,28 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
return rect;
|
||||
}
|
||||
|
||||
private Rectangle boundsCached;
|
||||
|
||||
private synchronized Rectangle getBoundsCached() {
|
||||
if (boundsCached == null) {
|
||||
boundsCached = getBoundsImpl();
|
||||
}
|
||||
return boundsCached;
|
||||
}
|
||||
|
||||
public synchronized void resetBoundsCache() {
|
||||
boundsCached = null;
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
if (X11GraphicsEnvironment.useBoundsCache()) {
|
||||
return getBoundsCached();
|
||||
}
|
||||
else {
|
||||
return getBoundsImpl();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identification string associated with this graphics
|
||||
* device.
|
||||
@@ -633,5 +656,6 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
|
||||
public void invalidate(X11GraphicsDevice device) {
|
||||
screen = device.screen;
|
||||
if (X11GraphicsEnvironment.useBoundsCache()) resetBoundsCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.security.AccessController;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
import sun.awt.X11.XToolkit;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
@@ -254,6 +256,12 @@ public final class X11GraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (useBoundsCache()) {
|
||||
for (final X11GraphicsDevice gd : devices.values()) {
|
||||
gd.resetBoundsCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -378,4 +386,12 @@ public final class X11GraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
@Override
|
||||
public void paletteChanged() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static final boolean cacheScreenBoundsValue = Boolean.parseBoolean(AccessController.doPrivileged(
|
||||
new GetPropertyAction("x11.cache.screen.bounds", "true")));
|
||||
|
||||
public static boolean useBoundsCache() {
|
||||
return cacheScreenBoundsValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1335,9 +1335,12 @@ static int getRemoteX11WorkaroundProperty() {
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
jstring name = (*env)->NewStringUTF(env, WORKAROUND_PROPERTY_NAME);
|
||||
CHECK_NULL_RETURN(name, ret);
|
||||
jstring jPropValue = JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "getProperty",
|
||||
"(Ljava/lang/String;)Ljava/lang/String;", name).l;
|
||||
if (jPropValue != NULL) {
|
||||
jobject jPropGetAction = JNU_NewObjectByName(env, "sun/security/action/GetPropertyAction", "(Ljava/lang/String;)V", name);
|
||||
CHECK_NULL_RETURN(name, ret);
|
||||
jboolean ignoreExc;
|
||||
jstring jPropValue = JNU_CallStaticMethodByName(env, &ignoreExc, "java/security/AccessController", "doPrivileged",
|
||||
"(Ljava/security/PrivilegedAction;)Ljava/lang/Object;", jPropGetAction).l;
|
||||
if (jPropValue != NULL && JNU_IsInstanceOfByName(env, jPropValue, "java/lang/String")) {
|
||||
const char * utf8string = (*env)->GetStringUTFChars(env, jPropValue, NULL);
|
||||
if (utf8string != NULL) {
|
||||
if (strcmp(utf8string, "true") == 0) {
|
||||
@@ -1348,7 +1351,6 @@ static int getRemoteX11WorkaroundProperty() {
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars(env, jPropValue, utf8string);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
#include "awt_p.h"
|
||||
#include "awt_GraphicsEnv.h"
|
||||
|
||||
#include "keycode_cache.h"
|
||||
|
||||
#define XK_KATAKANA
|
||||
#include <X11/keysym.h> /* standard X keysyms */
|
||||
#include <X11/DECkeysym.h> /* DEC vendor-specific */
|
||||
@@ -812,6 +814,7 @@ isXKBenabled(Display *display) {
|
||||
return awt_UseXKB;
|
||||
}
|
||||
|
||||
#ifndef USE_KEYCODE_CACHE
|
||||
/*
|
||||
* Map a keycode to the corresponding keysym.
|
||||
* This replaces the deprecated X11 function XKeycodeToKeysym
|
||||
@@ -836,6 +839,7 @@ keycodeToKeysym(Display *display, KeyCode keycode, int index) {
|
||||
XFree(key_syms);
|
||||
return ks;
|
||||
}
|
||||
#endif // USE_KEYCODE_CACHE
|
||||
|
||||
static Boolean
|
||||
isKPevent(XEvent *event)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "utility/rect.h"
|
||||
|
||||
#include "sun_awt_X11_XlibWrapper.h"
|
||||
#include "keycode_cache.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -56,9 +57,6 @@
|
||||
extern Bool statusWindowEventHandler(XEvent event);
|
||||
#endif
|
||||
|
||||
// From XWindow.c
|
||||
extern KeySym keycodeToKeysym(Display *display, KeyCode keycode, int index);
|
||||
|
||||
#if defined(DEBUG)
|
||||
static jmethodID lockIsHeldMID = NULL;
|
||||
|
||||
@@ -179,6 +177,11 @@ JNIEXPORT void JNICALL
|
||||
Java_sun_awt_X11_XlibWrapper_XCloseDisplay(JNIEnv *env, jclass clazz,
|
||||
jlong display) {
|
||||
AWT_CHECK_HAVE_LOCK();
|
||||
|
||||
#ifdef USE_KEYCODE_CACHE
|
||||
resetKeyCodeCache();
|
||||
#endif
|
||||
|
||||
XCloseDisplay((Display*) jlong_to_ptr(display));
|
||||
}
|
||||
|
||||
@@ -2023,6 +2026,11 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping
|
||||
(JNIEnv *env, jclass clazz, jlong event_ptr)
|
||||
{
|
||||
AWT_CHECK_HAVE_LOCK();
|
||||
|
||||
#ifdef USE_KEYCODE_CACHE
|
||||
resetKeyCodeCache();
|
||||
#endif
|
||||
|
||||
XRefreshKeyboardMapping((XMappingEvent*) jlong_to_ptr(event_ptr));
|
||||
}
|
||||
|
||||
|
||||
110
src/java.desktop/unix/native/libawt_xawt/xawt/keycode_cache.c
Normal file
110
src/java.desktop/unix/native/libawt_xawt/xawt/keycode_cache.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
* 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "keycode_cache.h"
|
||||
#include "awt.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_KEYCODE_CACHE
|
||||
|
||||
/**
|
||||
* Keeps the KeyCode -> KeySym mapping.
|
||||
*/
|
||||
typedef struct {
|
||||
KeySym* symbols; // array of KeySym indexed by the key code with min_code corresponding to index 0
|
||||
int syms_per_code; // number of elements in 'symbols' corresponding to one key code
|
||||
int min_code; // minimum valid key code (typically 8)
|
||||
int max_code; // maximum valid key code (typically 255)
|
||||
} KeyCodeCache;
|
||||
|
||||
static KeyCodeCache keycode_cache = {0};
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
dump_keycode_cache(const KeyCodeCache* cache) {
|
||||
fprintf(stderr, "KeyCodeCache dump\n");
|
||||
if (cache->symbols == NULL) {
|
||||
fprintf(stderr, "-- empty --\n");
|
||||
} else {
|
||||
fprintf(stderr, "syms_per_code=%d, min_code=%d, max_code=%d\n",
|
||||
cache->syms_per_code, cache->min_code, cache->max_code);
|
||||
for(int i = cache->min_code; i <= cache->max_code; i++) {
|
||||
fprintf(stderr, "0x%02x --", i);
|
||||
for(int j = 0; j < cache->syms_per_code; j++) {
|
||||
const int sym_index = (i - cache->min_code)*cache->syms_per_code + j;
|
||||
fprintf(stderr, "%04d - ", cache->symbols[sym_index]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
/**
|
||||
* Clears the cache and frees memory, if allocated.
|
||||
*
|
||||
* NB: not thread safe and is supposed to be called only when holding the AWT lock.
|
||||
*/
|
||||
extern void
|
||||
resetKeyCodeCache(void) {
|
||||
if (keycode_cache.symbols) {
|
||||
XFree(keycode_cache.symbols);
|
||||
}
|
||||
keycode_cache = (KeyCodeCache){0};
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the given keycode to the corresponding KeySym at the given index.
|
||||
* Caches the mapping for all valid key codes by using just one XGetKeyboardMapping() Xlib call,
|
||||
* which greatly reduces delays when working with a remote X server.
|
||||
*
|
||||
* NB: not thread safe and is supposed to be called only when holding the AWT lock.
|
||||
*/
|
||||
extern KeySym
|
||||
keycodeToKeysym(Display* display, KeyCode keycode, int index) {
|
||||
if (!keycode_cache.symbols) {
|
||||
XDisplayKeycodes(display, &keycode_cache.min_code, &keycode_cache.max_code);
|
||||
const int count_all = keycode_cache.max_code - keycode_cache.min_code + 1;
|
||||
keycode_cache.symbols = XGetKeyboardMapping(display, keycode_cache.min_code, count_all, &keycode_cache.syms_per_code);
|
||||
// NB: this may not always get free'ed
|
||||
}
|
||||
|
||||
if (keycode_cache.symbols) {
|
||||
const Boolean code_within_range = (keycode >= keycode_cache.min_code && keycode <= keycode_cache.max_code);
|
||||
const Boolean index_within_range = (index >= 0 && index < keycode_cache.syms_per_code);
|
||||
if (code_within_range && index_within_range) {
|
||||
const int sym_index = (keycode - keycode_cache.min_code)*keycode_cache.syms_per_code + index;
|
||||
KeySym sym = keycode_cache.symbols[sym_index];
|
||||
return sym;
|
||||
}
|
||||
}
|
||||
|
||||
return NoSymbol;
|
||||
}
|
||||
|
||||
#endif /* USE_KEYCODE_CACHE */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
* 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _KEYCODE_CACHE_H
|
||||
#define _KEYCODE_CACHE_H
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#define USE_KEYCODE_CACHE 1
|
||||
|
||||
void resetKeyCodeCache(void);
|
||||
|
||||
KeySym keycodeToKeysym(Display* display, KeyCode keycode, int index);
|
||||
|
||||
#endif /* _KEYCODE_CACHE_H */
|
||||
@@ -168,10 +168,6 @@ final class WInputMethod extends InputMethodAdapter
|
||||
|
||||
@Override
|
||||
public boolean setLocale(Locale lang) {
|
||||
return setLocale(lang, false);
|
||||
}
|
||||
|
||||
private boolean setLocale(Locale lang, boolean onActivate) {
|
||||
Locale[] available = WInputMethodDescriptor.getAvailableLocalesInternal();
|
||||
for (int i = 0; i < available.length; i++) {
|
||||
Locale locale = available[i];
|
||||
@@ -180,7 +176,7 @@ final class WInputMethod extends InputMethodAdapter
|
||||
locale.equals(Locale.JAPAN) && lang.equals(Locale.JAPANESE) ||
|
||||
locale.equals(Locale.KOREA) && lang.equals(Locale.KOREAN)) {
|
||||
if (isActive) {
|
||||
setNativeLocale(locale.toLanguageTag(), onActivate);
|
||||
setNativeLocale(locale.toLanguageTag());
|
||||
}
|
||||
currentLocale = locale;
|
||||
return true;
|
||||
@@ -319,9 +315,6 @@ final class WInputMethod extends InputMethodAdapter
|
||||
isLastFocussedActiveClient = isAc;
|
||||
}
|
||||
isActive = true;
|
||||
if (currentLocale != null) {
|
||||
setLocale(currentLocale, true);
|
||||
}
|
||||
|
||||
// Compare IM's composition string with Java's composition string
|
||||
if (hasCompositionString && !isCompositionStringAvailable(context)) {
|
||||
@@ -348,10 +341,6 @@ final class WInputMethod extends InputMethodAdapter
|
||||
@Override
|
||||
public void deactivate(boolean isTemporary)
|
||||
{
|
||||
// Sync currentLocale with the Windows keyboard layout which might be changed
|
||||
// by hot key
|
||||
getLocale();
|
||||
|
||||
// Delay calling disableNativeIME until activate is called and the newly
|
||||
// focussed component has a different peer as the last focussed component.
|
||||
if (awtFocussedComponentPeer != null) {
|
||||
@@ -667,7 +656,7 @@ final class WInputMethod extends InputMethodAdapter
|
||||
private native void setStatusWindowVisible(WComponentPeer peer, boolean visible);
|
||||
private native String getNativeIMMDescription();
|
||||
static native Locale getNativeLocale();
|
||||
static native boolean setNativeLocale(String localeName, boolean onActivate);
|
||||
static native boolean setNativeLocale(String localeName);
|
||||
private native void openCandidateWindow(WComponentPeer peer, int x, int y);
|
||||
private native boolean isCompositionStringAvailable(int context);
|
||||
}
|
||||
|
||||
@@ -866,7 +866,11 @@ void D3DRQ_FlushBuffer(void *pParam)
|
||||
|
||||
if (!JNU_IsNull(env, pFlush->runnable)) {
|
||||
J2dTraceLn(J2D_TRACE_VERBOSE, " executing runnable");
|
||||
JNU_CallMethodByName(env, NULL, pFlush->runnable, "run", "()V");
|
||||
jboolean hasException;
|
||||
JNU_CallMethodByName(env, &hasException, pFlush->runnable, "run", "()V");
|
||||
if (hasException) {
|
||||
J2dTraceLn(J2D_TRACE_ERROR, " exception occurred while executing runnable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,15 +87,6 @@ static DCList passiveDCList;
|
||||
|
||||
extern void CheckFontSmoothingSettings(HWND);
|
||||
|
||||
extern "C" {
|
||||
// Remember the input language has changed by some user's action
|
||||
// (Alt+Shift or through the language icon on the Taskbar) to control the
|
||||
// race condition between the toolkit thread and the AWT event thread.
|
||||
// This flag remains TRUE until the next WInputMethod.getNativeLocale() is
|
||||
// issued.
|
||||
BOOL g_bUserHasChangedInputLang = FALSE;
|
||||
}
|
||||
|
||||
BOOL AwtComponent::sm_suppressFocusAndActivation = FALSE;
|
||||
BOOL AwtComponent::sm_restoreFocusAndActivation = FALSE;
|
||||
HWND AwtComponent::sm_focusOwner = NULL;
|
||||
@@ -1847,9 +1838,6 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0),
|
||||
keyboardState, &ignored, 0, GetKeyboardLayout());
|
||||
|
||||
// Set this flag to block ActivateKeyboardLayout from
|
||||
// WInputMethod.activate()
|
||||
g_bUserHasChangedInputLang = TRUE;
|
||||
CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
|
||||
break;
|
||||
}
|
||||
@@ -1858,7 +1846,6 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
"new = 0x%08X",
|
||||
GetHWnd(), GetClassName(), (UINT)lParam);
|
||||
mr = WmInputLangChange(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam));
|
||||
g_bUserHasChangedInputLang = TRUE;
|
||||
CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
|
||||
// should return non-zero if we process this message
|
||||
retValue = 1;
|
||||
@@ -6706,11 +6693,11 @@ JNIEXPORT void JNICALL
|
||||
Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
|
||||
{
|
||||
TRY;
|
||||
jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent");
|
||||
CHECK_NULL(inputEventClazz);
|
||||
jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I");
|
||||
CHECK_NULL(getButtonDownMasksID);
|
||||
jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID);
|
||||
jboolean ignoreException;
|
||||
jintArray obj = (jintArray)JNU_CallStaticMethodByName(env, &ignoreException,
|
||||
"java/awt/event/InputEvent",
|
||||
"getButtonDownMasks", "()[I").l;
|
||||
CHECK_NULL(obj);
|
||||
jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE);
|
||||
CHECK_NULL(tmp);
|
||||
jsize len = env->GetArrayLength(obj);
|
||||
|
||||
@@ -823,6 +823,7 @@ void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) {
|
||||
key, jValue);
|
||||
GetEnv()->DeleteLocalRef(jValue);
|
||||
GetEnv()->DeleteLocalRef(key);
|
||||
(void)safe_ExceptionOccurred(GetEnv());
|
||||
}
|
||||
|
||||
void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
|
||||
@@ -835,6 +836,7 @@ void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
|
||||
AwtDesktopProperties::setIntegerPropertyID,
|
||||
key, (jint)value);
|
||||
GetEnv()->DeleteLocalRef(key);
|
||||
(void)safe_ExceptionOccurred(GetEnv());
|
||||
}
|
||||
|
||||
void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) {
|
||||
@@ -846,6 +848,7 @@ void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) {
|
||||
AwtDesktopProperties::setBooleanPropertyID,
|
||||
key, value ? JNI_TRUE : JNI_FALSE);
|
||||
GetEnv()->DeleteLocalRef(key);
|
||||
(void)safe_ExceptionOccurred(GetEnv());
|
||||
}
|
||||
|
||||
void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) {
|
||||
@@ -858,6 +861,7 @@ void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) {
|
||||
key, GetRValue(value), GetGValue(value),
|
||||
GetBValue(value));
|
||||
GetEnv()->DeleteLocalRef(key);
|
||||
(void)safe_ExceptionOccurred(GetEnv());
|
||||
}
|
||||
|
||||
void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID,
|
||||
@@ -920,6 +924,7 @@ void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID,
|
||||
key, fontName, style, pointSize);
|
||||
GetEnv()->DeleteLocalRef(key);
|
||||
GetEnv()->DeleteLocalRef(fontName);
|
||||
(void)safe_ExceptionOccurred(GetEnv());
|
||||
}
|
||||
}
|
||||
delete[] face;
|
||||
@@ -967,6 +972,7 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon
|
||||
key, fontName, style, pointSize);
|
||||
GetEnv()->DeleteLocalRef(key);
|
||||
GetEnv()->DeleteLocalRef(fontName);
|
||||
(void)safe_ExceptionOccurred(GetEnv());
|
||||
}
|
||||
|
||||
void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventName) {
|
||||
@@ -984,6 +990,7 @@ void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventNa
|
||||
key, event);
|
||||
GetEnv()->DeleteLocalRef(event);
|
||||
GetEnv()->DeleteLocalRef(key);
|
||||
(void)safe_ExceptionOccurred(GetEnv());
|
||||
}
|
||||
|
||||
void AwtDesktopProperties::PlayWindowsSound(LPCTSTR event) {
|
||||
|
||||
@@ -44,8 +44,6 @@ extern "C" {
|
||||
jobject CreateLocaleObject(JNIEnv *env, const char * name);
|
||||
HKL getDefaultKeyboardLayout();
|
||||
|
||||
extern BOOL g_bUserHasChangedInputLang;
|
||||
|
||||
/*
|
||||
* Class: sun_awt_windows_WInputMethod
|
||||
* Method: createNativeContext
|
||||
@@ -292,10 +290,6 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_WInputMethod_getNativeLocale
|
||||
|
||||
const char * javaLocaleName = getJavaIDFromLangID(AwtComponent::GetInputLanguage());
|
||||
if (javaLocaleName != NULL) {
|
||||
// Now WInputMethod.currentLocale and AwtComponent::m_idLang are get sync'ed,
|
||||
// so we can reset this flag.
|
||||
g_bUserHasChangedInputLang = FALSE;
|
||||
|
||||
jobject ret = CreateLocaleObject(env, javaLocaleName);
|
||||
free((void *)javaLocaleName);
|
||||
return ret;
|
||||
@@ -309,10 +303,10 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_WInputMethod_getNativeLocale
|
||||
/*
|
||||
* Class: sun_awt_windows_WInputMethod
|
||||
* Method: setNativeLocale
|
||||
* Signature: (Ljava/lang/String;Z)Z
|
||||
* Signature: (Ljava/lang/String;)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
|
||||
(JNIEnv *env, jclass cls, jstring localeString, jboolean onActivate)
|
||||
(JNIEnv *env, jclass cls, jstring localeString)
|
||||
{
|
||||
TRY;
|
||||
|
||||
@@ -353,7 +347,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
|
||||
if (supported != NULL) {
|
||||
if (strcmp(supported, requested) == 0) {
|
||||
// use special message to call ActivateKeyboardLayout() in main thread.
|
||||
if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, (WPARAM)onActivate, (LPARAM)hKLList[i])) {
|
||||
if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, 0, (LPARAM)hKLList[i])) {
|
||||
//also need to change the same keyboard layout for the Java AWT-EventQueue thread
|
||||
AwtToolkit::activateKeyboardLayout(hKLList[i]);
|
||||
retValue = JNI_TRUE;
|
||||
|
||||
@@ -71,7 +71,6 @@ extern void initScreens(JNIEnv *env);
|
||||
extern "C" void awt_dnd_initialize();
|
||||
extern "C" void awt_dnd_uninitialize();
|
||||
extern "C" void awt_clipboard_uninitialize(JNIEnv *env);
|
||||
extern "C" BOOL g_bUserHasChangedInputLang;
|
||||
|
||||
extern CriticalSection windowMoveLock;
|
||||
extern BOOL windowMoveLockHeld;
|
||||
@@ -1218,14 +1217,6 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
return cmode;
|
||||
}
|
||||
case WM_AWT_ACTIVATEKEYBOARDLAYOUT: {
|
||||
if (wParam && g_bUserHasChangedInputLang) {
|
||||
// Input language has been changed since the last WInputMethod.getNativeLocale()
|
||||
// call. So let's honor the user's selection.
|
||||
// Note: we need to check this flag inside the toolkit thread to synchronize access
|
||||
// to the flag.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lParam == (LPARAM)::GetKeyboardLayout(0)) {
|
||||
// already active
|
||||
return FALSE;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.jetbrains.impl;
|
||||
|
||||
import com.jetbrains.ExtendedGlyphCache;
|
||||
|
||||
import java.awt.*;
|
||||
import sun.font.FontUtilities;
|
||||
|
||||
public class ExtendedGlyphCacheImpl implements ExtendedGlyphCache.V1 {
|
||||
|
||||
@Override
|
||||
public Dimension getSubpixelResolution() {
|
||||
return FontUtilities.subpixelResolution;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.jetbrains.impl;
|
||||
|
||||
import com.jetbrains.SampleJBRApi;
|
||||
|
||||
// Here we just implement latest API version
|
||||
public class SampleJBRApiImpl implements SampleJBRApi.V2 {
|
||||
|
||||
@Override
|
||||
public void someMethod1(SomeDataClass arg) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SomeDataClass someMethod2() {
|
||||
return new SomeDataClass();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import com.jetbrains.JBRService;
|
||||
import com.jetbrains.impl.SampleJBRApiImpl;
|
||||
import com.jetbrains.impl.*;
|
||||
|
||||
module jetbrains.api.impl {
|
||||
|
||||
@@ -23,6 +23,6 @@ module jetbrains.api.impl {
|
||||
|
||||
// We probably don't want to add `provides with` for each version of API, so we just provide `JBRService`
|
||||
// implementation, `JBRService#load` will take care of the rest
|
||||
provides JBRService with SampleJBRApiImpl;
|
||||
provides JBRService with ExtendedGlyphCacheImpl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.jetbrains;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public interface ExtendedGlyphCache extends JBRService {
|
||||
|
||||
|
||||
interface V1 extends ExtendedGlyphCache {
|
||||
|
||||
Dimension getSubpixelResolution();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.jetbrains;
|
||||
|
||||
// SampleJBRApi is a base of our feature API, it's just a marker interface extending JBRService
|
||||
public interface SampleJBRApi extends JBRService {
|
||||
|
||||
|
||||
// And actual API goes from V1
|
||||
interface V1 extends SampleJBRApi {
|
||||
|
||||
void someMethod1(SomeDataClass arg);
|
||||
|
||||
class SomeDataClass {
|
||||
public SomeDataClass() {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// When we need to add something to our API, we create interface for a new version, extending previous one
|
||||
interface V2 extends V1 {
|
||||
|
||||
SomeDataClass someMethod2();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -18,6 +18,8 @@ import com.jetbrains.JBRService;
|
||||
|
||||
module jetbrains.api {
|
||||
|
||||
requires transitive java.desktop;
|
||||
|
||||
exports com.jetbrains;
|
||||
|
||||
uses JBRService;
|
||||
|
||||
87
test/jdk/java/awt/Debug/X11Trace.java
Normal file
87
test/jdk/java/awt/Debug/X11Trace.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary Verifies the -Dsun.awt.x11.trace option
|
||||
* @requires (os.family == "linux")
|
||||
* @library /test/lib
|
||||
* @run main X11Trace
|
||||
*/
|
||||
import java.awt.AWTException;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class X11Trace {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 0 && args[0].equals("runtest")) {
|
||||
runTest();
|
||||
} else {
|
||||
OutputAnalyzer oa = ProcessTools.executeTestJvm("-Dsun.awt.x11.trace=log,timestamp,stats,td=0", X11Trace.class.getName(), "runtest");
|
||||
oa.shouldContain("held AWT lock for").shouldContain("AWT Lock usage statistics").shouldHaveExitValue(0);
|
||||
|
||||
oa = ProcessTools.executeTestJvm("-Dsun.awt.x11.trace=log", X11Trace.class.getName(), "runtest");
|
||||
oa.shouldContain("held AWT lock for").shouldNotContain("AWT Lock usage statistics").shouldHaveExitValue(0);
|
||||
|
||||
oa = ProcessTools.executeTestJvm("-Dsun.awt.x11.trace=log,timestamp,stats,td=0,out:mylog", X11Trace.class.getName(), "runtest");
|
||||
oa.shouldHaveExitValue(0).stderrShouldBeEmpty();
|
||||
|
||||
final String logFileContents = Files.readString(Paths.get("mylog"));
|
||||
OutputAnalyzer logOA = new OutputAnalyzer(logFileContents);
|
||||
logOA.shouldContain("held AWT lock for").shouldContain("AWT Lock usage statistics");
|
||||
}
|
||||
}
|
||||
|
||||
public static void delay(int ms) {
|
||||
try {
|
||||
Thread.sleep(ms);
|
||||
} catch(InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void runTest() {
|
||||
runSwing(() -> {
|
||||
final JFrame frame = new JFrame("test");
|
||||
frame.setVisible(true);
|
||||
delay(500);
|
||||
frame.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
private static void runSwing(Runnable r) {
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(r);
|
||||
} catch (InterruptedException e) {
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
119
test/jdk/java/awt/a11y/AccessibleComponentTest.java
Normal file
119
test/jdk/java/awt/a11y/AccessibleComponentTest.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.*;
|
||||
import java.security.PublicKey;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.GridBagLayout;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JButton;
|
||||
|
||||
public abstract class AccessibleComponentTest {
|
||||
|
||||
protected static volatile boolean testResult = true;
|
||||
protected static volatile CountDownLatch countDownLatch;
|
||||
protected static String INSTRUCTIONS;
|
||||
protected static String exceptionString;
|
||||
protected JFrame mainFrame;
|
||||
protected static AccessibleComponentTest a11yTest;
|
||||
|
||||
public abstract CountDownLatch createCountDownLatch();
|
||||
|
||||
public void createUI(JPanel component, String testName) {
|
||||
mainFrame = new JFrame(testName);
|
||||
GridBagLayout layout = new GridBagLayout();
|
||||
JPanel mainControlPanel = new JPanel(layout);
|
||||
JPanel resultButtonPanel = new JPanel(layout);
|
||||
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
|
||||
JTextArea instructionTextArea = new JTextArea();
|
||||
instructionTextArea.setText(INSTRUCTIONS);
|
||||
instructionTextArea.setEditable(false);
|
||||
instructionTextArea.setBackground(Color.white);
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
mainControlPanel.add(instructionTextArea, gbc);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 1;
|
||||
mainControlPanel.add(component);
|
||||
|
||||
JButton passButton = new JButton("Pass");
|
||||
passButton.setActionCommand("Pass");
|
||||
passButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mainFrame.dispose();
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
JButton failButton = new JButton("Fail");
|
||||
failButton.setActionCommand("Fail");
|
||||
failButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
testResult = false;
|
||||
mainFrame.dispose();
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
resultButtonPanel.add(passButton, gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
gbc.gridy = 0;
|
||||
resultButtonPanel.add(failButton, gbc);
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 2;
|
||||
mainControlPanel.add(resultButtonPanel, gbc);
|
||||
|
||||
mainFrame.add(mainControlPanel);
|
||||
mainFrame.pack();
|
||||
|
||||
mainFrame.addWindowListener(new WindowAdapter() {
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
mainFrame.dispose();
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
});
|
||||
mainFrame.setVisible(true);
|
||||
}
|
||||
}
|
||||
80
test/jdk/java/awt/a11y/AccessibleJComboboxTest.java
Normal file
80
test/jdk/java/awt/a11y/AccessibleJComboboxTest.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8264287
|
||||
* @summary Test implementation of NSAccessibilityComboBox protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJComboboxTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.awt.FlowLayout;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class AccessibleJComboboxTest extends AccessibleComponentTest {
|
||||
|
||||
@java.lang.Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
void createCombobox() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JCombobox.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the combobox.\n\n"
|
||||
+ "If you can hear combobox selected item tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
String[] NAMES = {"One", "Two", "Three", "Four", "Five"};
|
||||
JComboBox<String> combo = new JComboBox<>(NAMES);
|
||||
|
||||
JLabel label = new JLabel("This is combobox:");
|
||||
label.setLabelFor(combo);
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(label);
|
||||
frame.add(combo);
|
||||
exceptionString = "AccessibleJCombobox test failed!";
|
||||
super.createUI(frame, "AccessibleJComboboxTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleJComboboxTest test = new AccessibleJComboboxTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(test::createCombobox);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
330
test/jdk/java/awt/a11y/AccessibleJListTest.java
Normal file
330
test/jdk/java/awt/a11y/AccessibleJListTest.java
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8264292
|
||||
* @summary Test implementation of NSAccessibilityList protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJListTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JWindow;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Popup;
|
||||
import javax.swing.PopupFactory;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Component;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Window;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AccessibleJListTest extends AccessibleComponentTest {
|
||||
|
||||
private static final String[] NAMES = {"One", "Two", "Three", "Four", "Five"};
|
||||
static JWindow window;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
a11yTest = new AccessibleJListTest();
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createSimpleList);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createSimpleListRenderer);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createSimpleListNamed);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createCombobox);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createPushButton);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createPushButtonHeavyWeight);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
public void createSimpleList() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the list.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear menu items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JList<String> list = new JList<>(NAMES);
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(list);
|
||||
exceptionString = "Accessible JList simple list test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public void createSimpleListRenderer() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList with renderer.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the list.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear menu items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JList<String> list = new JList<>(NAMES);
|
||||
list.setCellRenderer(new AccessibleJListTestRenderer());
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(list);
|
||||
exceptionString = "Accessible JList with renderer simple list test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public void createSimpleListNamed() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of named JList.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the list.\n"
|
||||
+ "Press the tab button to move to second list.\n\n"
|
||||
+ "If you can hear second list name: \"second list\" - tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JList<String> list = new JList<>(NAMES);
|
||||
JList<String> secondList = new JList<>(NAMES);
|
||||
secondList.getAccessibleContext().setAccessibleName("Second list");
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(list);
|
||||
frame.add(secondList);
|
||||
exceptionString = "Accessible JList simple list named test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
|
||||
public void createCombobox() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList in a combobox.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the combobox.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear combobox items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JComboBox<String> combo = new JComboBox<>(NAMES);
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(combo);
|
||||
exceptionString = "Accessible JList combobox test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public void createPushButton() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList in a popup in a simple window.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the show button and press space.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear popup menu items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JButton button = new JButton("show");
|
||||
button.setPreferredSize(new Dimension(100, 35));
|
||||
|
||||
button.addActionListener(new ActionListener() {
|
||||
|
||||
final Runnable dispose = () -> {
|
||||
window.dispose();
|
||||
window = null;
|
||||
button.setText("show");
|
||||
};
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (window == null) {
|
||||
Rectangle bounds = frame.getBounds();
|
||||
window = new JWindow(mainFrame);
|
||||
JList<String> winList = new JList<>(NAMES);
|
||||
winList.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
dispose.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
window.add(winList);
|
||||
window.setLocation(bounds.x + bounds.width + 20, bounds.y);
|
||||
window.pack();
|
||||
window.setVisible(true);
|
||||
button.setText("hide (ESC)");
|
||||
} else {
|
||||
dispose.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(button);
|
||||
exceptionString = "Accessible JList push button with simple window test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public void createPushButtonHeavyWeight() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList in a popup in a heavy weight window.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the show button and press space.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear popup menu items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JButton button = new JButton("show");
|
||||
button.setPreferredSize(new Dimension(100, 35));
|
||||
|
||||
button.addActionListener(new ActionListener() {
|
||||
private Popup popup = null;
|
||||
|
||||
final Runnable dispose = () -> {
|
||||
popup.hide();
|
||||
popup = null;
|
||||
button.requestFocus();
|
||||
button.setText("show");
|
||||
};
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (popup == null) {
|
||||
Rectangle bounds = frame.getBounds();
|
||||
PopupFactory factory = PopupFactory.getSharedInstance();
|
||||
JList<String> winList = new JList<>(NAMES);
|
||||
winList.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
dispose.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
popup = factory.getPopup(frame, winList, bounds.x + bounds.width + 20, bounds.y);
|
||||
Window c = SwingUtilities.getWindowAncestor(winList);
|
||||
if (c != null) {
|
||||
c.setAutoRequestFocus(true);
|
||||
c.setFocusableWindowState(true);
|
||||
}
|
||||
popup.show();
|
||||
button.setText("hide (ESC)");
|
||||
} else {
|
||||
dispose.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(button);
|
||||
exceptionString = "Accessible JList push button with heavy weight window test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public static class AccessibleJListTestRenderer extends JPanel implements ListCellRenderer {
|
||||
private JLabel labelAJT = new JLabel("AJL");
|
||||
private JLabel itemName = new JLabel();
|
||||
|
||||
AccessibleJListTestRenderer() {
|
||||
super(new FlowLayout());
|
||||
setFocusable(false);
|
||||
layoutComponents();
|
||||
}
|
||||
|
||||
private void layoutComponents() {
|
||||
add(labelAJT);
|
||||
add(itemName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = super.getPreferredSize();
|
||||
return new Dimension(Math.min(size.width, 245), size.height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
itemName.setText(((String) value));
|
||||
|
||||
getAccessibleContext().setAccessibleName(labelAJT.getText() + ", " + itemName.getText());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
93
test/jdk/java/awt/a11y/AccessibleJTabbedPaneTest.java
Normal file
93
test/jdk/java/awt/a11y/AccessibleJTabbedPaneTest.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8264303
|
||||
* @summary Test implementation of NSAccessibilityTabPanel protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJTabbedPaneTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class AccessibleJTabbedPaneTest extends AccessibleComponentTest {
|
||||
|
||||
@Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
void createTabPane() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTabbedPane.\n\n"
|
||||
+ "Turn screen reader on, and tab to the JTabbedPane.\n"
|
||||
+ "Use page up and page down arrow buttons to move through the tabs.\n\n"
|
||||
+ "If you can hear selected tab names tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JTabbedPane tabbedPane = new JTabbedPane();
|
||||
|
||||
JPanel panel1 = new JPanel();
|
||||
String[] names = {"One", "Two", "Three", "Four", "Five"};
|
||||
JList list = new JList(names);
|
||||
JLabel fieldName = new JLabel("Text field:");
|
||||
JTextField textField = new JTextField("some text");
|
||||
fieldName.setLabelFor(textField);
|
||||
panel1.add(fieldName);
|
||||
panel1.add(textField);
|
||||
panel1.add(list);
|
||||
tabbedPane.addTab("Tab 1", panel1);
|
||||
JPanel panel2 = new JPanel();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
panel2.add(new JCheckBox("CheckBox " + String.valueOf(i + 1)));
|
||||
}
|
||||
tabbedPane.addTab("tab 2", panel2);
|
||||
JPanel panel = new JPanel();
|
||||
panel.add(tabbedPane);
|
||||
|
||||
exceptionString = "AccessibleJTabbedPane test failed!";
|
||||
createUI(panel, "AccessibleJTabbedPaneTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleJTabbedPaneTest test = new AccessibleJTabbedPaneTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(test::createTabPane);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
114
test/jdk/java/awt/a11y/AccessibleJTableTest.java
Normal file
114
test/jdk/java/awt/a11y/AccessibleJTableTest.java
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267388
|
||||
* @summary Test implementation of NSAccessibilityTable protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJTableTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AccessibleJTableTest extends AccessibleComponentTest {
|
||||
private static final String[] columnNames = {"One", "Two", "Three"};
|
||||
private static final String[][] data = {
|
||||
{"One1", "Two1", "Three1"},
|
||||
{"One2", "Two2", "Three2"},
|
||||
{"One3", "Two3", "Three3"},
|
||||
{"One4", "Two4", "Three4"},
|
||||
{"One5", "Two5", "Three5"}
|
||||
};
|
||||
|
||||
@Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
public void createUI() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTable.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the table.\n"
|
||||
+ "On Windows press the arrow buttons to move through the table.\n\n"
|
||||
+ "On MacOS, use the up and down arrow buttons to move through rows, and VoiceOver fast navigation to move through columns.\n\n"
|
||||
+ "If you can hear table cells ctrl+tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JTable table = new JTable(data, columnNames);
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
panel.add(scrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTable test failed!";
|
||||
super.createUI(panel, "AccessibleJTableTest");
|
||||
}
|
||||
|
||||
public void createUINamed() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of named JTable.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the table.\n"
|
||||
+ "Press the ctrl+tab button to move to second table.\n\n"
|
||||
+ "If you can hear second table name: \"second table\" - ctrl+tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JTable table = new JTable(data, columnNames);
|
||||
JTable secondTable = new JTable(data, columnNames);
|
||||
secondTable.getAccessibleContext().setAccessibleName("Second table");
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
JScrollPane secondScrollPane = new JScrollPane(secondTable);
|
||||
panel.add(scrollPane);
|
||||
panel.add(secondScrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTable test failed!";
|
||||
super.createUI(panel, "AccessibleJTableTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleJTableTest test = new AccessibleJTableTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createUI);
|
||||
countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createUINamed);
|
||||
countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
239
test/jdk/java/awt/a11y/AccessibleJTreeTest.java
Normal file
239
test/jdk/java/awt/a11y/AccessibleJTreeTest.java
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267387
|
||||
* @summary Test implementation of NSAccessibilityOutLine protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJTreeTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreeCellRenderer;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.util.Hashtable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AccessibleJTreeTest extends AccessibleComponentTest {
|
||||
|
||||
@Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
public void createSampleTree() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTree.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the tree.\n"
|
||||
+ "Press the arrow buttons to move through the tree.\n\n"
|
||||
+ "If you can hear tree components tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
String root = "Root";
|
||||
String[] nodes = new String[] {"One node", "Two node"};
|
||||
String[][] leafs = new String[][]{{"leaf 1.1", "leaf 1.2", "leaf 1.3", "leaf 1.4"},
|
||||
{"leaf 2.1", "leaf 2.2", "leaf 2.3", "leaf 2.4"}};
|
||||
|
||||
Hashtable<String, String[]> data = new Hashtable<String, String[]>();
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
data.put(nodes[i], leafs[i]);
|
||||
}
|
||||
|
||||
JTree tree = new JTree(data);
|
||||
tree.setRootVisible(true);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(tree);
|
||||
panel.add(scrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTree sample item test failed!";
|
||||
super.createUI(panel, "AccessibleJTreeTest");
|
||||
}
|
||||
|
||||
public void createSampleTreeUnvisableRoot() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTree with invisible root.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the tree.\n"
|
||||
+ "Press the arrow buttons to move through the tree.\n\n"
|
||||
+ "If you can hear tree components tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
String root = "Root";
|
||||
String[] nodes = new String[] {"One node", "Two node"};
|
||||
String[][] leafs = new String[][]{{"leaf 1.1", "leaf 1.2", "leaf 1.3", "leaf 1.4"},
|
||||
{"leaf 2.1", "leaf 2.2", "leaf 2.3", "leaf 2.4"}};
|
||||
|
||||
Hashtable<String, String[]> data = new Hashtable<String, String[]>();
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
data.put(nodes[i], leafs[i]);
|
||||
}
|
||||
|
||||
JTree tree = new JTree(data);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(tree);
|
||||
panel.add(scrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTree sample item invisible root test failed!";
|
||||
super.createUI(panel, "AccessibleJTreeTest");
|
||||
}
|
||||
|
||||
public void createSampleTreeNamed() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of named JTree.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the tree.\n"
|
||||
+ "Press the tab button to move to second tree.\\n\n"
|
||||
+ "If you can hear second tree name: \"second tree\" - tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
String root = "Root";
|
||||
String[] nodes = new String[] {"One node", "Two node"};
|
||||
String[][] leafs = new String[][]{{"leaf 1.1", "leaf 1.2", "leaf 1.3", "leaf 1.4"},
|
||||
{"leaf 2.1", "leaf 2.2", "leaf 2.3", "leaf 2.4"}};
|
||||
|
||||
Hashtable<String, String[]> data = new Hashtable<String, String[]>();
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
data.put(nodes[i], leafs[i]);
|
||||
}
|
||||
|
||||
JTree tree = new JTree(data);
|
||||
JTree secondTree = new JTree(data);
|
||||
secondTree.getAccessibleContext().setAccessibleName("Second tree");
|
||||
tree.setRootVisible(true);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(tree);
|
||||
JScrollPane secondScrollPane = new JScrollPane(secondTree);
|
||||
panel.add(scrollPane);
|
||||
panel.add(secondScrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTree named test failed!";
|
||||
super.createUI(panel, "AccessibleJTreeTest");
|
||||
}
|
||||
|
||||
|
||||
public void createRendererTree() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTree using renderer.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the tree.\n"
|
||||
+ "Press the arrow buttons to move through the tree.\n\n"
|
||||
+ "If you can hear tree components tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
String root = "Root";
|
||||
String[] nodes = new String[] {"One node", "Two node"};
|
||||
String[][] leafs = new String[][]{{"leaf 1.1", "leaf 1.2", "leaf 1.3", "leaf 1.4"},
|
||||
{"leaf 2.1", "leaf 2.2", "leaf 2.3", "leaf 2.4"}};
|
||||
|
||||
Hashtable<String, String[]> data = new Hashtable<String, String[]>();
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
data.put(nodes[i], leafs[i]);
|
||||
}
|
||||
|
||||
JTree tree = new JTree(data);
|
||||
tree.setRootVisible(true);
|
||||
tree.setCellRenderer(new AccessibleJTreeTestRenderer());
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(tree);
|
||||
panel.add(scrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTree renderer item test failed!";
|
||||
super.createUI(panel, "AccessibleJTreeTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleJTreeTest test = new AccessibleJTreeTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createSampleTree);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createSampleTreeNamed);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createSampleTreeUnvisableRoot);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createRendererTree);
|
||||
countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(AccessibleComponentTest.exceptionString);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AccessibleJTreeTestRenderer extends JPanel implements TreeCellRenderer {
|
||||
private JLabel labelAJT = new JLabel("AJT");
|
||||
private JLabel itemName = new JLabel();
|
||||
|
||||
AccessibleJTreeTestRenderer() {
|
||||
super(new FlowLayout());
|
||||
setFocusable(false);
|
||||
layoutComponents();
|
||||
}
|
||||
|
||||
private void layoutComponents() {
|
||||
add(labelAJT);
|
||||
add(itemName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||
itemName.setText((String) (((DefaultMutableTreeNode) value).getUserObject()));
|
||||
|
||||
getAccessibleContext().setAccessibleName(labelAJT.getText() + ", " + itemName.getText());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = super.getPreferredSize();
|
||||
return new Dimension(Math.min(size.width, 245), size.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
293
test/jdk/java/awt/a11y/AccessibleTextTest.java
Normal file
293
test/jdk/java/awt/a11y/AccessibleTextTest.java
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8262031
|
||||
* @summary Test implementation of NSAccessibilityNavigableStaticTest and NSAccessibilityStaticText protocols peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleTextTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AccessibleTextTest extends AccessibleComponentTest {
|
||||
@Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
private void createSimpleLabel() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JLabel.\n\n"
|
||||
+ "Turn screen reader on.\n"
|
||||
+ "On MacOS, use the VO navigation keys to read the label text;\n"
|
||||
+ "ON Windows with JAWS, use window virtualization (insert+alt+w and arrows) to read the label text;\n"
|
||||
+ "ON Windows with NVDA, use the browse cursor (insert+num4 or insert+num6) to read the label text;\n\n"
|
||||
+ "If you can hear text from label tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JLabel label = new JLabel("this is a label");
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(label);
|
||||
exceptionString = "Simple label test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createOneLineTexField() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTextField.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text field and type some characters.\n\n"
|
||||
+ "If you can hear input results according to your screen reader settings, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JTextField textField = new JTextField("some text to edit");
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textField);
|
||||
exceptionString = "Simple text field test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createPassField() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JPasswordField.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the password field and type some characters.\n\n"
|
||||
+ "If you can hear sounds specific to your screen reader when interacting with password fields, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JPasswordField passwordField = new JPasswordField("12345678");
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(passwordField);
|
||||
exceptionString = "Simple passfield field test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createNamedTextField() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of named JTextField.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text field.\n\n"
|
||||
+ "If you can hear in addition to the fact that this text field is also the names of these fields, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JTextField textField = new JTextField("some text 1");
|
||||
textField.getAccessibleContext().setAccessibleName("This is the first text field:");
|
||||
|
||||
JLabel label = new JLabel("This is the second text field:");
|
||||
JTextField secondTextField = new JTextField("some text 2");
|
||||
label.setLabelFor(secondTextField);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textField);
|
||||
panel.add(label);
|
||||
panel.add(secondTextField);
|
||||
exceptionString = "Named text field test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createTextArea() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTextArea.\n\n"
|
||||
+ "Turn screen reader on and press the arrow keys.\n\n"
|
||||
+ "If you can hear this instructions, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
exceptionString = "Simple text area test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createEditableTextArea() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of editable JTextArea.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text area and type some characters.\n\n"
|
||||
+ "If you can hear input results according to your screen reader settings, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JTextArea textArea = new JTextArea("some text to edit");
|
||||
JLabel label = new JLabel(textArea.getText().length() + " chars");
|
||||
label.setLabelFor(textArea);
|
||||
textArea.setEditable(true);
|
||||
textArea.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
label.setText(String.valueOf(textArea.getText().length()) + " chars");
|
||||
}
|
||||
});
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textArea);
|
||||
panel.add(label);
|
||||
exceptionString = "Editable text area test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createTextPane() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of text in JTextPane.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text pane and press the arrow keys.\n\n"
|
||||
+ "If you can hear text, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
String str = "Line 1\nLine 2\nLine 3";
|
||||
JTextPane textPane = new JTextPane();
|
||||
textPane.setEditable(false);
|
||||
textPane.setText(str);
|
||||
JTextArea textArea = new JTextArea();
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textPane);
|
||||
exceptionString = "Simple text pane test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createHTMLTextPane() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of html text in JTextPane.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text pane and press the arrow keys.\n\n"
|
||||
+ "If you can hear text, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
String str = "<html><h1>Header</h1><ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul></html>";
|
||||
JTextPane textPane = new JTextPane();
|
||||
textPane.setEditable(false);
|
||||
textPane.setContentType("text/html");
|
||||
textPane.setText(str);
|
||||
JTextArea textArea = new JTextArea();
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textPane);
|
||||
exceptionString = "HTML text pane test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createEditableTextPane() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of editable JTextPane.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text pane and type some characters.\n\n"
|
||||
+ "If you can hear input results according to your screen reader settings, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JTextPane textPane = new JTextPane();
|
||||
textPane.setText("some text to edit");
|
||||
JLabel label = new JLabel(textPane.getText().length() + " chars");
|
||||
label.setLabelFor(textPane);
|
||||
textPane.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
label.setText(String.valueOf(textPane.getText().length()) + " chars");
|
||||
}
|
||||
});
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textPane);
|
||||
panel.add(label);
|
||||
exceptionString = "Editable text pane test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleTextTest test = new AccessibleTextTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createSimpleLabel);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createOneLineTexField);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createPassField);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createNamedTextField);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createTextArea);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createEditableTextArea);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createTextPane);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createHTMLTextPane);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createEditableTextPane);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
69
test/jdk/java/awt/font/JNICheck/FreeTypeScalerJNICheck.java
Normal file
69
test/jdk/java/awt/font/JNICheck/FreeTypeScalerJNICheck.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8269223
|
||||
* @summary Verifies that -Xcheck:jni issues no warnings from freetypeScaler.c
|
||||
* @library /test/lib
|
||||
* @run main FreeTypeScalerJNICheck
|
||||
*/
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.swing.JFrame;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class FreeTypeScalerJNICheck {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 0 && args[0].equals("runtest")) {
|
||||
runTest();
|
||||
} else {
|
||||
ProcessBuilder pb = ProcessTools.createTestJvm("-Xcheck:jni", FreeTypeScalerJNICheck.class.getName(), "runtest");
|
||||
OutputAnalyzer oa = ProcessTools.executeProcess(pb);
|
||||
oa.shouldContain("Done").shouldNotContain("WARNING").shouldHaveExitValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void runTest() {
|
||||
String families[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
|
||||
BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g2d = bi.createGraphics();
|
||||
|
||||
for (String ff : families)
|
||||
{
|
||||
Font font = new Font(ff, Font.PLAIN, 12);
|
||||
Rectangle2D bounds = font.getStringBounds("test", g2d.getFontRenderContext());
|
||||
g2d.setFont(font);
|
||||
FontMetrics metrics = g2d.getFontMetrics(font);
|
||||
System.out.println(bounds.getHeight() + metrics.getHeight()); // use bounds and metrics
|
||||
}
|
||||
|
||||
System.out.println("Done");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,20 +245,23 @@ public class CustomComboBoxFocusTest {
|
||||
System.out.println("Request focus on " + target);
|
||||
final Component c = target.getEditor().getEditorComponent();
|
||||
|
||||
c.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
SwingUtilities.invokeLater(focusHandler);
|
||||
}
|
||||
if (c.isFocusOwner()) {
|
||||
SwingUtilities.invokeLater(focusHandler);
|
||||
} else {
|
||||
c.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
SwingUtilities.invokeLater(focusHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
c.requestFocus();
|
||||
}
|
||||
});
|
||||
|
||||
c.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
public Step nextStep() {
|
||||
|
||||
@@ -56,21 +56,21 @@ public class JBRServiceTest {
|
||||
* it in 'instanceof' statement will cause loading this interface, which may in turn cause NoClassDefFoundError.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// Declaring variables is safe
|
||||
SampleJBRApi.V1 service;
|
||||
// We pass lambda instead of plain class. This allows JBRService#load to deal with NoClassDefFoundErrors
|
||||
service = JBRService.load(() -> SampleJBRApi.V1.class);
|
||||
// Null-checking variables is safe too
|
||||
Objects.requireNonNull(service);
|
||||
// When we ensured that SampleJBRApi.V1 is available, we can use anything that's inside
|
||||
service.someMethod1(null);
|
||||
// We can also create SampleJBRApi.V1.SomeDataClass instances, as we know they're supported with V1
|
||||
service.someMethod1(new SampleJBRApi.V1.SomeDataClass());
|
||||
|
||||
// But don't try doing 'service instanceof SampleJBRApi.V2' as it may cause NoClassDefFoundErrors!
|
||||
SampleJBRApi.V2 service2 = Objects.requireNonNull(JBRService.load(() -> SampleJBRApi.V2.class));
|
||||
// Versioned service interfaces are inherited, so V2 gives you access to both V2 and V1 API
|
||||
service2.someMethod1(service2.someMethod2());
|
||||
// // Declaring variables is safe
|
||||
// SampleJBRApi.V1 service;
|
||||
// // We pass lambda instead of plain class. This allows JBRService#load to deal with NoClassDefFoundErrors
|
||||
// service = JBRService.load(() -> SampleJBRApi.V1.class);
|
||||
// // Null-checking variables is safe too
|
||||
// Objects.requireNonNull(service);
|
||||
// // When we ensured that SampleJBRApi.V1 is available, we can use anything that's inside
|
||||
// service.someMethod1(null);
|
||||
// // We can also create SampleJBRApi.V1.SomeDataClass instances, as we know they're supported with V1
|
||||
// service.someMethod1(new SampleJBRApi.V1.SomeDataClass());
|
||||
//
|
||||
// // But don't try doing 'service instanceof SampleJBRApi.V2' as it may cause NoClassDefFoundErrors!
|
||||
// SampleJBRApi.V2 service2 = Objects.requireNonNull(JBRService.load(() -> SampleJBRApi.V2.class));
|
||||
// // Versioned service interfaces are inherited, so V2 gives you access to both V2 and V1 API
|
||||
// service2.someMethod1(service2.someMethod2());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ public class TypeaheadRequestFocusTest {
|
||||
initFinished.get(10, TimeUnit.SECONDS);
|
||||
clickOn(frameField);
|
||||
SwingUtilities.invokeAndWait(TypeaheadRequestFocusTest::showPopup);
|
||||
robot.delay(1000);
|
||||
pressAndRelease(KeyEvent.VK_ENTER);
|
||||
pressAndRelease(KeyEvent.VK_A);
|
||||
typedInPopup.get(10, TimeUnit.SECONDS);
|
||||
|
||||
133
test/jdk/jb/java/awt/Window/ModalDialogMinimizeOnKDE.java
Normal file
133
test/jdk/jb/java/awt/Window/ModalDialogMinimizeOnKDE.java
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
* 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 javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Regression test for JBR-3726 Modal windows 'disappear' on minimize in KDE
|
||||
* @key headful
|
||||
* @requires os.family == "linux"
|
||||
* @modules java.desktop/java.awt:open
|
||||
* java.desktop/sun.awt
|
||||
* java.desktop/sun.awt.X11:open
|
||||
*/
|
||||
|
||||
public class ModalDialogMinimizeOnKDE {
|
||||
private static final CompletableFuture<Boolean> dialogShown = new CompletableFuture<>();
|
||||
private static JFrame frame;
|
||||
private static JDialog dialog;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (!isKDE()) {
|
||||
System.out.println("This test is only valid for KDE");
|
||||
return;
|
||||
}
|
||||
Robot robot = new Robot();
|
||||
try {
|
||||
SwingUtilities.invokeLater(ModalDialogMinimizeOnKDE::initUI);
|
||||
dialogShown.get(5, TimeUnit.SECONDS);
|
||||
robot.delay(1000);
|
||||
minimize(dialog);
|
||||
robot.delay(1000);
|
||||
if (frame.getState() != Frame.ICONIFIED) {
|
||||
throw new RuntimeException("Parent frame isn't minimized");
|
||||
}
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(ModalDialogMinimizeOnKDE::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame = new JFrame("ModalDialogMinimizeOnKDE");
|
||||
frame.setSize(300, 200);
|
||||
frame.setVisible(true);
|
||||
dialog = new JDialog(frame, true);
|
||||
dialog.setSize(200, 100);
|
||||
dialog.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowOpened(WindowEvent e) {
|
||||
dialogShown.complete(true);
|
||||
}
|
||||
});
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame != null) frame.dispose();
|
||||
}
|
||||
|
||||
private static boolean isKDE() throws Exception {
|
||||
Class<?> xwmCls = Class.forName("sun.awt.X11.XWM");
|
||||
|
||||
Field kdeField = xwmCls.getDeclaredField("KDE2_WM");
|
||||
kdeField.setAccessible(true);
|
||||
|
||||
Method wmidMethod = xwmCls.getDeclaredMethod("getWMID");
|
||||
wmidMethod.setAccessible(true);
|
||||
|
||||
return kdeField.get(null).equals(wmidMethod.invoke(null));
|
||||
}
|
||||
|
||||
// We need to simulate user minimizing the dialog using button in title bar.
|
||||
// As we don't know the location of the button (and it can depend on KDE version),
|
||||
// we'll just use Xlib to minimize the window.
|
||||
private static void minimize(JDialog dialog) throws Exception {
|
||||
Class<?> toolkitCls = Class.forName("sun.awt.SunToolkit");
|
||||
Method lockMethod = toolkitCls.getDeclaredMethod("awtLock");
|
||||
Method unlockMethod = toolkitCls.getDeclaredMethod("awtUnlock");
|
||||
|
||||
Class<?> xToolkitClass = Class.forName("sun.awt.X11.XToolkit");
|
||||
Method displayMethod = xToolkitClass.getDeclaredMethod("getDisplay");
|
||||
|
||||
Class<?> wrapperClass = Class.forName("sun.awt.X11.XlibWrapper");
|
||||
Method iconifyMethod = wrapperClass.getDeclaredMethod("XIconifyWindow",
|
||||
long.class, long.class, long.class);
|
||||
iconifyMethod.setAccessible(true);
|
||||
|
||||
Class<?> windowClass = Class.forName("sun.awt.X11.XBaseWindow");
|
||||
Method windowMethod = windowClass.getDeclaredMethod("getWindow");
|
||||
Method screenMethod = windowClass.getDeclaredMethod("getScreenNumber");
|
||||
screenMethod.setAccessible(true);
|
||||
|
||||
Field peerField = Component.class.getDeclaredField("peer");
|
||||
peerField.setAccessible(true);
|
||||
Object peer = peerField.get(dialog);
|
||||
|
||||
lockMethod.invoke(null);
|
||||
try {
|
||||
iconifyMethod.invoke(null,
|
||||
displayMethod.invoke(null),
|
||||
windowMethod.invoke(peer),
|
||||
screenMethod.invoke(peer));
|
||||
} finally {
|
||||
unlockMethod.invoke(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,13 +61,11 @@ public class NestedDialogHideTest {
|
||||
button3 = new JButton("Hide");
|
||||
button3.addActionListener(eee -> d.setVisible(false));
|
||||
d2.add(button3);
|
||||
d2.pack();
|
||||
d2.setLocation(240, 240);
|
||||
d2.setBounds(240, 240, 200, 200);
|
||||
d2.setVisible(true);
|
||||
});
|
||||
d.add(button2);
|
||||
d.pack();
|
||||
d.setLocation(220, 220);
|
||||
d.setBounds(220, 220, 200, 200);
|
||||
d.setVisible(true);
|
||||
d.addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
@@ -77,8 +75,7 @@ public class NestedDialogHideTest {
|
||||
});
|
||||
});
|
||||
frame.add(button1);
|
||||
frame.pack();
|
||||
frame.setLocation(200, 200);
|
||||
frame.setBounds(200, 200, 200, 200);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java 8158801 wind
|
||||
java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java 8158801 windows-all
|
||||
java/awt/Mixing/MixingOnDialog.java 8225777 linux-all
|
||||
java/awt/Mixing/NonOpaqueInternalFrame.java 7124549 macosx-all
|
||||
java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java 8168388 linux-all
|
||||
java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java 8168388,8253184 linux-all,windows-all
|
||||
java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java 6829264 generic-all
|
||||
java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java 8080982 generic-all
|
||||
java/awt/datatransfer/SystemFlavorMap/AddFlavorTest.java 8079268 linux-all
|
||||
@@ -231,11 +231,14 @@ java/awt/TrayIcon/TrayIconPopup/TrayIconPopupClickTest.java 8150540 windows-all,
|
||||
java/awt/TrayIcon/TrayIconPopup/TrayIconPopupTest.java 8150540 windows-all
|
||||
java/awt/TrayIcon/PopupMenuLeakTest/PopupMenuLeakTest.java 8196440 linux-all
|
||||
|
||||
java/awt/Window/ShapedAndTranslucentWindows/SetShapeAndClick.java 8197936 macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/SetShapeDynamicallyAndClick.java 8013450 macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/SetShape.java 8253184 windows-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/SetShapeAndClick.java 8197936,8253184 macosx-all,windows-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/SetShapeDynamicallyAndClick.java 8013450,8253184 macosx-all,windows-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/ShapedTranslucentWindowClick.java 8013450 macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/TranslucentChoice.java 8221901 linux-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/TranslucentChoice.java 8221901,8253184 linux-all,windows-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/TranslucentWindowClick.java 8253184 windows-all
|
||||
java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java 8222323 windows-all
|
||||
java/awt/Window/MultiWindowApp/MultiWindowAppTest.java 8253184 windows-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/FocusAWTTest.java 8222328 windows-all,linux-all,macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/Shaped.java 8222328 windows-all,linux-all,macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/ShapedByAPI.java 8222328 windows-all,linux-all,macosx-all
|
||||
@@ -281,49 +284,50 @@ java/awt/Component/SetEnabledPerformance/SetEnabledPerformance.java 8165863 maco
|
||||
java/awt/Clipboard/HTMLTransferTest/HTMLTransferTest.java 8017454 macosx-all
|
||||
java/awt/Focus/NonFocusableWindowTest/NoEventsTest.java 8000171 windows-all
|
||||
java/awt/Frame/MiscUndecorated/RepaintTest.java 8079267 windows-all,linux-all
|
||||
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8253184 windows-all
|
||||
java/awt/Robot/ModifierRobotKey/ModifierRobotKeyTest.java 8157173 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal2Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal3Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal4Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal5Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal6Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal1Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal2Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal3Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal4Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal5Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal6Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal7Test.java 7186009 macosx-all,linux-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal1Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal2Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal3Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal4Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal5Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal6Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal1Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal2Test.java 7186009 macosx-all,linux-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal3Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal4Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal5Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal6Test.java 7186009 macosx-all,linux-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal7Test.java 7186009 macosx-all,linux-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal2Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal3Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal4Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal5Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal6Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal1Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal2Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal3Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal4Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal5Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal6Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal7Test.java 7186009,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal1Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal2Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal3Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal4Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal5Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal6Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal1Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal2Test.java 7186009,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal3Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal4Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal5Test.java 7186009,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal6Test.java 7186009,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal7Test.java 7186009,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal1Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal2Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal3Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal4Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal5Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal6Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal7Test.java 8196430 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDAppModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDDocModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDModelessTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDNonModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDSetModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDToolkitModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFAppModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFSetModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFToolkitModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal7Test.java 8196430,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDAppModalTest.java 8198665,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDDocModalTest.java 8198665,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDModelessTest.java 8198665,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDNonModalTest.java 8198665,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDSetModalTest.java 8198665,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDToolkitModalTest.java 8198665,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFAppModalTest.java 8198665,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFSetModalTest.java 8198665,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFToolkitModalTest.java 8198665,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFWModeless1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFWModeless2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFWNonModal1Test.java 8198665 macosx-all
|
||||
@@ -384,9 +388,10 @@ java/awt/Modal/ModalExclusionTests/ToolkitExcludeFramePageSetupTest.java 8196431
|
||||
java/awt/Modal/ModalExclusionTests/ToolkitExcludeFramePrintSetupTest.java 8196431 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFAppModal2Test.java 8058813 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFModeless2Test.java 8196191 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFDocModalTest.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFModelessTest.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFNonModalTest.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFAppModalTest.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFDocModalTest.java 8196432,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFModelessTest.java 8196432,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFNonModalTest.java 8196432,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsModelessTest.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsNonModalTest.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFDWDocModalTest.java 8196432 linux-all
|
||||
@@ -408,81 +413,121 @@ java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDNonModal1Test.java 819643
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDNonModal2Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDNonModal3Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDNonModal4Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFAppModal1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFDocModal2Test.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal2Test.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFAppModal3Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFDocModal1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFDocModal2Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFDocModal3Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFModeless1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFModeless3Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal2Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal3Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalInternalFrameTest/ModalInternalFrameTest.java 8253184 windows-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs3Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs4Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs5Test.java 8198665 macosx-all
|
||||
java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java 8177326 macosx-all
|
||||
java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java 8177326,8253184 macosx-all,windows-all
|
||||
java/awt/Mouse/EnterExitEvents/DragWindowTest.java 8023562 macosx-all
|
||||
java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8005021 macosx-all
|
||||
java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java 8051455 macosx-all
|
||||
java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java 7124407 macosx-all
|
||||
java/awt/Mouse/RemovedComponentMouseListener/RemovedComponentMouseListener.java 8157170 macosx-all
|
||||
java/awt/Modal/ToFront/DialogToFrontModeless1Test.java 8213530 linux-all
|
||||
java/awt/Modal/ToFront/DialogToFrontNonModalTest.java 8221899 linux-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal1Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal2Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal3Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal4Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal5Test.java 8196441 macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal6Test.java 8196441 linux-all
|
||||
java/awt/Modal/ToBack/ToBackModal1Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackModal2Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackModal3Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackModal4Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal1Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal2Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal3Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal4Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal5Test.java 8196441 macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal1Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal2Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal3Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal4Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal5Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackModeless1Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackModeless2Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackModeless3Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackModeless4Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackModeless5Test.java 8196441 macosx-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal1Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal2Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal3Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal4Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal5Test.java 8196441 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal1Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal2Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal3Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal4Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal5Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal6Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal1Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal2Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal3Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal4Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal5Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal6Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModal1Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModal2Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModal3Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModal4Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModal5Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModal6Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModeless1Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModeless2Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModeless3Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModeless4Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModeless5Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopModeless6Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal1Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal2Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal3Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal4Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal5Test.java 8198666 macosx-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal6Test.java 8198666 macosx-all
|
||||
java/awt/Modal/ToFront/DialogToFrontAppModalTest.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/DialogToFrontDocModalTest.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/DialogToFrontModalTest.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/DialogToFrontModeless1Test.java 8213530,8253184 linux-all,windows-all
|
||||
java/awt/Modal/ToFront/DialogToFrontNonModalTest.java 8221899,8253184 linux-all,windows-all
|
||||
java/awt/Modal/ToFront/DialogToFrontTKModalTest.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontAppModal1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontAppModal2Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontAppModal3Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontAppModal4Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontAppModal5Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontDocModal1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontDocModal2Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontModal1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontModal2Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontModal3Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontModal4Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontModal5Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontModeless1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontNonModalTest.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontTKModal1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontTKModal2Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontTKModal3Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontTKModal4Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToFront/FrameToFrontTKModal5Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal1Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal2Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal3Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal4Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal5Test.java 8196441,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal6Test.java 8196441,8253184 linux-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModal1Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModal2Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModal3Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModal4Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModal5Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToBack/ToBackModal6Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal1Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal2Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal3Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal4Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal5Test.java 8196441,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal6Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal1Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal2Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal3Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal4Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal5Test.java 8196441,8253184 linux-all,macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal6Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToBack/ToBackModeless1Test.java 8196441,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModeless2Test.java 8196441,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModeless3Test.java 8196441,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModeless4Test.java 8196441,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModeless5Test.java 8196441,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackModeless6Test.java 8253184 windows-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal1Test.java 8196441,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal2Test.java 8196441,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal3Test.java 8196441,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal4Test.java 8196441,8253184 macosx-all,linux-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal5Test.java 8196441,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal6Test.java 8253184 windows-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal1Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal2Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal3Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal4Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal5Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopAppModal6Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal1Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal2Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal3Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal4Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal5Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopDocModal6Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModal1Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModal2Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModal3Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModal4Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModal5Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModal6Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModeless1Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModeless2Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModeless3Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModeless4Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModeless5Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopModeless6Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal1Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal2Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal3Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal4Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal5Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/Modal/OnTop/OnTopTKModal6Test.java 8198666,8253184 macosx-all,windows-all
|
||||
java/awt/List/SingleModeDeselect/SingleModeDeselect.java 8196367 windows-all
|
||||
java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java 8061235 macosx-all
|
||||
javax/print/PrintSEUmlauts/PrintSEUmlauts.java 8135174 generic-all
|
||||
|
||||
52
test/jdk/tools/launcher/MuslCheck.java
Normal file
52
test/jdk/tools/launcher/MuslCheck.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary Verifies that the launcher doesn't unnecessarily set LD_LIBRARY_PATH on
|
||||
* non-musl-based systems.
|
||||
* @requires (os.family == "linux")
|
||||
* @library /test/lib
|
||||
* @run main MuslCheck
|
||||
*/
|
||||
|
||||
import java.util.Map;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class MuslCheck extends TestHelper {
|
||||
public static void main(String[] args) throws Exception {
|
||||
final Map<String, String> envMap = Map.of("_JAVA_LAUNCHER_DEBUG", "true");
|
||||
TestResult tr = doExec(envMap, javaCmd, "-help");
|
||||
if (!tr.contains("mustsetenv:")) {
|
||||
throw new RuntimeException("Test error: the necessary tracing is missing in the output");
|
||||
}
|
||||
|
||||
if (!tr.contains("micro seconds to check for the musl compatibility layer for glibc")) {
|
||||
throw new RuntimeException("The check for libgcompat seems to be missing");
|
||||
}
|
||||
|
||||
if (tr.contains("mustsetenv: TRUE")) {
|
||||
throw new RuntimeException("launcher is not supposed to set LD_LIBRARY_PATH");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user