mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-07 09:59:37 +01:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b11a421ce |
@@ -25,56 +25,13 @@
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#import "JavaElementAccessibility.h"
|
||||
|
||||
#import <AppKit/AppKit.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;
|
||||
|
||||
NSMutableDictionary *fActions;
|
||||
NSObject *fActionsLOCK;
|
||||
@interface JavaComponentAccessibility : JavaElementAccessibility {
|
||||
}
|
||||
|
||||
- (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;
|
||||
@@ -138,8 +95,44 @@
|
||||
- (NSString *)accessibilityActionDescription:(NSString *)action;
|
||||
- (void)accessibilityPerformAction:(NSString *)action;
|
||||
|
||||
- (BOOL)accessibilityIsIgnored;
|
||||
- (id)accessibilityHitTest:(NSPoint)point withEnv:(JNIEnv *)env;
|
||||
- (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
|
||||
|
||||
@@ -46,27 +46,11 @@
|
||||
#import "ThreadUtilities.h"
|
||||
#import "AWTView.h"
|
||||
|
||||
|
||||
// these constants are duplicated in CAccessibility.java
|
||||
#define JAVA_AX_ALL_CHILDREN (-1)
|
||||
#define JAVA_AX_SELECTED_CHILDREN (-2)
|
||||
#define JAVA_AX_VISIBLE_CHILDREN (-3)
|
||||
// If the value is >=0, it's an index
|
||||
|
||||
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;
|
||||
|
||||
// sAttributeNamesForRoleCache holds the names of the attributes to which each java
|
||||
// AccessibleRole responds (see AccessibleRole.java).
|
||||
@@ -74,331 +58,14 @@ static jobject sAccessibilityClass = NULL;
|
||||
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
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@(title:'%@', desc:'%@', value:'%@')", [self accessibilityRoleAttribute],
|
||||
[self accessibilityTitleAttribute], [self accessibilityRoleDescriptionAttribute], [self accessibilityValueAttribute]];
|
||||
}
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
{
|
||||
self = [super 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;
|
||||
|
||||
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;
|
||||
|
||||
[fActionsLOCK release];
|
||||
fActionsLOCK = 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 +200,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
|
||||
{
|
||||
@@ -731,7 +303,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
- (NSArray *)accessibilityChildrenAttribute
|
||||
{
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self
|
||||
NSArray *children = [JavaElementAccessibility childrenOfParent:self
|
||||
withEnv:env
|
||||
withChildrenCode:JAVA_AX_ALL_CHILDREN
|
||||
allowIgnored:NO];
|
||||
@@ -762,8 +334,8 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
jint returnValue =
|
||||
JNFCallStaticIntMethod( [ThreadUtilities getJNIEnv],
|
||||
sjm_getAccessibleIndexInParent,
|
||||
((JavaComponentAccessibility *)child)->fAccessible,
|
||||
((JavaComponentAccessibility *)child)->fComponent );
|
||||
((JavaElementAccessibility *)child)->fAccessible,
|
||||
((JavaElementAccessibility *)child)->fComponent );
|
||||
return (returnValue == -1) ? NSNotFound : returnValue;
|
||||
}
|
||||
|
||||
@@ -771,7 +343,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount {
|
||||
if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
// Children codes for ALL, SELECTED, VISIBLE are <0. If the code is >=0, we treat it as an index to a single child
|
||||
NSArray *child = [JavaComponentAccessibility childrenOfParent:self withEnv:[ThreadUtilities getJNIEnv] withChildrenCode:(NSInteger)index allowIgnored:NO];
|
||||
NSArray *child = [JavaElementAccessibility childrenOfParent:self withEnv:[ThreadUtilities getJNIEnv] withChildrenCode:(NSInteger)index allowIgnored:NO];
|
||||
if ([child count] > 0) {
|
||||
return child;
|
||||
}
|
||||
@@ -1030,7 +602,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
- (NSArray *)accessibilitySelectedChildrenAttribute
|
||||
{
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *selectedChildren = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_SELECTED_CHILDREN allowIgnored:NO];
|
||||
NSArray *selectedChildren = [JavaElementAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_SELECTED_CHILDREN allowIgnored:NO];
|
||||
if ([selectedChildren count] > 0) {
|
||||
return selectedChildren;
|
||||
}
|
||||
@@ -1177,7 +749,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
if ( [[self javaRole] isEqualToString:@"popupmenu"] &&
|
||||
![[parent javaRole] isEqualToString:@"combobox"] ) {
|
||||
NSArray *children =
|
||||
[JavaComponentAccessibility childrenOfParent:self
|
||||
[JavaElementAccessibility childrenOfParent:self
|
||||
withEnv:env
|
||||
withChildrenCode:JAVA_AX_ALL_CHILDREN
|
||||
allowIgnored:YES];
|
||||
@@ -1186,7 +758,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
// need to ask menu what is selected
|
||||
NSArray *selectedChildrenOfMenu =
|
||||
[self accessibilitySelectedChildrenAttribute];
|
||||
JavaComponentAccessibility *selectedMenuItem =
|
||||
JavaElementAccessibility *selectedMenuItem =
|
||||
[selectedChildrenOfMenu objectAtIndex:0];
|
||||
if (selectedMenuItem != nil) {
|
||||
jobject itemValue =
|
||||
@@ -1253,7 +825,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
- (NSArray *)accessibilityVisibleChildrenAttribute
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *visibleChildren = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_VISIBLE_CHILDREN allowIgnored:NO];
|
||||
NSArray *visibleChildren = [JavaElementAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_VISIBLE_CHILDREN allowIgnored:NO];
|
||||
if ([visibleChildren count] <= 0) return nil;
|
||||
return visibleChildren;
|
||||
}
|
||||
@@ -1298,194 +870,8 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
[(id <JavaAccessibilityAction>)[[self getActions:env] objectForKey:action] perform];
|
||||
}
|
||||
|
||||
|
||||
// -- misc accessibility --
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
#ifdef JAVA_AX_NO_IGNORES
|
||||
return NO;
|
||||
#else
|
||||
return [[self accessibilityRoleAttribute] isEqualToString:JavaAccessibilityIgnore];
|
||||
#endif /* JAVA_AX_NO_IGNORES */
|
||||
}
|
||||
|
||||
- (id)accessibilityHitTest:(NSPoint)point withEnv:(JNIEnv *)env
|
||||
{
|
||||
static JNF_CLASS_CACHE(jc_Container, "java/awt/Container");
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_accessibilityHitTest, sjc_CAccessibility, "accessibilityHitTest", "(Ljava/awt/Container;FF)Ljavax/accessibility/Accessible;");
|
||||
|
||||
// Make it into java screen coords
|
||||
point.y = [[[[self view] window] screen] frame].size.height - point.y;
|
||||
|
||||
jobject jparent = fComponent;
|
||||
|
||||
id value = 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];
|
||||
(*env)->DeleteLocalRef(env, jaccessible);
|
||||
}
|
||||
}
|
||||
|
||||
if (value == nil) {
|
||||
value = self;
|
||||
}
|
||||
|
||||
if ([value accessibilityIsIgnored]) {
|
||||
value = NSAccessibilityUnignoredAncestor(value);
|
||||
}
|
||||
|
||||
#ifdef JAVA_AX_DEBUG
|
||||
NSLog(@"%s: %@", __FUNCTION__, value);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
- (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;
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@@ -1573,7 +959,7 @@ JNF_COCOA_EXIT(env);
|
||||
id currentTab = [self currentTabWithEnv:env withAxContext:axContext];
|
||||
if (currentTab == nil) return nil;
|
||||
|
||||
NSArray *contents = [JavaComponentAccessibility childrenOfParent:currentTab withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
|
||||
NSArray *contents = [JavaElementAccessibility childrenOfParent:currentTab withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
|
||||
if ([contents count] <= 0) return nil;
|
||||
return contents;
|
||||
}
|
||||
@@ -1765,7 +1151,7 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
NSArray *children = [JavaElementAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
if ([children count] <= 0) return nil;
|
||||
|
||||
// The scroll bars are in the children.
|
||||
@@ -1794,7 +1180,7 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
NSArray *children = [JavaElementAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
if ([children count] <= 0) return nil;
|
||||
|
||||
// The scroll bars are in the children.
|
||||
@@ -1822,7 +1208,7 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
- (NSArray *)accessibilityContentsAttribute
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
NSArray *children = [JavaElementAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
|
||||
if ([children count] <= 0) return nil;
|
||||
NSArray *contents = [NSMutableArray arrayWithCapacity:[children count]];
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// 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>
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.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
|
||||
|
||||
extern JNFClassInfo sjc_CAccessible;
|
||||
extern JNFMemberInfo *jm_getChildrenAndRoles;
|
||||
extern JNFMemberInfo *jf_ptr;
|
||||
extern JNFMemberInfo *sjm_getCAccessible;
|
||||
extern JNFMemberInfo *sjm_getAccessibleIndexInParent;
|
||||
|
||||
@interface JavaElementAccessibility : NSAccessibilityElement
|
||||
{
|
||||
NSView *fView;
|
||||
NSObject *fParent;
|
||||
|
||||
NSString *fNSRole;
|
||||
NSString *fJavaRole;
|
||||
|
||||
jint fIndex;
|
||||
jobject fAccessible;
|
||||
jobject fComponent;
|
||||
|
||||
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:(JavaElementAccessibility*)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored;
|
||||
+ (JavaElementAccessibility *) createWithParent:(JavaElementAccessibility *)parent accessible:(jobject)jaccessible role:(NSString *)javaRole index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view;
|
||||
+ (JavaElementAccessibility *) createWithAccessible:(jobject)jaccessible role:(NSString *)role index:(jint)index withEnv:(JNIEnv *)env withView:(NSView *)view;
|
||||
+ (JavaElementAccessibility *) 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;
|
||||
|
||||
- (BOOL)accessibilityIsIgnored;
|
||||
- (id)accessibilityHitTest:(NSPoint)point withEnv:(JNIEnv *)env;
|
||||
- (id)accessibilityFocusedUIElement;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,603 @@
|
||||
// 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 "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
|
||||
|
||||
#import <dlfcn.h>
|
||||
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "JavaTextAccessibility.h"
|
||||
#import "JavaListAccessibility.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "AWTView.h"
|
||||
|
||||
JNF_CLASS_CACHE(sjc_CAccessible, "sun/lwawt/macosx/CAccessible");
|
||||
JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
|
||||
JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleIndexInParent, sjc_CAccessibility, "getAccessibleIndexInParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
|
||||
JNF_STATIC_MEMBER_CACHE(sjm_getCAccessible, sjc_CAccessible, "getCAccessible", "(Ljavax/accessibility/Accessible;)Lsun/lwawt/macosx/CAccessible;");
|
||||
JNF_MEMBER_CACHE(jf_ptr, sjc_CAccessible, "ptr", "J");
|
||||
|
||||
@class TabGroupAccessibility;
|
||||
@class ScrollAreaAccessibility;
|
||||
|
||||
@implementation JavaElementAccessibility
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame]; // todo: implement
|
||||
}
|
||||
|
||||
// - (nullable id)accessibilityParent
|
||||
// {
|
||||
// return [self parent]; // conflicts
|
||||
// }
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@(title:'%@', desc:'%@', value:'%@')", [self accessibilityRoleAttribute],
|
||||
[self accessibilityTitleAttribute], [self accessibilityRoleDescriptionAttribute], [self accessibilityValueAttribute]];
|
||||
}
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
{
|
||||
self = [super 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;
|
||||
|
||||
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;
|
||||
|
||||
[fActionsLOCK release];
|
||||
fActionsLOCK = 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;
|
||||
JavaElementAccessibility *accessibility = (JavaElementAccessibility *) 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();
|
||||
}
|
||||
}
|
||||
|
||||
+ (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:(JavaElementAccessibility *)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);
|
||||
}
|
||||
|
||||
JavaElementAccessibility *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;
|
||||
}
|
||||
|
||||
+ (JavaElementAccessibility *)createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view
|
||||
{
|
||||
JavaElementAccessibility *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;
|
||||
}
|
||||
|
||||
+ (JavaElementAccessibility *)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];
|
||||
}
|
||||
|
||||
+ (JavaElementAccessibility *)createWithParent:(JavaElementAccessibility *)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 = [JavaElementAccessibility getCAccessible:jaccessible withEnv:env];
|
||||
if (jCAX == NULL) return nil;
|
||||
JavaElementAccessibility *value = (JavaElementAccessibility *) jlong_to_ptr(JNFGetLongField(env, jCAX, jf_ptr));
|
||||
if (value != nil) {
|
||||
(*env)->DeleteLocalRef(env, jCAX);
|
||||
return [[value retain] autorelease];
|
||||
}
|
||||
|
||||
// otherwise, create a new instance
|
||||
JavaElementAccessibility *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 if ([nsRole isEqualToString:NSAccessibilityListRole]) {
|
||||
newChild = [JavaListAccessibility alloc];
|
||||
// } else if ([nsRole isEqualToString:NSAccessibilityRowRole]) {
|
||||
// newChild = [JavaRowAccessibility alloc];
|
||||
} else {
|
||||
newChild = [JavaElementAccessibility 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];
|
||||
}
|
||||
|
||||
- (NSDictionary *)getActions:(JNIEnv *)env
|
||||
{
|
||||
@synchronized (fActionsLOCK) {
|
||||
if (fActions == nil) {
|
||||
fActions = [[NSMutableDictionary alloc] initWithCapacity:3];
|
||||
[self getActionsWithEnv:env];
|
||||
}
|
||||
}
|
||||
|
||||
return fActions;
|
||||
}
|
||||
|
||||
- (void)getActionsWithEnv:(JNIEnv *)env
|
||||
{
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleAction, sjc_CAccessibility,
|
||||
"getAccessibleAction", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleAction;");
|
||||
|
||||
// On MacOSX, text doesn't have actions, in java it does.
|
||||
// cmcnote: NOT TRUE - Editable text has AXShowMenu. Textfields have AXConfirm. Static text has no actions.
|
||||
jobject axAction = JNFCallStaticObjectMethod(env, jm_getAccessibleAction, fAccessible,
|
||||
fComponent); // AWT_THREADING Safe (AWTRunLoop)
|
||||
if (axAction != NULL) {
|
||||
//+++gdb NOTE: In MacOSX, there is just a single Action, not multiple. In java,
|
||||
// the first one seems to be the most basic, so this will be used.
|
||||
// cmcnote: NOT TRUE - Sometimes there are multiple actions, eg sliders have AXDecrement AND AXIncrement (radr://3893192)
|
||||
JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent];
|
||||
[fActions setObject:action forKey:[self isMenu] ? NSAccessibilityPickAction : NSAccessibilityPressAction];
|
||||
[action release];
|
||||
(*env)->DeleteLocalRef(env, axAction);
|
||||
}
|
||||
}
|
||||
|
||||
- (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 = [JavaElementAccessibility 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, ((JavaElementAccessibility *) [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;
|
||||
}
|
||||
|
||||
// -- misc accessibility --
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
#ifdef JAVA_AX_NO_IGNORES
|
||||
return NO;
|
||||
#else
|
||||
return [[self accessibilityRoleAttribute] isEqualToString:JavaAccessibilityIgnore];
|
||||
#endif /* JAVA_AX_NO_IGNORES */
|
||||
}
|
||||
|
||||
- (id)accessibilityHitTest:(NSPoint)point withEnv:(JNIEnv *)env
|
||||
{
|
||||
static JNF_CLASS_CACHE(jc_Container, "java/awt/Container");
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_accessibilityHitTest, sjc_CAccessibility, "accessibilityHitTest", "(Ljava/awt/Container;FF)Ljavax/accessibility/Accessible;");
|
||||
|
||||
// Make it into java screen coords
|
||||
point.y = [[[[self view] window] screen] frame].size.height - point.y;
|
||||
|
||||
jobject jparent = fComponent;
|
||||
|
||||
id value = 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 = [JavaElementAccessibility createWithAccessible:jaccessible withEnv:env withView:fView];
|
||||
(*env)->DeleteLocalRef(env, jaccessible);
|
||||
}
|
||||
}
|
||||
|
||||
if (value == nil) {
|
||||
value = self;
|
||||
}
|
||||
|
||||
if ([value accessibilityIsIgnored]) {
|
||||
value = NSAccessibilityUnignoredAncestor(value);
|
||||
}
|
||||
|
||||
#ifdef JAVA_AX_DEBUG
|
||||
NSLog(@"%s: %@", __FUNCTION__, value);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
- (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 = [JavaElementAccessibility 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;
|
||||
}
|
||||
|
||||
@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:[JavaElementAccessibility 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:(JavaElementAccessibility *)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:(JavaElementAccessibility *)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:(JavaElementAccessibility *)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:(JavaElementAccessibility *)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:(JavaElementAccessibility *)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:(JavaElementAccessibility *)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:(JavaElementAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// 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<NSAccessibilityList> {
|
||||
}
|
||||
@end
|
||||
|
||||
//@interface JavaRowAccessibility : JavaElementAccessibility<NSAccessibilityRow> {
|
||||
//}
|
||||
//@end
|
||||
@@ -0,0 +1,51 @@
|
||||
// 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 "ThreadUtilities.h"
|
||||
|
||||
@implementation JavaListAccessibility
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityRows
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *children = [JavaElementAccessibility childrenOfParent:self
|
||||
withEnv:env
|
||||
withChildrenCode:JAVA_AX_ALL_CHILDREN
|
||||
allowIgnored:NO];
|
||||
NSArray *value = nil;
|
||||
if ([children count] > 0) {
|
||||
value = children;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityElement
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
return @"List";
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilitySelectedChildren
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *selectedChildren = [JavaElementAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_SELECTED_CHILDREN allowIgnored:NO];
|
||||
if ([selectedChildren count] > 0) {
|
||||
return selectedChildren;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame]; // todo: implement
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//@implementation JavaRowAccessibility
|
||||
//@end
|
||||
Reference in New Issue
Block a user