Skip to content

Commit

Permalink
8264299: Create implementation of native accessibility peer for Scrol…
Browse files Browse the repository at this point in the history
…lPane and ScrollBar Java Accessibility roles

Reviewed-by: phh
Backport-of: 6c107fd
  • Loading branch information
Autumn808 authored and Paul Hohensee committed Mar 3, 2023
1 parent 915ac57 commit 8a726af
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 122 deletions.
Expand Up @@ -46,13 +46,6 @@
#import "JNIUtilities.h"
#import "AWTView.h"


// these constants are duplicated in CAccessibility.java
#define JAVA_AX_ALL_CHILDREN (-1)
#define JAVA_AX_SELECTED_CHILDREN (-2)
#define JAVA_AX_VISIBLE_CHILDREN (-3)
// If the value is >=0, it's an index

// GET* macros defined in JavaAccessibilityUtilities.h, so they can be shared.
static jclass sjc_CAccessibility = NULL;

Expand Down Expand Up @@ -126,19 +119,6 @@ - (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

@interface TableAccessibility : JavaComponentAccessibility {

}
Expand Down Expand Up @@ -395,8 +375,6 @@ + (JavaComponentAccessibility *) createWithParent:(JavaComponentAccessibility *)
newChild = [TabGroupAccessibility alloc];
} else if ([javaRole isEqualToString:@"table"]) {
newChild = [TableAccessibility alloc];
} else if ([javaRole isEqualToString:@"scrollpane"]) {
newChild = [ScrollAreaAccessibility alloc];
} else {
NSString *nsRole = [sRoles objectForKey:javaRole];
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole] ||
Expand Down Expand Up @@ -1891,105 +1869,6 @@ - (jobject)tabGroup
@end


@implementation ScrollAreaAccessibility

- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
{
NSMutableArray *names = (NSMutableArray *)[super initializeAttributeNamesWithEnv:env];

[names addObject:NSAccessibilityHorizontalScrollBarAttribute];
[names addObject:NSAccessibilityVerticalScrollBarAttribute];
[names addObject:NSAccessibilityContentsAttribute];

return names;
}

- (id)accessibilityHorizontalScrollBarAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];

NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;

// The scroll bars are in the children.
JavaComponentAccessibility *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)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
(*env)->DeleteLocalRef(env, elementAxContext);
}
}

return nil;
}

- (BOOL)accessibilityIsHorizontalScrollBarAttributeSettable
{
return NO;
}

- (id)accessibilityVerticalScrollBarAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];

NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;

// The scroll bars are in the children.
NSEnumerator *enumerator = [children objectEnumerator];
JavaComponentAccessibility *aElement;
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [aElement axContextWithEnv:env];
if (isVertical(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
(*env)->DeleteLocalRef(env, elementAxContext);
}
}

return nil;
}

- (BOOL)accessibilityIsVerticalScrollBarAttributeSettable
{
return NO;
}

- (NSArray *)accessibilityContentsAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];

if ([children count] <= 0) return nil;
NSArray *contents = [NSMutableArray arrayWithCapacity:[children count]];

// The scroll bars are in the children. children less the scroll bars is the contents
NSEnumerator *enumerator = [children objectEnumerator];
JavaComponentAccessibility *aElement;
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
if (![[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
// no scroll bars in contents
[(NSMutableArray *)contents addObject:aElement];
}
}

return contents;
}

- (BOOL)accessibilityIsContentsAttributeSettable
{
return NO;
}

@end

// these constants are duplicated in CAccessibility.java
#define JAVA_AX_ROWS (1)
#define JAVA_AX_COLS (2)
Expand Down
Expand Up @@ -29,6 +29,12 @@
#import "JavaComponentAccessibility.h"
#import "JavaAccessibilityUtilities.h"

// these constants are duplicated in CAccessibility.java
#define JAVA_AX_ALL_CHILDREN (-1)
#define JAVA_AX_SELECTED_CHILDREN (-2)
#define JAVA_AX_VISIBLE_CHILDREN (-3)
// If the value is >=0, it's an index

