Compare commits

..

12 Commits
1196 ... 1202

Author SHA1 Message Date
Alexey Ushakov
2c8cdb221b JBR-2382 Provide detailed stack trace in crash dumps for unhandled ObjC exceptions
Used user home dir for jbr_err files. Removed logging with reportException method
2020-11-25 20:12:54 +03:00
Mikhail Grishchenko
d34d6528fe JBR-2890 Disable jcef tests on 32-bit and aarch64 platforms 2020-11-25 21:06:09 +07:00
Dmitry Batrak
1d525a2d2f added RobotSmokeTest
this test failing in jtreg launch most probably indicates either some problem with the environment (e.g. some windows left open from previously launched processes) or with java.awt.Robot implementation
2020-11-25 16:33:47 +03:00
Artem Semenov
3038fc95c6 JR-CR-698: JBR-2877 Fix accessibility Label for lists 2020-11-24 11:04:53 +03:00
Artem Semenov
10a30e2135 JR-CR-673: JBR-2649 A11y Make accessibility for JTable 2020-11-24 11:04:52 +03:00
Artem Semenov
b46c4429b4 [a11y] Renderer lists are not spoken: JBR-2457 2020-11-24 11:04:52 +03:00
Anton Tarasov
e51648f368 [a11y] Rename JavaAxObjectProvider and PlatformAxObject
Renamed:
  JavaAxObjectProvider -> JavaBaseProvider
  PlatformAxObject -> PlatformAxElement
  PlatformAxObjectProvider -> PlatformAxElementProvider

Reasoning:
  JavaBaseProvider provides JavaBaseAccessibility and subclasses
  PlatformAxElement inherits from NSAccessibilityElement
2020-11-24 11:04:52 +03:00
Anton Tarasov
235dbdc3f0 [a11y] Add getAccessibilityWindow to PlatformAxObject 2020-11-24 11:04:52 +03:00
Anton Tarasov
c8f68f23d9 [a11y] Add JavaElementAccessibility for all NSAccessibilityElement subclasses
- JavaElementAccessibility (and respective PlatformAxObject) is the base class for elements conforming to the new a11y protocol
2020-11-24 11:04:52 +03:00
Anton Tarasov
5cc0870756 [a11y] Split NSElementAccessibilty and NSObject hierarchies
- Mixing the two hierarchies does not work, so split it
- Implement binding b/w associated objects of the two hierarchies via new protocols: JavaAxObjectProvider, PlatformAxObjectProvider
2020-11-24 11:04:52 +03:00
Anton Tarasov
a50a5f1bea [a11y] Separate base part from JavaComponentAccessibility
- Create JavaBaseAccessibility and JavaListAccessibility for the new a11y
- Adopt NSAccessibilityList protocol (based on investigations by Artem Semenov)
- Use JavaComponentAccessibility for the legacy a11y
2020-11-24 11:04:52 +03:00
Alexey Ushakov
95a47810d5 JBR-2382 Provide detailed stack trace in crash dumps for unhandled ObjC exceptions
Used process workdir for jbr_err files. Added one more logging to reportException method
2020-11-23 21:04:02 +03:00
27 changed files with 1711 additions and 629 deletions

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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];
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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);
}
}

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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

View File

@@ -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
*/

View File

@@ -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
*/

View File

@@ -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
*/

View File

@@ -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