mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-25 10:49:41 +01:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc754d6d76 | ||
|
|
0c3b4bf9b7 | ||
|
|
216bf92575 | ||
|
|
4c6f3e4510 | ||
|
|
8d74e8e30b | ||
|
|
f4a8e51d4a | ||
|
|
db9032755a | ||
|
|
db017fbd56 | ||
|
|
479ceadb35 | ||
|
|
ad1d5061a9 | ||
|
|
ff0a538ebd | ||
|
|
c81adfed61 | ||
|
|
2ccf6b65a7 | ||
|
|
a34eeb7735 | ||
|
|
ba6b9c085e | ||
|
|
04f1cf9b47 | ||
|
|
80c6e03ec4 | ||
|
|
9001a78701 | ||
|
|
703cab8d0d | ||
|
|
3c9cdc9251 | ||
|
|
032805520d | ||
|
|
b37f7cfdb1 | ||
|
|
3668d631ca | ||
|
|
7fa3ea24ac | ||
|
|
8a521cbf64 | ||
|
|
fe9601aa6d |
@@ -1354,18 +1354,109 @@ static int _print_module(const char* fname, address base_address,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static errno_t convert_to_UTF16(char const* source_str, UINT source_encoding, LPWSTR* dest_utf16_str) {
|
||||
const int flag_source_str_is_null_terminated = -1;
|
||||
const int flag_estimate_chars_count = 0;
|
||||
int utf16_chars_count_estimated = MultiByteToWideChar(source_encoding,
|
||||
MB_ERR_INVALID_CHARS,
|
||||
source_str, flag_source_str_is_null_terminated,
|
||||
NULL, flag_estimate_chars_count);
|
||||
if (utf16_chars_count_estimated == 0) {
|
||||
// Probably source_str contains characters that cannot be represented in the source_encoding given.
|
||||
*dest_utf16_str = NULL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*dest_utf16_str = NEW_C_HEAP_ARRAY(WCHAR, utf16_chars_count_estimated, mtInternal);
|
||||
|
||||
int utf16_chars_count_real = MultiByteToWideChar(source_encoding,
|
||||
MB_ERR_INVALID_CHARS,
|
||||
source_str, flag_source_str_is_null_terminated,
|
||||
*dest_utf16_str, utf16_chars_count_estimated);
|
||||
assert(utf16_chars_count_real == utf16_chars_count_estimated, "length already checked above");
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// Converts a string in the "platform" encoding to UTF16.
|
||||
static errno_t convert_to_UTF16(char const* platform_str, LPWSTR* utf16_str) {
|
||||
return convert_to_UTF16(platform_str, CP_ACP, utf16_str);
|
||||
}
|
||||
|
||||
static errno_t convert_UTF8_to_UTF16(char const* utf8_str, LPWSTR* utf16_str) {
|
||||
return convert_to_UTF16(utf8_str, CP_UTF8, utf16_str);
|
||||
}
|
||||
|
||||
// Converts a wide-character string in UTF-16 encoding to the 8-bit "platform" encoding.
|
||||
// Unless the platform encoding is UTF-8, not all characters in the source string can be represented in the dest string.
|
||||
// The function succeeds in this case anyway and just replaces these with a certain character.
|
||||
static errno_t convert_UTF16_to_platform(LPWSTR source_utf16_str, char*& dest_str) {
|
||||
const int flag_source_str_is_null_terminated = -1;
|
||||
const int flag_estimate_chars_count = 0;
|
||||
int chars_count_estimated = WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
source_utf16_str, flag_source_str_is_null_terminated,
|
||||
NULL, flag_estimate_chars_count, NULL, NULL);
|
||||
if (chars_count_estimated == 0) {
|
||||
dest_str = NULL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
dest_str = NEW_C_HEAP_ARRAY(CHAR, chars_count_estimated, mtInternal);
|
||||
|
||||
int chars_count_real = WideCharToMultiByte(CP_ACP,
|
||||
0,
|
||||
source_utf16_str, flag_source_str_is_null_terminated,
|
||||
dest_str, chars_count_estimated, NULL, NULL);
|
||||
assert(chars_count_real == chars_count_estimated, "length already checked above");
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
class MemoryReleaserW : public StackObj {
|
||||
private:
|
||||
WCHAR* _object_ptr;
|
||||
|
||||
public:
|
||||
MemoryReleaserW(WCHAR * object_ptr) : _object_ptr(object_ptr) {}
|
||||
~MemoryReleaserW() { if (_object_ptr != NULL) FREE_C_HEAP_ARRAY(WCHAR, _object_ptr); }
|
||||
};
|
||||
|
||||
class MemoryReleaser : public StackObj {
|
||||
private:
|
||||
CHAR* _object_ptr;
|
||||
|
||||
public:
|
||||
MemoryReleaser(CHAR * object_ptr) : _object_ptr(object_ptr) {}
|
||||
~MemoryReleaser() { if (_object_ptr != NULL) FREE_C_HEAP_ARRAY(CHAR, _object_ptr); }
|
||||
};
|
||||
|
||||
// Loads .dll/.so and
|
||||
// in case of error it checks if .dll/.so was built for the
|
||||
// same architecture as Hotspot is running on
|
||||
void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
||||
log_info(os)("attempting shared library load of %s", name);
|
||||
// The name given is in UTF-8.
|
||||
void * os::dll_load(const char *utf8_name, char *ebuf, int ebuflen) {
|
||||
LPWSTR utf16_name = NULL;
|
||||
errno_t err = convert_UTF8_to_UTF16(utf8_name, &utf16_name);
|
||||
MemoryReleaserW release_utf16_name(utf16_name);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
errno = err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* platform_name = NULL; // name of the library converted to the "platform" encoding for use in log messages
|
||||
errno_t ignored_err = convert_UTF16_to_platform(utf16_name, platform_name);
|
||||
MemoryReleaser release_platform_name(platform_name);
|
||||
|
||||
log_info(os)("attempting shared library load of %s", platform_name);
|
||||
|
||||
void * result = LoadLibraryW(utf16_name);
|
||||
|
||||
void * result = LoadLibrary(name);
|
||||
if (result != NULL) {
|
||||
Events::log(NULL, "Loaded shared library %s", name);
|
||||
Events::log(NULL, "Loaded shared library %s", platform_name);
|
||||
// Recalculate pdb search path if a DLL was loaded successfully.
|
||||
SymbolEngine::recalc_search_path();
|
||||
log_info(os)("shared library load of %s was successful", name);
|
||||
log_info(os)("shared library load of %s was successful", platform_name);
|
||||
return result;
|
||||
}
|
||||
DWORD errcode = GetLastError();
|
||||
@@ -1373,8 +1464,8 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
||||
// It may or may not be overwritten below (in the for loop and just above)
|
||||
lasterror(ebuf, (size_t) ebuflen);
|
||||
ebuf[ebuflen - 1] = '\0';
|
||||
Events::log(NULL, "Loading shared library %s failed, error code %lu", name, errcode);
|
||||
log_info(os)("shared library load of %s failed, error code %lu", name, errcode);
|
||||
Events::log(NULL, "Loading shared library %s failed, error code %lu", platform_name, errcode);
|
||||
log_info(os)("shared library load of %s failed, error code %lu", platform_name, errcode);
|
||||
|
||||
if (errcode == ERROR_MOD_NOT_FOUND) {
|
||||
strncpy(ebuf, "Can't find dependent libraries", ebuflen - 1);
|
||||
@@ -1387,7 +1478,7 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
||||
// for an architecture other than Hotspot is running in
|
||||
// - then print to buffer "DLL was built for a different architecture"
|
||||
// else call os::lasterror to obtain system error message
|
||||
int fd = ::open(name, O_RDONLY | O_BINARY, 0);
|
||||
int fd = ::wopen(utf16_name, O_RDONLY | O_BINARY, 0);
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -4246,27 +4337,6 @@ static void file_attribute_data_to_stat(struct stat* sbuf, WIN32_FILE_ATTRIBUTE_
|
||||
}
|
||||
}
|
||||
|
||||
static errno_t convert_to_unicode(char const* char_path, LPWSTR* unicode_path) {
|
||||
// Get required buffer size to convert to Unicode
|
||||
int unicode_path_len = MultiByteToWideChar(CP_ACP,
|
||||
MB_ERR_INVALID_CHARS,
|
||||
char_path, -1,
|
||||
NULL, 0);
|
||||
if (unicode_path_len == 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*unicode_path = NEW_C_HEAP_ARRAY(WCHAR, unicode_path_len, mtInternal);
|
||||
|
||||
int result = MultiByteToWideChar(CP_ACP,
|
||||
MB_ERR_INVALID_CHARS,
|
||||
char_path, -1,
|
||||
*unicode_path, unicode_path_len);
|
||||
assert(result == unicode_path_len, "length already checked above");
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static errno_t get_full_path(LPCWSTR unicode_path, LPWSTR* full_path) {
|
||||
// Get required buffer size to convert to full path. The return
|
||||
// value INCLUDES the terminating null character.
|
||||
@@ -4327,7 +4397,7 @@ static wchar_t* wide_abs_unc_path(char const* path, errno_t & err, int additiona
|
||||
set_path_prefix(buf, &prefix, &prefix_off, &needs_fullpath);
|
||||
|
||||
LPWSTR unicode_path = NULL;
|
||||
err = convert_to_unicode(buf, &unicode_path);
|
||||
err = convert_to_UTF16(buf, &unicode_path);
|
||||
FREE_C_HEAP_ARRAY(char, buf);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
return NULL;
|
||||
|
||||
@@ -3442,6 +3442,7 @@ JVM_END
|
||||
|
||||
// Library support ///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// The name of the library is in UTF8
|
||||
JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name))
|
||||
//%note jvm_ct
|
||||
JVMWrapper("JVM_LoadLibrary");
|
||||
@@ -3455,14 +3456,10 @@ JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name))
|
||||
if (load_result == NULL) {
|
||||
char msg[1024];
|
||||
jio_snprintf(msg, sizeof msg, "%s: %s", name, ebuf);
|
||||
// Since 'ebuf' may contain a string encoded using
|
||||
// platform encoding scheme, we need to pass
|
||||
// Exceptions::unsafe_to_utf8 to the new_exception method
|
||||
// as the last argument. See bug 6367357.
|
||||
Handle h_exception =
|
||||
Exceptions::new_exception(thread,
|
||||
vmSymbols::java_lang_UnsatisfiedLinkError(),
|
||||
msg, Exceptions::unsafe_to_utf8);
|
||||
msg);
|
||||
|
||||
THROW_HANDLE_0(h_exception);
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ inline int g_isfinite(jdouble f) { return _finite(f); }
|
||||
// Visual Studio 2005 deprecates POSIX names - use ISO C++ names instead
|
||||
#if _MSC_VER >= 1400
|
||||
#define open _open
|
||||
#define wopen _wopen
|
||||
#define close _close
|
||||
#define read _read
|
||||
#define write _write
|
||||
|
||||
@@ -338,7 +338,6 @@ JNIEXPORT jboolean JNICALL
|
||||
Java_java_lang_ClassLoader_00024NativeLibrary_load0
|
||||
(JNIEnv *env, jobject this, jstring name, jboolean isBuiltin)
|
||||
{
|
||||
const char *cname;
|
||||
jint jniVersion;
|
||||
jthrowable cause;
|
||||
void * handle;
|
||||
@@ -347,7 +346,8 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load0
|
||||
if (!initIDs(env))
|
||||
return JNI_FALSE;
|
||||
|
||||
cname = JNU_GetStringPlatformChars(env, name, 0);
|
||||
char cname_buf[128];
|
||||
char * cname = getUTF(env, name, cname_buf, sizeof(cname_buf));
|
||||
if (cname == 0)
|
||||
return JNI_FALSE;
|
||||
handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname);
|
||||
@@ -400,7 +400,9 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load0
|
||||
loaded = JNI_TRUE;
|
||||
|
||||
done:
|
||||
JNU_ReleaseStringPlatformChars(env, name, cname);
|
||||
if (cname != NULL && cname != cname_buf) {
|
||||
free(cname);
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
|
||||
|
||||
@@ -211,17 +211,6 @@ ImageFileReaderTable::ImageFileReaderTable() : _count(0), _max(_growth) {
|
||||
assert(_table != NULL && "allocation failed");
|
||||
}
|
||||
|
||||
ImageFileReaderTable::~ImageFileReaderTable() {
|
||||
for (u4 i = 0; i < _count; i++) {
|
||||
ImageFileReader* image = _table[i];
|
||||
|
||||
if (image != NULL) {
|
||||
delete image;
|
||||
}
|
||||
}
|
||||
free(_table);
|
||||
}
|
||||
|
||||
// Add a new image entry to the table.
|
||||
void ImageFileReaderTable::add(ImageFileReader* image) {
|
||||
if (_count == _max) {
|
||||
|
||||
@@ -371,7 +371,12 @@ private:
|
||||
|
||||
public:
|
||||
ImageFileReaderTable();
|
||||
~ImageFileReaderTable();
|
||||
// ~ImageFileReaderTable()
|
||||
// Bug 8166727
|
||||
//
|
||||
// WARNING: Should never close jimage files.
|
||||
// Threads may still be running during shutdown.
|
||||
//
|
||||
|
||||
// Return the number of entries.
|
||||
inline u4 count() { return _count; }
|
||||
|
||||
@@ -189,7 +189,10 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
|
||||
|
||||
protected synchronized long getNativeFontPtr() {
|
||||
if (nativeFontPtr == 0L) {
|
||||
nativeFontPtr = createNativeFont(nativeFontName, style);
|
||||
/* Do not try to create native italic font when isFakeItalic
|
||||
* is true, otherwise we can make it italic twice */
|
||||
nativeFontPtr = createNativeFont(nativeFontName, style &
|
||||
(isFakeItalic ? ~Font.ITALIC : -1));
|
||||
}
|
||||
return nativeFontPtr;
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ class CAccessibility implements PropertyChangeListener {
|
||||
}, c);
|
||||
}
|
||||
|
||||
public static void requestSelection(final Accessible a, final Component c) {
|
||||
public static void requestSelection(final Accessible a, final Component c, final boolean selected) {
|
||||
if (a == null) return;
|
||||
invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
@@ -480,7 +480,15 @@ class CAccessibility implements PropertyChangeListener {
|
||||
if (pac == null) return;
|
||||
AccessibleSelection as = pac.getAccessibleSelection();
|
||||
if (as == null) return;
|
||||
as.addAccessibleSelection(i);
|
||||
if (parent instanceof JList) {
|
||||
((JList) parent).setSelectedIndex(i);
|
||||
return;
|
||||
}
|
||||
if (selected) {
|
||||
as.addAccessibleSelection(i);
|
||||
} else {
|
||||
as.removeAccessibleSelection(i);
|
||||
}
|
||||
}
|
||||
}, c);
|
||||
}
|
||||
|
||||
@@ -100,8 +100,12 @@ public class CEmbeddedFrame extends EmbeddedFrame {
|
||||
deltaY, NSEvent.SCROLL_PHASE_UNSUPPORTED);
|
||||
}
|
||||
|
||||
public void handleKeyEvent(NSEvent nsEvent) {
|
||||
responder.handleKeyEvent(nsEvent);
|
||||
public void handleKeyEvent(int eventType, int modifierFlags, String characters,
|
||||
String charsIgnoringMods, boolean isRepeat, short keyCode,
|
||||
boolean needsKeyTyped) {
|
||||
responder.handleKeyEvent(eventType, modifierFlags, characters,
|
||||
charsIgnoringMods, /*charsIgnoringModifiersAndShift*/ null,
|
||||
keyCode, needsKeyTyped, isRepeat);
|
||||
}
|
||||
|
||||
public void handleInputEvent(String text) {
|
||||
|
||||
@@ -29,24 +29,20 @@ import sun.awt.SunToolkit;
|
||||
import sun.awt.event.KeyEventProcessing;
|
||||
import sun.lwawt.LWWindowPeer;
|
||||
import sun.lwawt.PlatformEventNotifier;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;import java.util.MissingResourceException;import java.util.ResourceBundle;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Translates NSEvents/NPCocoaEvents into AWT events.
|
||||
*/
|
||||
final class CPlatformResponder {
|
||||
|
||||
private static final PlatformLogger keyboardLog = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformResponder");
|
||||
|
||||
private final PlatformEventNotifier eventNotifier;
|
||||
private final boolean isNpapiCallback;
|
||||
private int lastKeyPressCode = KeyEvent.VK_UNDEFINED;
|
||||
@@ -61,7 +57,6 @@ final class CPlatformResponder {
|
||||
private int lastDraggedRelativeX;
|
||||
private int lastDraggedRelativeY;
|
||||
|
||||
|
||||
CPlatformResponder(final PlatformEventNotifier eventNotifier,
|
||||
final boolean isNpapiCallback) {
|
||||
this.eventNotifier = eventNotifier;
|
||||
@@ -166,41 +161,6 @@ final class CPlatformResponder {
|
||||
-roundDelta, -delta, null);
|
||||
}
|
||||
|
||||
private void handleFlagChangedEvent(int modifierFlags, short keyCode) {
|
||||
int[] in = new int[] {modifierFlags, keyCode};
|
||||
int[] out = new int[3]; // [jkeyCode, jkeyLocation, jkeyType]
|
||||
|
||||
NSEvent.nsKeyModifiersToJavaKeyInfo(in, out);
|
||||
|
||||
int jkeyCode = out[0];
|
||||
int jkeyLocation = out[1];
|
||||
int jeventType = out[2];
|
||||
|
||||
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
|
||||
long when = System.currentTimeMillis();
|
||||
|
||||
if (jeventType == KeyEvent.KEY_PRESSED) {
|
||||
lastKeyPressCode = jkeyCode;
|
||||
}
|
||||
eventNotifier.notifyKeyEvent(jeventType, when, jmodifiers,
|
||||
jkeyCode, KeyEvent.CHAR_UNDEFINED, jkeyLocation);
|
||||
}
|
||||
|
||||
private static char mapNsCharsToCompatibleWithJava (char ch) {
|
||||
switch (ch) {
|
||||
case 0x0003: // NSEnterCharacter
|
||||
case 0x000d: // NSCarriageReturnCharacter
|
||||
return 0x000a; // NSNewlineCharacter
|
||||
// case 0x007f: // NSDeleteCharacter
|
||||
// return 0x0008; // NSBackspaceCharacter
|
||||
case 0xF728: // NSDeleteFunctionKey
|
||||
return 0x0008; // NSDeleteCharacter
|
||||
case 0x0019: // NSBackTabCharacter
|
||||
return 0x0009; // NSTabCharacter
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
private static final String [] cyrillicKeyboardLayouts = new String [] {
|
||||
"com.apple.keylayout.Russian",
|
||||
"com.apple.keylayout.RussianWin",
|
||||
@@ -216,181 +176,6 @@ final class CPlatformResponder {
|
||||
return Arrays.stream(cyrillicKeyboardLayouts).anyMatch(l -> l.equals(LWCToolkit.getKeyboardLayoutId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles key events.
|
||||
*/
|
||||
void handleKeyEvent(NSEvent nsEvent)
|
||||
{
|
||||
|
||||
if (!KeyEventProcessing.useNationalLayouts || isCyrillicKeyboardLayout()) {
|
||||
handleKeyEvent(
|
||||
nsEvent.getType(),
|
||||
nsEvent.getModifierFlags(),
|
||||
nsEvent.getOldCharacters(),
|
||||
nsEvent.getOldCharactersIgnoringModifiers(),
|
||||
nsEvent.getKeyCode(),
|
||||
true,
|
||||
false
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isFlagsChangedEvent =
|
||||
isNpapiCallback ? (nsEvent.getType() == CocoaConstants.NPCocoaEventFlagsChanged) :
|
||||
(nsEvent.getType() == CocoaConstants.NSFlagsChanged);
|
||||
|
||||
int jeventType = KeyEvent.KEY_PRESSED;
|
||||
int jkeyCode = KeyEvent.VK_UNDEFINED;
|
||||
int jkeyLocation = KeyEvent.KEY_LOCATION_UNKNOWN;
|
||||
boolean postsTyped = false;
|
||||
boolean spaceKeyTyped = false;
|
||||
|
||||
|
||||
if (isFlagsChangedEvent) {
|
||||
handleFlagChangedEvent(nsEvent.getModifierFlags(), nsEvent.getKeyCode());
|
||||
return;
|
||||
}
|
||||
|
||||
int jmodifiers = NSEvent.nsToJavaModifiers(nsEvent.getModifierFlags());
|
||||
|
||||
boolean metaAltCtrlAreNotPressed = (jmodifiers &
|
||||
(InputEvent.META_DOWN_MASK
|
||||
| InputEvent.ALT_DOWN_MASK
|
||||
| InputEvent.CTRL_DOWN_MASK)
|
||||
) == 0;
|
||||
|
||||
boolean shiftIsPressed = (jmodifiers & InputEvent.SHIFT_DOWN_MASK) != 0;
|
||||
|
||||
boolean useShiftedCharacters = metaAltCtrlAreNotPressed && shiftIsPressed;
|
||||
|
||||
boolean shiftAltDownAreNotPressed = (jmodifiers &
|
||||
(InputEvent.META_DOWN_MASK
|
||||
| InputEvent.ALT_DOWN_MASK
|
||||
| InputEvent.SHIFT_DOWN_MASK)
|
||||
) == 0;
|
||||
|
||||
boolean ctrlIsPressed = (jmodifiers & InputEvent.CTRL_DOWN_MASK) != 0;
|
||||
|
||||
boolean isISOControl = false;
|
||||
|
||||
char checkedChar = (nsEvent.getCharacters() == null
|
||||
|| nsEvent.getCharacters().isEmpty()) ? KeyEvent.CHAR_UNDEFINED : nsEvent.getCharacters().charAt(0);
|
||||
|
||||
if (shiftAltDownAreNotPressed && ctrlIsPressed) {
|
||||
if (Character.isISOControl(checkedChar)) {
|
||||
isISOControl = true;
|
||||
}
|
||||
}
|
||||
|
||||
char characterToGetKeyCode = KeyEvent.CHAR_UNDEFINED;
|
||||
|
||||
boolean charactersIgnoringModifiersIsValid = (nsEvent.getCharactersIgnoringModifiers() != null && nsEvent.getCharactersIgnoringModifiers().length() > 0);
|
||||
boolean charactersIsValid = (nsEvent.getCharacters() != null && nsEvent.getCharacters().length() > 0);
|
||||
|
||||
// We use this char to find a character that is printed depending on pressing modifiers
|
||||
characterToGetKeyCode = charactersIgnoringModifiersIsValid
|
||||
? nsEvent.getCharactersIgnoringModifiers().charAt(0)
|
||||
: charactersIsValid ? nsEvent.getCharacters().charAt(0) : KeyEvent.CHAR_UNDEFINED;
|
||||
|
||||
if (useShiftedCharacters && nsEvent.getCharactersIgnoringModifiers() != null && !nsEvent.getCharactersIgnoringModifiers().isEmpty()) {
|
||||
characterToGetKeyCode = nsEvent.getCharactersIgnoringModifiers().charAt(0);
|
||||
} else if (nsEvent.getCharactersIgnoringModifiersAndShift() != null && !nsEvent.getCharactersIgnoringModifiersAndShift().isEmpty()) {
|
||||
characterToGetKeyCode = nsEvent.getCharactersIgnoringModifiersAndShift().charAt(0);
|
||||
} else if (nsEvent.getCharacters() != null && !nsEvent.getCharacters().isEmpty() && metaAltCtrlAreNotPressed && shiftIsPressed) {
|
||||
characterToGetKeyCode = checkedChar;
|
||||
}
|
||||
|
||||
// We use char candidate if modifiers are not used
|
||||
// otherwise, we use char ignoring modifiers
|
||||
int[] in = new int[] {
|
||||
characterToGetKeyCode,
|
||||
nsEvent.isHasDeadKey() ? 1 : 0,
|
||||
nsEvent.getModifierFlags(),
|
||||
nsEvent.getKeyCode(),
|
||||
/*useNationalLayouts*/ 1
|
||||
};
|
||||
|
||||
int[] out = new int[3]; // [jkeyCode, jkeyLocation, deadChar]
|
||||
|
||||
postsTyped = NSEvent.nsToJavaKeyInfo(in, out);
|
||||
|
||||
char characterToSendWithTheEvent = characterToGetKeyCode;
|
||||
|
||||
if(nsEvent.isHasDeadKey()){
|
||||
characterToSendWithTheEvent = (char) out[2];
|
||||
jkeyCode = nsEvent.getDeadKeyCode();
|
||||
if(characterToSendWithTheEvent == 0){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If Pinyin Simplified input method is selected, CAPS_LOCK key is supposed to switch
|
||||
// input to la tin letters.
|
||||
// It is necessary to use charIgnoringModifiers instead of charCandidate for event
|
||||
// generation in such case to avoid uppercase letters in text components.
|
||||
LWCToolkit lwcToolkit = (LWCToolkit)Toolkit.getDefaultToolkit();
|
||||
if (lwcToolkit.getLockingKeyState(KeyEvent.VK_CAPS_LOCK) &&
|
||||
Locale.SIMPLIFIED_CHINESE.equals(lwcToolkit.getDefaultKeyboardLocale())) {
|
||||
characterToSendWithTheEvent = characterToGetKeyCode;
|
||||
}
|
||||
|
||||
jkeyCode = out[0];
|
||||
|
||||
jkeyLocation = out[1];
|
||||
jeventType = isNpapiCallback ? NSEvent.npToJavaEventType(nsEvent.getType()) :
|
||||
NSEvent.nsToJavaEventType(nsEvent.getType());
|
||||
|
||||
|
||||
if (isISOControl) {
|
||||
characterToSendWithTheEvent = checkedChar;
|
||||
} else {
|
||||
characterToSendWithTheEvent = mapNsCharsToCompatibleWithJava(characterToSendWithTheEvent);
|
||||
}
|
||||
|
||||
String stringWithChar = NSEvent.nsToJavaChar(characterToSendWithTheEvent, nsEvent.getModifierFlags(), spaceKeyTyped);
|
||||
characterToSendWithTheEvent = stringWithChar == null ? KeyEvent.CHAR_UNDEFINED : stringWithChar.charAt(0);
|
||||
|
||||
long when = System.currentTimeMillis();
|
||||
|
||||
if (jeventType == KeyEvent.KEY_PRESSED) {
|
||||
lastKeyPressCode = jkeyCode;
|
||||
}
|
||||
|
||||
eventNotifier.notifyKeyEvent(jeventType, when, jmodifiers,
|
||||
jkeyCode, characterToSendWithTheEvent, jkeyLocation);
|
||||
|
||||
// Current browser may be sending input events, so don't
|
||||
// post the KEY_TYPED here.
|
||||
postsTyped &= true;
|
||||
|
||||
// That's the reaction on the PRESSED (not RELEASED) event as it comes to
|
||||
// appear in MacOSX.
|
||||
// Modifier keys (shift, etc) don't want to send TYPED events.
|
||||
// On the other hand we don't want to generate keyTyped events
|
||||
// for clipboard related shortcuts like Meta + [CVX]
|
||||
if (jeventType == KeyEvent.KEY_PRESSED && postsTyped &&
|
||||
(jmodifiers & KeyEvent.META_DOWN_MASK) == 0) {
|
||||
|
||||
char characterToSendWithTypedEvent = KeyEvent.CHAR_UNDEFINED;
|
||||
|
||||
if (nsEvent.getCharacters()!= null ) {
|
||||
characterToSendWithTypedEvent = mapNsCharsToCompatibleWithJava(checkedChar);
|
||||
stringWithChar = NSEvent.nsToJavaChar(characterToSendWithTypedEvent, nsEvent.getModifierFlags(), spaceKeyTyped);
|
||||
characterToSendWithTypedEvent = stringWithChar == null ? KeyEvent.CHAR_UNDEFINED : stringWithChar.charAt(0);
|
||||
}
|
||||
|
||||
boolean nonInputMethodsModifiersAreNotPressed = (jmodifiers &
|
||||
(InputEvent.META_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)
|
||||
) == 0;
|
||||
|
||||
if (nonInputMethodsModifiersAreNotPressed) {
|
||||
eventNotifier.notifyKeyEvent(KeyEvent.KEY_TYPED, when, jmodifiers,
|
||||
jkeyCode, characterToSendWithTypedEvent,
|
||||
KeyEvent.KEY_LOCATION_UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handleInputEvent(String text) {
|
||||
if (text != null) {
|
||||
int index = 0, length = text.length();
|
||||
@@ -412,10 +197,9 @@ final class CPlatformResponder {
|
||||
|
||||
/**
|
||||
* Handles key events.
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
void handleKeyEvent(int eventType, int modifierFlags, String chars, String charsIgnoringModifiers,
|
||||
void handleKeyEvent(int eventType, int modifierFlags, String chars,
|
||||
String charsIgnoringModifiers, String charsIgnoringModifiersAndShift,
|
||||
short keyCode, boolean needsKeyTyped, boolean needsKeyReleased) {
|
||||
boolean isFlagsChangedEvent =
|
||||
isNpapiCallback ? (eventType == CocoaConstants.NPCocoaEventFlagsChanged) :
|
||||
@@ -425,6 +209,9 @@ final class CPlatformResponder {
|
||||
int jkeyCode = KeyEvent.VK_UNDEFINED;
|
||||
int jkeyLocation = KeyEvent.KEY_LOCATION_UNKNOWN;
|
||||
boolean postsTyped = false;
|
||||
boolean spaceKeyTyped = false;
|
||||
|
||||
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
|
||||
|
||||
char testChar = KeyEvent.CHAR_UNDEFINED;
|
||||
boolean isDeadChar = (chars!= null && chars.length() == 0);
|
||||
@@ -441,12 +228,26 @@ final class CPlatformResponder {
|
||||
} else {
|
||||
if (chars != null && chars.length() > 0) {
|
||||
testChar = chars.charAt(0);
|
||||
|
||||
//Check if String chars contains SPACE character.
|
||||
if (chars.trim().isEmpty()) {
|
||||
spaceKeyTyped = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for JBR-2981
|
||||
int metaAltCtrlMods = KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK;
|
||||
boolean metaAltCtrlAreNotPressed = (jmodifiers & metaAltCtrlMods) == 0;
|
||||
boolean useShiftedCharacter = ((jmodifiers & KeyEvent.SHIFT_DOWN_MASK) == KeyEvent.SHIFT_DOWN_MASK) && metaAltCtrlAreNotPressed;
|
||||
|
||||
char testCharIgnoringModifiers = charsIgnoringModifiers != null && charsIgnoringModifiers.length() > 0 ?
|
||||
charsIgnoringModifiers.charAt(0) : KeyEvent.CHAR_UNDEFINED;
|
||||
if (!useShiftedCharacter && charsIgnoringModifiersAndShift != null && charsIgnoringModifiersAndShift.length() > 0) {
|
||||
testCharIgnoringModifiers = charsIgnoringModifiersAndShift.charAt(0);
|
||||
}
|
||||
|
||||
int[] in = new int[] {testCharIgnoringModifiers, isDeadChar ? 1 : 0, modifierFlags, keyCode, /*useNationalLayouts*/ 0};
|
||||
int useNationalLayouts = (!KeyEventProcessing.useNationalLayouts || isCyrillicKeyboardLayout()) ? 0 : 1;
|
||||
int[] in = new int[] {testCharIgnoringModifiers, isDeadChar ? 1 : 0, modifierFlags, keyCode, useNationalLayouts};
|
||||
int[] out = new int[3]; // [jkeyCode, jkeyLocation, deadChar]
|
||||
|
||||
postsTyped = NSEvent.nsToJavaKeyInfo(in, out);
|
||||
@@ -480,7 +281,7 @@ final class CPlatformResponder {
|
||||
NSEvent.nsToJavaEventType(eventType);
|
||||
}
|
||||
|
||||
char javaChar = NSEvent.nsToJavaCharOld(testChar, modifierFlags);
|
||||
char javaChar = NSEvent.nsToJavaChar(testChar, modifierFlags, spaceKeyTyped);
|
||||
// Some keys may generate a KEY_TYPED, but we can't determine
|
||||
// what that character is. That's likely a bug, but for now we
|
||||
// just check for CHAR_UNDEFINED.
|
||||
@@ -488,8 +289,6 @@ final class CPlatformResponder {
|
||||
postsTyped = false;
|
||||
}
|
||||
|
||||
|
||||
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
|
||||
long when = System.currentTimeMillis();
|
||||
|
||||
if (jeventType == KeyEvent.KEY_PRESSED) {
|
||||
|
||||
@@ -220,8 +220,10 @@ public class CPlatformView extends CFRetainedResource {
|
||||
}
|
||||
}
|
||||
|
||||
private void deliverKeyEvent(NSEvent nsEvent) {
|
||||
responder.handleKeyEvent(nsEvent);
|
||||
private void deliverKeyEvent(NSEvent event) {
|
||||
responder.handleKeyEvent(event.getType(), event.getModifierFlags(), event.getCharacters(),
|
||||
event.getCharactersIgnoringModifiers(), event.getCharactersIgnoringModifiersAndShift(),
|
||||
event.getKeyCode(), true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -745,6 +745,8 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
execute(CPlatformWindow::nativeSetNSWindowLocationByPlatform);
|
||||
}
|
||||
|
||||
this.visible = visible;
|
||||
|
||||
// Actually show or hide the window
|
||||
LWWindowPeer blocker = (peer == null)? null : peer.getBlocker();
|
||||
if (blocker == null || !visible) {
|
||||
@@ -796,7 +798,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
});
|
||||
});
|
||||
}
|
||||
this.visible = visible;
|
||||
|
||||
// Manage the extended state when showing
|
||||
if (visible) {
|
||||
|
||||
@@ -298,8 +298,7 @@ final class NSEvent {
|
||||
* There is a small number of NS characters that need to be converted
|
||||
* into other characters before we pass them to AWT.
|
||||
*/
|
||||
static native String nsToJavaChar(char nsChar, int modifierFlags, boolean spaceKeyTyped);
|
||||
static native char nsToJavaCharOld(char nsChar, int modifierFlags);
|
||||
static native char nsToJavaChar(char nsChar, int modifierFlags, boolean spaceKeyTyped);
|
||||
|
||||
static boolean isPopupTrigger(int jmodifiers) {
|
||||
final boolean isRightButtonDown = ((jmodifiers & InputEvent.BUTTON3_DOWN_MASK) != 0);
|
||||
|
||||
@@ -222,6 +222,7 @@ struct CharToVKEntry {
|
||||
static const struct CharToVKEntry charToDeadVKTable[] = {
|
||||
{0x0060, java_awt_event_KeyEvent_VK_DEAD_GRAVE},
|
||||
{0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
|
||||
{0xFFFF, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
|
||||
{0x0384, java_awt_event_KeyEvent_VK_DEAD_ACUTE}, // Unicode "GREEK TONOS" -- Greek keyboard, semicolon key
|
||||
{0x005E, java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX},
|
||||
{0x007E, java_awt_event_KeyEvent_VK_DEAD_TILDE},
|
||||
@@ -887,42 +888,20 @@ JNF_COCOA_ENTER(env);
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_NSEvent
|
||||
* Method: nsToJavaChar
|
||||
* Signature: (CI)Ljava/lang/String
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_sun_lwawt_macosx_NSEvent_nsToJavaChar
|
||||
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags, jboolean spaceKeyTyped)
|
||||
{
|
||||
jstring charAsString = NULL;
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
NSString * nsStr = [NSString stringWithFormat: @"%C", nsChar];
|
||||
charAsString = JNFNSToJavaString(env, nsStr);
|
||||
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
return charAsString;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_NSEvent
|
||||
* Method: nsToJavaChar
|
||||
* Signature: (CI)C
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_lwawt_macosx_NSEvent_nsToJavaCharOld
|
||||
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags)
|
||||
Java_sun_lwawt_macosx_NSEvent_nsToJavaChar
|
||||
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags, jboolean spaceKeyTyped)
|
||||
{
|
||||
jchar javaChar = 0;
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
javaChar = NsCharToJavaChar(nsChar, modifierFlags, false);
|
||||
javaChar = NsCharToJavaChar(nsChar, modifierFlags, spaceKeyTyped);
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
|
||||
@@ -374,6 +374,21 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
if (![self hasMarkedText] && !fInPressAndHold) {
|
||||
[self deliverJavaKeyEventHelper: event];
|
||||
}
|
||||
// Workaround for 8020209: special case for "Cmd =" and "Cmd ."
|
||||
// because Cocoa calls performKeyEquivalent twice for these keystrokes
|
||||
NSUInteger modFlags = [event modifierFlags] &
|
||||
(NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask);
|
||||
if (modFlags == NSCommandKeyMask) {
|
||||
NSString *eventChars = [event charactersIgnoringModifiers];
|
||||
if ([eventChars length] == 1) {
|
||||
unichar ch = [eventChars characterAtIndex:0];
|
||||
if (ch == '=' || ch == '.' ||
|
||||
ch == 0x044E) { // small cyrillic u
|
||||
[[NSApp mainMenu] performKeyEquivalent: event];
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSUInteger deviceIndependentModifierFlagsMask =
|
||||
[event modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||
@@ -507,10 +522,10 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
|
||||
const UCKeyboardLayout *keyboardLayout = (UCKeyboardLayout*)CFDataGetBytePtr(keyLayoutPtr);
|
||||
|
||||
UInt32 isDeadKeyPressed;
|
||||
UInt32 isDeadKeyPressed = 0;
|
||||
UInt32 lengthOfBuffer = 8;
|
||||
UniChar stringWithChars[lengthOfBuffer];
|
||||
UniCharCount actualLength;
|
||||
UniCharCount actualLength = 0;
|
||||
|
||||
OSStatus status = UCKeyTranslate(
|
||||
keyboardLayout,
|
||||
@@ -770,7 +785,7 @@ 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 = [[[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] platformAxElement] autorelease];
|
||||
(*env)->DeleteLocalRef(env, jcomponent);
|
||||
return ax;
|
||||
}
|
||||
@@ -803,9 +818,9 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
}
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
return YES;
|
||||
|
||||
- (BOOL)isAccessibilityElement {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (id)accessibilityHitTest:(NSPoint)point
|
||||
@@ -815,7 +830,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);
|
||||
|
||||
@@ -844,7 +859,7 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
|
||||
{
|
||||
id focused = [self accessibilityFocusedUIElement];
|
||||
if (![focused respondsToSelector:@selector(accessibilitySelectedText)]) return nil;
|
||||
return [focused accessibilitySelectedTextAttribute];
|
||||
return [focused accessibilitySelectedText];
|
||||
}
|
||||
|
||||
// same as above, but converts to RTFD
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <jni.h>
|
||||
|
||||
extern NSMutableDictionary *sActions;
|
||||
extern NSMutableDictionary *sActionSelectores;
|
||||
extern NSMutableArray *sAllActionSelectores;
|
||||
void initializeActions();
|
||||
|
||||
@protocol JavaAccessibilityAction
|
||||
|
||||
|
||||
@@ -28,11 +28,18 @@
|
||||
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
NSMutableDictionary *sActions = nil;
|
||||
NSMutableDictionary *sActionSelectores = nil;
|
||||
NSMutableArray *sAllActionSelectores = nil;
|
||||
void initializeActions();
|
||||
|
||||
@implementation JavaAxAction
|
||||
|
||||
- (id)initWithEnv:(JNIEnv *)env withAccessibleAction:(jobject)accessibleAction withIndex:(jint)index withComponent:(jobject)component
|
||||
{
|
||||
if (sActions == nil) {
|
||||
initializeActions();
|
||||
}
|
||||
self = [super init];
|
||||
if (self) {
|
||||
fAccessibleAction = JNFNewWeakGlobalRef(env, accessibleAction);
|
||||
@@ -130,3 +137,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:@"toggle popup"];
|
||||
[sActions setObject:NSAccessibilityPressAction forKey:@"toggleexpand"];
|
||||
|
||||
sActionSelectores = [[NSMutableDictionary alloc] initWithCapacity:actionsCount];
|
||||
|
||||
[sActionSelectores setObject:NSStringFromSelector(@selector(accessibilityPerformPress)) forKey:NSAccessibilityPressAction];
|
||||
[sActionSelectores setObject:NSStringFromSelector(@selector(accessibilityPerformShowMenu)) forKey:NSAccessibilityShowMenuAction];
|
||||
[sActionSelectores setObject:NSStringFromSelector(@selector(accessibilityPerformDecrement)) forKey:NSAccessibilityDecrementAction];
|
||||
[sActionSelectores setObject:NSStringFromSelector(@selector(accessibilityPerformIncrement)) forKey:NSAccessibilityIncrementAction];
|
||||
[sActionSelectores setObject:NSStringFromSelector(@selector(accessibilityPerformPick)) forKey:NSAccessibilityPickAction];
|
||||
|
||||
sAllActionSelectores = [[NSMutableArray alloc] initWithCapacity:actionsCount];
|
||||
|
||||
[sAllActionSelectores addObject:NSStringFromSelector(@selector(accessibilityPerformPick))];
|
||||
[sAllActionSelectores addObject:NSStringFromSelector(@selector(accessibilityPerformIncrement))];
|
||||
[sAllActionSelectores addObject:NSStringFromSelector(@selector(accessibilityPerformDecrement))];
|
||||
[sAllActionSelectores addObject:NSStringFromSelector(@selector(accessibilityPerformShowMenu))];
|
||||
[sAllActionSelectores addObject:NSStringFromSelector(@selector(accessibilityPerformPress))];
|
||||
}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
//#define JAVA_AX_DEBUG 1
|
||||
//#define JAVA_AX_NO_IGNORES 1
|
||||
//#define JAVA_AX_DEBUG_PARMS 1
|
||||
|
||||
// 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
|
||||
|
||||
@class JavaBaseAccessibility;
|
||||
|
||||
@protocol JavaBaseProvider
|
||||
|
||||
@property (nonatomic, retain) JavaBaseAccessibility *javaBase;
|
||||
|
||||
@end
|
||||
|
||||
@protocol PlatformAxElementProvider
|
||||
@required
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName;
|
||||
|
||||
@property (nonatomic, retain) NSObject <JavaBaseProvider> *platformAxElement;
|
||||
|
||||
@end
|
||||
|
||||
@interface JavaBaseAccessibility : NSObject <JavaBaseProvider, PlatformAxElementProvider> {
|
||||
NSView *fView;
|
||||
NSObject *fParent;
|
||||
|
||||
NSString *fNSRole;
|
||||
NSString *fJavaRole;
|
||||
|
||||
jint fIndex;
|
||||
jobject fAccessible;
|
||||
jobject fComponent;
|
||||
}
|
||||
|
||||
- (id)initWithParent:(NSObject*)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole;
|
||||
- (void)unregisterFromCocoaAXSystem;
|
||||
- (void)postValueChanged;
|
||||
- (void)postSelectedTextChanged;
|
||||
- (void)postSelectionChanged;
|
||||
- (BOOL)isEqual:(id)anObject;
|
||||
- (BOOL)isAccessibleWithEnv:(JNIEnv *)env forAccessible:(jobject)accessible;
|
||||
|
||||
+ (void)postFocusChanged:(id)message;
|
||||
|
||||
+ (NSArray *)childrenOfParent:(JavaBaseAccessibility *) parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored;
|
||||
+ (NSArray *)childrenOfParent:(JavaBaseAccessibility *) parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored recursive:(BOOL)recursive;
|
||||
+ (JavaBaseAccessibility *) createWithParent:(JavaBaseAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view;
|
||||
+ (JavaBaseAccessibility *) createWithAccessible:(jobject)jaccessible role:(NSString *)role index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view;
|
||||
+ (JavaBaseAccessibility *) createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)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.
|
||||
+ (JavaBaseAccessibility *) createWithParent:(JavaBaseAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)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
|
||||
+ (JavaBaseAccessibility *) createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view isCurrent:(BOOL)current;
|
||||
|
||||
@property(readonly) jobject accessible;
|
||||
@property(readonly) jobject component;
|
||||
@property(readonly) jint index;
|
||||
|
||||
- (jobject)axContextWithEnv:(JNIEnv *)env;
|
||||
- (NSView*)view;
|
||||
- (NSWindow*)window;
|
||||
- (id)parent;
|
||||
-(void)setParent:(id)javaBaseAccessibilityParent;
|
||||
- (NSString *)javaRole;
|
||||
- (NSString *)nsRole;
|
||||
- (BOOL)isMenu;
|
||||
- (BOOL)isSelected:(JNIEnv *)env;
|
||||
- (BOOL)isSelectable:(JNIEnv *)env;
|
||||
- (BOOL)isVisible:(JNIEnv *)env;
|
||||
- (NSSize)getSize;
|
||||
- (NSRect)getBounds;
|
||||
- (id)getFocusedElement;
|
||||
|
||||
@end
|
||||
@@ -1,719 +0,0 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaBaseAccessibility.h"
|
||||
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
|
||||
|
||||
#import <dlfcn.h>
|
||||
|
||||
#import "JavaBaseAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "JavaListAccessibility.h"
|
||||
#import "JavaTableAccessibility.h"
|
||||
#import "JavaListRowAccessibility.h"
|
||||
#import "JavaTableRowAccessibility.h"
|
||||
#import "JavaCellAccessibility.h"
|
||||
#import "JavaOutlineAccessibility.h"
|
||||
#import "JavaOutlineRowAccessibility.h"
|
||||
#import "JavaStaticTextAccessibility.h"
|
||||
#import "JavaNavigableTextAccessibility.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "AWTView.h"
|
||||
|
||||
// getChildrenAndRolesRecursive
|
||||
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRolesRecursive, sjc_CAccessibility, "getChildrenAndRolesRecursive", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZI)[Ljava/lang/Object;");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleComponent, sjc_CAccessibility, "getAccessibleComponent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleComponent;");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleValue, sjc_CAccessibility, "getAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleValue;");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleDescription, sjc_CAccessibility, "getAccessibleDescription", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_isFocusTraversable, sjc_CAccessibility, "isFocusTraversable", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Z");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleIndexInParent, sjc_CAccessibility, "getAccessibleIndexInParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
|
||||
|
||||
static JNF_CLASS_CACHE(sjc_CAccessible, "sun/lwawt/macosx/CAccessible");
|
||||
|
||||
static JNF_MEMBER_CACHE(jf_ptr, sjc_CAccessible, "ptr", "J");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getCAccessible, sjc_CAccessible, "getCAccessible", "(Ljavax/accessibility/Accessible;)Lsun/lwawt/macosx/CAccessible;");
|
||||
|
||||
static jobject sAccessibilityClass = NULL;
|
||||
|
||||
@implementation JavaBaseAccessibility
|
||||
|
||||
@synthesize platformAxElement;
|
||||
@synthesize javaBase;
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
NSString *className = [self getPlatformAxElementClassName];
|
||||
self.platformAxElement = className != NULL ? [[NSClassFromString(className) alloc] init] : self; // defaults to [self]
|
||||
self.platformAxElement.javaBase = self;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// to override in subclasses
|
||||
- (NSString *)getPlatformAxElementClassName
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
{
|
||||
self = [self init];
|
||||
if (self) {
|
||||
fParent = [parent retain];
|
||||
fView = [view retain];
|
||||
fJavaRole = [javaRole retain];
|
||||
|
||||
fAccessible = (*env)->NewWeakGlobalRef(env, accessible);
|
||||
(*env)->ExceptionClear(env); // in case of OOME
|
||||
jobject jcomponent = [(AWTView *)fView awtComponent:env];
|
||||
fComponent = (*env)->NewWeakGlobalRef(env, jcomponent);
|
||||
(*env)->DeleteLocalRef(env, jcomponent);
|
||||
|
||||
fIndex = index;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)unregisterFromCocoaAXSystem
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
static dispatch_once_t initialize_unregisterUniqueId_once;
|
||||
static void (*unregisterUniqueId)(id);
|
||||
dispatch_once(&initialize_unregisterUniqueId_once, ^{
|
||||
void *jrsFwk = dlopen("/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport", RTLD_LAZY | RTLD_LOCAL);
|
||||
unregisterUniqueId = dlsym(jrsFwk, "JRSAccessibilityUnregisterUniqueIdForUIElement");
|
||||
});
|
||||
if (unregisterUniqueId) unregisterUniqueId(self);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self unregisterFromCocoaAXSystem];
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
|
||||
|
||||
(*env)->DeleteWeakGlobalRef(env, fAccessible);
|
||||
fAccessible = NULL;
|
||||
|
||||
(*env)->DeleteWeakGlobalRef(env, fComponent);
|
||||
fComponent = NULL;
|
||||
|
||||
[fParent release];
|
||||
fParent = nil;
|
||||
|
||||
[fNSRole release];
|
||||
fNSRole = nil;
|
||||
|
||||
[fJavaRole release];
|
||||
fJavaRole = nil;
|
||||
|
||||
[fView release];
|
||||
fView = nil;
|
||||
|
||||
if (self.platformAxElement != self) {
|
||||
[self.platformAxElement dealloc];
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)postValueChanged
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self.platformAxElement, NSAccessibilityValueChangedNotification);
|
||||
}
|
||||
|
||||
- (void)postSelectedTextChanged
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self.platformAxElement, NSAccessibilitySelectedTextChangedNotification);
|
||||
}
|
||||
|
||||
- (void)postSelectionChanged
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self.platformAxElement, NSAccessibilitySelectedChildrenChangedNotification);
|
||||
}
|
||||
|
||||
- (void)postMenuOpened
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self.platformAxElement, (NSString *)kAXMenuOpenedNotification);
|
||||
}
|
||||
|
||||
- (void)postMenuClosed
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self.platformAxElement, (NSString *)kAXMenuClosedNotification);
|
||||
}
|
||||
|
||||
- (void)postMenuItemSelected
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self.platformAxElement, (NSString *)kAXMenuItemSelectedNotification);
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)anObject
|
||||
{
|
||||
if (![anObject isKindOfClass:[self class]]) return NO;
|
||||
JavaBaseAccessibility *accessibility = (JavaBaseAccessibility *)anObject;
|
||||
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
return (*env)->IsSameObject(env, accessibility->fAccessible, fAccessible);
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibleWithEnv:(JNIEnv *)env forAccessible:(jobject)accessible
|
||||
{
|
||||
return (*env)->IsSameObject(env, fAccessible, accessible);
|
||||
}
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (sRoles == nil) {
|
||||
initializeRoles();
|
||||
}
|
||||
|
||||
if (sAccessibilityClass == NULL) {
|
||||
JNF_STATIC_MEMBER_CACHE(jm_getAccessibility, sjc_CAccessibility, "getAccessibility", "([Ljava/lang/String;)Lsun/lwawt/macosx/CAccessibility;");
|
||||
|
||||
#ifdef JAVA_AX_NO_IGNORES
|
||||
NSArray *ignoredKeys = [NSArray array];
|
||||
#else
|
||||
NSArray *ignoredKeys = [sRoles allKeysForObject:JavaAccessibilityIgnore];
|
||||
#endif
|
||||
jobjectArray result = NULL;
|
||||
jsize count = [ignoredKeys count];
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
static JNF_CLASS_CACHE(jc_String, "java/lang/String");
|
||||
result = JNFNewObjectArray(env, &jc_String, count);
|
||||
if (!result) {
|
||||
NSLog(@"In %s, can't create Java array of String objects", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
NSInteger i;
|
||||
for (i = 0; i < count; i++) {
|
||||
jstring jString = JNFNSToJavaString(env, [ignoredKeys objectAtIndex:i]);
|
||||
(*env)->SetObjectArrayElement(env, result, i, jString);
|
||||
(*env)->DeleteLocalRef(env, jString);
|
||||
}
|
||||
|
||||
sAccessibilityClass = JNFCallStaticObjectMethod(env, jm_getAccessibility, result); // AWT_THREADING Safe (known object)
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)postFocusChanged:(id)message
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification([NSApp accessibilityFocusedUIElement], NSAccessibilityFocusedUIElementChangedNotification);
|
||||
}
|
||||
|
||||
+ (jobject) getCAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env {
|
||||
if (JNFIsInstanceOf(env, jaccessible, &sjc_CAccessible)) {
|
||||
return jaccessible;
|
||||
} else if (JNFIsInstanceOf(env, jaccessible, &sjc_Accessible)) {
|
||||
return JNFCallStaticObjectMethod(env, sjm_getCAccessible, jaccessible);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ (NSArray *) childrenOfParent:(JavaBaseAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored
|
||||
{
|
||||
return [JavaBaseAccessibility childrenOfParent:parent withEnv:env withChildrenCode:whichChildren allowIgnored:allowIgnored recursive:NO];
|
||||
}
|
||||
|
||||
+ (NSArray *) childrenOfParent:(JavaBaseAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored recursive:(BOOL)recursive
|
||||
{
|
||||
if ([parent isKindOfClass:[JavaTableAccessibility class]]) {
|
||||
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
|
||||
NSArray<NSNumber *> *selectedRowIndexses = [(JavaTableAccessibility *)parent selectedAccessibleRows];
|
||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[selectedRowIndexses count]];
|
||||
for (NSNumber *index in selectedRowIndexses) {
|
||||
[children addObject:[[JavaTableRowAccessibility alloc] initWithParent:parent
|
||||
withEnv:env
|
||||
withAccessible:NULL
|
||||
withIndex:index.unsignedIntValue
|
||||
withView:[parent view]
|
||||
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
|
||||
}
|
||||
return [NSArray arrayWithArray:children];
|
||||
} else if (whichChildren == JAVA_AX_ALL_CHILDREN) {
|
||||
int rowCount = [(JavaTableAccessibility *)parent accessibleRowCount];
|
||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:rowCount];
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
[children addObject:[[JavaTableRowAccessibility alloc] initWithParent:parent
|
||||
withEnv:env
|
||||
withAccessible:NULL
|
||||
withIndex:i
|
||||
withView:[parent view]
|
||||
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
|
||||
}
|
||||
return [NSArray arrayWithArray:children];
|
||||
} else {
|
||||
return [NSArray arrayWithObject:[[JavaTableRowAccessibility alloc] initWithParent:parent
|
||||
withEnv:env
|
||||
withAccessible:NULL
|
||||
withIndex:whichChildren
|
||||
withView:[parent view]
|
||||
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
|
||||
}
|
||||
}
|
||||
if (parent->fAccessible == NULL) return nil;
|
||||
jobjectArray jchildrenAndRoles = NULL;
|
||||
if (recursive) {
|
||||
jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRolesRecursive, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored, 1);
|
||||
} else {
|
||||
jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
|
||||
}
|
||||
if (jchildrenAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
|
||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:arrayLen/2]; //childrenAndRoles array contains two elements (child, role) for each child
|
||||
|
||||
NSInteger i;
|
||||
NSUInteger childIndex = (whichChildren >= 0) ? whichChildren : 0; // if we're getting one particular child, make sure to set its index correctly
|
||||
int inc = recursive ? 3 : 2;
|
||||
for(i = 0; 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) {
|
||||
jobject jkey = JNFGetObjectField(env, jchildJavaRole, sjf_key);
|
||||
childJavaRole = JNFJavaToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
}
|
||||
|
||||
JavaBaseAccessibility *child = [self createWithParent:parent accessible:jchild role:childJavaRole index:childIndex withEnv:env withView:parent->fView];
|
||||
if ([child isKindOfClass:[JavaOutlineRowAccessibility class]]) {
|
||||
jobject jLevel = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+2);
|
||||
NSString *sLevel = nil;
|
||||
if (jLevel != NULL) {
|
||||
sLevel = JNFJavaToNSString(env, jLevel);
|
||||
(*env)->DeleteLocalRef(env, jLevel);
|
||||
int level = sLevel.intValue;
|
||||
[(JavaOutlineRowAccessibility *)child setAccessibleLevel:level];
|
||||
}
|
||||
}
|
||||
|
||||
[children addObject:child.platformAxElement];
|
||||
|
||||
(*env)->DeleteLocalRef(env, jchild);
|
||||
(*env)->DeleteLocalRef(env, jchildJavaRole);
|
||||
|
||||
childIndex++;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
+ (JavaBaseAccessibility *) createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view
|
||||
{
|
||||
return [JavaBaseAccessibility createWithAccessible:jaccessible withEnv:env withView:view isCurrent:NO];
|
||||
}
|
||||
|
||||
+ (JavaBaseAccessibility *) createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view isCurrent:(BOOL)current
|
||||
{
|
||||
JavaBaseAccessibility *ret = nil;
|
||||
jobject jcomponent = [(AWTView *)view awtComponent:env];
|
||||
jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent);
|
||||
NSString *javaRole = getJavaRole(env, jaccessible, jcomponent);
|
||||
if ((index >= 0) || current) {
|
||||
ret = [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view];
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jcomponent);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ (JavaBaseAccessibility *) createWithAccessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view
|
||||
{
|
||||
return [self createWithParent:nil accessible:jaccessible role:javaRole index:index withEnv:env withView:view];
|
||||
}
|
||||
|
||||
+ (JavaBaseAccessibility *) createWithParent:(JavaBaseAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view
|
||||
{
|
||||
return [JavaBaseAccessibility createWithParent:parent accessible:jaccessible role:javaRole index:index withEnv:env withView:view isWrapped:NO];
|
||||
}
|
||||
|
||||
+ (JavaBaseAccessibility *) createWithParent:(JavaBaseAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view isWrapped:(BOOL)wrapped
|
||||
{
|
||||
// try to fetch the jCAX from Java, and return autoreleased
|
||||
jobject jCAX = [JavaBaseAccessibility getCAccessible:jaccessible withEnv:env];
|
||||
if (jCAX == NULL) return nil;
|
||||
if (!wrapped) { // If wrapped is true, then you don't need to get an existing instance, you need to create a new one
|
||||
JavaBaseAccessibility *value = (JavaBaseAccessibility *) jlong_to_ptr(JNFGetLongField(env, jCAX, jf_ptr));
|
||||
if (value != nil) {
|
||||
(*env)->DeleteLocalRef(env, jCAX);
|
||||
return [[value retain] autorelease];
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise, create a new instance
|
||||
JavaBaseAccessibility *newChild = nil;
|
||||
if ([[sRoles objectForKey:[parent javaRole]] isEqualToString:NSAccessibilityListRole]) {
|
||||
newChild = [JavaListRowAccessibility alloc];
|
||||
} else if ([parent isKindOfClass:[JavaOutlineAccessibility class]]) {
|
||||
newChild = [JavaOutlineRowAccessibility alloc];
|
||||
} else if ([javaRole isEqualToString:@"pagetablist"]) {
|
||||
newChild = [TabGroupAccessibility alloc];
|
||||
} else if ([javaRole isEqualToString:@"scrollpane"]) {
|
||||
newChild = [ScrollAreaAccessibility alloc];
|
||||
} else {
|
||||
NSString *nsRole = [sRoles objectForKey:javaRole];
|
||||
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole]) {
|
||||
newChild = [JavaStaticTextAccessibility alloc];
|
||||
} else if ([nsRole isEqualToString:NSAccessibilityTextAreaRole] || [nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
|
||||
newChild = [JavaNavigableTextAccessibility alloc];
|
||||
} else if ([nsRole isEqualToString:NSAccessibilityListRole]) {
|
||||
newChild = [JavaListAccessibility alloc];
|
||||
} else if ([nsRole isEqualToString:NSAccessibilityTableRole]) {
|
||||
newChild = [JavaTableAccessibility alloc];
|
||||
} else if ([nsRole isEqualToString:NSAccessibilityOutlineRole]) {
|
||||
newChild = [JavaOutlineAccessibility alloc];
|
||||
} else {
|
||||
newChild = [JavaComponentAccessibility alloc];
|
||||
}
|
||||
}
|
||||
|
||||
// must init freshly -alloc'd object
|
||||
[newChild initWithParent:parent withEnv:env withAccessible:jCAX withIndex:index withView:view withJavaRole:javaRole]; // must init new instance
|
||||
|
||||
// If creating a JPopupMenu (not a combobox popup list) need to fire menuOpened.
|
||||
// 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"] ) {
|
||||
[newChild postMenuOpened];
|
||||
}
|
||||
|
||||
// must hard retain pointer poked into Java object
|
||||
[newChild retain];
|
||||
JNFSetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild));
|
||||
|
||||
// the link is removed in the wrapper
|
||||
if (!wrapped) {
|
||||
(*env)->DeleteLocalRef(env, jCAX);
|
||||
}
|
||||
|
||||
// return autoreleased instance
|
||||
return [newChild autorelease];
|
||||
}
|
||||
|
||||
- (jobject)axContextWithEnv:(JNIEnv *)env
|
||||
{
|
||||
return getAxContext(env, fAccessible, fComponent);
|
||||
}
|
||||
|
||||
- (id)parent
|
||||
{
|
||||
static JNF_CLASS_CACHE(sjc_Window, "java/awt/Window");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleParent, sjc_CAccessibility, "getAccessibleParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getSwingAccessible, sjc_CAccessible, "getSwingAccessible", "(Ljavax/accessibility/Accessible;)Ljavax/accessibility/Accessible;");
|
||||
|
||||
if(fParent == nil) {
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
jobject jparent = JNFCallStaticObjectMethod(env, sjm_getAccessibleParent, fAccessible, fComponent);
|
||||
|
||||
if (jparent == NULL) {
|
||||
fParent = fView;
|
||||
} else {
|
||||
AWTView *view = fView;
|
||||
jobject jax = JNFCallStaticObjectMethod(env, sjm_getSwingAccessible, fAccessible);
|
||||
|
||||
if (JNFIsInstanceOf(env, jax, &sjc_Window)) {
|
||||
// In this case jparent is an owner toplevel and we should retrieve its own view
|
||||
view = [AWTView awtView:env ofAccessible:jparent];
|
||||
}
|
||||
if (view != nil) {
|
||||
fParent = [JavaBaseAccessibility createWithAccessible:jparent withEnv:env withView:view];
|
||||
}
|
||||
if (fParent == nil) {
|
||||
fParent = fView;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jparent);
|
||||
(*env)->DeleteLocalRef(env, jax );
|
||||
}
|
||||
[fParent retain];
|
||||
}
|
||||
return fParent;
|
||||
}
|
||||
|
||||
- (NSView *)view
|
||||
{
|
||||
return fView;
|
||||
}
|
||||
|
||||
- (NSWindow *)window
|
||||
{
|
||||
return [[self view] window];
|
||||
}
|
||||
|
||||
- (NSString *)javaRole
|
||||
{
|
||||
if(fJavaRole == nil) {
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
fJavaRole = getJavaRole(env, fAccessible, fComponent);
|
||||
[fJavaRole retain];
|
||||
}
|
||||
return fJavaRole;
|
||||
}
|
||||
|
||||
- (BOOL)isMenu
|
||||
{
|
||||
id role = [self accessibilityRoleAttribute];
|
||||
return [role isEqualToString:NSAccessibilityMenuBarRole] || [role isEqualToString:NSAccessibilityMenuRole] || [role isEqualToString:NSAccessibilityMenuItemRole];
|
||||
}
|
||||
|
||||
- (BOOL)isSelected:(JNIEnv *)env
|
||||
{
|
||||
if (fIndex == -1) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
return isChildSelected(env, ((JavaBaseAccessibility *)[self parent])->fAccessible, fIndex, fComponent);
|
||||
}
|
||||
|
||||
- (BOOL)isSelectable:(JNIEnv *)env
|
||||
{
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
BOOL selectable = isSelectable(env, axContext, fComponent);
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return selectable;
|
||||
}
|
||||
|
||||
- (BOOL)isVisible:(JNIEnv *)env
|
||||
{
|
||||
if (fIndex == -1) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
BOOL showing = isShowing(env, axContext, fComponent);
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return showing;
|
||||
}
|
||||
|
||||
- (NSSize)getSize
|
||||
{
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
|
||||
NSSize size = getAxComponentSize(env, axComponent, fComponent);
|
||||
(*env)->DeleteLocalRef(env, axComponent);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
- (NSRect)getBounds
|
||||
{
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
|
||||
|
||||
// NSAccessibility wants the bottom left point of the object in
|
||||
// bottom left based screen coords
|
||||
|
||||
// Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent.
|
||||
NSSize size = getAxComponentSize(env, axComponent, fComponent);
|
||||
NSPoint point = getAxComponentLocationOnScreen(env, axComponent, fComponent);
|
||||
(*env)->DeleteLocalRef(env, axComponent);
|
||||
|
||||
point.y += size.height;
|
||||
// Now make it into Cocoa screen coords.
|
||||
point.y = [[[[self view] window] screen] frame].size.height - point.y;
|
||||
|
||||
return NSMakeRect(point.x, point.y, size.width, size.height);
|
||||
}
|
||||
|
||||
- (id)getFocusedElement
|
||||
{
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getFocusOwner, sjc_CAccessibility, "getFocusOwner", "(Ljava/awt/Component;)Ljavax/accessibility/Accessible;");
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
id value = nil;
|
||||
|
||||
NSWindow* hostWindow = [[self->fView window] retain];
|
||||
jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop)
|
||||
[hostWindow release];
|
||||
|
||||
if (focused != NULL) {
|
||||
if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
|
||||
value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];
|
||||
value = ((JavaBaseAccessibility *)value).platformAxElement;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, focused);
|
||||
}
|
||||
|
||||
if (value == nil) {
|
||||
value = self;
|
||||
}
|
||||
#ifdef JAVA_AX_DEBUG
|
||||
NSLog(@"%s: %@", __FUNCTION__, value);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
- (jobject)accessible {
|
||||
return fAccessible;
|
||||
}
|
||||
|
||||
- (jobject)component {
|
||||
return fComponent;
|
||||
}
|
||||
|
||||
-(jint)index {
|
||||
return fIndex;
|
||||
}
|
||||
|
||||
- (void)setParent:(id)javaBaseAccessibilityParent {
|
||||
fParent = javaBaseAccessibilityParent;
|
||||
}
|
||||
|
||||
- (NSString *)nsRole {
|
||||
return fNSRole;
|
||||
}
|
||||
|
||||
- (NSUInteger)accessibilityIndexOfChild:(id)child {
|
||||
|
||||
if ([child isKindOfClass:[PlatformAxElement class]]) {
|
||||
child = [child javaBase];
|
||||
}
|
||||
jint returnValue = JNFCallStaticIntMethod( [ThreadUtilities getJNIEnv],
|
||||
sjm_getAccessibleIndexInParent,
|
||||
[child accessible],
|
||||
[child component]);
|
||||
return (returnValue == -1) ? NSNotFound : returnValue;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CAccessibility
|
||||
* Method: focusChanged
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessibility_focusChanged
|
||||
(JNIEnv *env, jobject jthis)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
[ThreadUtilities performOnMainThread:@selector(postFocusChanged:) on:[JavaBaseAccessibility class] withObject:nil waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CAccessible
|
||||
* Method: valueChanged
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_valueChanged
|
||||
(JNIEnv *env, jclass jklass, jlong element)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
[ThreadUtilities performOnMainThread:@selector(postValueChanged) on:(JavaBaseAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CAccessible
|
||||
* Method: selectedTextChanged
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectedTextChanged
|
||||
(JNIEnv *env, jclass jklass, jlong element)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
[ThreadUtilities performOnMainThread:@selector(postSelectedTextChanged)
|
||||
on:(JavaBaseAccessibility *)jlong_to_ptr(element)
|
||||
withObject:nil
|
||||
waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CAccessible
|
||||
* Method: selectionChanged
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectionChanged
|
||||
(JNIEnv *env, jclass jklass, jlong element)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
[ThreadUtilities performOnMainThread:@selector(postSelectionChanged) on:(JavaBaseAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CAccessible
|
||||
* Method: menuOpened
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuOpened
|
||||
(JNIEnv *env, jclass jklass, jlong element)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
[ThreadUtilities performOnMainThread:@selector(postMenuOpened)
|
||||
on:(JavaBaseAccessibility *)jlong_to_ptr(element)
|
||||
withObject:nil
|
||||
waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CAccessible
|
||||
* Method: menuClosed
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuClosed
|
||||
(JNIEnv *env, jclass jklass, jlong element)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
[ThreadUtilities performOnMainThread:@selector(postMenuClosed)
|
||||
on:(JavaBaseAccessibility *)jlong_to_ptr(element)
|
||||
withObject:nil
|
||||
waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CAccessible
|
||||
* Method: menuItemSelected
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuItemSelected
|
||||
(JNIEnv *env, jclass jklass, jlong element)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
[ThreadUtilities performOnMainThread:@selector(postMenuItemSelected)
|
||||
on:(JavaBaseAccessibility *)jlong_to_ptr(element)
|
||||
withObject:nil
|
||||
waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CAccessible
|
||||
* Method: unregisterFromCocoaAXSystem
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_unregisterFromCocoaAXSystem
|
||||
(JNIEnv *env, jclass jklass, jlong element)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
[ThreadUtilities performOnMainThread:@selector(unregisterFromCocoaAXSystem) on:(JavaBaseAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaCellAccessibility : JavaElementAccessibility
|
||||
@interface JavaCellAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxCell : PlatformAxElement
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
- (NSArray *)accessibilityChildren {
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
NSString *javaRole = [[self javaBase] javaRole];
|
||||
JavaBaseAccessibility *newChild = [JavaBaseAccessibility createWithParent:[self javaBase]
|
||||
accessible:[[self javaBase] accessible]
|
||||
NSString *javaRole = [[self javaComponent] javaRole];
|
||||
JavaComponentAccessibility *newChild = [JavaComponentAccessibility createWithParent:[self javaComponent]
|
||||
accessible:[[self javaComponent] accessible]
|
||||
role:javaRole
|
||||
index:[[self javaBase] index]
|
||||
index:[[self javaComponent] index]
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withView:[[self javaBase] view]
|
||||
withView:[[self javaComponent] view]
|
||||
isWrapped:YES];
|
||||
return [NSArray arrayWithObject:newChild.platformAxElement];
|
||||
} else {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaColumnAccessibility : JavaElementAccessibility
|
||||
@interface JavaColumnAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxColumn : PlatformAxElement
|
||||
|
||||
@@ -30,8 +30,8 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
if ([[[self accessibilityParent] javaBase] accessible] == NULL) return nil;
|
||||
jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, [[[self accessibilityParent] javaBase] accessible], [[[self accessibilityParent] javaBase] component], JAVA_AX_ALL_CHILDREN, NO);
|
||||
if ([[[self accessibilityParent] javaComponent] accessible] == NULL) return nil;
|
||||
jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, [[[self accessibilityParent] javaComponent] accessible], [[[self accessibilityParent] javaComponent] component], JAVA_AX_ALL_CHILDREN, NO);
|
||||
if (jchildrenAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
|
||||
@@ -39,8 +39,8 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
|
||||
NSUInteger childIndex = [self columnNumberInTable];
|
||||
|
||||
JavaColumnAccessibility *selfRow = [self javaBase];
|
||||
int inc = [(JavaTableAccessibility *)[[self accessibilityParent] javaBase] accessibleColCount] * 2;
|
||||
JavaColumnAccessibility *selfRow = [self javaComponent];
|
||||
int inc = [(JavaTableAccessibility *) [[self accessibilityParent] javaComponent] accessibleColCount] * 2;
|
||||
NSInteger i = childIndex * 2;
|
||||
for(NSInteger i; i < arrayLen; i += inc)
|
||||
{
|
||||
@@ -75,7 +75,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
}
|
||||
|
||||
- (NSUInteger)columnNumberInTable {
|
||||
return [[self javaBase] index];
|
||||
return [[self javaComponent] index];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaComboBoxAccessibility : JavaComponentAccessibility
|
||||
|
||||
@property(readonly) NSString *accessibleSelectedText;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformAxComboBox : PlatformAxElement
|
||||
@end
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaComboBoxAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
|
||||
|
||||
static const char* ACCESSIBLE_JCOMBOBOX_NAME = "javax.swing.JComboBox$AccessibleJComboBox";
|
||||
|
||||
@implementation JavaComboBoxAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxComboBox";
|
||||
}
|
||||
|
||||
- (NSString *)accessibleSelectedText {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
JNFClassInfo clsInfo;
|
||||
clsInfo.name = ACCESSIBLE_JCOMBOBOX_NAME;
|
||||
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
|
||||
JNF_MEMBER_CACHE(jm_getAccessibleSelection, clsInfo, "getAccessibleSelection", "(I)Ljavax/accessibility/Accessible;");
|
||||
jobject axSelectedChild = JNFCallObjectMethod(env, [self axContextWithEnv:env], jm_getAccessibleSelection, 0);
|
||||
if (axSelectedChild == NULL) {
|
||||
return nil;
|
||||
}
|
||||
jobject childName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, axSelectedChild, fComponent);
|
||||
if (childName == NULL) {
|
||||
(*env)->DeleteLocalRef(env, axSelectedChild);
|
||||
return nil;
|
||||
}
|
||||
NSString *selectedText = JNFObjectToString(env, childName);
|
||||
(*env)->DeleteLocalRef(env, axSelectedChild);
|
||||
(*env)->DeleteLocalRef(env, childName);
|
||||
return selectedText;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxComboBox
|
||||
|
||||
- (id)accessibilityValue {
|
||||
return [(JavaComboBoxAccessibility *) [self javaComponent] accessibleSelectedText];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,147 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. 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 "jni.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "JavaBaseAccessibility.h"
|
||||
|
||||
@interface JavaComponentAccessibility : JavaBaseAccessibility {
|
||||
//#define JAVA_AX_DEBUG 1
|
||||
//#define JAVA_AX_NO_IGNORES 1
|
||||
//#define JAVA_AX_DEBUG_PARMS 1
|
||||
|
||||
// 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
|
||||
|
||||
@class JavaComponentAccessibility;
|
||||
|
||||
@protocol JavaComponentProvider
|
||||
|
||||
@property (nonatomic, retain) JavaComponentAccessibility *javaComponent;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformAxElement : NSAccessibilityElement <JavaComponentProvider>
|
||||
|
||||
// begin of NSAccessibility protocol methods
|
||||
- (BOOL)isAccessibilityElement;
|
||||
- (NSString *)accessibilityLabel;
|
||||
- (NSArray *)accessibilityChildren;
|
||||
- (NSArray *)accessibilitySelectedChildren;
|
||||
- (NSRect)accessibilityFrame;
|
||||
- (id)accessibilityParent;
|
||||
- (BOOL)isAccessibilityEnabled;
|
||||
- (id)accessibilityApplicationFocusedUIElement;
|
||||
- (id)getAccessibilityWindow;
|
||||
// end of NSAccessibility protocol methods
|
||||
|
||||
@end
|
||||
|
||||
@protocol PlatformAxElementProvider
|
||||
@required
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName;
|
||||
|
||||
@property (nonatomic, retain) PlatformAxElement *platformAxElement;
|
||||
|
||||
@end
|
||||
|
||||
@interface JavaComponentAccessibility : NSObject <PlatformAxElementProvider> {
|
||||
NSView *fView;
|
||||
NSObject *fParent;
|
||||
|
||||
NSString *fNSRole;
|
||||
NSString *fJavaRole;
|
||||
|
||||
jint fIndex;
|
||||
jobject fAccessible;
|
||||
jobject fComponent;
|
||||
|
||||
NSMutableDictionary *fActions;
|
||||
NSMutableArray *fActionSElectors;
|
||||
NSObject *fActionsLOCK;
|
||||
}
|
||||
|
||||
- (NSDictionary*)getActions:(JNIEnv *)env;
|
||||
- (id)initWithParent:(NSObject*)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole;
|
||||
- (void)unregisterFromCocoaAXSystem;
|
||||
- (void)postValueChanged;
|
||||
- (void)postSelectedTextChanged;
|
||||
- (void)postSelectionChanged;
|
||||
- (BOOL)isEqual:(id)anObject;
|
||||
- (BOOL)isAccessibleWithEnv:(JNIEnv *)env forAccessible:(jobject)accessible;
|
||||
|
||||
+ (void)postFocusChanged:(id)message;
|
||||
|
||||
+ (NSArray *)childrenOfParent:(JavaComponentAccessibility *) parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored;
|
||||
+ (NSArray *)childrenOfParent:(JavaComponentAccessibility *) parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored recursive:(BOOL)recursive;
|
||||
+ (JavaComponentAccessibility *) createWithParent:(JavaComponentAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view;
|
||||
+ (JavaComponentAccessibility *) createWithAccessible:(jobject)jaccessible role:(NSString *)role index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view;
|
||||
+ (JavaComponentAccessibility *) createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)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.
|
||||
+ (JavaComponentAccessibility *) createWithParent:(JavaComponentAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)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
|
||||
+ (JavaComponentAccessibility *) createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view isCurrent:(BOOL)current;
|
||||
|
||||
@property(readonly) jobject accessible;
|
||||
@property(readonly) jobject component;
|
||||
@property(readonly) jint index;
|
||||
@property(readonly, copy) NSArray *actionSelectores;;
|
||||
|
||||
- (jobject)axContextWithEnv:(JNIEnv *)env;
|
||||
- (NSView*)view;
|
||||
- (NSWindow*)window;
|
||||
- (id)parent;
|
||||
- (void)setParent:(id)javaComponentAccessibilityParent;
|
||||
- (NSString *)javaRole;
|
||||
- (NSString *)nsRole;
|
||||
- (BOOL)isMenu;
|
||||
- (BOOL)isSelected:(JNIEnv *)env;
|
||||
- (BOOL)isSelectable:(JNIEnv *)env;
|
||||
- (BOOL)isVisible:(JNIEnv *)env;
|
||||
- (NSSize)getSize;
|
||||
- (NSRect)getBounds;
|
||||
- (id)getFocusedElement;
|
||||
|
||||
@property(readonly) int accessibleIndexOfParent;
|
||||
@property(readonly) BOOL accessibleEnabled;
|
||||
@property(readwrite) BOOL accessibleFocused;
|
||||
@property(readonly) NSNumber *accessibleMaxValue;
|
||||
@property(readonly) NSNumber *accessibleMinValue;
|
||||
@property(readonly) id accessibleOrientation;
|
||||
@property(readonly) NSValue *accessiblePosition;
|
||||
@property(readonly) NSString *accessibleRole;
|
||||
@property(readonly) NSString *accessibleRoleDescription;
|
||||
@property(readonly) id accessibleParent;
|
||||
@property(readwrite, copy) NSNumber *accessibleSelected;
|
||||
@property(readonly) id accessibleValue;;
|
||||
@property(readonly) NSMutableDictionary *getActions;
|
||||
|
||||
- (id)accessibleHitTest:(NSPoint)point;
|
||||
- (void)getActionsWithEnv:(JNIEnv *)env;
|
||||
|
||||
// attribute names
|
||||
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
|
||||
- (NSArray *)accessibilityAttributeNames;
|
||||
|
||||
// attributes
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute;
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute;
|
||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute;
|
||||
|
||||
- (NSArray *)accessibilityChildrenAttribute;
|
||||
- (BOOL)accessibilityIsChildrenAttributeSettable;
|
||||
- (NSUInteger)accessibilityIndexOfChild:(id)child;
|
||||
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute
|
||||
index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
|
||||
- (NSNumber *)accessibilityEnabledAttribute;
|
||||
- (BOOL)accessibilityIsEnabledAttributeSettable;
|
||||
- (NSNumber *)accessibilityFocusedAttribute;
|
||||
- (BOOL)accessibilityIsFocusedAttributeSettable;
|
||||
- (void)accessibilitySetFocusedAttribute:(id)value;
|
||||
- (NSString *)accessibilityHelpAttribute;
|
||||
- (BOOL)accessibilityIsHelpAttributeSettable;
|
||||
- (NSValue *)accessibilityIndexAttribute;
|
||||
- (BOOL)accessibilityIsIndexAttributeSettable;
|
||||
- (id)accessibilityMaxValueAttribute;
|
||||
- (BOOL)accessibilityIsMaxValueAttributeSettable;
|
||||
- (id)accessibilityMinValueAttribute;
|
||||
- (BOOL)accessibilityIsMinValueAttributeSettable;
|
||||
- (id)accessibilityOrientationAttribute;
|
||||
- (BOOL)accessibilityIsOrientationAttributeSettable;
|
||||
- (id)accessibilityParentAttribute;
|
||||
- (BOOL)accessibilityIsParentAttributeSettable;
|
||||
- (NSValue *)accessibilityPositionAttribute;
|
||||
- (BOOL)accessibilityIsPositionAttributeSettable;
|
||||
- (NSString *)accessibilityRoleAttribute;
|
||||
- (BOOL)accessibilityIsRoleAttributeSettable;
|
||||
- (NSString *)accessibilityRoleDescriptionAttribute;
|
||||
- (BOOL)accessibilityIsRoleDescriptionAttributeSettable;
|
||||
- (NSArray *)accessibilitySelectedChildrenAttribute;
|
||||
- (BOOL)accessibilityIsSelectedChildrenAttributeSettable;
|
||||
- (NSNumber *)accessibilitySelectedAttribute;
|
||||
- (BOOL)accessibilityIsSelectedAttributeSettable;
|
||||
- (void)accessibilitySetSelectedAttribute:(id)value;
|
||||
- (NSValue *)accessibilitySizeAttribute;
|
||||
- (BOOL)accessibilityIsSizeAttributeSettable;
|
||||
- (NSString *)accessibilitySubroleAttribute;
|
||||
- (BOOL)accessibilityIsSubroleAttributeSettable;
|
||||
- (NSString *)accessibilityTitleAttribute;
|
||||
- (BOOL)accessibilityIsTitleAttributeSettable;
|
||||
- (NSWindow *)accessibilityTopLevelUIElementAttribute;
|
||||
- (BOOL)accessibilityIsTopLevelUIElementAttributeSettable;
|
||||
- (id)accessibilityValueAttribute;
|
||||
- (BOOL)accessibilityIsValueAttributeSettable;
|
||||
- (void)accessibilitySetValueAttribute:(id)value;
|
||||
- (NSArray *)accessibilityVisibleChildrenAttribute;
|
||||
- (BOOL)accessibilityIsVisibleChildrenAttributeSettable;
|
||||
- (id)accessibilityWindowAttribute;
|
||||
- (BOOL)accessibilityIsWindowAttributeSettable;
|
||||
|
||||
// actions
|
||||
- (NSArray *)accessibilityActionNames;
|
||||
- (NSString *)accessibilityActionDescription:(NSString *)action;
|
||||
- (void)accessibilityPerformAction:(NSString *)action;
|
||||
|
||||
- (BOOL)accessibilityIsIgnored;
|
||||
- (id)accessibilityHitTest:(NSPoint)point withEnv:(JNIEnv *)env;
|
||||
- (id)accessibilityFocusedUIElement;
|
||||
- (BOOL)accessiblePerformAction:(NSAccessibilityActionName)actionName;
|
||||
|
||||
@end
|
||||
|
||||
@interface TabGroupAccessibility : JavaComponentAccessibility {
|
||||
NSInteger _numTabs;
|
||||
}
|
||||
|
||||
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext;
|
||||
- (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
|
||||
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
|
||||
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
|
||||
|
||||
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
|
||||
- (NSArray *)accessibilityChildrenAttribute;
|
||||
- (id) accessibilityTabsAttribute;
|
||||
- (BOOL)accessibilityIsTabsAttributeSettable;
|
||||
- (NSArray *)accessibilityContentsAttribute;
|
||||
- (BOOL)accessibilityIsContentsAttributeSettable;
|
||||
- (id) accessibilityValueAttribute;
|
||||
|
||||
@end
|
||||
|
||||
@interface TabGroupControlAccessibility : JavaComponentAccessibility {
|
||||
jobject fTabGroupAxContext;
|
||||
}
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole;
|
||||
- (jobject)tabGroup;
|
||||
- (void)getActionsWithEnv:(JNIEnv *)env;
|
||||
|
||||
- (id)accessibilityValueAttribute;
|
||||
@end
|
||||
|
||||
@interface ScrollAreaAccessibility : JavaComponentAccessibility {
|
||||
|
||||
}
|
||||
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
|
||||
- (NSArray *)accessibilityContentsAttribute;
|
||||
- (BOOL)accessibilityIsContentsAttributeSettable;
|
||||
- (id)accessibilityVerticalScrollBarAttribute;
|
||||
- (BOOL)accessibilityIsVerticalScrollBarAttributeSettable;
|
||||
- (id)accessibilityHorizontalScrollBarAttribute;
|
||||
- (BOOL)accessibilityIsHorizontalScrollBarAttributeSettable;
|
||||
@end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaBaseAccessibility.h"
|
||||
|
||||
@interface JavaElementAccessibility : JavaBaseAccessibility
|
||||
|
||||
@property(readonly) int accessibleIndexOfParent;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformAxElement : NSAccessibilityElement <JavaBaseProvider>
|
||||
|
||||
// begin of NSAccessibility protocol methods
|
||||
- (BOOL)isAccessibilityElement;
|
||||
- (NSString *)accessibilityLabel;
|
||||
- (NSArray *)accessibilityChildren;
|
||||
- (NSArray *)accessibilitySelectedChildren;
|
||||
- (NSRect)accessibilityFrame;
|
||||
- (id)accessibilityParent;
|
||||
- (BOOL)accessibilityIsIgnored;
|
||||
- (BOOL)isAccessibilityEnabled;
|
||||
- (id)accessibilityApplicationFocusedUIElement;
|
||||
- (id)getAccessibilityWindow;
|
||||
// end of NSAccessibility protocol methods
|
||||
|
||||
@end
|
||||
@@ -1,133 +0,0 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleDescription, sjc_CAccessibility, "getAccessibleDescription", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
|
||||
|
||||
static JNF_CLASS_CACHE(sjc_CAccessible, "sun/lwawt/macosx/CAccessible");
|
||||
static JNF_MEMBER_CACHE(jm_getAccessibleContext, sjc_CAccessible, "getAccessibleContext", "()Ljavax/accessibility/AccessibleContext;");
|
||||
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleIndexInParent, sjc_CAccessibility, "getAccessibleIndexInParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
|
||||
|
||||
static void RaiseMustOverrideException(NSString *method)
|
||||
{
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||
reason:[NSString stringWithFormat:@"You must override %@ in a subclass", method]
|
||||
userInfo:nil];
|
||||
};
|
||||
|
||||
@implementation JavaElementAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName
|
||||
{
|
||||
RaiseMustOverrideException(@"getPlatformAxElementClassName");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (int)accessibleIndexOfParent {
|
||||
return (int)JNFCallStaticIntMethod ([ThreadUtilities getJNIEnv], sjm_getAccessibleIndexInParent, fAccessible, fComponent);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxElement
|
||||
|
||||
@synthesize javaBase;
|
||||
|
||||
- (BOOL)isAccessibilityElement
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
// RaiseMustOverrideException(@"accessibilityLabel");
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, [javaBase accessible], [javaBase component]);
|
||||
NSString* str = JNFJavaToNSString(env, axName);
|
||||
(*env)->DeleteLocalRef(env, axName);
|
||||
return str;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityHelp {
|
||||
// RaiseMustOverrideException(@"accessibilityLabel");
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, [javaBase accessible], [javaBase component]);
|
||||
NSString* str = JNFJavaToNSString(env, axName);
|
||||
(*env)->DeleteLocalRef(env, axName);
|
||||
return str;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *children = [JavaBaseAccessibility childrenOfParent:self.javaBase
|
||||
withEnv:env
|
||||
withChildrenCode:JAVA_AX_ALL_CHILDREN
|
||||
allowIgnored:([[self accessibilityRole] isEqualToString:NSAccessibilityListRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityTableRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityOutlineRole])
|
||||
recursive:[[self accessibilityRole] isEqualToString:NSAccessibilityOutlineRole]];
|
||||
if ([children count] > 0) {
|
||||
return children;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilitySelectedChildren
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *selectedChildren = [JavaBaseAccessibility childrenOfParent:self.javaBase
|
||||
withEnv:env
|
||||
withChildrenCode:JAVA_AX_SELECTED_CHILDREN
|
||||
allowIgnored:([[self accessibilityRole] isEqualToString:NSAccessibilityListRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityTableRole] || [[self accessibilityRole] isEqualToString:NSAccessibilityOutlineRole])
|
||||
recursive:[[self accessibilityRole] isEqualToString:NSAccessibilityOutlineRole]];
|
||||
if ([selectedChildren count] > 0) {
|
||||
return selectedChildren;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [self.javaBase getBounds];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
id parent = [self.javaBase parent];
|
||||
// Checking for protocol compliance can slow down at runtime. See: https://developer.apple.com/documentation/objectivec/nsobject/1418893-conformstoprotocol?language=objc
|
||||
return [parent respondsToSelector:@selector(platformAxElement)] ? [parent platformAxElement] : parent;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
RaiseMustOverrideException(@"accessibilityIsIgnored");
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityEnabled
|
||||
{
|
||||
RaiseMustOverrideException(@"isAccessibilityEnabled");
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)accessibilityApplicationFocusedUIElement
|
||||
{
|
||||
return [self.javaBase getFocusedElement];
|
||||
}
|
||||
|
||||
- (id)getAccessibilityWindow
|
||||
{
|
||||
return [self.javaBase window];
|
||||
}
|
||||
|
||||
- (void)setAccessibilityParent:(id)accessibilityParent {
|
||||
[[self javaBase] setParent:accessibilityParent];
|
||||
}
|
||||
|
||||
- (NSUInteger)accessibilityIndexOfChild:(id)child {
|
||||
return [[self javaBase] accessibilityIndexOfChild:child];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,14 +1,9 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef NATIVE_JAVALISTACCESSIBILITY_H
|
||||
#define NATIVE_JAVALISTACCESSIBILITY_H
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
#endif // NATIVE_JAVALISTACCESSIBILITY_H
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
|
||||
@interface JavaListAccessibility : JavaElementAccessibility
|
||||
@interface JavaListAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxList : PlatformAxElement <NSAccessibilityList>
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -15,13 +15,11 @@
|
||||
|
||||
@implementation PlatformAxList
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityRows
|
||||
{
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityRows {
|
||||
return [self accessibilityChildren];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedRows
|
||||
{
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedRows {
|
||||
return [self accessibilitySelectedChildren];
|
||||
}
|
||||
|
||||
@@ -30,23 +28,15 @@
|
||||
return [super accessibilityLabel] == NULL ? @"list" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityEnabled
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
// 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];
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaListRowAccessibility : JavaElementAccessibility
|
||||
@interface JavaListRowAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxListRow : PlatformAxElement <NSAccessibilityRow>
|
||||
|
||||
@@ -22,12 +22,12 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
- (NSArray *)accessibilityChildren {
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
JavaBaseAccessibility *newChild = [JavaBaseAccessibility createWithParent:[self javaBase]
|
||||
accessible:[[self javaBase] accessible]
|
||||
role:[[self javaBase] javaRole]
|
||||
index:[[self javaBase] index]
|
||||
JavaComponentAccessibility *newChild = [JavaComponentAccessibility createWithParent:[self javaComponent]
|
||||
accessible:[[self javaComponent] accessible]
|
||||
role:[[self javaComponent] javaRole]
|
||||
index:[[self javaComponent] index]
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withView:[[self javaBase] view]
|
||||
withView:[[self javaComponent] view]
|
||||
isWrapped:YES];
|
||||
return [NSArray arrayWithObject:[newChild autorelease].platformAxElement];
|
||||
} else {
|
||||
@@ -36,7 +36,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex {
|
||||
return [super accessibilityIndex];
|
||||
return [[self accessibilityParent] accessibilityIndexOfChild:self];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
@@ -44,4 +44,8 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame {
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -185,66 +185,66 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
|
||||
@implementation PlatformAxNavigableText
|
||||
|
||||
- (NSRect)accessibilityFrameForRange:(NSRange)range {
|
||||
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleBoundsForRange:range] rectValue];
|
||||
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleBoundsForRange:range] rectValue];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityLineForIndex:(NSInteger)index {
|
||||
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleLineForIndex:index] integerValue];
|
||||
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleLineForIndex:index] integerValue];
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRangeForLine:(NSInteger)line {
|
||||
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleRangeForLine:line] rangeValue];
|
||||
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleRangeForLine:line] rangeValue];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityStringForRange:(NSRange)range {
|
||||
return [(JavaNavigableTextAccessibility *)[self javaBase] accessibleStringForRange:range];
|
||||
return [(JavaNavigableTextAccessibility *) [self javaComponent] accessibleStringForRange:range];
|
||||
}
|
||||
|
||||
- (id)accessibilityValue {
|
||||
return [(JavaNavigableTextAccessibility *)[self javaBase] accessibleValue];
|
||||
return [(JavaNavigableTextAccessibility *) [self javaComponent] accessibleValue];
|
||||
}
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole {
|
||||
if ([(JavaNavigableTextAccessibility *)[self javaBase] accessibleIsPasswordText]) {
|
||||
if ([(JavaNavigableTextAccessibility *) [self javaComponent] accessibleIsPasswordText]) {
|
||||
return NSAccessibilitySecureTextFieldSubrole;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRangeForIndex:(NSInteger)index {
|
||||
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleRangeForIndex:index] rangeValue];
|
||||
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleRangeForIndex:index] rangeValue];
|
||||
}
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole {
|
||||
return [sRoles objectForKey:[self javaBase].javaRole];
|
||||
return [sRoles objectForKey:[self javaComponent].javaRole];
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRangeForPosition:(NSPoint)point {
|
||||
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleRangeForPosition:point] rangeValue];
|
||||
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleRangeForPosition:point] rangeValue];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilitySelectedText {
|
||||
return [(JavaNavigableTextAccessibility *)[self javaBase] accessibleSelectedText];
|
||||
return [(JavaNavigableTextAccessibility *) [self javaComponent] accessibleSelectedText];
|
||||
}
|
||||
|
||||
- (NSRange)accessibilitySelectedTextRange {
|
||||
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleSelectedTextRange] rangeValue];
|
||||
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleSelectedTextRange] rangeValue];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityNumberOfCharacters {
|
||||
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleNumberOfCharacters] integerValue];
|
||||
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleNumberOfCharacters] integerValue];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityInsertionPointLineNumber {
|
||||
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleInsertionPointLineNumber] integerValue];
|
||||
return [[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleInsertionPointLineNumber] integerValue];
|
||||
}
|
||||
|
||||
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText {
|
||||
[(JavaNavigableTextAccessibility *)[self javaBase] accessibleSetSelectedText:accessibilitySelectedText];
|
||||
[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleSetSelectedText:accessibilitySelectedText];
|
||||
}
|
||||
|
||||
- (void)setAccessibilitySelectedTextRange:(NSRange)accessibilitySelectedTextRange {
|
||||
[(JavaNavigableTextAccessibility *)[self javaBase] accessibleSetSelectedTextRange:accessibilitySelectedTextRange];
|
||||
[(JavaNavigableTextAccessibility *) [self javaComponent] accessibleSetSelectedTextRange:accessibilitySelectedTextRange];
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityEdited {
|
||||
|
||||
@@ -41,25 +41,29 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getCAccessible, sjc_CAccessible, "getCAccessi
|
||||
|
||||
- (NSArray *)accessibilityChildren {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject currentAccessible = [(JavaOutlineRowAccessibility *)[self javaBase] currentAccessibleWithENV:env];
|
||||
jobject currentAccessible = [(JavaOutlineRowAccessibility *) [self javaComponent] currentAccessibleWithENV:env];
|
||||
if (currentAccessible == NULL) {
|
||||
return nil;
|
||||
}
|
||||
JavaBaseAccessibility *currentElement = [JavaBaseAccessibility createWithAccessible:currentAccessible withEnv:env withView:[[self javaBase] view] isCurrent:YES];
|
||||
NSArray *children = [JavaBaseAccessibility childrenOfParent:currentElement withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
JavaComponentAccessibility *currentElement = [JavaComponentAccessibility createWithAccessible:currentAccessible withEnv:env withView:[[self javaComponent] view] isCurrent:YES];
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:currentElement withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
if ([children count] == 0) {
|
||||
return [NSArray arrayWithObject:[JavaBaseAccessibility createWithParent:[self javaBase] accessible:[[self javaBase] accessible] role:[[self javaBase] javaRole] index:[[self javaBase] index] withEnv:env withView:[[self javaBase] view] isWrapped:YES].platformAxElement];
|
||||
return [NSArray arrayWithObject:[JavaComponentAccessibility createWithParent:[self javaComponent] accessible:[[self javaComponent] accessible] role:[[self javaComponent] javaRole] index:[[self javaComponent] index] withEnv:env withView:[[self javaComponent] view] isWrapped:YES].platformAxElement];
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityDisclosureLevel {
|
||||
return [(JavaOutlineRowAccessibility *)[self javaBase] accessibleLevel];
|
||||
return [(JavaOutlineRowAccessibility *) [self javaComponent] accessibleLevel];
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityDisclosed {
|
||||
return isExpanded([ThreadUtilities getJNIEnv], [[self javaBase] axContextWithEnv:[ThreadUtilities getJNIEnv]], [[self javaBase] component]);
|
||||
return isExpanded([ThreadUtilities getJNIEnv], [[self javaComponent] axContextWithEnv:[ThreadUtilities getJNIEnv]], [[self javaComponent] component]);
|
||||
}
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole {
|
||||
return NSAccessibilityOutlineRowSubrole;;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaScrollAreaAccessibility : JavaComponentAccessibility
|
||||
|
||||
@property(readonly) NSArray *accessibleContents;
|
||||
@property(readonly) id accessibleVerticalScrollBar;
|
||||
@property(readonly) id accessibleHorizontalScrollBar;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformAxScrollArea : PlatformAxElement
|
||||
@end
|
||||
@@ -0,0 +1,99 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaScrollAreaAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
@implementation JavaScrollAreaAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxScrollArea";
|
||||
}
|
||||
|
||||
- (NSArray *)accessibleContents {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode: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];
|
||||
id aElement;
|
||||
while ((aElement = [enumerator nextObject])) {
|
||||
NSString *nsRole = [aElement accessibilityRole]; // todo: Remove this solution when JavaComponentAccessibility is removed
|
||||
if (![nsRole isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
// no scroll bars in contents
|
||||
[(NSMutableArray *) contents addObject:aElement];
|
||||
}
|
||||
}
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
- (id)accessibleVerticalScrollBar {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
if ([children count] <= 0) return nil;
|
||||
|
||||
// The scroll bars are in the children.
|
||||
NSEnumerator *enumerator = [children objectEnumerator];
|
||||
id aElement;
|
||||
while ((aElement = (PlatformAxElement *)[enumerator nextObject])) {
|
||||
NSString *nsRole = [aElement accessibilityRole]; // todo: Remove this solution when JavaComponentAccessibility is removed
|
||||
if ([nsRole isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
jobject elementAxContext = [[aElement javaComponent] axContextWithEnv:env];
|
||||
if (isVertical(env, elementAxContext, fComponent)) {
|
||||
(*env)->DeleteLocalRef(env, elementAxContext);
|
||||
return aElement;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, elementAxContext);
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id)accessibleHorizontalScrollBar {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
if ([children count] <= 0) return nil;
|
||||
|
||||
// The scroll bars are in the children.
|
||||
id aElement;
|
||||
NSEnumerator *enumerator = [children objectEnumerator];
|
||||
while ((aElement = [enumerator nextObject])) {
|
||||
NSString *nsRole = [aElement accessibilityRole]; // todo: Remove this solution when JavaComponentAccessibility is removed
|
||||
if ([nsRole isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
jobject elementAxContext = [[aElement javaComponent] axContextWithEnv:env];
|
||||
if (isHorizontal(env, elementAxContext, fComponent)) {
|
||||
(*env)->DeleteLocalRef(env, elementAxContext);
|
||||
return aElement;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, elementAxContext);
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxScrollArea
|
||||
|
||||
- (NSArray *)accessibilityContents {
|
||||
return [(JavaScrollAreaAccessibility *) [self javaComponent] accessibleContents];
|
||||
}
|
||||
|
||||
- (id)accessibilityVerticalScrollBar {
|
||||
return [(JavaScrollAreaAccessibility *) [self javaComponent] accessibleVerticalScrollBar];
|
||||
}
|
||||
|
||||
- (id)accessibilityHorizontalScrollBar {
|
||||
return [(JavaScrollAreaAccessibility *) [self javaComponent] accessibleHorizontalScrollBar];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaStaticTextAccessibility : JavaElementAccessibility
|
||||
@interface JavaStaticTextAccessibility : JavaComponentAccessibility
|
||||
|
||||
/*
|
||||
* Converts an int array to an NSRange wrapped inside an NSValue
|
||||
|
||||
@@ -42,7 +42,7 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
|
||||
@implementation PlatformAxStaticText
|
||||
|
||||
- (id)accessibilityValue {
|
||||
return [(JavaStaticTextAccessibility *)[self javaBase] accessibleValue];
|
||||
return [(JavaStaticTextAccessibility *) [self javaComponent] accessibleValue];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame {
|
||||
@@ -54,7 +54,7 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityVisibleCharacterRange {
|
||||
return [[(JavaStaticTextAccessibility *)[self javaBase] accessibleVisibleCharacterRange] rangeValue];
|
||||
return [[(JavaStaticTextAccessibility *) [self javaComponent] accessibleVisibleCharacterRange] rangeValue];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaTabButtonAccessibility : JavaComponentAccessibility {
|
||||
jobject fTabGroupAxContext;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@property(readonly) jobject tabGroup;
|
||||
@property(readonly) id accessibleValue;
|
||||
- (void)performPressAction;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformAxTabButton : PlatformAxElement
|
||||
@end
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaTabButtonAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
|
||||
@implementation JavaTabButtonAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxTabButton";
|
||||
}
|
||||
|
||||
- (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 = JNFNewWeakGlobalRef(env, tabGroup);
|
||||
} else {
|
||||
fTabGroupAxContext = NULL;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (jobject)tabGroup {
|
||||
if (fTabGroupAxContext == NULL) {
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env];
|
||||
fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext);
|
||||
(*env)->DeleteLocalRef(env, tabGroupAxContext);
|
||||
}
|
||||
return fTabGroupAxContext;
|
||||
}
|
||||
|
||||
- (id)accessibleValue {
|
||||
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:javaObjectEquals(env, axContext, selAccessible, fComponent)];
|
||||
|
||||
(*env)->DeleteLocalRef(env, selAccessible);
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return val;
|
||||
}
|
||||
|
||||
- (void)performPressAction {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
TabGroupAction *action = [[TabGroupAction alloc] initWithEnv:env withTabGroup:[self tabGroup] withIndex:fIndex withComponent:fComponent];
|
||||
[action perform];
|
||||
[action release];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxTabButton
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole {
|
||||
return NSAccessibilityTabButtonSubrole;
|
||||
}
|
||||
|
||||
- (id)accessibilityValue {
|
||||
return [(JavaTabButtonAccessibility *) [self javaComponent] accessibleValue];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformPress {
|
||||
[(JavaTabButtonAccessibility *) [self javaComponent] performPressAction];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static JNF_CLASS_CACHE(sjc_Object, "java/lang/Object");
|
||||
static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component) {
|
||||
static JNF_MEMBER_CACHE(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z");
|
||||
|
||||
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
|
||||
static JNF_CLASS_CACHE(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit");
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_doEquals, sjc_LWCToolkit, "doEquals", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z");
|
||||
return JNFCallStaticBooleanMethod(env, jm_doEquals, a, b, component); // AWT_THREADING Safe (AWTRunLoopMode)
|
||||
}
|
||||
|
||||
return JNFCallBooleanMethod(env, a, jm_equals, b); // AWT_THREADING Safe (!appKit)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaTabGroupAccessibility : JavaComponentAccessibility {
|
||||
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;
|
||||
|
||||
@property(readonly) NSArray *accessibleTabs;
|
||||
@property(readonly) NSArray *accessibleContents;
|
||||
@property(readonly) id accessibleValue;
|
||||
@property(readonly) NSInteger numTabs;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformAxTabGroup : PlatformAxElement
|
||||
@end
|
||||
@@ -0,0 +1,179 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaTabGroupAccessibility.h"
|
||||
#import "JavaTabButtonAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
|
||||
|
||||
@implementation JavaTabGroupAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxTabGroup";
|
||||
}
|
||||
|
||||
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext {
|
||||
NSArray *tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode: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];
|
||||
JavaComponentAccessibility *aTab;
|
||||
NSInteger i;
|
||||
for (i = 0; i < _numTabs; i++) {
|
||||
aTab = [(PlatformAxElement *) [tabs objectAtIndex:i] javaComponent];
|
||||
if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
|
||||
(*env)->DeleteLocalRef(env, selAccessible);
|
||||
return [aTab platformAxElement];
|
||||
}
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, selAccessible);
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored {
|
||||
jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
|
||||
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;
|
||||
}
|
||||
jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key);
|
||||
NSString *tabJavaRole = JNFJavaToNSString(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);
|
||||
JavaComponentAccessibility *tab = [[[JavaTabButtonAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
|
||||
(*env)->DeleteLocalRef(env, jtab);
|
||||
[tabs addObject:[tab platformAxElement]];
|
||||
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.
|
||||
PlatformAxElement *currentTab = [self currentTabWithEnv:env withAxContext:axContext];
|
||||
if (currentTab == nil) return nil;
|
||||
|
||||
NSArray *contents = [JavaComponentAccessibility childrenOfParent:[currentTab javaComponent] withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
|
||||
if ([contents count] <= 0) return nil;
|
||||
return contents;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibleTabs {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
id tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return tabs;
|
||||
}
|
||||
|
||||
- (NSArray *) accessibleContents {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return cont;
|
||||
}
|
||||
|
||||
-(id) accessibleValue {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
id val = [self currentTabWithEnv:env withAxContext:axContext];
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return val;
|
||||
}
|
||||
|
||||
- (NSInteger)numTabs {
|
||||
return _numTabs;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxTabGroup
|
||||
|
||||
- (NSArray *)accessibilityTabs {
|
||||
return [(JavaTabGroupAccessibility *) [self javaComponent] accessibleTabs];
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityContents {
|
||||
return [(JavaTabGroupAccessibility *) [self javaComponent] accessibleContents];
|
||||
}
|
||||
|
||||
- (id)accessibilityValue {
|
||||
return [(JavaTabGroupAccessibility *) [self javaComponent] accessibleValue];
|
||||
}
|
||||
|
||||
- (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 = [(JavaTabGroupAccessibility *) [self javaComponent] axContextWithEnv:env];
|
||||
|
||||
//children = AXTabs + AXContents
|
||||
NSArray *children = [(JavaTabGroupAccessibility *) [self javaComponent] tabButtonsWithEnv:env
|
||||
withTabGroupAxContext:axContext
|
||||
withTabCode:index
|
||||
allowIgnored:NO]; // first look at the tabs
|
||||
if ([children count] > 0) {
|
||||
result = children;
|
||||
} else {
|
||||
children= [(JavaTabGroupAccessibility *) [self javaComponent] contentsWithEnv:env
|
||||
withTabGroupAxContext:axContext
|
||||
withTabCode:(index-[(JavaTabGroupAccessibility *) [self javaComponent] 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 {
|
||||
NSNumber *number = (NSNumber *)accessibilityValue;
|
||||
if (![number boolValue]) return;
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
setAxContextSelection(env, axContext, [[self javaComponent] index], [[self javaComponent] component]);
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
@interface JavaTableAccessibility : JavaElementAccessibility
|
||||
@interface JavaTableAccessibility : JavaComponentAccessibility
|
||||
|
||||
@property(readonly) int accessibleRowCount;
|
||||
@property(readonly) int accessibleColCount;
|
||||
|
||||
@@ -57,6 +57,7 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
|
||||
for (int i = 0; i < arrayLen; i++) {
|
||||
[nsArraySelectidRowNumbers addObject:[NSNumber numberWithInt:indexsis[i]]];
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, selectidRowNumbers);
|
||||
return [NSArray<NSNumber *> arrayWithArray:nsArraySelectidRowNumbers];
|
||||
}
|
||||
|
||||
@@ -76,18 +77,17 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
|
||||
for (int i = 0; i < arrayLen; i++) {
|
||||
[nsArraySelectidColumnNumbers addObject:[NSNumber numberWithInt:indexsis[i]]];
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, selectidColumnNumbers);
|
||||
return [NSArray<NSNumber *> arrayWithArray:nsArraySelectidColumnNumbers];
|
||||
}
|
||||
|
||||
- (int)accessibleRowAtIndex:(int)index {
|
||||
printf("Пришёл индекс %d\n", index);
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
JNFClassInfo clsInfo;
|
||||
clsInfo.name = ACCESSIBLE_JTABLE_NAME;
|
||||
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
|
||||
JNF_MEMBER_CACHE(jm_getAccessibleRowAtIndex, clsInfo, "getAccessibleRowAtIndex", "(I)I");
|
||||
jint rowAtIndex = JNFCallIntMethod(env, [self axContextWithEnv:env], jm_getAccessibleRowAtIndex, (jint)index);
|
||||
printf("Получен индекс %d\n", rowAtIndex);
|
||||
return (int)rowAtIndex;
|
||||
}
|
||||
|
||||
@@ -145,28 +145,28 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilityColumns {
|
||||
int colCount = [(JavaTableAccessibility *)[self javaBase] accessibleColCount];
|
||||
int colCount = [(JavaTableAccessibility *) [self javaComponent] accessibleColCount];
|
||||
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:colCount];
|
||||
for (int i = 0; i < colCount; i++) {
|
||||
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:[self javaBase]
|
||||
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:[self javaComponent]
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i
|
||||
withView:[[self javaBase] view]
|
||||
withView:[[self javaComponent] view]
|
||||
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
|
||||
}
|
||||
return [NSArray arrayWithArray:columns];
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilitySelectedColumns {
|
||||
NSArray<NSNumber *> *indexes = [(JavaTableAccessibility *)[self javaBase] selectedAccessibleColumns];
|
||||
NSArray<NSNumber *> *indexes = [(JavaTableAccessibility *) [self javaComponent] selectedAccessibleColumns];
|
||||
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:[indexes count]];
|
||||
for (NSNumber *i in indexes) {
|
||||
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:[self javaBase]
|
||||
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:[self javaComponent]
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i.unsignedIntValue
|
||||
withView:[[self javaBase] view]
|
||||
withView:[[self javaComponent] view]
|
||||
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
|
||||
}
|
||||
return [NSArray arrayWithArray:columns];
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef JavaTableRowAccessibility_h
|
||||
#define JavaTableRowAccessibility_h
|
||||
#import "JavaComponentAccessibility.h"
|
||||
|
||||
|
||||
#endif /* JavaTableRowAccessibility_h */
|
||||
#import "JavaElementAccessibility.h"
|
||||
|
||||
@interface JavaTableRowAccessibility : JavaElementAccessibility
|
||||
@interface JavaTableRowAccessibility : JavaComponentAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxTableRow : PlatformAxElement <NSAccessibilityRow>
|
||||
|
||||
@@ -24,17 +24,17 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
if ([[[self accessibilityParent] javaBase] accessible] == NULL) return nil;
|
||||
jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, [[[self accessibilityParent] javaBase] accessible], [[[self accessibilityParent] javaBase] component], JAVA_AX_ALL_CHILDREN, NO);
|
||||
if ([[[self accessibilityParent] javaComponent] accessible] == NULL) return nil;
|
||||
jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, [[[self accessibilityParent] javaComponent] accessible], [[[self accessibilityParent] javaComponent] component], JAVA_AX_ALL_CHILDREN, NO);
|
||||
if (jchildrenAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
|
||||
NSMutableArray *childrenCells = [NSMutableArray arrayWithCapacity:arrayLen/2];
|
||||
|
||||
NSUInteger childIndex = [self rowNumberInTable] * [(JavaTableAccessibility *)[[self accessibilityParent] javaBase] accessibleColCount];
|
||||
NSUInteger childIndex = [self rowNumberInTable] * [(JavaTableAccessibility *) [[self accessibilityParent] javaComponent] accessibleColCount];
|
||||
NSInteger i = childIndex * 2;
|
||||
NSInteger n = ([self rowNumberInTable] + 1) * [(JavaTableAccessibility *)[[self accessibilityParent] javaBase] accessibleColCount] * 2;
|
||||
JavaTableRowAccessibility *selfRow = [self javaBase];
|
||||
NSInteger n = ([self rowNumberInTable] + 1) * [(JavaTableAccessibility *) [[self accessibilityParent] javaComponent] accessibleColCount] * 2;
|
||||
JavaTableRowAccessibility *selfRow = [self javaComponent];
|
||||
for(i; i < n; i+=2)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
@@ -68,7 +68,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex {
|
||||
return [[self javaBase] index];
|
||||
return [[self accessibilityParent] accessibilityIndexOfChild:self];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel {
|
||||
@@ -89,7 +89,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
}
|
||||
|
||||
- (NSUInteger)rowNumberInTable {
|
||||
return [[self javaBase] index];
|
||||
return [[self javaComponent] index];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame {
|
||||
@@ -102,5 +102,9 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
return NSMakeRect(point.x, point.y, width, height);
|
||||
}
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole {
|
||||
return NSAccessibilityTableRowSubrole;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
private LinkedList<TypeAheadMarker> typeAheadMarkers = new LinkedList<TypeAheadMarker>();
|
||||
private boolean consumeNextKeyTyped;
|
||||
private Component restoreFocusTo;
|
||||
private Component keyPressedComponent;
|
||||
private WeakReference<Component> lastKeyPressedOrReleasedTarget = NULL_COMPONENT_WR;
|
||||
|
||||
private static boolean fxAppThreadIsDispatchThread;
|
||||
|
||||
@@ -1100,19 +1100,15 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
||||
if (((AWTEvent) ke).isPosted) {
|
||||
Component focusOwner;
|
||||
if (ke.getID() == KeyEvent.KEY_TYPED) {
|
||||
focusOwner = keyPressedComponent;
|
||||
focusOwner = lastKeyPressedOrReleasedTarget.get();
|
||||
} else {
|
||||
focusOwner = getFocusOwner();
|
||||
if (focusOwner == null) {
|
||||
focusOwner = getFocusedWindow();
|
||||
}
|
||||
lastKeyPressedOrReleasedTarget = new WeakReference<>(focusOwner);
|
||||
}
|
||||
ke.setSource(focusOwner);
|
||||
if (ke.getID() == KeyEvent.KEY_PRESSED) {
|
||||
keyPressedComponent = focusOwner;
|
||||
} else if (ke.getID() == KeyEvent.KEY_RELEASED) {
|
||||
keyPressedComponent = null;
|
||||
}
|
||||
}
|
||||
if (ke.getSource() == null) {
|
||||
return true;
|
||||
|
||||
@@ -603,8 +603,8 @@ public abstract class Toolkit {
|
||||
toolkit = new HeadlessToolkit(toolkit);
|
||||
}
|
||||
}
|
||||
} catch (final ReflectiveOperationException ignored) {
|
||||
throw new AWTError("Could not create Toolkit: " + nm);
|
||||
} catch (final ReflectiveOperationException e) {
|
||||
newAWTError(e, "Could not create Toolkit: " + nm);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -5266,7 +5266,6 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
// Start editing when a key is typed. UI classes can disable this behavior
|
||||
// by setting the client property JTable.autoStartsEdit to Boolean.FALSE.
|
||||
if (!retValue && condition == WHEN_ANCESTOR_OF_FOCUSED_COMPONENT &&
|
||||
isFocusOwner() &&
|
||||
!Boolean.FALSE.equals(getClientProperty("JTable.autoStartsEdit"))) {
|
||||
// We do not have a binding for the event.
|
||||
Component editorComponent = getEditorComponent();
|
||||
@@ -5295,11 +5294,6 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
if (editorComponent == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If the editorComponent is a JComponent, pass the event to it.
|
||||
if (editorComponent instanceof JComponent) {
|
||||
retValue = ((JComponent)editorComponent).processKeyBinding
|
||||
(ks, e, WHEN_FOCUSED, pressed);
|
||||
// If we have started an editor as a result of the user
|
||||
// pressing a key and the surrendersFocusOnKeystroke property
|
||||
// is true, give the focus to the new editor.
|
||||
@@ -5309,6 +5303,11 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
editorComponent.requestFocus();
|
||||
}
|
||||
}
|
||||
// If the editorComponent is a JComponent, pass the event to it.
|
||||
if (editorComponent instanceof JComponent) {
|
||||
retValue = ((JComponent)editorComponent).processKeyBinding
|
||||
(ks, e, WHEN_FOCUSED, pressed);
|
||||
}
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public class KeyEventProcessing {
|
||||
@Native
|
||||
public final static boolean useNationalLayouts = "true".equals(
|
||||
Util.getProperty(useNationalLayoutsOption,
|
||||
FontUtilities.isMacOSX && !FontUtilities.isMacOSX_aarch64 ? "true" : "false"));
|
||||
FontUtilities.isMacOSX ? "true" : "false"));
|
||||
|
||||
// Used on windows to emulate latin OEM keys on cyrillic keyboards
|
||||
public final static String useLatinNonAlphaNumKeycodesOption = "com.sun.awt.useLatinNonAlphaNumKeycodes";
|
||||
|
||||
@@ -111,11 +111,12 @@ public class FontStrikeDesc {
|
||||
*/
|
||||
public static int getAAHintIntVal(Object aa, Font2D font2D, int ptSize) {
|
||||
|
||||
if (FontUtilities.isMacOSX14 &&
|
||||
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_ON ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_GASP))
|
||||
if (FontUtilities.isMacOSX16 ||
|
||||
(FontUtilities.isMacOSX14 &&
|
||||
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_ON ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_GASP)))
|
||||
{
|
||||
return INTVAL_TEXT_ANTIALIAS_ON;
|
||||
}
|
||||
@@ -153,11 +154,12 @@ public class FontStrikeDesc {
|
||||
FontRenderContext frc) {
|
||||
Object aa = frc.getAntiAliasingHint();
|
||||
|
||||
if (FontUtilities.isMacOSX14 &&
|
||||
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_ON ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_GASP))
|
||||
if (FontUtilities.isMacOSX16 ||
|
||||
(FontUtilities.isMacOSX14 &&
|
||||
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_ON ||
|
||||
aa == VALUE_TEXT_ANTIALIAS_GASP)))
|
||||
{
|
||||
return INTVAL_TEXT_ANTIALIAS_ON;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public final class FontUtilities {
|
||||
|
||||
public static boolean isMacOSX;
|
||||
public static boolean isMacOSX14;
|
||||
public static boolean isMacOSX16;
|
||||
public static boolean isMacOSX_aarch64;
|
||||
|
||||
public static boolean useJDKScaler;
|
||||
@@ -83,9 +84,10 @@ public final class FontUtilities {
|
||||
isMacOSX = osName.contains("OS X"); // TODO: MacOSX
|
||||
if (isMacOSX) {
|
||||
// os.version has values like 10.13.6, 10.14.6
|
||||
// If it is not positively recognised as 10.13 or less,
|
||||
// assume it means 10.14 or some later version.
|
||||
// If it is not positively recognised as 10.13 (10.15) or less,
|
||||
// assume it means 10.14 (10.16) or some later version.
|
||||
isMacOSX14 = true;
|
||||
isMacOSX16 = true;
|
||||
String version = System.getProperty("os.version", "");
|
||||
if (version.startsWith("10.")) {
|
||||
version = version.substring(3);
|
||||
@@ -96,6 +98,7 @@ public final class FontUtilities {
|
||||
try {
|
||||
int v = Integer.parseInt(version);
|
||||
isMacOSX14 = (v >= 14);
|
||||
isMacOSX16 = (v >= 16);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,8 +772,9 @@ public final class SunGraphics2D
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FontUtilities.isMacOSX14 &&
|
||||
(aahint == SunHints.INTVAL_TEXT_ANTIALIAS_OFF))
|
||||
if (FontUtilities.isMacOSX16 ||
|
||||
(FontUtilities.isMacOSX14 &&
|
||||
aahint == SunHints.INTVAL_TEXT_ANTIALIAS_OFF))
|
||||
{
|
||||
aahint = SunHints.INTVAL_TEXT_ANTIALIAS_ON;
|
||||
}
|
||||
|
||||
@@ -456,7 +456,11 @@ public abstract class SurfaceData
|
||||
} else {
|
||||
solidTextRenderer = new SolidTextRenderer();
|
||||
}
|
||||
lcdTextRenderer = new LCDTextRenderer();
|
||||
if (FontUtilities.isMacOSX16) {
|
||||
lcdTextRenderer = aaTextRenderer;
|
||||
} else {
|
||||
lcdTextRenderer = new LCDTextRenderer();
|
||||
}
|
||||
|
||||
colorPipe = new AlphaColorPipe();
|
||||
// colorShape = colorPrimitives;
|
||||
|
||||
@@ -695,7 +695,7 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative(
|
||||
return (jlong) 0;
|
||||
}
|
||||
(*env)->GetDoubleArrayRegion(env, matrix, 0, 4, dmat);
|
||||
ptsz = euclidianDistance(dmat[2], dmat[3]); //i.e. y-size
|
||||
ptsz = euclidianDistance(dmat[0], dmat[1]); //i.e. x-size
|
||||
if (ptsz < 1.0) {
|
||||
//text can not be smaller than 1 point
|
||||
ptsz = 1.0;
|
||||
|
||||
@@ -1062,7 +1062,9 @@ public class XBaseWindow {
|
||||
buttonState = xbe.get_state() & XConstants.ALL_BUTTONS_MASK;
|
||||
|
||||
boolean isWheel = (theButton == XConstants.MouseWheelUp ||
|
||||
theButton == XConstants.MouseWheelDown);
|
||||
theButton == XConstants.MouseWheelDown ||
|
||||
theButton == XConstants.ScrollLeft ||
|
||||
theButton == XConstants.ScrollRight);
|
||||
|
||||
// don't give focus if it's just the mouse wheel turning
|
||||
if (!isWheel) {
|
||||
|
||||
@@ -211,6 +211,8 @@ public final class XConstants {
|
||||
// as it may be possible to remap them via x11 configuration files
|
||||
public static final int MouseWheelUp = buttons[3];
|
||||
public static final int MouseWheelDown = buttons[4];
|
||||
public static final int ScrollLeft = buttons[5];
|
||||
public static final int ScrollRight = buttons[6];
|
||||
|
||||
/* Notify modes */
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8195129
|
||||
* @summary regression test for 8195129,
|
||||
* verifies the ability to System.load() from a location containing non-Latin characters
|
||||
* @requires os.family == "win" | os.family == "mac" | os.family == "linux"
|
||||
* @library /test/lib
|
||||
* @run main/native LoadLibraryUnicode
|
||||
*/
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
public class LoadLibraryUnicode {
|
||||
|
||||
static native int giveANumber();
|
||||
|
||||
private static final String NON_LATIN_PATH_NAME = "ka-\u1889-omega-\u03c9";
|
||||
|
||||
public static void verifySystemLoad() throws Exception {
|
||||
String osDependentLibraryFileName = null;
|
||||
if (Platform.isLinux()) {
|
||||
osDependentLibraryFileName = "libLoadLibraryUnicode.so";
|
||||
} else if (Platform.isOSX()) {
|
||||
osDependentLibraryFileName = "libLoadLibraryUnicode.dylib";
|
||||
} else if (Platform.isWindows()) {
|
||||
osDependentLibraryFileName = "LoadLibraryUnicode.dll";
|
||||
} else {
|
||||
throw new Error("Unsupported OS");
|
||||
}
|
||||
|
||||
String testNativePath = getSystemProperty("test.nativepath");
|
||||
Path origLibraryPath = Paths.get(testNativePath).resolve(osDependentLibraryFileName);
|
||||
|
||||
Path currentDirPath = Paths.get(".").toAbsolutePath();
|
||||
Path newLibraryPath = currentDirPath.resolve(NON_LATIN_PATH_NAME);
|
||||
Files.createDirectory(newLibraryPath);
|
||||
newLibraryPath = newLibraryPath.resolve(osDependentLibraryFileName);
|
||||
|
||||
System.out.println(String.format("Copying '%s' to '%s'", origLibraryPath, newLibraryPath));
|
||||
Files.copy(origLibraryPath, newLibraryPath);
|
||||
|
||||
System.out.println(String.format("Loading '%s'", newLibraryPath));
|
||||
System.load(newLibraryPath.toString());
|
||||
|
||||
final int retval = giveANumber();
|
||||
Asserts.assertEquals(retval, 42);
|
||||
}
|
||||
|
||||
public static void verifyExceptionMessage() throws Exception {
|
||||
Path currentDirPath = Paths.get(".").toAbsolutePath();
|
||||
Path newLibraryPath = currentDirPath.resolve(NON_LATIN_PATH_NAME).resolve("non-existent-library");
|
||||
|
||||
System.out.println(String.format("Loading '%s'", newLibraryPath));
|
||||
try {
|
||||
System.load(newLibraryPath.toString());
|
||||
} catch(UnsatisfiedLinkError e) {
|
||||
// The name of the library may have been corrupted by encoding/decoding it improperly.
|
||||
// Verify that it is still the same.
|
||||
Asserts.assertTrue(e.getMessage().contains(NON_LATIN_PATH_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
verifySystemLoad();
|
||||
verifyExceptionMessage();
|
||||
}
|
||||
|
||||
// Utility method to retrieve and validate system properties
|
||||
private static String getSystemProperty(String propertyName) throws Error {
|
||||
String systemProperty = System.getProperty(propertyName, "").trim();
|
||||
System.out.println(propertyName + " = " + systemProperty);
|
||||
if (systemProperty.isEmpty()) {
|
||||
throw new Error("TESTBUG: property " + propertyName + " is empty");
|
||||
}
|
||||
return systemProperty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_LoadLibraryUnicode_giveANumber(JNIEnv *env) {
|
||||
return 42;
|
||||
}
|
||||
@@ -731,7 +731,7 @@ javax/swing/AbstractButton/6711682/bug6711682.java 8060765 windows-all,macosx-al
|
||||
javax/swing/Action/8133039/bug8133039.java 8196089 windows-all,macosx-all
|
||||
javax/swing/JComboBox/6559152/bug6559152.java 8196090 windows-all,macosx-all
|
||||
javax/swing/JComboBox/6607130/bug6607130.java 8196091 windows-all
|
||||
javax/swing/JComboBox/8032878/bug8032878.java 8196092 windows-all,macosx-all
|
||||
javax/swing/JComboBox/8032878/bug8032878.java 8196092 macosx-all
|
||||
javax/swing/JComboBox/8057893/bug8057893.java 8169953 windows-all,macosx-all
|
||||
javax/swing/JComboBox/8072767/bug8072767.java 8196093 windows-all,macosx-all
|
||||
javax/swing/JComponent/4337267/bug4337267.java 8146451 windows-all
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
* @summary Checks that JComboBox as JTable cell editor processes key events
|
||||
* even where setSurrendersFocusOnKeystroke flag in JTable is false and
|
||||
* that it does not lose the first key press where the flag is true.
|
||||
* @library ../../regtesthelpers
|
||||
* @build Util
|
||||
* @author Alexey Ivanov
|
||||
* @run main bug8032878
|
||||
*/
|
||||
|
||||
@@ -86,6 +83,7 @@ public class bug8032878 implements Runnable {
|
||||
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
frame.setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
private void test(final boolean flag) throws Exception {
|
||||
@@ -93,11 +91,13 @@ public class bug8032878 implements Runnable {
|
||||
surrender = flag;
|
||||
SwingUtilities.invokeAndWait(this);
|
||||
|
||||
robot.waitForIdle();
|
||||
robot.delay(1000);
|
||||
runTest();
|
||||
checkResult();
|
||||
} finally {
|
||||
if (frame != null) {
|
||||
frame.dispose();
|
||||
SwingUtilities.invokeAndWait(() -> frame.dispose());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,12 +105,20 @@ public class bug8032878 implements Runnable {
|
||||
private void runTest() throws Exception {
|
||||
robot.waitForIdle();
|
||||
// Select 'one'
|
||||
Util.hitKeys(robot, KeyEvent.VK_TAB);
|
||||
robot.keyPress(KeyEvent.VK_TAB);
|
||||
robot.keyRelease(KeyEvent.VK_TAB);
|
||||
robot.waitForIdle();
|
||||
Util.hitKeys(robot, KeyEvent.VK_1);
|
||||
Util.hitKeys(robot, KeyEvent.VK_2);
|
||||
Util.hitKeys(robot, KeyEvent.VK_3);
|
||||
Util.hitKeys(robot, KeyEvent.VK_ENTER);
|
||||
robot.keyPress(KeyEvent.VK_1);
|
||||
robot.keyRelease(KeyEvent.VK_1);
|
||||
robot.waitForIdle();
|
||||
robot.keyPress(KeyEvent.VK_2);
|
||||
robot.keyRelease(KeyEvent.VK_2);
|
||||
robot.waitForIdle();
|
||||
robot.keyPress(KeyEvent.VK_3);
|
||||
robot.keyRelease(KeyEvent.VK_3);
|
||||
robot.waitForIdle();
|
||||
robot.keyPress(KeyEvent.VK_ENTER);
|
||||
robot.keyRelease(KeyEvent.VK_ENTER);
|
||||
robot.waitForIdle();
|
||||
}
|
||||
|
||||
|
||||
53
test/jdk/jb/java/a11y/AccessibleJComboboxTest.java
Normal file
53
test/jdk/jb/java/a11y/AccessibleJComboboxTest.java
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary manual test for JBR-3241
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJComboboxTest
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
68
test/jdk/jb/java/a11y/AccessibleJScrollPaneTest.java
Normal file
68
test/jdk/jb/java/a11y/AccessibleJScrollPaneTest.java
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary manual test for JBR-3239
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJScrollPaneTest
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class AccessibleJScrollPaneTest extends AccessibleComponentTest {
|
||||
|
||||
@java.lang.Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
void createScrollPane() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JScrollPane in a simple Window.\n\n"
|
||||
+ "Turn screen reader on, and tab to the table.\n"
|
||||
+ "this table has 10 rows and 10 columns, few cells are invisible.\n\n"
|
||||
+ "On Windows press arrow buttons to move through the table.\n\n"
|
||||
+ "On MacOS, use up and down arrow buttons to move through the rows, use VoiceOver fast navigation to move through the columns.\n\n"
|
||||
+ "If you can hear table cells tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
final int n = 10;
|
||||
|
||||
String[][] data = new String[n][n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
data[i][j] = "Cell " + String.valueOf(i) + ":" + String.valueOf(j);
|
||||
}
|
||||
}
|
||||
String[] columnNames = new String[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
columnNames[i] = "Header " + String.valueOf(i);
|
||||
}
|
||||
|
||||
JTable table = new JTable(data, columnNames);
|
||||
table.setPreferredScrollableViewportSize(new Dimension(table.getPreferredScrollableViewportSize().width / 2, table.getRowHeight() * 5));
|
||||
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
||||
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
|
||||
panel.add(scrollPane);
|
||||
|
||||
exceptionString = "AccessibleJScrollPane test failed!";
|
||||
super.createUI(panel, "AccessibleJScrollTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleJScrollPaneTest test = new AccessibleJScrollPaneTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(test::createScrollPane);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
62
test/jdk/jb/java/a11y/AccessibleJTabbedPaneTest.java
Normal file
62
test/jdk/jb/java/a11y/AccessibleJTabbedPaneTest.java
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary manual test for JBR-3240
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJTabbedPaneTest
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
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 in a simple Window.\n\n"
|
||||
+ "Turn screen reader on, and tab to the JTabbedPane.\n"
|
||||
+ "Use up and 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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
165
test/jdk/jb/java/awt/Toolkit/ToolkitExceptionTest.java
Normal file
165
test/jdk/jb/java/awt/Toolkit/ToolkitExceptionTest.java
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2000-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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @summary regression test on JBR-3295 Fix error handling in Toolkit — do not ignore error and pass it as a cause
|
||||
* @run main/othervm -Dawt.toolkit=ToolkitExceptionTest ToolkitExceptionTest
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.im.InputMethodHighlight;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class ToolkitExceptionTest extends Toolkit {
|
||||
|
||||
public static void main (String[] args) {
|
||||
try {
|
||||
Toolkit.getDefaultToolkit();
|
||||
} catch (Throwable e) {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bos));
|
||||
if (!bos.toString().contains("MyToolkitException")) {
|
||||
throw new RuntimeException("Failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ToolkitExceptionTest() {
|
||||
throw new RuntimeException("MyToolkitException");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getScreenSize() throws HeadlessException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getScreenResolution() throws HeadlessException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorModel getColorModel() throws HeadlessException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getFontList() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontMetrics getFontMetrics(Font font) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sync() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getImage(String filename) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getImage(URL url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image createImage(String filename) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image createImage(URL url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int checkImage(Image image, int width, int height, ImageObserver observer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image createImage(ImageProducer producer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image createImage(byte[] imagedata, int imageoffset, int imagelength) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintJob getPrintJob(Frame frame, String jobtitle, Properties props) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beep() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard getSystemClipboard() throws HeadlessException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EventQueue getSystemEventQueueImpl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType modalExclusionType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) throws HeadlessException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
87
test/jdk/jb/java/awt/Window/SiblingOrderTest.java
Normal file
87
test/jdk/jb/java/awt/Window/SiblingOrderTest.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.InputEvent;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Regression test for JBR-3353 Sibling popup window is shown below dialog on macOS
|
||||
* @key headful
|
||||
*/
|
||||
|
||||
public class SiblingOrderTest {
|
||||
private static Robot robot;
|
||||
private static JFrame frame;
|
||||
private static final CompletableFuture<Boolean> popupButtonPressed = new CompletableFuture<>();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(SiblingOrderTest::initUI);
|
||||
click(); // button in frame
|
||||
click(); // button in dialog
|
||||
click(); // button in popup
|
||||
popupButtonPressed.get(3, TimeUnit.SECONDS);
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(SiblingOrderTest::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame = new JFrame("SiblingOrderTest");
|
||||
JButton b = new JButton("Dialog");
|
||||
b.addActionListener(e -> {
|
||||
JDialog d = new JDialog(frame, "Dialog");
|
||||
JButton b1 = new JButton("Popup");
|
||||
b1.addActionListener(e1 -> {
|
||||
JWindow w = new JWindow(frame);
|
||||
JButton b2 = new JButton("Finish");
|
||||
b2.addActionListener(e2 -> popupButtonPressed.complete(true));
|
||||
w.add(b2);
|
||||
w.setBounds(150, 150, 100, 100);
|
||||
w.setVisible(true);
|
||||
});
|
||||
d.add(b1);
|
||||
d.setBounds(100, 100, 200, 200);
|
||||
d.setVisible(true);
|
||||
});
|
||||
frame.add(b);
|
||||
frame.setBounds(50, 50, 300, 300);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame != null) frame.dispose();
|
||||
}
|
||||
|
||||
private static void click() {
|
||||
robot.delay(1000);
|
||||
robot.mouseMove(200, 200);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
}
|
||||
}
|
||||
62
test/jdk/jb/java/jcef/HandleJSQueryTest3314.sh
Normal file
62
test/jdk/jb/java/jcef/HandleJSQueryTest3314.sh
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Copyright 2000-2021 JetBrains s.r.o.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# @test
|
||||
# @summary Regression test for JBR-3314
|
||||
# It executes the test HandleJSQueryTest.java in a loop till a crash happens or number of iterations
|
||||
# exceeds a limit.
|
||||
# Number of iterations can be specified via the environment variable RUN_NUMBER, by default it is set to 100.
|
||||
# @run shell/timeout=300 HandleJSQueryTest3314.sh
|
||||
|
||||
RUNS_NUMBER=${RUN_NUMBER:-50}
|
||||
echo "number of iterations: $RUNS_NUMBER"
|
||||
|
||||
if [ -z "${TESTSRC}" ]; then
|
||||
echo "TESTSRC undefined: set to ."
|
||||
TESTSRC=.
|
||||
fi
|
||||
|
||||
if [ -z "${TESTCLASSES}" ]; then
|
||||
echo "TESTCLASSES undefined: set to ."
|
||||
TESTCLASSES=.
|
||||
fi
|
||||
|
||||
if [ -z "${TESTJAVA}" ]; then
|
||||
echo "TESTJAVA undefined: testing cancelled"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
curdir=$(pwd)
|
||||
cd ${TESTSRC}
|
||||
${TESTJAVA}/bin/javac -d ${TESTCLASSES} HandleJSQueryTest.java
|
||||
cd $curdir
|
||||
|
||||
i=0
|
||||
while [ "$i" -le "$RUNS_NUMBER" ]; do
|
||||
echo "iteration - $i"
|
||||
${TESTJAVA}/bin/java -cp ${TESTCLASSES} HandleJSQueryTest
|
||||
exit_code=$?
|
||||
echo "exit_xode=$exit_code"
|
||||
if [ $exit_code -ne "0" ]; then
|
||||
[[ $exit_code -eq "134" ]] && echo "FAILED: Test crashed" && exit $exit_code
|
||||
echo "Test failed because of not a crash. Execution is being conituned"
|
||||
fi
|
||||
i=$(( i + 1 ))
|
||||
done
|
||||
echo "PASSED: Test did never crash during 100 iterations"
|
||||
exit 0
|
||||
@@ -885,8 +885,7 @@ javax/swing/JComboBox/6236162/bug6236162.java
|
||||
javax/swing/JComboBox/6559152/bug6559152.java 8196090 windows-all,macosx-all,linux-all
|
||||
javax/swing/JComboBox/6607130/bug6607130.java 8196091 windows-all
|
||||
javax/swing/JComboBox/7031551/bug7031551.java 8199056 generic-all
|
||||
javax/swing/JComboBox/8032878/bug8032878.java 8196092 windows-all,macosx-all
|
||||
javax/swing/JComboBox/8032878/bug8032878.java 8196439 macosx-all,windows-all,linux-all
|
||||
javax/swing/JComboBox/8032878/bug8032878.java 8196092,8196439 macosx-all,linux-all
|
||||
javax/swing/JComboBox/8033069/bug8033069NoScrollBar.java 8163367 macosx-all,windows-all,linux-all
|
||||
javax/swing/JComboBox/8033069/bug8033069ScrollBar.java 8163367 generic-all
|
||||
javax/swing/JComboBox/8041909/ActionListenerExceptionTest.java 8197552 macosx-all,windows-all,linux-all
|
||||
|
||||
Reference in New Issue
Block a user