mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-28 20:29:45 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c8cdb221b | ||
|
|
d34d6528fe | ||
|
|
1d525a2d2f | ||
|
|
3038fc95c6 | ||
|
|
10a30e2135 | ||
|
|
b46c4429b4 | ||
|
|
e51648f368 | ||
|
|
235dbdc3f0 | ||
|
|
c8f68f23d9 | ||
|
|
5cc0870756 | ||
|
|
a50a5f1bea | ||
|
|
95a47810d5 |
@@ -0,0 +1,81 @@
|
||||
// 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;
|
||||
+ (JavaBaseAccessibility *) createWithParent:(JavaBaseAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view isWrapped:(BOOL)wrapped;
|
||||
+ (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;
|
||||
|
||||
@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
|
||||
@@ -0,0 +1,675 @@
|
||||
// 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 "JavaTextAccessibility.h"
|
||||
#import "JavaListAccessibility.h"
|
||||
#import "JavaTableAccessibility.h"
|
||||
#import "JavaListRowAccessibility.h"
|
||||
#import "JavaTableRowAccessibility.h"
|
||||
#import "JavaCellAccessibility.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "AWTView.h"
|
||||
|
||||
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(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
|
||||
{
|
||||
if ([parent isKindOfClass:[JavaTableAccessibility class]]) {
|
||||
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
|
||||
NSArray<NSNumber *> *selectedRowIndexses = [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 = [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 = (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
|
||||
for(i = 0; i < arrayLen; i += 2)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
NSString *childJavaRole = nil;
|
||||
if (jchildJavaRole != NULL) {
|
||||
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];
|
||||
|
||||
(*env)->DeleteLocalRef(env, jchild);
|
||||
(*env)->DeleteLocalRef(env, jchildJavaRole);
|
||||
|
||||
[children addObject:child.platformAxElement];
|
||||
childIndex++;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
+ (JavaBaseAccessibility *)createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view
|
||||
{
|
||||
JavaBaseAccessibility *ret = nil;
|
||||
jobject jcomponent = [(AWTView *)view awtComponent:env];
|
||||
jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent);
|
||||
if (index >= 0) {
|
||||
NSString *javaRole = getJavaRole(env, jaccessible, jcomponent);
|
||||
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) {
|
||||
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 ([javaRole isEqualToString:@"pagetablist"]) {
|
||||
newChild = [TabGroupAccessibility alloc];
|
||||
} else if ([javaRole isEqualToString:@"scrollpane"]) {
|
||||
newChild = [ScrollAreaAccessibility alloc];
|
||||
} else {
|
||||
NSString *nsRole = [sRoles objectForKey:javaRole];
|
||||
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole] || [nsRole isEqualToString:NSAccessibilityTextAreaRole] || [nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
|
||||
newChild = [JavaTextAccessibility alloc];
|
||||
} else if ([nsRole isEqualToString:NSAccessibilityListRole]) {
|
||||
newChild = [JavaListAccessibility alloc];
|
||||
} else if ([nsRole isEqualToString:NSAccessibilityTableRole]) {
|
||||
newChild = [JavaTableAccessibility 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));
|
||||
(*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);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// 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"
|
||||
|
||||
@interface JavaCellAccessibility : JavaElementAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxCell : PlatformAxElement
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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 "JavaCellAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
@implementation JavaCellAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxCell";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxCell
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole {
|
||||
return NSAccessibilityCellRole;;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren {
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
NSString *javaRole = [[self javaBase] javaRole];
|
||||
JavaBaseAccessibility *newChild = [JavaBaseAccessibility createWithParent:[self javaBase]
|
||||
accessible:[[self javaBase] accessible]
|
||||
role:javaRole
|
||||
index:[[self javaBase] index]
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withView:[[self javaBase] view]
|
||||
isWrapped:YES];
|
||||
return [NSArray arrayWithObject:newChild.platformAxElement];
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame {
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent {
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (void)setAccessibilityParent:(id)accessibilityParent {
|
||||
[super setAccessibilityParent:accessibilityParent];
|
||||
}
|
||||
|
||||
@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 "JavaElementAccessibility.h"
|
||||
|
||||
@interface JavaColumnAccessibility : JavaElementAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxColumn : PlatformAxElement
|
||||
|
||||
@property(readonly) NSUInteger columnNumberInTable;
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// 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 "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "JavaCellAccessibility.h"
|
||||
#import "JavaColumnAccessibility.h"
|
||||
#import "JavaTableAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
|
||||
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
|
||||
|
||||
@implementation JavaColumnAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxColumn";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxColumn
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole {
|
||||
return NSAccessibilityColumnRole;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren {
|
||||
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 (jchildrenAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
|
||||
NSMutableArray *childrenCells = [NSMutableArray arrayWithCapacity:arrayLen/2];
|
||||
|
||||
NSUInteger childIndex = [self columnNumberInTable];
|
||||
|
||||
JavaColumnAccessibility *selfRow = [self javaBase];
|
||||
int inc = [(JavaTableAccessibility *)[[self accessibilityParent] javaBase] accessibleColCount] * 2;
|
||||
NSInteger i = childIndex * 2;
|
||||
for(NSInteger i; i < arrayLen; i += inc)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
NSString *childJavaRole = nil;
|
||||
if (jchildJavaRole != NULL) {
|
||||
jobject jkey = JNFGetObjectField(env, jchildJavaRole, sjf_key);
|
||||
childJavaRole = JNFJavaToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
}
|
||||
|
||||
JavaCellAccessibility *child = [[JavaCellAccessibility alloc] initWithParent:selfRow
|
||||
withEnv:env
|
||||
withAccessible:jchild
|
||||
withIndex:childIndex
|
||||
withView:[selfRow view]
|
||||
withJavaRole:childJavaRole];
|
||||
[childrenCells addObject:[child autorelease].platformAxElement];
|
||||
|
||||
(*env)->DeleteLocalRef(env, jchild);
|
||||
(*env)->DeleteLocalRef(env, jchildJavaRole);
|
||||
|
||||
childIndex += (inc / 2);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
|
||||
return childrenCells;
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)columnNumberInTable {
|
||||
return [[self javaBase] index];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -26,55 +26,16 @@
|
||||
#include "jni.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "JavaBaseAccessibility.h"
|
||||
|
||||
//#define JAVA_AX_DEBUG 1
|
||||
//#define JAVA_AX_NO_IGNORES 1
|
||||
//#define JAVA_AX_DEBUG_PARMS 1
|
||||
|
||||
|
||||
@interface JavaComponentAccessibility : NSObject {
|
||||
NSView *fView;
|
||||
NSObject *fParent;
|
||||
|
||||
NSString *fNSRole;
|
||||
NSString *fJavaRole;
|
||||
|
||||
jint fIndex;
|
||||
jobject fAccessible;
|
||||
jobject fComponent;
|
||||
|
||||
@interface JavaComponentAccessibility : JavaBaseAccessibility {
|
||||
NSMutableDictionary *fActions;
|
||||
NSObject *fActionsLOCK;
|
||||
}
|
||||
|
||||
- (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;
|
||||
+ (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;
|
||||
|
||||
- (NSDictionary*)getActions:(JNIEnv *)env;
|
||||
- (void)getActionsWithEnv:(JNIEnv *)env;
|
||||
|
||||
- (jobject)axContextWithEnv:(JNIEnv *)env;
|
||||
- (NSView*)view;
|
||||
- (NSWindow*)window;
|
||||
- (id)parent;
|
||||
- (NSString *)javaRole;
|
||||
- (BOOL)isMenu;
|
||||
- (BOOL)isSelected:(JNIEnv *)env;
|
||||
- (BOOL)isSelectable:(JNIEnv *)env;
|
||||
- (BOOL)isVisible:(JNIEnv *)env;
|
||||
|
||||
// attribute names
|
||||
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
|
||||
- (NSArray *)accessibilityAttributeNames;
|
||||
@@ -143,3 +104,44 @@
|
||||
- (id)accessibilityFocusedUIElement;
|
||||
|
||||
@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
|
||||
|
||||
@@ -66,58 +66,12 @@ 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;
|
||||
|
||||
// sAttributeNamesForRoleCache holds the names of the attributes to which each java
|
||||
// AccessibleRole responds (see AccessibleRole.java).
|
||||
// This cache is queried before attempting to access a given attribute for a particular role.
|
||||
static NSMutableDictionary *sAttributeNamesForRoleCache = nil;
|
||||
static NSObject *sAttributeNamesLOCK = nil;
|
||||
|
||||
@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
|
||||
|
||||
|
||||
@implementation JavaComponentAccessibility
|
||||
|
||||
- (NSString *)description
|
||||
@@ -128,63 +82,17 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
{
|
||||
self = [super init];
|
||||
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
|
||||
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;
|
||||
|
||||
fActions = nil;
|
||||
fActionsLOCK = [[NSObject alloc] init];
|
||||
}
|
||||
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;
|
||||
|
||||
[fActions release];
|
||||
fActions = nil;
|
||||
|
||||
@@ -194,211 +102,12 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)postValueChanged
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self, NSAccessibilityValueChangedNotification);
|
||||
}
|
||||
|
||||
- (void)postSelectedTextChanged
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self, NSAccessibilitySelectedTextChangedNotification);
|
||||
}
|
||||
|
||||
- (void)postSelectionChanged
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self, NSAccessibilitySelectedChildrenChangedNotification);
|
||||
}
|
||||
|
||||
- (void)postMenuOpened
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self, (NSString *)kAXMenuOpenedNotification);
|
||||
}
|
||||
|
||||
- (void)postMenuClosed
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self, (NSString *)kAXMenuClosedNotification);
|
||||
}
|
||||
|
||||
- (void)postMenuItemSelected
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
NSAccessibilityPostNotification(self, (NSString *)kAXMenuItemSelectedNotification);
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)anObject
|
||||
{
|
||||
if (![anObject isKindOfClass:[self class]]) return NO;
|
||||
JavaComponentAccessibility *accessibility = (JavaComponentAccessibility *)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 (sAttributeNamesForRoleCache == nil) {
|
||||
sAttributeNamesLOCK = [[NSObject alloc] init];
|
||||
sAttributeNamesForRoleCache = [[NSMutableDictionary alloc] initWithCapacity:60];
|
||||
}
|
||||
|
||||
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:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored
|
||||
{
|
||||
if (parent->fAccessible == NULL) return nil;
|
||||
jobjectArray 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
|
||||
for(i = 0; i < arrayLen; i+=2)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
NSString *childJavaRole = nil;
|
||||
if (jchildJavaRole != NULL) {
|
||||
jobject jkey = JNFGetObjectField(env, jchildJavaRole, sjf_key);
|
||||
childJavaRole = JNFJavaToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
}
|
||||
|
||||
JavaComponentAccessibility *child = [self createWithParent:parent accessible:jchild role:childJavaRole index:childIndex withEnv:env withView:parent->fView];
|
||||
|
||||
(*env)->DeleteLocalRef(env, jchild);
|
||||
(*env)->DeleteLocalRef(env, jchildJavaRole);
|
||||
|
||||
[children addObject:child];
|
||||
childIndex++;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
+ (JavaComponentAccessibility *)createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view
|
||||
{
|
||||
JavaComponentAccessibility *ret = nil;
|
||||
jobject jcomponent = [(AWTView *)view awtComponent:env];
|
||||
jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent);
|
||||
if (index >= 0) {
|
||||
NSString *javaRole = getJavaRole(env, jaccessible, jcomponent);
|
||||
ret = [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view];
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jcomponent);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ (JavaComponentAccessibility *) 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];
|
||||
}
|
||||
|
||||
+ (JavaComponentAccessibility *) createWithParent:(JavaComponentAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view
|
||||
{
|
||||
// try to fetch the jCAX from Java, and return autoreleased
|
||||
jobject jCAX = [JavaComponentAccessibility getCAccessible:jaccessible withEnv:env];
|
||||
if (jCAX == NULL) return nil;
|
||||
JavaComponentAccessibility *value = (JavaComponentAccessibility *) jlong_to_ptr(JNFGetLongField(env, jCAX, jf_ptr));
|
||||
if (value != nil) {
|
||||
(*env)->DeleteLocalRef(env, jCAX);
|
||||
return [[value retain] autorelease];
|
||||
}
|
||||
|
||||
// otherwise, create a new instance
|
||||
JavaComponentAccessibility *newChild = nil;
|
||||
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] || [nsRole isEqualToString:NSAccessibilityTextAreaRole] || [nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
|
||||
newChild = [JavaTextAccessibility 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));
|
||||
(*env)->DeleteLocalRef(env, jCAX);
|
||||
|
||||
// return autoreleased instance
|
||||
return [newChild autorelease];
|
||||
}
|
||||
|
||||
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
|
||||
@@ -533,101 +242,6 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (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 = [JavaComponentAccessibility 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, ((JavaComponentAccessibility *)[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;
|
||||
}
|
||||
|
||||
// the array of names for each role is cached in the sAttributeNamesForRoleCache
|
||||
- (NSArray *)accessibilityAttributeNames
|
||||
{
|
||||
@@ -932,7 +546,11 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
// Element containing current element (id)
|
||||
- (id)accessibilityParentAttribute
|
||||
{
|
||||
return NSAccessibilityUnignoredAncestor([self parent]);
|
||||
id parent = [self parent];
|
||||
if ([parent isKindOfClass:[JavaBaseAccessibility class]]) {
|
||||
parent = ((JavaBaseAccessibility *)parent).platformAxElement;
|
||||
}
|
||||
return NSAccessibilityUnignoredAncestor(parent);
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsParentAttributeSettable
|
||||
@@ -943,23 +561,8 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
// Screen position of element's lower-left corner in lower-left relative screen coordinates (NSValue)
|
||||
- (NSValue *)accessibilityPositionAttribute
|
||||
{
|
||||
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 [NSValue valueWithPoint:point];
|
||||
NSRect bounds = [self getBounds];
|
||||
return [NSValue valueWithPoint:NSMakePoint(bounds.origin.x, bounds.origin.y)];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsPositionAttributeSettable
|
||||
@@ -1072,11 +675,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
|
||||
// Element size (NSValue)
|
||||
- (NSValue *)accessibilitySizeAttribute {
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
|
||||
NSValue* size = [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)];
|
||||
(*env)->DeleteLocalRef(env, axComponent);
|
||||
return size;
|
||||
return [NSValue valueWithSize:[self getSize]];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsSizeAttributeSettable
|
||||
@@ -1323,7 +922,8 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
if (JNFIsInstanceOf(env, jparent, &jc_Container)) {
|
||||
jobject jaccessible = JNFCallStaticObjectMethod(env, jm_accessibilityHitTest, jparent, (jfloat)point.x, (jfloat)point.y); // AWT_THREADING Safe (AWTRunLoop)
|
||||
if (jaccessible != NULL) {
|
||||
value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView];
|
||||
value = [JavaBaseAccessibility createWithAccessible:jaccessible withEnv:env withView:fView];
|
||||
value = ((JavaBaseAccessibility *)value).platformAxElement;
|
||||
(*env)->DeleteLocalRef(env, jaccessible);
|
||||
}
|
||||
}
|
||||
@@ -1344,149 +944,11 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
|
||||
- (id)accessibilityFocusedUIElement
|
||||
{
|
||||
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];
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, focused);
|
||||
}
|
||||
|
||||
if (value == nil) {
|
||||
value = self;
|
||||
}
|
||||
#ifdef JAVA_AX_DEBUG
|
||||
NSLog(@"%s: %@", __FUNCTION__, value);
|
||||
#endif
|
||||
return value;
|
||||
return [self getFocusedElement];
|
||||
}
|
||||
|
||||
@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:[JavaComponentAccessibility 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:(JavaComponentAccessibility *)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:(JavaComponentAccessibility *)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:(JavaComponentAccessibility *)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:(JavaComponentAccessibility *)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:(JavaComponentAccessibility *)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:(JavaComponentAccessibility *)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:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
@implementation TabGroupAccessibility
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
@@ -1769,16 +1231,18 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
if ([children count] <= 0) return nil;
|
||||
|
||||
// The scroll bars are in the children.
|
||||
JavaComponentAccessibility *aElement;
|
||||
NSObject *aElement;
|
||||
NSEnumerator *enumerator = [children objectEnumerator];
|
||||
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
|
||||
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
jobject elementAxContext = [aElement axContextWithEnv:env];
|
||||
if (isHorizontal(env, elementAxContext, fComponent)) {
|
||||
while ((aElement = [enumerator nextObject])) {
|
||||
if ([aElement respondsToSelector:@selector(accessibilityRoleAttribute)]) {
|
||||
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
jobject elementAxContext = [((NSObject <JavaBaseProvider> *)aElement).javaBase axContextWithEnv:env];
|
||||
if (isHorizontal(env, elementAxContext, fComponent)) {
|
||||
(*env)->DeleteLocalRef(env, elementAxContext);
|
||||
return aElement;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, elementAxContext);
|
||||
return aElement;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, elementAxContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1829,11 +1293,13 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
|
||||
// The scroll bars are in the children. children less the scroll bars is the contents
|
||||
NSEnumerator *enumerator = [children objectEnumerator];
|
||||
JavaComponentAccessibility *aElement;
|
||||
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
|
||||
if (![[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
// no scroll bars in contents
|
||||
[(NSMutableArray *)contents addObject:aElement];
|
||||
NSObject *aElement;
|
||||
while ((aElement = [enumerator nextObject])) {
|
||||
if ([aElement respondsToSelector:@selector(accessibilityRoleAttribute)]) {
|
||||
if (![[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
// no scroll bars in contents
|
||||
[(NSMutableArray *) contents addObject:aElement];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// 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
|
||||
@@ -0,0 +1,120 @@
|
||||
// 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_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;
|
||||
}
|
||||
|
||||
- (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])];
|
||||
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])];
|
||||
if ([selectedChildren count] > 0) {
|
||||
return selectedChildren;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [self.javaBase getBounds];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
JavaBaseAccessibility *parent = (JavaBaseAccessibility *) [self.javaBase parent];
|
||||
return parent.platformAxElement;
|
||||
}
|
||||
|
||||
- (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
|
||||
@@ -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.
|
||||
|
||||
#ifndef NATIVE_JAVALISTACCESSIBILITY_H
|
||||
#define NATIVE_JAVALISTACCESSIBILITY_H
|
||||
|
||||
#endif // NATIVE_JAVALISTACCESSIBILITY_H
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
|
||||
@interface JavaListAccessibility : JavaElementAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxList : PlatformAxElement <NSAccessibilityList>
|
||||
@end
|
||||
@@ -0,0 +1,56 @@
|
||||
// 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 "JavaListAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
@implementation JavaListAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName
|
||||
{
|
||||
return @"PlatformAxList";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxList
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityRows
|
||||
{
|
||||
return [self accessibilityChildren];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedRows
|
||||
{
|
||||
return [self accessibilitySelectedChildren];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
return [super accessibilityLabel] == NULL ? @"list" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (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];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +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.
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
|
||||
@interface JavaListRowAccessibility : JavaElementAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxListRow : PlatformAxElement <NSAccessibilityRow>
|
||||
@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.
|
||||
|
||||
#include "jni.h"
|
||||
#import "JavaListRowAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "JavaTextAccessibility.h"
|
||||
#import "JavaListAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
|
||||
|
||||
@implementation JavaListRowAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxListRow";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxListRow
|
||||
|
||||
- (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]
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withView:[[self javaBase] view]
|
||||
isWrapped:YES];
|
||||
return [NSArray arrayWithObject:[newChild autorelease].platformAxElement];
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex {
|
||||
return [super accessibilityIndex];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,18 @@
|
||||
// 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"
|
||||
|
||||
@interface JavaTableAccessibility : JavaElementAccessibility
|
||||
|
||||
@property(readonly) int accessibleRowCount;
|
||||
@property(readonly) int accessibleColCount;
|
||||
@property(readonly) NSArray<NSNumber *> *selectedAccessibleRows;
|
||||
@property(readonly) NSArray<NSNumber *> *selectedAccessibleColumns;
|
||||
- (BOOL)isAccessibleChildSelectedFromIndex:(int)index;
|
||||
- (int) accessibleRowAtIndex:(int)index;
|
||||
- (int) accessibleColumnAtIndex:(int)index;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformAxTable : PlatformAxElement <NSAccessibilityTable>
|
||||
@end
|
||||
@@ -0,0 +1,187 @@
|
||||
// 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 <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
#import "JavaTableRowAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "JavaTableAccessibility.h"
|
||||
#import "JavaCellAccessibility.h"
|
||||
#import "JavaColumnAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
|
||||
|
||||
static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable";
|
||||
|
||||
@implementation JavaTableAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxTable";
|
||||
}
|
||||
|
||||
- (int)accessibleRowCount {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
JNFClassInfo clsInfo;
|
||||
clsInfo.name = ACCESSIBLE_JTABLE_NAME;
|
||||
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
|
||||
JNF_MEMBER_CACHE(jm_getAccessibleRowCount, clsInfo, "getAccessibleRowCount", "()I");
|
||||
jint javaRowsCount = JNFCallIntMethod(env, [self axContextWithEnv:env], jm_getAccessibleRowCount);
|
||||
return (int)javaRowsCount;
|
||||
}
|
||||
|
||||
- (int)accessibleColCount {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
JNFClassInfo clsInfo;
|
||||
clsInfo.name = ACCESSIBLE_JTABLE_NAME;
|
||||
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
|
||||
JNF_MEMBER_CACHE(jm_getAccessibleColumnCount, clsInfo, "getAccessibleColumnCount", "()I");
|
||||
jint javaColsCount = JNFCallIntMethod(env, [self axContextWithEnv:env], jm_getAccessibleColumnCount);
|
||||
return (int)javaColsCount;
|
||||
}
|
||||
|
||||
- (NSArray<NSNumber *> *)selectedAccessibleRows {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
JNFClassInfo clsInfo;
|
||||
clsInfo.name = ACCESSIBLE_JTABLE_NAME;
|
||||
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
|
||||
JNF_MEMBER_CACHE(jm_getSelectedAccessibleRows, clsInfo, "getSelectedAccessibleRows", "()[I");
|
||||
jintArray selectidRowNumbers = JNFCallObjectMethod(env, [self axContextWithEnv:env], jm_getSelectedAccessibleRows);
|
||||
if (selectidRowNumbers == NULL) {
|
||||
return nil;
|
||||
}
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, selectidRowNumbers);
|
||||
jint *indexsis = (*env)->GetIntArrayElements(env, selectidRowNumbers, 0);
|
||||
NSMutableArray<NSNumber *> *nsArraySelectidRowNumbers = [NSMutableArray<NSNumber *> arrayWithCapacity:arrayLen];
|
||||
for (int i = 0; i < arrayLen; i++) {
|
||||
[nsArraySelectidRowNumbers addObject:[NSNumber numberWithInt:indexsis[i]]];
|
||||
}
|
||||
return [NSArray<NSNumber *> arrayWithArray:nsArraySelectidRowNumbers];
|
||||
}
|
||||
|
||||
- (NSArray<NSNumber *> *)selectedAccessibleColumns {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
JNFClassInfo clsInfo;
|
||||
clsInfo.name = ACCESSIBLE_JTABLE_NAME;
|
||||
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
|
||||
JNF_MEMBER_CACHE(jm_getSelectedAccessibleColumns, clsInfo, "getSelectedAccessibleColumns", "()[I");
|
||||
jintArray selectidColumnNumbers = JNFCallObjectMethod(env, [self axContextWithEnv:env], jm_getSelectedAccessibleColumns);
|
||||
if (selectidColumnNumbers == NULL) {
|
||||
return nil;
|
||||
}
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, selectidColumnNumbers);
|
||||
jint *indexsis = (*env)->GetIntArrayElements(env, selectidColumnNumbers, 0);
|
||||
NSMutableArray<NSNumber *> *nsArraySelectidColumnNumbers = [NSMutableArray<NSNumber *> arrayWithCapacity:arrayLen];
|
||||
for (int i = 0; i < arrayLen; i++) {
|
||||
[nsArraySelectidColumnNumbers addObject:[NSNumber numberWithInt:indexsis[i]]];
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
- (int)accessibleColumnAtIndex:(int)index {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
JNFClassInfo clsInfo;
|
||||
clsInfo.name = ACCESSIBLE_JTABLE_NAME;
|
||||
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
|
||||
JNF_MEMBER_CACHE(jm_getAccessibleColumnAtIndex, clsInfo, "getAccessibleColumnAtIndex", "(I)I");
|
||||
jint columnAtIndex = JNFCallIntMethod(env, [self axContextWithEnv:env], jm_getAccessibleColumnAtIndex, (jint)index);
|
||||
return (int)columnAtIndex;
|
||||
}
|
||||
|
||||
- (BOOL) isAccessibleChildSelectedFromIndex:(int)index {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
JNFClassInfo clsInfo;
|
||||
clsInfo.name = ACCESSIBLE_JTABLE_NAME;
|
||||
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
|
||||
JNF_MEMBER_CACHE(jm_isAccessibleChildSelected, clsInfo, "isAccessibleChildSelected", "(I)Z");
|
||||
jboolean isAccessibleChildSelected = JNFCallIntMethod(env, [self axContextWithEnv:env], jm_isAccessibleChildSelected, (jint)index);
|
||||
return isAccessibleChildSelected;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxTable
|
||||
|
||||
- (NSArray *)accessibilityChildren {
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
NSArray *columns = [self accessibilityColumns];
|
||||
NSMutableArray *results = [NSMutableArray arrayWithCapacity:[children count] + [columns count]];
|
||||
[results addObjectsFromArray:children];
|
||||
[results addObjectsFromArray:columns];
|
||||
return [NSArray arrayWithArray:results];
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityRows {
|
||||
return [super accessibilityChildren];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedRows {
|
||||
return [super accessibilitySelectedChildren];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel {
|
||||
return [super accessibilityLabel] == NULL ? @"table" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame {
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent {
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilityColumns {
|
||||
int colCount = [(JavaTableAccessibility *)[self javaBase] accessibleColCount];
|
||||
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:colCount];
|
||||
for (int i = 0; i < colCount; i++) {
|
||||
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:[self javaBase]
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i
|
||||
withView:[[self javaBase] view]
|
||||
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
|
||||
}
|
||||
return [NSArray arrayWithArray:columns];
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilitySelectedColumns {
|
||||
NSArray<NSNumber *> *indexes = [(JavaTableAccessibility *)[self javaBase] selectedAccessibleColumns];
|
||||
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:[indexes count]];
|
||||
for (NSNumber *i in indexes) {
|
||||
[columns addObject:[[JavaColumnAccessibility alloc] initWithParent:[self javaBase]
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i.unsignedIntValue
|
||||
withView:[[self javaBase] view]
|
||||
withJavaRole:JavaAccessibilityIgnore].platformAxElement];
|
||||
}
|
||||
return [NSArray arrayWithArray:columns];
|
||||
}
|
||||
|
||||
/*
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityVisibleRows;
|
||||
- (nullable NSArray *)accessibilityColumns;
|
||||
- (nullable NSArray *)accessibilitySelectedColumns;
|
||||
- (nullable NSArray *)accessibilityVisibleColumns;
|
||||
|
||||
- (nullable NSArray *)accessibilitySelectedCells;
|
||||
- (nullable NSArray *)accessibilityVisibleCells;
|
||||
- (nullable NSArray *)accessibilityRowHeaderUIElements;
|
||||
- (nullable NSArray *)accessibilityColumnHeaderUIElements;
|
||||
*/
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
// 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
|
||||
|
||||
|
||||
#endif /* JavaTableRowAccessibility_h */
|
||||
#import "JavaElementAccessibility.h"
|
||||
|
||||
@interface JavaTableRowAccessibility : JavaElementAccessibility
|
||||
@end
|
||||
|
||||
@interface PlatformAxTableRow : PlatformAxElement <NSAccessibilityRow>
|
||||
|
||||
@property(readonly) NSUInteger rowNumberInTable;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,106 @@
|
||||
// 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 "JavaTableRowAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "JavaTableAccessibility.h"
|
||||
#import "JavaCellAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
|
||||
|
||||
@implementation JavaTableRowAccessibility
|
||||
|
||||
- (NSString *)getPlatformAxElementClassName {
|
||||
return @"PlatformAxTableRow";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformAxTableRow
|
||||
|
||||
- (NSArray *)accessibilityChildren {
|
||||
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 (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];
|
||||
NSInteger i = childIndex * 2;
|
||||
NSInteger n = ([self rowNumberInTable] + 1) * [(JavaTableAccessibility *)[[self accessibilityParent] javaBase] accessibleColCount] * 2;
|
||||
JavaTableRowAccessibility *selfRow = [self javaBase];
|
||||
for(i; i < n; i+=2)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
NSString *childJavaRole = nil;
|
||||
if (jchildJavaRole != NULL) {
|
||||
jobject jkey = JNFGetObjectField(env, jchildJavaRole, sjf_key);
|
||||
childJavaRole = JNFJavaToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
}
|
||||
|
||||
JavaCellAccessibility *child = [[JavaCellAccessibility alloc] initWithParent:selfRow
|
||||
withEnv:env
|
||||
withAccessible:jchild
|
||||
withIndex:childIndex
|
||||
withView:[selfRow view]
|
||||
withJavaRole:childJavaRole];
|
||||
[childrenCells addObject:[child autorelease].platformAxElement];
|
||||
|
||||
(*env)->DeleteLocalRef(env, jchild);
|
||||
(*env)->DeleteLocalRef(env, jchildJavaRole);
|
||||
|
||||
childIndex++;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
|
||||
return childrenCells;
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex {
|
||||
return [[self javaBase] index];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel {
|
||||
NSString *accessibilityName = @"";
|
||||
for (id cell in [self accessibilityChildren]) {
|
||||
if ([accessibilityName isEqualToString:@""]) {
|
||||
accessibilityName = [cell accessibilityLabel];
|
||||
} else {
|
||||
accessibilityName = [accessibilityName stringByAppendingFormat:@", %@", [cell accessibilityLabel]];
|
||||
}
|
||||
}
|
||||
return accessibilityName;
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (NSUInteger)rowNumberInTable {
|
||||
return [[self javaBase] index];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame {
|
||||
int height = [[[self accessibilityChildren] objectAtIndex:0] accessibilityFrame].size.height;
|
||||
int width = 0;
|
||||
NSPoint point = [[[self accessibilityChildren] objectAtIndex:0] accessibilityFrame].origin;
|
||||
for (id cell in [self accessibilityChildren]) {
|
||||
width += [cell accessibilityFrame].size.width;
|
||||
}
|
||||
return NSMakeRect(point.x, point.y, width, height);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -472,32 +472,47 @@ untilDate:(NSDate *)expiration inMode:(NSString *)mode dequeue:(BOOL)deqFlag {
|
||||
}
|
||||
|
||||
//Provide info from unhandled ObjectiveC exceptions
|
||||
- (void)_crashOnException:(NSException *)exception {
|
||||
NSMutableString *info = [[[NSMutableString alloc] init] autorelease];
|
||||
[info appendString:
|
||||
[NSString stringWithFormat:
|
||||
@"Exception in NSApplicationAWT:\n %@\n",
|
||||
exception]];
|
||||
+ (void)logException:(NSException *)exception forProcess:(NSProcessInfo*)processInfo {
|
||||
@autoreleasepool {
|
||||
NSMutableString *info = [[[NSMutableString alloc] init] autorelease];
|
||||
[info appendString:
|
||||
[NSString stringWithFormat:
|
||||
@"Exception in NSApplicationAWT:\n %@\n",
|
||||
exception]];
|
||||
|
||||
NSArray<NSString *> *stack = [exception callStackSymbols];
|
||||
NSArray<NSString *> *stack = [exception callStackSymbols];
|
||||
|
||||
for (int i = 0; i < stack.count; i++) {
|
||||
[info appendString:stack[i]];
|
||||
[info appendString:@"\n"];
|
||||
for (int i = 0; i < stack.count; i++) {
|
||||
[info appendString:stack[i]];
|
||||
[info appendString:@"\n"];
|
||||
}
|
||||
|
||||
NSLog(@"%@", info);
|
||||
|
||||
int processID = [processInfo processIdentifier];
|
||||
NSDictionary *env = [[NSProcessInfo processInfo] environment];
|
||||
NSString *homePath = env[@"HOME"];
|
||||
if (homePath != nil) {
|
||||
NSString *fileName =
|
||||
[NSString stringWithFormat:@"%@/jbr_err_pid%d.log",
|
||||
homePath, processID];
|
||||
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:fileName]) {
|
||||
[info writeToFile:fileName
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:NULL];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSLog(@"%@", info);
|
||||
|
||||
- (void)_crashOnException:(NSException *)exception {
|
||||
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
|
||||
int processID = [processInfo processIdentifier];
|
||||
NSString* fileName = [NSString stringWithFormat:@"jbr_err_pid%d.log", processID];
|
||||
|
||||
[info writeToFile:fileName
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:NULL];
|
||||
[NSApplicationAWT logException:exception
|
||||
forProcess:processInfo];
|
||||
// Use SIGILL to generate hs_err_ file as well
|
||||
kill(processID, SIGILL);
|
||||
kill([processInfo processIdentifier], SIGILL);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
88
test/jdk/jb/java/awt/Focus/RobotSmokeTest.java
Normal file
88
test/jdk/jb/java/awt/Focus/RobotSmokeTest.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test validating basic java.awt.Robot functionality (mouse clicks and key presses)
|
||||
* @key headful
|
||||
*/
|
||||
|
||||
public class RobotSmokeTest {
|
||||
private static final CompletableFuture<Boolean> mouseClicked = new CompletableFuture<>();
|
||||
private static final CompletableFuture<Boolean> keyTyped = new CompletableFuture<>();
|
||||
private static Robot robot;
|
||||
private static JFrame frame;
|
||||
private static JTextField field;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(RobotSmokeTest::initUI);
|
||||
robot.delay(5000);
|
||||
clickOn(field);
|
||||
mouseClicked.get(10, TimeUnit.SECONDS);
|
||||
pressAndRelease(KeyEvent.VK_A);
|
||||
keyTyped.get(10, TimeUnit.SECONDS);
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(RobotSmokeTest::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame = new JFrame("RobotSmokeTest");
|
||||
field = new JTextField(20);
|
||||
field.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
mouseClicked.complete(Boolean.TRUE);
|
||||
}
|
||||
});
|
||||
field.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
keyTyped.complete(Boolean.TRUE);
|
||||
}
|
||||
});
|
||||
frame.add(field);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame != null) frame.dispose();
|
||||
}
|
||||
|
||||
private static void pressAndRelease(int keyCode) {
|
||||
robot.keyPress(keyCode);
|
||||
robot.keyRelease(keyCode);
|
||||
}
|
||||
|
||||
private static void clickAt(int x, int y) {
|
||||
robot.mouseMove(x, y);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
}
|
||||
|
||||
private static void clickOn(Component component) {
|
||||
Point location = component.getLocationOnScreen();
|
||||
clickAt(location.x + component.getWidth() / 2, location.y + component.getHeight() / 2);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @requires (os.arch != "x86" & os.arch != "i386" & os.arch != "aarch64")
|
||||
* @summary Regression test for JBR-2430. The test checks that JS Query is handled in 2nd opened browser.
|
||||
* @run main/othervm HandleJSQueryTest
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.function.Consumer;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @requires (os.family == "windows")
|
||||
* @requires (os.family == "windows") & (os.arch != "x86" & os.arch != "i386" & os.arch != "aarch64")
|
||||
* @summary JBR-2866 - Tests that HwFacade window used in IDEA does not bring to front when shown.
|
||||
* @author Anton Tarasov
|
||||
* @run main/othervm HwFacadeWindowNoFrontTest
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @requires (os.arch != "x86" & os.arch != "i386" & os.arch != "aarch64")
|
||||
* @summary Tests that JCEF starts and loads empty page with no crash
|
||||
* @author Anton Tarasov
|
||||
* @run main JCEFStartupTest
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @requires (os.arch != "x86" & os.arch != "i386" & os.arch != "aarch64")
|
||||
* @summary Regression test for JBR-2259. The test checks that website is loaded with and without showing Browser UI.
|
||||
* @run main LoadPageWithoutUI
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @requires (os.arch != "x86" & os.arch != "i386" & os.arch != "aarch64")
|
||||
* @summary Regression test for JBR-2412. The test checks that mouse actions are handled on jcef browser after hide and show it.
|
||||
* @run main/othervm MouseEventAfterHideAndShowBrowserTest
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @requires (os.arch != "x86" & os.arch != "i386" & os.arch != "aarch64")
|
||||
* @summary Regression test for JBR-2639. The test checks that mouse actions are handled on jcef browser.
|
||||
* @run main/othervm MouseEventTest
|
||||
*/
|
||||
|
||||
@@ -1265,11 +1265,8 @@ javax/swing/LookAndFeel/8145547/DemandGTK.java
|
||||
javax/swing/LookAndFeel/8146276/NimbusGlueTest.java JBR-1977 linux-aarch64
|
||||
sanity/client/SwingSet/src/GridBagLayoutDemoTest.java JBR-1977 linux-aarch64
|
||||
|
||||
jb/java/jcef/JCEFStartupTest.java JBR-1996 linux-i386,windows-x86
|
||||
jb/java/jcef/MouseEventTest.java JBR-2750,JBR-1996 linux-all, windows-x86
|
||||
jb/java/jcef/MouseEventAfterHideAndShowBrowserTest.java JBR-2750,JBR-1996 linux-all, windows-x86
|
||||
jb/java/jcef/LoadPageWithoutUI.java JBR-1996 linux-i386,windows-x86
|
||||
jb/java/jcef/HandleJSQueryTest.java JBR-1996 linux-i386,windows-x86
|
||||
jb/java/jcef/MouseEventTest.java JBR-2750 linux-all
|
||||
jb/java/jcef/MouseEventAfterHideAndShowBrowserTest.java JBR-2750 linux-all
|
||||
jb/java/awt/event/TouchScreenEvent/TouchScreenEventsTest.java JBR-2585 linux-all,windows-all nobug windows-6.1 not supported on Windows 7
|
||||
jb/java/awt/event/TouchScreenEvent/TouchScreenEventsTestLinux.sh JBR-2585 linux-all
|
||||
jb/java/awt/Focus/ChainOfPopupsFocusTest.java JBR-2657 windows-all,linux-all
|
||||
|
||||
Reference in New Issue
Block a user