@interface CommonComponentAccessibility : JavaComponentAccessibility <NSAccessibilityElement> {

}
Expand Down
Expand Up @@ -48,7 +48,7 @@ + (void) initializeRolesMap {
/*
* Here we should keep all the mapping between the accessibility roles and implementing classes
*/
rolesMap = [[NSMutableDictionary alloc] initWithCapacity:26];
rolesMap = [[NSMutableDictionary alloc] initWithCapacity:29];

[rolesMap setObject:@"ButtonAccessibility" forKey:@"pushbutton"];
[rolesMap setObject:@"ImageAccessibility" forKey:@"icon"];
Expand All @@ -58,6 +58,9 @@ + (void) initializeRolesMap {
[rolesMap setObject:@"StaticTextAccessibility" forKey:@"label"];
[rolesMap setObject:@"RadiobuttonAccessibility" forKey:@"radiobutton"];
[rolesMap setObject:@"CheckboxAccessibility" forKey:@"checkbox"];
// [rolesMap setObject:@"SliderAccessibility" forKey:@"slider"];
[rolesMap setObject:@"ScrollAreaAccessibility" forKey:@"scrollpane"];
[rolesMap setObject:@"ScrollBarAccessibility" forKey:@"scrollbar"];

/*
* All the components below should be ignored by the accessibility subsystem,
Expand Down
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

#import "JavaComponentAccessibility.h"
#import "CommonComponentAccessibility.h"

#import <AppKit/AppKit.h>

@interface ScrollAreaAccessibility : CommonComponentAccessibility {

};
- (NSString * _Nonnull)accessibilityRole;
- (NSArray * _Nullable)accessibilityContents;
- (id _Nullable)accessibilityHorizontalScrollBar;
- (id _Nullable)accessibilityVerticalScrollBar;

- (NSArray * _Nullable)accessibilityContentsAttribute;
- (id _Nullable)getScrollBarwithOrientation:(enum NSAccessibilityOrientation)orientation;
@end
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

#import "ScrollAreaAccessibility.h"
#import "ThreadUtilities.h"
#import "JNIUtilities.h"

/*
* Implementation of the accessibility peer for the ScrollArea role
*/
@implementation ScrollAreaAccessibility

- (NSArray * _Nullable)accessibilityContentsAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];

if ([children count] <= 0) return nil;
NSArray *contents = [NSMutableArray arrayWithCapacity:[children count]];

// The scroll bars are in the children. children less the scroll bars is the contents
NSEnumerator *enumerator = [children objectEnumerator];
JavaComponentAccessibility *aElement;
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
if (![[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
// no scroll bars in contents
[(NSMutableArray *)contents addObject:aElement];
}
}
return contents;
}

- (id _Nullable)getScrollBarwithOrientation:(enum NSAccessibilityOrientation)orientation
{
JNIEnv *env = [ThreadUtilities getJNIEnv];

NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;

// The scroll bars are in the children.
JavaComponentAccessibility *aElement;
NSEnumerator *enumerator = [children objectEnumerator];
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [aElement axContextWithEnv:env];
if (orientation == NSAccessibilityOrientationHorizontal) {
if (isHorizontal(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
} else if (orientation == NSAccessibilityOrientationVertical) {
if (isVertical(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
} else {
(*env)->DeleteLocalRef(env, elementAxContext);
}
}
}
return nil;
}

- (NSString * _Nonnull)accessibilityRole
{
return [self accessibilityRoleAttribute];
}

- (NSArray * _Nullable)accessibilityContents
{
return [self accessibilityContentsAttribute];
}

- (id _Nullable)accessibilityHorizontalScrollBar
{
return [self getScrollBarwithOrientation:NSAccessibilityOrientationHorizontal];
}

- (id _Nullable)accessibilityVerticalScrollBar
{
return [self getScrollBarwithOrientation:NSAccessibilityOrientationVertical];
}
@end
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

#import "JavaComponentAccessibility.h"
#import "CommonComponentAccessibility.h"

#import <AppKit/AppKit.h>

@interface ScrollBarAccessibility : CommonComponentAccessibility {

};
- (NSString * _Nonnull)accessibilityRole;
- (NSAccessibilityOrientation) accessibilityOrientation;
@end

1 comment on commit 8a726af

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.