Compare commits

...

23 Commits

Author SHA1 Message Date
Alexey Ushakov
1f0f43b4da JBR-1430 Problem with JNA when username contains unicode symbol
Added unicode conversion
2021-04-07 19:27:46 +03:00
Artem Semenov
04f1cf9b47 JBR-3241: MAke a11y element for combobox 2021-04-07 17:23:49 +03:00
Jim Laskey
80c6e03ec4 JBR-2607 backport the fix for crash in [libjimage] ImageStrings::find from OpenJDK
backported from OpenJDK - 8166727: javac crashed: [jimage.dll+0x1942] ImageStrings::find+0x28

Reviewed-by: iklam, alanb
2021-04-07 14:33:38 +07:00
Artem Semenov
9001a78701 JBR-3274: macOS: SIGILL at [libsystem_kernel] __kill -[PlatformAxNavigableText accessibilitySelectedTextAttribute] 2021-04-05 14:47:34 +03:00
Artem Semenov
703cab8d0d JBR-3240: MAke a11y element for TabGroup 2021-04-02 15:51:57 +03:00
Nikita Gubarkov
3c9cdc9251 JBR-3269 Disabled subpixel antialiasing for MacOS Big Sur and newer 2021-04-02 01:24:57 +03:00
Denis Konoplev
032805520d JBR-3214: CR: remove double negation 2021-04-01 16:54:47 +03:00
Dmitry Batrak
b37f7cfdb1 JBR-3255 Applying 'incline' transform might change character's advance 2021-03-30 18:37:21 +03:00
Denis Konoplev
3668d631ca JBR-3214: Reuse openjdk logic and add unicode keycodes 2021-03-30 16:12:29 +03:00
Denis Konoplev
7fa3ea24ac JBR-2509: Fix Escape emulation after Cmd . 2021-03-30 16:05:16 +03:00
Artem Semenov
8a521cbf64 JR-CR-776: JBR-3239: MAke a11y component for ScrollView 2021-03-30 13:43:22 +03:00
Denis Konoplev
fe9601aa6d JBR-3214: Initialize stack variables to fix dead key prefix and enable support on aarch64 2021-03-29 20:06:22 +03:00
Artem Semenov
65e8162d67 JR-CR-775: JBR-3188: NSAccessibilityNavigableStaticText 2021-03-26 14:35:34 +03:00
Artem Semenov
b99be427ce JR-CR-774: JBR-3218: IDEA crash with opening drop down menu and click whatever next. 2021-03-24 18:38:32 +03:00
Denis Konoplev
6b3b011d0b Revert "JBR-2509: Fix Escape emulation after Cmd ."
This reverts commit f096bd2b
2021-03-24 14:01:10 +03:00
Denis Konoplev
b53ef867e4 Revert "JBR-2509: Remove Fokin code."
This reverts commit 99a8e455
2021-03-24 14:01:10 +03:00
Denis Konoplev
215fd32738 Revert "JBR-2509: Turn on option on M1"
This reverts commit 542ee611
2021-03-24 14:01:10 +03:00
Artem Semenov
921603e356 JBR-3028: macOS: SIGILL at [libsystem_kernel] __kill -[PlatformAxList accessibilityParent]
JR-CR-773: JBR-3028: macOS: SIGILL at [libsystem_kernel] __kill -[PlatformAxList accessibilityParent]
2021-03-23 21:04:25 +03:00
Denis Konoplev
542ee611fc JBR-2509: Turn on option on M1 2021-03-23 19:38:58 +03:00
Denis Konoplev
99a8e45598 JBR-2509: Remove Fokin code.
Reuse openjdk logic and add unicode keycodes
2021-03-23 16:45:33 +03:00
Denis Konoplev
f096bd2b0d JBR-2509: Fix Escape emulation after Cmd . 2021-03-23 16:45:33 +03:00
Ivan Migalev
26dd87ab7c JBR-3227 Reload type of required native file dialogs each time a file dialog is requested 2021-03-23 16:00:08 +03:00
Alexey Ushakov
a6ea081ba2 JBR-3023 Gray idea frame after project open with ide.mac.transparentTitleBarAppearance.
Initiate move/resize event on first appearance of window having FULL_WINDOW_CONTENT property set
2021-03-23 00:44:30 +03:00
42 changed files with 1129 additions and 1250 deletions

View File

@@ -1354,6 +1354,7 @@ static int _print_module(const char* fname, address base_address,
return 0;
}
static errno_t convert_to_unicode(char const* char_path, LPWSTR* unicode_path);
// Loads .dll/.so and
// in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on

View File

@@ -211,17 +211,6 @@ ImageFileReaderTable::ImageFileReaderTable() : _count(0), _max(_growth) {
assert(_table != NULL && "allocation failed");
}
ImageFileReaderTable::~ImageFileReaderTable() {
for (u4 i = 0; i < _count; i++) {
ImageFileReader* image = _table[i];
if (image != NULL) {
delete image;
}
}
free(_table);
}
// Add a new image entry to the table.
void ImageFileReaderTable::add(ImageFileReader* image) {
if (_count == _max) {

View File

@@ -371,7 +371,12 @@ private:
public:
ImageFileReaderTable();
~ImageFileReaderTable();
// ~ImageFileReaderTable()
// Bug 8166727
//
// WARNING: Should never close jimage files.
// Threads may still be running during shutdown.
//
// Return the number of entries.
inline u4 count() { return _count; }

View File

@@ -100,8 +100,12 @@ public class CEmbeddedFrame extends EmbeddedFrame {
deltaY, NSEvent.SCROLL_PHASE_UNSUPPORTED);
}
public void handleKeyEvent(NSEvent nsEvent) {
responder.handleKeyEvent(nsEvent);
public void handleKeyEvent(int eventType, int modifierFlags, String characters,
String charsIgnoringMods, boolean isRepeat, short keyCode,
boolean needsKeyTyped) {
responder.handleKeyEvent(eventType, modifierFlags, characters,
charsIgnoringMods, /*charsIgnoringModifiersAndShift*/ null,
keyCode, needsKeyTyped, isRepeat);
}
public void handleInputEvent(String text) {

View File

@@ -29,24 +29,20 @@ import sun.awt.SunToolkit;
import sun.awt.event.KeyEventProcessing;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformEventNotifier;
import sun.util.logging.PlatformLogger;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.KeyEvent;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Locale;import java.util.MissingResourceException;import java.util.ResourceBundle;
import java.util.Locale;
/**
* Translates NSEvents/NPCocoaEvents into AWT events.
*/
final class CPlatformResponder {
private static final PlatformLogger keyboardLog = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformResponder");
private final PlatformEventNotifier eventNotifier;
private final boolean isNpapiCallback;
private int lastKeyPressCode = KeyEvent.VK_UNDEFINED;
@@ -61,7 +57,6 @@ final class CPlatformResponder {
private int lastDraggedRelativeX;
private int lastDraggedRelativeY;
CPlatformResponder(final PlatformEventNotifier eventNotifier,
final boolean isNpapiCallback) {
this.eventNotifier = eventNotifier;
@@ -166,41 +161,6 @@ final class CPlatformResponder {
-roundDelta, -delta, null);
}
private void handleFlagChangedEvent(int modifierFlags, short keyCode) {
int[] in = new int[] {modifierFlags, keyCode};
int[] out = new int[3]; // [jkeyCode, jkeyLocation, jkeyType]
NSEvent.nsKeyModifiersToJavaKeyInfo(in, out);
int jkeyCode = out[0];
int jkeyLocation = out[1];
int jeventType = out[2];
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
long when = System.currentTimeMillis();
if (jeventType == KeyEvent.KEY_PRESSED) {
lastKeyPressCode = jkeyCode;
}
eventNotifier.notifyKeyEvent(jeventType, when, jmodifiers,
jkeyCode, KeyEvent.CHAR_UNDEFINED, jkeyLocation);
}
private static char mapNsCharsToCompatibleWithJava (char ch) {
switch (ch) {
case 0x0003: // NSEnterCharacter
case 0x000d: // NSCarriageReturnCharacter
return 0x000a; // NSNewlineCharacter
// case 0x007f: // NSDeleteCharacter
// return 0x0008; // NSBackspaceCharacter
case 0xF728: // NSDeleteFunctionKey
return 0x0008; // NSDeleteCharacter
case 0x0019: // NSBackTabCharacter
return 0x0009; // NSTabCharacter
}
return ch;
}
private static final String [] cyrillicKeyboardLayouts = new String [] {
"com.apple.keylayout.Russian",
"com.apple.keylayout.RussianWin",
@@ -216,181 +176,6 @@ final class CPlatformResponder {
return Arrays.stream(cyrillicKeyboardLayouts).anyMatch(l -> l.equals(LWCToolkit.getKeyboardLayoutId()));
}
/**
* Handles key events.
*/
void handleKeyEvent(NSEvent nsEvent)
{
if (!KeyEventProcessing.useNationalLayouts || isCyrillicKeyboardLayout()) {
handleKeyEvent(
nsEvent.getType(),
nsEvent.getModifierFlags(),
nsEvent.getOldCharacters(),
nsEvent.getOldCharactersIgnoringModifiers(),
nsEvent.getKeyCode(),
true,
false
);
return;
}
boolean isFlagsChangedEvent =
isNpapiCallback ? (nsEvent.getType() == CocoaConstants.NPCocoaEventFlagsChanged) :
(nsEvent.getType() == CocoaConstants.NSFlagsChanged);
int jeventType = KeyEvent.KEY_PRESSED;
int jkeyCode = KeyEvent.VK_UNDEFINED;
int jkeyLocation = KeyEvent.KEY_LOCATION_UNKNOWN;
boolean postsTyped = false;
boolean spaceKeyTyped = false;
if (isFlagsChangedEvent) {
handleFlagChangedEvent(nsEvent.getModifierFlags(), nsEvent.getKeyCode());
return;
}
int jmodifiers = NSEvent.nsToJavaModifiers(nsEvent.getModifierFlags());
boolean metaAltCtrlAreNotPressed = (jmodifiers &
(InputEvent.META_DOWN_MASK
| InputEvent.ALT_DOWN_MASK
| InputEvent.CTRL_DOWN_MASK)
) == 0;
boolean shiftIsPressed = (jmodifiers & InputEvent.SHIFT_DOWN_MASK) != 0;
boolean useShiftedCharacters = metaAltCtrlAreNotPressed && shiftIsPressed;
boolean shiftAltDownAreNotPressed = (jmodifiers &
(InputEvent.META_DOWN_MASK
| InputEvent.ALT_DOWN_MASK
| InputEvent.SHIFT_DOWN_MASK)
) == 0;
boolean ctrlIsPressed = (jmodifiers & InputEvent.CTRL_DOWN_MASK) != 0;
boolean isISOControl = false;
char checkedChar = (nsEvent.getCharacters() == null
|| nsEvent.getCharacters().isEmpty()) ? KeyEvent.CHAR_UNDEFINED : nsEvent.getCharacters().charAt(0);
if (shiftAltDownAreNotPressed && ctrlIsPressed) {
if (Character.isISOControl(checkedChar)) {
isISOControl = true;
}
}
char characterToGetKeyCode = KeyEvent.CHAR_UNDEFINED;
boolean charactersIgnoringModifiersIsValid = (nsEvent.getCharactersIgnoringModifiers() != null && nsEvent.getCharactersIgnoringModifiers().length() > 0);
boolean charactersIsValid = (nsEvent.getCharacters() != null && nsEvent.getCharacters().length() > 0);
// We use this char to find a character that is printed depending on pressing modifiers
characterToGetKeyCode = charactersIgnoringModifiersIsValid
? nsEvent.getCharactersIgnoringModifiers().charAt(0)
: charactersIsValid ? nsEvent.getCharacters().charAt(0) : KeyEvent.CHAR_UNDEFINED;
if (useShiftedCharacters && nsEvent.getCharactersIgnoringModifiers() != null && !nsEvent.getCharactersIgnoringModifiers().isEmpty()) {
characterToGetKeyCode = nsEvent.getCharactersIgnoringModifiers().charAt(0);
} else if (nsEvent.getCharactersIgnoringModifiersAndShift() != null && !nsEvent.getCharactersIgnoringModifiersAndShift().isEmpty()) {
characterToGetKeyCode = nsEvent.getCharactersIgnoringModifiersAndShift().charAt(0);
} else if (nsEvent.getCharacters() != null && !nsEvent.getCharacters().isEmpty() && metaAltCtrlAreNotPressed && shiftIsPressed) {
characterToGetKeyCode = checkedChar;
}
// We use char candidate if modifiers are not used
// otherwise, we use char ignoring modifiers
int[] in = new int[] {
characterToGetKeyCode,
nsEvent.isHasDeadKey() ? 1 : 0,
nsEvent.getModifierFlags(),
nsEvent.getKeyCode(),
/*useNationalLayouts*/ 1
};
int[] out = new int[3]; // [jkeyCode, jkeyLocation, deadChar]
postsTyped = NSEvent.nsToJavaKeyInfo(in, out);
char characterToSendWithTheEvent = characterToGetKeyCode;
if(nsEvent.isHasDeadKey()){
characterToSendWithTheEvent = (char) out[2];
jkeyCode = nsEvent.getDeadKeyCode();
if(characterToSendWithTheEvent == 0){
return;
}
}
// If Pinyin Simplified input method is selected, CAPS_LOCK key is supposed to switch
// input to la tin letters.
// It is necessary to use charIgnoringModifiers instead of charCandidate for event
// generation in such case to avoid uppercase letters in text components.
LWCToolkit lwcToolkit = (LWCToolkit)Toolkit.getDefaultToolkit();
if (lwcToolkit.getLockingKeyState(KeyEvent.VK_CAPS_LOCK) &&
Locale.SIMPLIFIED_CHINESE.equals(lwcToolkit.getDefaultKeyboardLocale())) {
characterToSendWithTheEvent = characterToGetKeyCode;
}
jkeyCode = out[0];
jkeyLocation = out[1];
jeventType = isNpapiCallback ? NSEvent.npToJavaEventType(nsEvent.getType()) :
NSEvent.nsToJavaEventType(nsEvent.getType());
if (isISOControl) {
characterToSendWithTheEvent = checkedChar;
} else {
characterToSendWithTheEvent = mapNsCharsToCompatibleWithJava(characterToSendWithTheEvent);
}
String stringWithChar = NSEvent.nsToJavaChar(characterToSendWithTheEvent, nsEvent.getModifierFlags(), spaceKeyTyped);
characterToSendWithTheEvent = stringWithChar == null ? KeyEvent.CHAR_UNDEFINED : stringWithChar.charAt(0);
long when = System.currentTimeMillis();
if (jeventType == KeyEvent.KEY_PRESSED) {
lastKeyPressCode = jkeyCode;
}
eventNotifier.notifyKeyEvent(jeventType, when, jmodifiers,
jkeyCode, characterToSendWithTheEvent, jkeyLocation);
// Current browser may be sending input events, so don't
// post the KEY_TYPED here.
postsTyped &= true;
// That's the reaction on the PRESSED (not RELEASED) event as it comes to
// appear in MacOSX.
// Modifier keys (shift, etc) don't want to send TYPED events.
// On the other hand we don't want to generate keyTyped events
// for clipboard related shortcuts like Meta + [CVX]
if (jeventType == KeyEvent.KEY_PRESSED && postsTyped &&
(jmodifiers & KeyEvent.META_DOWN_MASK) == 0) {
char characterToSendWithTypedEvent = KeyEvent.CHAR_UNDEFINED;
if (nsEvent.getCharacters()!= null ) {
characterToSendWithTypedEvent = mapNsCharsToCompatibleWithJava(checkedChar);
stringWithChar = NSEvent.nsToJavaChar(characterToSendWithTypedEvent, nsEvent.getModifierFlags(), spaceKeyTyped);
characterToSendWithTypedEvent = stringWithChar == null ? KeyEvent.CHAR_UNDEFINED : stringWithChar.charAt(0);
}
boolean nonInputMethodsModifiersAreNotPressed = (jmodifiers &
(InputEvent.META_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)
) == 0;
if (nonInputMethodsModifiersAreNotPressed) {
eventNotifier.notifyKeyEvent(KeyEvent.KEY_TYPED, when, jmodifiers,
jkeyCode, characterToSendWithTypedEvent,
KeyEvent.KEY_LOCATION_UNKNOWN);
}
}
}
void handleInputEvent(String text) {
if (text != null) {
int index = 0, length = text.length();
@@ -412,10 +197,9 @@ final class CPlatformResponder {
/**
* Handles key events.
* @deprecated
*/
@Deprecated
void handleKeyEvent(int eventType, int modifierFlags, String chars, String charsIgnoringModifiers,
void handleKeyEvent(int eventType, int modifierFlags, String chars,
String charsIgnoringModifiers, String charsIgnoringModifiersAndShift,
short keyCode, boolean needsKeyTyped, boolean needsKeyReleased) {
boolean isFlagsChangedEvent =
isNpapiCallback ? (eventType == CocoaConstants.NPCocoaEventFlagsChanged) :
@@ -425,6 +209,9 @@ final class CPlatformResponder {
int jkeyCode = KeyEvent.VK_UNDEFINED;
int jkeyLocation = KeyEvent.KEY_LOCATION_UNKNOWN;
boolean postsTyped = false;
boolean spaceKeyTyped = false;
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
char testChar = KeyEvent.CHAR_UNDEFINED;
boolean isDeadChar = (chars!= null && chars.length() == 0);
@@ -441,12 +228,26 @@ final class CPlatformResponder {
} else {
if (chars != null && chars.length() > 0) {
testChar = chars.charAt(0);
//Check if String chars contains SPACE character.
if (chars.trim().isEmpty()) {
spaceKeyTyped = true;
}
}
// Workaround for JBR-2981
int metaAltCtrlMods = KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK;
boolean metaAltCtrlAreNotPressed = (jmodifiers & metaAltCtrlMods) == 0;
boolean useShiftedCharacter = ((jmodifiers & KeyEvent.SHIFT_DOWN_MASK) == KeyEvent.SHIFT_DOWN_MASK) && metaAltCtrlAreNotPressed;
char testCharIgnoringModifiers = charsIgnoringModifiers != null && charsIgnoringModifiers.length() > 0 ?
charsIgnoringModifiers.charAt(0) : KeyEvent.CHAR_UNDEFINED;
if (!useShiftedCharacter && charsIgnoringModifiersAndShift != null && charsIgnoringModifiersAndShift.length() > 0) {
testCharIgnoringModifiers = charsIgnoringModifiersAndShift.charAt(0);
}
int[] in = new int[] {testCharIgnoringModifiers, isDeadChar ? 1 : 0, modifierFlags, keyCode, /*useNationalLayouts*/ 0};
int useNationalLayouts = (KeyEventProcessing.useNationalLayouts && !isCyrillicKeyboardLayout()) ? 1 : 0;
int[] in = new int[] {testCharIgnoringModifiers, isDeadChar ? 1 : 0, modifierFlags, keyCode, useNationalLayouts};
int[] out = new int[3]; // [jkeyCode, jkeyLocation, deadChar]
postsTyped = NSEvent.nsToJavaKeyInfo(in, out);
@@ -480,7 +281,7 @@ final class CPlatformResponder {
NSEvent.nsToJavaEventType(eventType);
}
char javaChar = NSEvent.nsToJavaCharOld(testChar, modifierFlags);
char javaChar = NSEvent.nsToJavaChar(testChar, modifierFlags, spaceKeyTyped);
// Some keys may generate a KEY_TYPED, but we can't determine
// what that character is. That's likely a bug, but for now we
// just check for CHAR_UNDEFINED.
@@ -488,8 +289,6 @@ final class CPlatformResponder {
postsTyped = false;
}
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
long when = System.currentTimeMillis();
if (jeventType == KeyEvent.KEY_PRESSED) {

View File

@@ -220,8 +220,10 @@ public class CPlatformView extends CFRetainedResource {
}
}
private void deliverKeyEvent(NSEvent nsEvent) {
responder.handleKeyEvent(nsEvent);
private void deliverKeyEvent(NSEvent event) {
responder.handleKeyEvent(event.getType(), event.getModifierFlags(), event.getCharacters(),
event.getCharactersIgnoringModifiers(), event.getCharactersIgnoringModifiersAndShift(),
event.getKeyCode(), true, false);
}
/**

View File

@@ -298,8 +298,7 @@ final class NSEvent {
* There is a small number of NS characters that need to be converted
* into other characters before we pass them to AWT.
*/
static native String nsToJavaChar(char nsChar, int modifierFlags, boolean spaceKeyTyped);
static native char nsToJavaCharOld(char nsChar, int modifierFlags);
static native char nsToJavaChar(char nsChar, int modifierFlags, boolean spaceKeyTyped);
static boolean isPopupTrigger(int jmodifiers) {
final boolean isRightButtonDown = ((jmodifiers & InputEvent.BUTTON3_DOWN_MASK) != 0);

View File

@@ -222,6 +222,7 @@ struct CharToVKEntry {
static const struct CharToVKEntry charToDeadVKTable[] = {
{0x0060, java_awt_event_KeyEvent_VK_DEAD_GRAVE},
{0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
{0xFFFF, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
{0x0384, java_awt_event_KeyEvent_VK_DEAD_ACUTE}, // Unicode "GREEK TONOS" -- Greek keyboard, semicolon key
{0x005E, java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX},
{0x007E, java_awt_event_KeyEvent_VK_DEAD_TILDE},
@@ -887,42 +888,20 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_NSEvent
* Method: nsToJavaChar
* Signature: (CI)Ljava/lang/String
*/
JNIEXPORT jstring JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaChar
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags, jboolean spaceKeyTyped)
{
jstring charAsString = NULL;
JNF_COCOA_ENTER(env);
NSString * nsStr = [NSString stringWithFormat: @"%C", nsChar];
charAsString = JNFNSToJavaString(env, nsStr);
JNF_COCOA_EXIT(env);
return charAsString;
}
/*
* Class: sun_lwawt_macosx_NSEvent
* Method: nsToJavaChar
* Signature: (CI)C
*/
JNIEXPORT jint JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaCharOld
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags)
Java_sun_lwawt_macosx_NSEvent_nsToJavaChar
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags, jboolean spaceKeyTyped)
{
jchar javaChar = 0;
JNF_COCOA_ENTER(env);
javaChar = NsCharToJavaChar(nsChar, modifierFlags, false);
javaChar = NsCharToJavaChar(nsChar, modifierFlags, spaceKeyTyped);
JNF_COCOA_EXIT(env);

View File

@@ -34,7 +34,7 @@
#import "AWTView.h"
#import "AWTWindow.h"
#import "JavaComponentAccessibility.h"
#import "JavaTextAccessibility.h"
#import "JavaStaticTextAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "GeomUtilities.h"
#import "CGLLayer.h"
@@ -374,6 +374,21 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
if (![self hasMarkedText] && !fInPressAndHold) {
[self deliverJavaKeyEventHelper: event];
}
// Workaround for 8020209: special case for "Cmd =" and "Cmd ."
// because Cocoa calls performKeyEquivalent twice for these keystrokes
NSUInteger modFlags = [event modifierFlags] &
(NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask);
if (modFlags == NSCommandKeyMask) {
NSString *eventChars = [event charactersIgnoringModifiers];
if ([eventChars length] == 1) {
unichar ch = [eventChars characterAtIndex:0];
if (ch == '=' || ch == '.' ||
ch == 0x044E) { // small cyrillic u
[[NSApp mainMenu] performKeyEquivalent: event];
return YES;
}
}
}
NSUInteger deviceIndependentModifierFlagsMask =
[event modifierFlags] & NSDeviceIndependentModifierFlagsMask;
@@ -507,10 +522,10 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
const UCKeyboardLayout *keyboardLayout = (UCKeyboardLayout*)CFDataGetBytePtr(keyLayoutPtr);
UInt32 isDeadKeyPressed;
UInt32 isDeadKeyPressed = 0;
UInt32 lengthOfBuffer = 8;
UniChar stringWithChars[lengthOfBuffer];
UniCharCount actualLength;
UniCharCount actualLength = 0;
OSStatus status = UCKeyTranslate(
keyboardLayout,
@@ -843,8 +858,8 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
- (NSString *)accessibleSelectedText
{
id focused = [self accessibilityFocusedUIElement];
if (![focused isKindOfClass:[JavaTextAccessibility class]]) return nil;
return [(JavaTextAccessibility *)focused accessibilitySelectedTextAttribute];
if (![focused respondsToSelector:@selector(accessibilitySelectedText)]) return nil;
return [focused accessibilitySelectedText];
}
// same as above, but converts to RTFD
@@ -863,8 +878,8 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
- (BOOL)replaceAccessibleTextSelection:(NSString *)text
{
id focused = [self accessibilityFocusedUIElement];
if (![focused isKindOfClass:[JavaTextAccessibility class]]) return NO;
[(JavaTextAccessibility *)focused accessibilitySetSelectedTextAttribute:text];
if (![focused respondsToSelector:@selector(setAccessibilitySelectedText)]) return NO;
[focused setAccessibilitySelectedText:text];
return YES;
}

View File

@@ -49,6 +49,7 @@
BOOL isMinimizing;
NSWindowTabbingMode javaWindowTabbingMode;
BOOL isEnterFullScreen;
BOOL isJustCreated;
}
// An instance of either AWTWindow_Normal or AWTWindow_Panel
@@ -66,6 +67,7 @@
@property (nonatomic) BOOL isMinimizing;
@property (nonatomic) NSWindowTabbingMode javaWindowTabbingMode;
@property (nonatomic) BOOL isEnterFullScreen;
@property (nonatomic) BOOL isJustCreated;
- (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow
ownerWindow:owner

View File

@@ -303,6 +303,7 @@ AWT_NS_WINDOW_IMPLEMENTATION
@synthesize isMinimizing;
@synthesize javaWindowTabbingMode;
@synthesize isEnterFullScreen;
@synthesize isJustCreated;
- (void) updateMinMaxSize:(BOOL)resizable {
if (resizable) {
@@ -446,6 +447,7 @@ AWT_ASSERT_APPKIT_THREAD;
self.javaWindowTabbingMode = [self getJavaWindowTabbingMode];
self.isEnterFullScreen = NO;
self.isJustCreated = YES;
return self;
}
@@ -1191,6 +1193,11 @@ JNF_COCOA_ENTER(env);
nsWindow.contentView.frame = contentFrame;
resized = YES;
}
if (window.isJustCreated) {
// Perform Move/Resize event for just created windows
resized = YES;
window.isJustCreated = NO;
}
}
// resets the NSWindow's style mask if the mask intersects any of those bits

View File

@@ -14,7 +14,6 @@
#import "JavaBaseAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "JavaTextAccessibility.h"
#import "JavaListAccessibility.h"
#import "JavaTableAccessibility.h"
#import "JavaListRowAccessibility.h"
@@ -23,6 +22,10 @@
#import "JavaOutlineAccessibility.h"
#import "JavaOutlineRowAccessibility.h"
#import "JavaStaticTextAccessibility.h"
#import "JavaNavigableTextAccessibility.h"
#import "JavaScrollAreaAccessibility.h"
#import "JavaTabGroupAccessibility.h"
#import "JavaComboBoxAccessibility.h"
#import "JavaComponentAccessibility.h"
#import "ThreadUtilities.h"
#import "AWTView.h"
@@ -240,7 +243,7 @@ static jobject sAccessibilityClass = NULL;
{
if ([parent isKindOfClass:[JavaTableAccessibility class]]) {
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
NSArray<NSNumber *> *selectedRowIndexses = [parent selectedAccessibleRows];
NSArray<NSNumber *> *selectedRowIndexses = [(JavaTableAccessibility *)parent selectedAccessibleRows];
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[selectedRowIndexses count]];
for (NSNumber *index in selectedRowIndexses) {
[children addObject:[[JavaTableRowAccessibility alloc] initWithParent:parent
@@ -252,7 +255,7 @@ static jobject sAccessibilityClass = NULL;
}
return [NSArray arrayWithArray:children];
} else if (whichChildren == JAVA_AX_ALL_CHILDREN) {
int rowCount = [parent accessibleRowCount];
int rowCount = [(JavaTableAccessibility *)parent accessibleRowCount];
NSMutableArray *children = [NSMutableArray arrayWithCapacity:rowCount];
for (int i = 0; i < rowCount; i++) {
[children addObject:[[JavaTableRowAccessibility alloc] initWithParent:parent
@@ -371,21 +374,23 @@ static jobject sAccessibilityClass = NULL;
} else if ([parent isKindOfClass:[JavaOutlineAccessibility class]]) {
newChild = [JavaOutlineRowAccessibility alloc];
} else if ([javaRole isEqualToString:@"pagetablist"]) {
newChild = [TabGroupAccessibility alloc];
newChild = [JavaTabGroupAccessibility alloc];
} else if ([javaRole isEqualToString:@"scrollpane"]) {
newChild = [ScrollAreaAccessibility alloc];
newChild = [JavaScrollAreaAccessibility alloc];
} else {
NSString *nsRole = [sRoles objectForKey:javaRole];
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole]) {
newChild = [JavaStaticTextAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityTextAreaRole] || [nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
newChild = [JavaTextAccessibility alloc];
newChild = [JavaNavigableTextAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityListRole]) {
newChild = [JavaListAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityTableRole]) {
newChild = [JavaTableAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityOutlineRole]) {
newChild = [JavaOutlineAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityComboBoxRole]) {
newChild = [JavaComboBoxAccessibility alloc];
} else {
newChild = [JavaComponentAccessibility alloc];
}

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.
#import "JavaElementAccessibility.h"
@interface JavaComboBoxAccessibility : JavaElementAccessibility
@property(readonly) NSString *accessibleSelectedText;
- (void)accessibleShowMenu;
@end
@interface PlatformAxComboBox : PlatformAxElement
@end

View File

@@ -0,0 +1,75 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaComboBoxAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
static const char* ACCESSIBLE_JCOMBOBOX_NAME = "javax.swing.JComboBox$AccessibleJComboBox";
@implementation JavaComboBoxAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxComboBox";
}
- (NSString *)accessibleSelectedText {
JNIEnv *env = [ThreadUtilities getJNIEnv];
JNFClassInfo clsInfo;
clsInfo.name = ACCESSIBLE_JCOMBOBOX_NAME;
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
JNF_MEMBER_CACHE(jm_getAccessibleSelection, clsInfo, "getAccessibleSelection", "(I)Ljavax/accessibility/Accessible;");
jobject axSelectedChild = JNFCallObjectMethod(env, [self axContextWithEnv:env], jm_getAccessibleSelection, 0);
if (axSelectedChild == NULL) {
return nil;
}
jobject childName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, axSelectedChild, fComponent);
if (childName == NULL) {
(*env)->DeleteLocalRef(env, axSelectedChild);
return nil;
}
NSString *selectedText = JNFObjectToString(env, childName);
(*env)->DeleteLocalRef(env, axSelectedChild);
(*env)->DeleteLocalRef(env, childName);
return selectedText;
}
- (void)accessibleShowMenu {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleAction, sjc_CAccessibility, "getAccessibleAction", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleAction;");
// On MacOSX, text doesn't have actions, in java it does.
// cmcnote: NOT TRUE - Editable text has AXShowMenu. Textfields have AXConfirm. Static text has no actions.
jobject axAction = JNFCallStaticObjectMethod(env, jm_getAccessibleAction, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axAction != NULL) {
//+++gdb NOTE: In MacOSX, there is just a single Action, not multiple. In java,
// the first one seems to be the most basic, so this will be used.
// cmcnote: NOT TRUE - Sometimes there are multiple actions, eg sliders have AXDecrement AND AXIncrement (radr://3893192)
JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent];
[action perform];
[action release];
(*env)->DeleteLocalRef(env, axAction);
}
}
@end
@implementation PlatformAxComboBox
- (id)accessibilityValue {
return [(JavaComboBoxAccessibility *)[self javaBase] accessibleSelectedText];
}
- (BOOL)accessibilityPerformPress {
[(JavaComboBoxAccessibility *)[self javaBase] accessibleShowMenu];
return YES;
}
- (BOOL)isAccessibilityEnabled {
return YES;
}
@end

View File

@@ -104,44 +104,3 @@
- (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

@@ -42,7 +42,7 @@
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "JavaTextAccessibility.h"
#import "JavaStaticTextAccessibility.h"
#import "ThreadUtilities.h"
#import "AWTView.h"
@@ -582,7 +582,8 @@ static NSObject *sAttributeNamesLOCK = nil;
// The sRoles NSMutableDictionary maps popupmenu to Mac's popup button.
// JComboBox behavior currently relies on this. However this is not the
// proper mapping for a JPopupMenu so fix that.
if ( [javaRole isEqualToString:@"popupmenu"] &&
if ([[self parent] isKindOfClass:[JavaBaseAccessibility class]] &&
[javaRole isEqualToString:@"popupmenu"] &&
![[[self parent] javaRole] isEqualToString:@"combobox"] ) {
fNSRole = NSAccessibilityMenuRole;
}
@@ -948,390 +949,3 @@ static NSObject *sAttributeNamesLOCK = nil;
}
@end
@implementation TabGroupAccessibility
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
{
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
if (self) {
_numTabs = -1; //flag for uninitialized numTabs
}
return self;
}
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
{
NSMutableArray *names = (NSMutableArray *)[super initializeAttributeNamesWithEnv:env];
[names addObject:NSAccessibilityTabsAttribute];
[names addObject:NSAccessibilityContentsAttribute];
[names addObject:NSAccessibilityValueAttribute];
return names;
}
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext
{
NSArray *tabs = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
// Looking at the JTabbedPane sources, there is always one AccessibleSelection.
jobject selAccessible = getAxContextSelection(env, axContext, 0, fComponent);
if (selAccessible == NULL) return nil;
// Go through the tabs and find selAccessible
_numTabs = [tabs count];
JavaComponentAccessibility *aTab;
NSInteger i;
for (i = 0; i < _numTabs; i++) {
aTab = (JavaComponentAccessibility *)[tabs objectAtIndex:i];
if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
(*env)->DeleteLocalRef(env, selAccessible);
return aTab;
}
}
(*env)->DeleteLocalRef(env, selAccessible);
return nil;
}
- (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
{
jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
if(jtabsAndRoles == NULL) return nil;
jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles);
if (arrayLen == 0) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return nil;
}
NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)];
// all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs
jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1.
if (jtabJavaRole == NULL) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return nil;
}
jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key);
NSString *tabJavaRole = JNFJavaToNSString(env, jkey);
(*env)->DeleteLocalRef(env, jkey);
NSInteger i;
NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly
for(i = 0; i < arrayLen; i+=2) {
jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i);
JavaComponentAccessibility *tab = [[[TabGroupControlAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
(*env)->DeleteLocalRef(env, jtab);
[tabs addObject:tab];
tabIndex++;
}
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return tabs;
}
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
{
// Contents are the children of the selected tab.
id currentTab = [self currentTabWithEnv:env withAxContext:axContext];
if (currentTab == nil) return nil;
NSArray *contents = [JavaComponentAccessibility childrenOfParent:currentTab withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
if ([contents count] <= 0) return nil;
return contents;
}
- (id) accessibilityTabsAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id tabs = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return tabs;
}
- (BOOL)accessibilityIsTabsAttributeSettable
{
return NO; //cmcnote: not sure.
}
- (NSInteger)numTabs
{
if (_numTabs == -1) {
_numTabs = [[self accessibilityTabsAttribute] count];
}
return _numTabs;
}
- (NSArray *) accessibilityContentsAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return cont;
}
- (BOOL)accessibilityIsContentsAttributeSettable
{
return NO;
}
// axValue is the currently selected tab
-(id) accessibilityValueAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id val = [self currentTabWithEnv:env withAxContext:axContext];
(*env)->DeleteLocalRef(env, axContext);
return val;
}
- (BOOL)accessibilityIsValueAttributeSettable
{
return YES;
}
- (void)accessibilitySetValueAttribute:(id)value //cmcnote: not certain this is ever actually called. investigate.
{
// set the current tab
NSNumber *number = (NSNumber *)value;
if (![number boolValue]) return;
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
setAxContextSelection(env, axContext, fIndex, fComponent);
(*env)->DeleteLocalRef(env, axContext);
}
- (NSArray *)accessibilityChildrenAttribute
{
//children = AXTabs + AXContents
NSArray *tabs = [self accessibilityTabsAttribute];
NSArray *contents = [self accessibilityContentsAttribute];
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[tabs count] + [contents count]];
[children addObjectsFromArray:tabs];
[children addObjectsFromArray:contents];
return (NSArray *)children;
}
// Without this optimization accessibilityChildrenAttribute is called in order to get the entire array of children.
// See similar optimization in JavaComponentAccessibility. We have to extend the base implementation here, since
// children of tabs are AXTabs + AXContents
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount {
NSArray *result = nil;
if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
// Children codes for ALL, SELECTED, VISIBLE are <0. If the code is >=0, we treat it as an index to a single child
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
//children = AXTabs + AXContents
NSArray *children = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:index allowIgnored:NO]; // first look at the tabs
if ([children count] > 0) {
result = children;
} else {
children= [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:(index-[self numTabs]) allowIgnored:NO];
if ([children count] > 0) {
result = children;
}
}
(*env)->DeleteLocalRef(env, axContext);
} else {
result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
}
return result;
}
@end
static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
@implementation TabGroupControlAccessibility
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole
{
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
if (self) {
if (tabGroup != NULL) {
fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroup);
} else {
fTabGroupAxContext = NULL;
}
}
return self;
}
- (void)dealloc
{
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
if (fTabGroupAxContext != NULL) {
JNFDeleteWeakGlobalRef(env, fTabGroupAxContext);
fTabGroupAxContext = NULL;
}
[super dealloc];
}
- (id)accessibilityValueAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent);
// Returns the current selection of the page tab list
id val = [NSNumber numberWithBool:ObjectEquals(env, axContext, selAccessible, fComponent)];
(*env)->DeleteLocalRef(env, selAccessible);
(*env)->DeleteLocalRef(env, axContext);
return val;
}
- (void)getActionsWithEnv:(JNIEnv *)env
{
TabGroupAction *action = [[TabGroupAction alloc] initWithEnv:env withTabGroup:[self tabGroup] withIndex:fIndex withComponent:fComponent];
[fActions setObject:action forKey:NSAccessibilityPressAction];
[action release];
}
- (jobject)tabGroup
{
if (fTabGroupAxContext == NULL) {
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env];
fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext);
(*env)->DeleteLocalRef(env, tabGroupAxContext);
}
return fTabGroupAxContext;
}
@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.
NSObject *aElement;
NSEnumerator *enumerator = [children objectEnumerator];
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 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];
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];
}
}
}
return contents;
}
- (BOOL)accessibilityIsContentsAttributeSettable
{
return NO;
}
@end
/*
* Returns Object.equals for the two items
* This may use LWCToolkit.invokeAndWait(); don't call while holding fLock
* and try to pass a component so the event happens on the correct thread.
*/
static JNF_CLASS_CACHE(sjc_Object, "java/lang/Object");
static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component)
{
static JNF_MEMBER_CACHE(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z");
if ((a == NULL) && (b == NULL)) return YES;
if ((a == NULL) || (b == NULL)) return NO;
if (pthread_main_np() != 0) {
// If we are on the AppKit thread
static JNF_CLASS_CACHE(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit");
static JNF_STATIC_MEMBER_CACHE(jm_doEquals, sjc_LWCToolkit, "doEquals", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z");
return JNFCallStaticBooleanMethod(env, jm_doEquals, a, b, component); // AWT_THREADING Safe (AWTRunLoopMode)
}
return JNFCallBooleanMethod(env, a, jm_equals, b); // AWT_THREADING Safe (!appKit)
}

View File

@@ -95,8 +95,9 @@ static void RaiseMustOverrideException(NSString *method)
- (id)accessibilityParent
{
JavaBaseAccessibility *parent = (JavaBaseAccessibility *) [self.javaBase parent];
return parent.platformAxElement;
id parent = [self.javaBase parent];
// Checking for protocol compliance can slow down at runtime. See: https://developer.apple.com/documentation/objectivec/nsobject/1418893-conformstoprotocol?language=objc
return [parent respondsToSelector:@selector(platformAxElement)] ? [parent platformAxElement] : parent;
}
- (BOOL)accessibilityIsIgnored
@@ -129,4 +130,8 @@ static void RaiseMustOverrideException(NSString *method)
return [[self javaBase] accessibilityIndexOfChild:child];
}
- (NSAccessibilityRole)accessibilityRole {
return [sRoles objectForKey:[[self javaBase] javaRole]];
}
@end

View File

@@ -4,7 +4,6 @@
#import "JavaListRowAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "JavaTextAccessibility.h"
#import "JavaListAccessibility.h"
#import "ThreadUtilities.h"

View File

@@ -0,0 +1,29 @@
// 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 "JavaStaticTextAccessibility.h"
@interface JavaNavigableTextAccessibility : JavaStaticTextAccessibility
// protocol methods
- (NSValue *)accessibleBoundsForRange:(NSRange)range;
- (NSNumber *)accessibleLineForIndex:(NSInteger)index;
- (NSValue *)accessibleRangeForLine:(NSInteger)line;
- (NSString *)accessibleStringForRange:(NSRange)range;
- (NSValue *)accessibleRangeForIndex:(NSInteger)index;
- (NSValue *)accessibleRangeForPosition:(NSPoint)point;
@property(readonly) NSString *accessibleSelectedText;
@property(readonly) NSValue *accessibleSelectedTextRange;
@property(readonly) NSNumber *accessibleNumberOfCharacters;
@property(readonly) NSNumber *accessibleInsertionPointLineNumber;
@property(readonly) BOOL accessibleIsValueSettable;
@property(readonly) BOOL accessibleIsPasswordText;
- (void)accessibleSetSelectedText:(NSString *)accessibilitySelectedText;
- (void)accessibleSetSelectedTextRange:(NSRange)accessibilitySelectedTextRange;
@end
@interface PlatformAxNavigableText : PlatformAxStaticText <NSAccessibilityNavigableStaticText>
@end

View File

@@ -0,0 +1,267 @@
// 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 "JavaNavigableTextAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
static JNF_CLASS_CACHE(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleText, sjc_CAccessibility, "getAccessibleText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
@implementation JavaNavigableTextAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxNavigableText";
}
- (NSString *)accessibleValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
// cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return nil;
(*env)->DeleteLocalRef(env, axText);
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return nil;
static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;");
jobject jrange = JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent);
NSString *string = JNFJavaToNSString(env, jrange); // AWT_THREADING Safe (AWTRunLoop)
(*env)->DeleteLocalRef(env, jrange);
(*env)->DeleteLocalRef(env, axEditableText);
if (string == nil) string = @"";
return string;
}
- (NSValue *)accessibleBoundsForRange:(NSRange)range {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D");
jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (axBounds == NULL) return nil;
// We cheat because we know that the array is 4 elements long (x, y, width, height)
jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0);
if (values == NULL) {
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
NSLog(@"%s failed calling GetDoubleArrayElements", __FUNCTION__);
return nil;
};
NSRect bounds;
bounds.origin.x = values[0];
bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping
bounds.size.width = values[2];
bounds.size.height = values[3];
NSValue *result = [NSValue valueWithRect:bounds];
(*env)->ReleaseDoubleArrayElements(env, axBounds, values, 0);
return result;
}
- (NSNumber *)accessibleLineForIndex:(NSInteger)index {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
}
- (NSValue *)accessibleRangeForLine:(NSInteger)line {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, line); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaConvertIntArrayToNSRangeValue(env,axTextRange);
}
- (NSString *)accessibleStringForRange:(NSRange)range {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;");
jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (jstringForRange == NULL) return @"";
NSString* str = JNFJavaToNSString(env, jstringForRange);
(*env)->DeleteLocalRef(env, jstringForRange);
return str;
}
- (NSValue *)accessibleRangeForIndex:(NSInteger)index {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaConvertIntArrayToNSRangeValue(env, axTextRange);
}
- (NSValue *)accessibleRangeForPosition:(NSPoint)point {
point.y = [[[[self view] window] screen] frame].size.height - point.y; // flip into java screen coords (0 is at upper-left corner of screen)
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getCharacterIndexAtPosition, sjc_CAccessibleText, "getCharacterIndexAtPosition", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)I");
jint charIndex = JNFCallStaticIntMethod(env, jm_getCharacterIndexAtPosition, fAccessible, fComponent, point.x, point.y); // AWT_THREADING Safe (AWTRunLoop)
if (charIndex == -1) return nil;
// AccessibleText.getIndexAtPoint returns -1 for an invalid point
NSRange range = NSMakeRange(charIndex, 1); //range's length is 1 - one-character range
return [NSValue valueWithRange:range];
}
- (NSString *)accessibleSelectedText {
JNIEnv* env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return @"";
NSString* str = JNFJavaToNSString(env, axText);
(*env)->DeleteLocalRef(env, axText);
return str;
}
- (NSValue *)accessibleSelectedTextRange {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedTextRange, sjc_CAccessibleText, "getSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getSelectedTextRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaConvertIntArrayToNSRangeValue(env, axTextRange);
}
- (NSNumber *)accessibleNumberOfCharacters {
// cmcnote: should coalesce these two calls - radr://3951923
// also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)];
(*env)->DeleteLocalRef(env, axText);
return num;
}
- (NSNumber *)accessibleInsertionPointLineNumber {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText, "getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForInsertionPoint, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
}
- (BOOL)accessibleIsValueSettable {
// if text is enabled and editable, it's settable (according to NSCellTextAttributesAccessibility)
BOOL isEnabled = [(NSNumber *)[self accessibilityEnabledAttribute] boolValue];
if (!isEnabled) return NO;
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return NO;
(*env)->DeleteLocalRef(env, axEditableText);
return YES;
}
- (BOOL)accessibleIsPasswordText {
return [[self javaRole] isEqualToString:@"passwordtext"];
}
- (void)accessibleSetSelectedText:(NSString *)accessibilitySelectedText {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jstring jstringValue = JNFNSToJavaString(env, accessibilitySelectedText);
static JNF_STATIC_MEMBER_CACHE(jm_setSelectedText, sjc_CAccessibleText, "setSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;Ljava/lang/String;)V");
JNFCallStaticVoidMethod(env, jm_setSelectedText, fAccessible, fComponent, jstringValue); // AWT_THREADING Safe (AWTRunLoop)
}
- (void)accessibleSetSelectedTextRange:(NSRange)accessibilitySelectedTextRange {
jint startIndex = accessibilitySelectedTextRange.location;
jint endIndex = startIndex + accessibilitySelectedTextRange.length;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_setSelectedTextRange, sjc_CAccessibleText, "setSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)V");
JNFCallStaticVoidMethod(env, jm_setSelectedTextRange, fAccessible, fComponent, startIndex, endIndex); // AWT_THREADING Safe (AWTRunLoop)
}
@end
@implementation PlatformAxNavigableText
- (NSRect)accessibilityFrameForRange:(NSRange)range {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleBoundsForRange:range] rectValue];
}
- (NSInteger)accessibilityLineForIndex:(NSInteger)index {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleLineForIndex:index] integerValue];
}
- (NSRange)accessibilityRangeForLine:(NSInteger)line {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleRangeForLine:line] rangeValue];
}
- (NSString *)accessibilityStringForRange:(NSRange)range {
return [(JavaNavigableTextAccessibility *)[self javaBase] accessibleStringForRange:range];
}
- (id)accessibilityValue {
return [(JavaNavigableTextAccessibility *)[self javaBase] accessibleValue];
}
- (NSAccessibilitySubrole)accessibilitySubrole {
if ([(JavaNavigableTextAccessibility *)[self javaBase] accessibleIsPasswordText]) {
return NSAccessibilitySecureTextFieldSubrole;
}
return nil;
}
- (NSRange)accessibilityRangeForIndex:(NSInteger)index {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleRangeForIndex:index] rangeValue];
}
- (NSAccessibilityRole)accessibilityRole {
return [sRoles objectForKey:[self javaBase].javaRole];
}
- (NSRange)accessibilityRangeForPosition:(NSPoint)point {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleRangeForPosition:point] rangeValue];
}
- (NSString *)accessibilitySelectedText {
return [(JavaNavigableTextAccessibility *)[self javaBase] accessibleSelectedText];
}
- (NSRange)accessibilitySelectedTextRange {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleSelectedTextRange] rangeValue];
}
- (NSInteger)accessibilityNumberOfCharacters {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleNumberOfCharacters] integerValue];
}
- (NSInteger)accessibilityInsertionPointLineNumber {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleInsertionPointLineNumber] integerValue];
}
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText {
[(JavaNavigableTextAccessibility *)[self javaBase] accessibleSetSelectedText:accessibilitySelectedText];
}
- (void)setAccessibilitySelectedTextRange:(NSRange)accessibilitySelectedTextRange {
[(JavaNavigableTextAccessibility *)[self javaBase] accessibleSetSelectedTextRange:accessibilitySelectedTextRange];
}
- (BOOL)isAccessibilityEdited {
return YES;
}
- (BOOL)isAccessibilityEnabled {
return YES;
}
/*
* Other text methods
- (NSRange)accessibilitySharedCharacterRange;
- (NSArray *)accessibilitySharedTextUIElements;
- (NSData *)accessibilityRTFForRange:(NSRange)range;
- (NSRange)accessibilityStyleRangeForIndex:(NSInteger)index;
*/
@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.
#import "JavaElementAccessibility.h"
@interface JavaScrollAreaAccessibility : JavaElementAccessibility
@property(readonly) NSArray *accessibleContents;
@property(readonly) id accessibleVerticalScrollBar;
@property(readonly) id accessibleHorizontalScrollBar;
@end
@interface PlatformAxScrollArea : PlatformAxElement
@end

View File

@@ -0,0 +1,100 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaScrollAreaAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import "JavaComponentAccessibility.h"
@implementation JavaScrollAreaAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxScrollArea";
}
- (NSArray *)accessibleContents {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaBaseAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;
NSArray *contents = [NSMutableArray arrayWithCapacity:[children count]];
// The scroll bars are in the children. children less the scroll bars is the contents
NSEnumerator *enumerator = [children objectEnumerator];
id aElement;
while ((aElement = [enumerator nextObject])) {
NSString *nsRole = [aElement isKindOfClass:[JavaComponentAccessibility class]] ? [aElement accessibilityRoleAttribute] : [aElement accessibilityRole]; // todo: Remove this solution when JavaComponentAccessibility is removed
if (![nsRole isEqualToString:NSAccessibilityScrollBarRole]) {
// no scroll bars in contents
[(NSMutableArray *) contents addObject:aElement];
}
}
return contents;
}
- (id)accessibleVerticalScrollBar {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaBaseAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;
// The scroll bars are in the children.
NSEnumerator *enumerator = [children objectEnumerator];
id aElement;
while ((aElement = (PlatformAxElement *)[enumerator nextObject])) {
NSString *nsRole = [aElement isKindOfClass:[JavaComponentAccessibility class]] ? [aElement accessibilityRoleAttribute] : [aElement accessibilityRole]; // todo: Remove this solution when JavaComponentAccessibility is removed
if ([nsRole isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [[aElement javaBase] axContextWithEnv:env];
if (isVertical(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
(*env)->DeleteLocalRef(env, elementAxContext);
}
}
return nil;
}
- (id)accessibleHorizontalScrollBar {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaBaseAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;
// The scroll bars are in the children.
id aElement;
NSEnumerator *enumerator = [children objectEnumerator];
while ((aElement = [enumerator nextObject])) {
NSString *nsRole = [aElement isKindOfClass:[JavaComponentAccessibility class]] ? [aElement accessibilityRoleAttribute] : [aElement accessibilityRole]; // todo: Remove this solution when JavaComponentAccessibility is removed
if ([nsRole isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [[aElement javaBase] axContextWithEnv:env];
if (isHorizontal(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
(*env)->DeleteLocalRef(env, elementAxContext);
}
}
return nil;
}
@end
@implementation PlatformAxScrollArea
- (NSArray *)accessibilityContents {
return [(JavaScrollAreaAccessibility *)[self javaBase] accessibleContents];
}
- (id)accessibilityVerticalScrollBar {
return [(JavaScrollAreaAccessibility *)[self javaBase] accessibleVerticalScrollBar];
}
- (id)accessibilityHorizontalScrollBar {
return [(JavaScrollAreaAccessibility *)[self javaBase] accessibleHorizontalScrollBar];
}
@end

View File

@@ -4,6 +4,12 @@
@interface JavaStaticTextAccessibility : JavaElementAccessibility
/*
* Converts an int array to an NSRange wrapped inside an NSValue
* takes [start, end] values and returns [start, end - start]
*/
NSValue *javaConvertIntArrayToNSRangeValue(JNIEnv* env, jintArray array);
@property(readonly) NSString *accessibleValue;
@property(readonly) NSValue *accessibleVisibleCharacterRange;

View File

@@ -10,12 +10,6 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleText, sjc_CAccessibility, "getAc
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
/*
* Converts an int array to an NSRange wrapped inside an NSValue
* takes [start, end] values and returns [start, end - start]
*/
NSValue *javaConvertIntArrayToNSRangeValue(JNIEnv* env, jintArray array) ;
@implementation JavaStaticTextAccessibility
- (NSString *)getPlatformAxElementClassName {
@@ -24,15 +18,15 @@ NSValue *javaConvertIntArrayToNSRangeValue(JNIEnv* env, jintArray array) ;
- (NSString *)accessibleValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
// if it's static text, the AppKit AXValue is the java accessibleName
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axName != NULL) {
NSString* str = JNFJavaToNSString(env, axName);
(*env)->DeleteLocalRef(env, axName);
return str;
}
return @"";;
}
return @"";
}
- (NSValue *)accessibleVisibleCharacterRange {
JNIEnv *env = [ThreadUtilities getJNIEnv];

View File

@@ -0,0 +1,19 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaElementAccessibility.h"
@interface JavaTabButtonAccessibility : JavaElementAccessibility {
jobject fTabGroupAxContext;
}
// from TabGroup controller
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole;
@property(readonly) jobject tabGroup;
@property(readonly) id accessibleValue;
- (void)performPressAction;
@end
@interface PlatformAxTabButton : PlatformAxElement
@end

View File

@@ -0,0 +1,93 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaTabButtonAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
@implementation JavaTabButtonAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxTabButton";
}
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole {
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
if (self) {
if (tabGroup != NULL) {
fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroup);
} else {
fTabGroupAxContext = NULL;
}
}
return self;
}
- (jobject)tabGroup {
if (fTabGroupAxContext == NULL) {
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject tabGroupAxContext = [(JavaBaseAccessibility *)[self parent] axContextWithEnv:env];
fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext);
(*env)->DeleteLocalRef(env, tabGroupAxContext);
}
return fTabGroupAxContext;
}
- (id)accessibleValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent);
// Returns the current selection of the page tab list
id val = [NSNumber numberWithBool:javaObjectEquals(env, axContext, selAccessible, fComponent)];
(*env)->DeleteLocalRef(env, selAccessible);
(*env)->DeleteLocalRef(env, axContext);
return val;
}
- (void)performPressAction {
JNIEnv *env = [ThreadUtilities getJNIEnv];
TabGroupAction *action = [[TabGroupAction alloc] initWithEnv:env withTabGroup:[self tabGroup] withIndex:fIndex withComponent:fComponent];
[action perform];
[action release];
}
@end
@implementation PlatformAxTabButton
- (NSAccessibilitySubrole)accessibilitySubrole {
return NSAccessibilityTabButtonSubrole;
}
- (id)accessibilityValue {
return [(JavaTabButtonAccessibility *)[self javaBase] accessibleValue];
}
- (BOOL)accessibilityPerformPress {
[(JavaTabButtonAccessibility *)[self javaBase] performPressAction];
return YES;
}
@end
static JNF_CLASS_CACHE(sjc_Object, "java/lang/Object");
static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component) {
static JNF_MEMBER_CACHE(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z");
if ((a == NULL) && (b == NULL)) return YES;
if ((a == NULL) || (b == NULL)) return NO;
if (pthread_main_np() != 0) {
// If we are on the AppKit thread
static JNF_CLASS_CACHE(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit");
static JNF_STATIC_MEMBER_CACHE(jm_doEquals, sjc_LWCToolkit, "doEquals", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z");
return JNFCallStaticBooleanMethod(env, jm_doEquals, a, b, component); // AWT_THREADING Safe (AWTRunLoopMode)
}
return JNFCallBooleanMethod(env, a, jm_equals, b); // AWT_THREADING Safe (!appKit)
}

View File

@@ -0,0 +1,21 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaElementAccessibility.h"
@interface JavaTabGroupAccessibility : JavaElementAccessibility {
NSInteger _numTabs;
}
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext;
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
@property(readonly) NSArray *accessibleTabs;
@property(readonly) NSArray *accessibleContents;
@property(readonly) id accessibleValue;
@property(readonly) NSInteger numTabs;
@end
@interface PlatformAxTabGroup : PlatformAxElement
@end

View File

@@ -0,0 +1,179 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaTabGroupAccessibility.h"
#import "JavaTabButtonAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
@implementation JavaTabGroupAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxTabGroup";
}
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext {
NSArray *tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
// Looking at the JTabbedPane sources, there is always one AccessibleSelection.
jobject selAccessible = getAxContextSelection(env, axContext, 0, fComponent);
if (selAccessible == NULL) return nil;
// Go through the tabs and find selAccessible
_numTabs = [tabs count];
JavaBaseAccessibility *aTab;
NSInteger i;
for (i = 0; i < _numTabs; i++) {
aTab = [(PlatformAxElement *)[tabs objectAtIndex:i] javaBase];
if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
(*env)->DeleteLocalRef(env, selAccessible);
return [aTab platformAxElement];
}
}
(*env)->DeleteLocalRef(env, selAccessible);
return nil;
}
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored {
jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
if(jtabsAndRoles == NULL) return nil;
jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles);
if (arrayLen == 0) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return nil;
}
NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)];
// all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs
jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1.
if (jtabJavaRole == NULL) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return nil;
}
jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key);
NSString *tabJavaRole = JNFJavaToNSString(env, jkey);
(*env)->DeleteLocalRef(env, jkey);
NSInteger i;
NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly
for(i = 0; i < arrayLen; i+=2) {
jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i);
JavaBaseAccessibility *tab = [[[JavaTabButtonAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
(*env)->DeleteLocalRef(env, jtab);
[tabs addObject:[tab platformAxElement]];
tabIndex++;
}
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return tabs;
}
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored {
// Contents are the children of the selected tab.
PlatformAxElement *currentTab = [self currentTabWithEnv:env withAxContext:axContext];
if (currentTab == nil) return nil;
NSArray *contents = [JavaBaseAccessibility childrenOfParent:[currentTab javaBase] withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
if ([contents count] <= 0) return nil;
return contents;
}
- (NSArray *)accessibleTabs {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return tabs;
}
- (NSArray *) accessibleContents {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return cont;
}
-(id) accessibleValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id val = [self currentTabWithEnv:env withAxContext:axContext];
(*env)->DeleteLocalRef(env, axContext);
return val;
}
- (NSInteger)numTabs {
return _numTabs;
}
@end
@implementation PlatformAxTabGroup
- (NSArray *)accessibilityTabs {
return [(JavaTabGroupAccessibility *)[self javaBase] accessibleTabs];
}
- (NSArray *)accessibilityContents {
return [(JavaTabGroupAccessibility *)[self javaBase] accessibleContents];
}
- (id)accessibilityValue {
return [(JavaTabGroupAccessibility *)[self javaBase] accessibleValue];
}
- (NSArray *)accessibilityChildren {
//children = AXTabs + AXContents
NSArray *tabs = [self accessibilityTabs];
NSArray *contents = [self accessibilityContents];
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[tabs count] + [contents count]];
[children addObjectsFromArray:tabs];
[children addObjectsFromArray:contents];
return (NSArray *)children;
}
- (NSArray *)accessibilityArrayAttributeValues:(NSAccessibilityAttributeName)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount {
NSArray *result = nil;
if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
// Children codes for ALL, SELECTED, VISIBLE are <0. If the code is >=0, we treat it as an index to a single child
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [(JavaTabGroupAccessibility *)[self javaBase] axContextWithEnv:env];
//children = AXTabs + AXContents
NSArray *children = [(JavaTabGroupAccessibility *)[self javaBase] tabButtonsWithEnv:env
withTabGroupAxContext:axContext
withTabCode:index
allowIgnored:NO]; // first look at the tabs
if ([children count] > 0) {
result = children;
} else {
children= [(JavaTabGroupAccessibility *)[self javaBase] contentsWithEnv:env
withTabGroupAxContext:axContext
withTabCode:(index-[(JavaTabGroupAccessibility *)[self javaBase] numTabs])
allowIgnored:NO];
if ([children count] > 0) {
result = children;
}
}
(*env)->DeleteLocalRef(env, axContext);
} else {
result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
}
return result;
}
- (void)setAccessibilityValue:(id)accessibilityValue {
NSNumber *number = (NSNumber *)accessibilityValue;
if (![number boolValue]) return;
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
setAxContextSelection(env, axContext, [[self javaBase] index], [[self javaBase] component]);
(*env)->DeleteLocalRef(env, axContext);
}
@end

View File

@@ -57,6 +57,7 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
for (int i = 0; i < arrayLen; i++) {
[nsArraySelectidRowNumbers addObject:[NSNumber numberWithInt:indexsis[i]]];
}
(*env)->DeleteLocalRef(env, selectidRowNumbers);
return [NSArray<NSNumber *> arrayWithArray:nsArraySelectidRowNumbers];
}
@@ -76,18 +77,17 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
for (int i = 0; i < arrayLen; i++) {
[nsArraySelectidColumnNumbers addObject:[NSNumber numberWithInt:indexsis[i]]];
}
(*env)->DeleteLocalRef(env, selectidColumnNumbers);
return [NSArray<NSNumber *> arrayWithArray:nsArraySelectidColumnNumbers];
}
- (int)accessibleRowAtIndex:(int)index {
printf("Пришёл индекс %d\n", index);
JNIEnv *env = [ThreadUtilities getJNIEnv];
JNFClassInfo clsInfo;
clsInfo.name = ACCESSIBLE_JTABLE_NAME;
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
JNF_MEMBER_CACHE(jm_getAccessibleRowAtIndex, clsInfo, "getAccessibleRowAtIndex", "(I)I");
jint rowAtIndex = JNFCallIntMethod(env, [self axContextWithEnv:env], jm_getAccessibleRowAtIndex, (jint)index);
printf("Получен индекс %d\n", rowAtIndex);
return (int)rowAtIndex;
}

View File

@@ -1,10 +1,5 @@
// 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

View File

@@ -1,63 +0,0 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#import "JavaComponentAccessibility.h"
#import <AppKit/NSAccessibility.h>
@interface JavaTextAccessibility : JavaComponentAccessibility {
}
// attributes
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
- (NSString *)accessibilityValueAttribute;
- (BOOL)accessibilityIsValueAttributeSettable;
- (void)accessibilitySetValueAttribute:(id)value;
- (NSString *)accessibilitySelectedTextAttribute;
- (BOOL)accessibilityIsSelectedTextAttributeSettable;
- (NSValue *)accessibilitySelectedTextRangeAttribute;
- (BOOL)accessibilityIsSelectedTextRangeAttributeSettable;
- (NSNumber *)accessibilityNumberOfCharactersAttribute;
- (BOOL)accessibilityIsNumberOfCharactersAttributeSettable;
- (NSValue *)accessibilityVisibleCharacterRangeAttribute;
- (BOOL)accessibilityIsVisibleCharacterRangeAttributeSettable;
- (NSValue *)accessibilityInsertionPointLineNumberAttribute;
- (BOOL)accessibilityIsInsertionPointLineNumberAttributeSettable;
- (void)accessibilitySetSelectedTextAttribute:(id)value;
- (NSValue *)accessibilitySelectedTextRangeAttribute;
- (NSValue *)accessibilityInsertionPointLineNumberAttribute;
- (BOOL)accessibilityIsInsertionPointLineNumberAttributeSettable;
// parameterized attributes
- (NSArray *)accessibilityParameterizedAttributeNames;
- (NSValue *)accessibilityBoundsForRangeAttributeForParameter:(id)parameter;
- (NSNumber *)accessibilityLineForIndexAttributeForParameter:(id)parameter;
- (NSValue *)accessibilityRangeForLineAttributeForParameter:(id)parameter;
- (NSString *)accessibilityStringForRangeAttributeForParameter:(id)parameter;
- (NSValue *)accessibilityRangeForPositionAttributeForParameter:(id)parameter;
- (NSValue *)accessibilityRangeForIndexAttributeForParameter:(id)parameter;
@end

View File

@@ -1,441 +0,0 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#import "JavaTextAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
static JNF_CLASS_CACHE(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleText, sjc_CAccessibility, "getAccessibleText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
/*
* Converts an int array to an NSRange wrapped inside an NSValue
* takes [start, end] values and returns [start, end - start]
*/
NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
jint *values = (*env)->GetIntArrayElements(env, array, 0);
if (values == NULL) {
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
NSLog(@"%s failed calling GetIntArrayElements", __FUNCTION__);
return nil;
};
NSValue *value = [NSValue valueWithRange:NSMakeRange(values[0], values[1] - values[0])];
(*env)->ReleaseIntArrayElements(env, array, values, 0);
return value;
}
@implementation JavaTextAccessibility
// based strongly upon NSTextViewAccessibility:accessibilityAttributeNames
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
{
static NSArray *attributes = nil;
if (attributes == nil) {
//APPKIT_LOCK;
if (attributes == nil) {
NSMutableArray *temp = [[super initializeAttributeNamesWithEnv:env] mutableCopy];
//[temp removeObject:NSAccessibilityTitleAttribute]; // title may have been set in the superclass implementation - some static text reports from java that it has a name
[temp addObjectsFromArray:[NSArray arrayWithObjects:
NSAccessibilityValueAttribute,
NSAccessibilitySelectedTextAttribute,
NSAccessibilitySelectedTextRangeAttribute,
NSAccessibilityNumberOfCharactersAttribute,
NSAccessibilityVisibleCharacterRangeAttribute,
NSAccessibilityInsertionPointLineNumberAttribute,
// NSAccessibilitySharedTextUIElementsAttribute, // cmcnote: investigate what these two are for. currently unimplemented
// NSAccessibilitySharedCharacterRangeAttribute,
nil]];
attributes = [[NSArray alloc] initWithArray:temp];
[temp release];
}
//APPKIT_UNLOCK;
}
return attributes;
}
// copied from NSTextViewAccessibility.
- (NSArray *)accessibilityParameterizedAttributeNames
{
static NSArray *attributes = nil;
if (attributes == nil) {
//APPKIT_LOCK;
if (attributes == nil) {
attributes = [[NSArray alloc] initWithObjects:
NSAccessibilityLineForIndexParameterizedAttribute,
NSAccessibilityRangeForLineParameterizedAttribute,
NSAccessibilityStringForRangeParameterizedAttribute,
NSAccessibilityRangeForPositionParameterizedAttribute,
NSAccessibilityRangeForIndexParameterizedAttribute,
NSAccessibilityBoundsForRangeParameterizedAttribute,
//NSAccessibilityRTFForRangeParameterizedAttribute, // cmcnote: not sure when/how these three are used. Investigate. radr://3960026
//NSAccessibilityStyleRangeForIndexParameterizedAttribute,
//NSAccessibilityAttributedStringForRangeParameterizedAttribute,
nil];
}
//APPKIT_UNLOCK;
}
return attributes;
}
- (NSString *)accessibilityValueAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
if ([[self accessibilityRoleAttribute] isEqualToString:NSAccessibilityStaticTextRole]) {
// if it's static text, the AppKit AXValue is the java accessibleName
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axName != NULL) {
NSString* str = JNFJavaToNSString(env, axName);
(*env)->DeleteLocalRef(env, axName);
return str;
}
// value is still nil if no accessibleName for static text. Below, try to get the accessibleText.
}
// cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return nil;
(*env)->DeleteLocalRef(env, axText);
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return nil;
static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;");
jobject jrange = JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent);
NSString *string = JNFJavaToNSString(env, jrange); // AWT_THREADING Safe (AWTRunLoop)
(*env)->DeleteLocalRef(env, jrange);
(*env)->DeleteLocalRef(env, axEditableText);
if (string == nil) string = @"";
return string;
}
- (BOOL)accessibilityIsValueAttributeSettable
{
// if text is enabled and editable, it's settable (according to NSCellTextAttributesAccessibility)
BOOL isEnabled = [(NSNumber *)[self accessibilityEnabledAttribute] boolValue];
if (!isEnabled) return NO;
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return NO;
(*env)->DeleteLocalRef(env, axEditableText);
return YES;
}
- (void)accessibilitySetValueAttribute:(id)value
{
// cmcnote: should set the accessibleEditableText to the stringValue of value - AccessibleEditableText.setTextContents(String s)
#ifdef JAVA_AX_DEBUG
NSLog(@"Not yet implemented: %s\n", __FUNCTION__); // radr://3954018
#endif
}
// Currently selected text (NSString)
- (NSString *)accessibilitySelectedTextAttribute
{
JNIEnv* env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return @"";
NSString* str = JNFJavaToNSString(env, axText);
(*env)->DeleteLocalRef(env, axText);
return str;
}
- (BOOL)accessibilityIsSelectedTextAttributeSettable
{
return YES; //cmcnote: for AXTextField that's selectable, it's settable. Investigate further.
}
- (void)accessibilitySetSelectedTextAttribute:(id)value
{
#ifdef JAVA_AX_DEBUG_PARMS
if (![value isKindOfClass:[NSString class]]) {
JavaAccessibilityRaiseSetAttributeToIllegalTypeException(__FUNCTION__, self, NSAccessibilitySelectedTextAttribute, value);
return;
}
#endif
JNIEnv *env = [ThreadUtilities getJNIEnv];
jstring jstringValue = JNFNSToJavaString(env, (NSString *)value);
static JNF_STATIC_MEMBER_CACHE(jm_setSelectedText, sjc_CAccessibleText, "setSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;Ljava/lang/String;)V");
JNFCallStaticVoidMethod(env, jm_setSelectedText, fAccessible, fComponent, jstringValue); // AWT_THREADING Safe (AWTRunLoop)
}
// Range of selected text (NSValue)
- (NSValue *)accessibilitySelectedTextRangeAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedTextRange, sjc_CAccessibleText, "getSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getSelectedTextRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env, axTextRange);
}
- (BOOL)accessibilityIsSelectedTextRangeAttributeSettable
{
return [(NSNumber *)[self accessibilityEnabledAttribute] boolValue]; // cmcnote: also may want to find out if isSelectable. Investigate.
}
- (void)accessibilitySetSelectedTextRangeAttribute:(id)value
{
#ifdef JAVA_AX_DEBUG_PARMS
if (!([value isKindOfClass:[NSValue class]] && strcmp([(NSValue *)value objCType], @encode(NSRange)) == 0)) {
JavaAccessibilityRaiseSetAttributeToIllegalTypeException(__FUNCTION__, self, NSAccessibilitySelectedTextRangeAttribute, value);
return;
}
#endif
NSRange range = [(NSValue *)value rangeValue];
jint startIndex = range.location;
jint endIndex = startIndex + range.length;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_setSelectedTextRange, sjc_CAccessibleText, "setSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)V");
JNFCallStaticVoidMethod(env, jm_setSelectedTextRange, fAccessible, fComponent, startIndex, endIndex); // AWT_THREADING Safe (AWTRunLoop)
}
- (NSNumber *)accessibilityNumberOfCharactersAttribute
{
// cmcnote: should coalesce these two calls - radr://3951923
// also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)];
(*env)->DeleteLocalRef(env, axText);
return num;
}
- (BOOL)accessibilityIsNumberOfCharactersAttributeSettable
{
return NO; // according to NSTextViewAccessibility.m and NSCellTextAttributesAccessibility.m
}
- (NSValue *)accessibilityVisibleCharacterRangeAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getVisibleCharacterRange, sjc_CAccessibleText, "getVisibleCharacterRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getVisibleCharacterRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env, axTextRange);
}
- (BOOL)accessibilityIsVisibleCharacterRangeAttributeSettable
{
#ifdef JAVA_AX_DEBUG
NSLog(@"Not yet implemented: %s\n", __FUNCTION__);
#endif
return NO;
}
- (NSValue *)accessibilityInsertionPointLineNumberAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText, "getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForInsertionPoint, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
}
- (BOOL)accessibilityIsInsertionPointLineNumberAttributeSettable
{
#ifdef JAVA_AX_DEBUG
NSLog(@"Not yet implemented: %s\n", __FUNCTION__);
#endif
return NO;
}
// parameterized attributes
//
// Usage of accessibilityBoundsForRangeAttributeForParameter:
// ---
// called by VoiceOver when interacting with text via ctrl-option-shift-downArrow.
// Need to know bounding box for the character / word / line of interest in
// order to draw VoiceOver cursor
//
- (NSValue *)accessibilityBoundsForRangeAttributeForParameter:(id)parameter
{
#ifdef JAVA_AX_DEBUG_PARMS
if (!([parameter isKindOfClass:[NSValue class]] && strcmp([(NSValue *)parameter objCType], @encode(NSRange)) == 0)) {
JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityBoundsForRangeParameterizedAttribute, parameter);
return nil;
}
#endif
NSRange range = [(NSValue *)parameter rangeValue];
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D");
jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (axBounds == NULL) return nil;
// We cheat because we know that the array is 4 elements long (x, y, width, height)
jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0);
if (values == NULL) {
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
NSLog(@"%s failed calling GetDoubleArrayElements", __FUNCTION__);
return nil;
};
NSRect bounds;
bounds.origin.x = values[0];
bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping
bounds.size.width = values[2];
bounds.size.height = values[3];
NSValue *result = [NSValue valueWithRect:bounds];
(*env)->ReleaseDoubleArrayElements(env, axBounds, values, 0);
return result;
}
- (NSNumber *)accessibilityLineForIndexAttributeForParameter:(id)parameter
{
NSNumber *line = (NSNumber *) parameter;
if (line == nil) return nil;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForIndex, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
}
- (NSValue *)accessibilityRangeForLineAttributeForParameter:(id)parameter
{
NSNumber *line = (NSNumber *) parameter;
if (line == nil) return nil;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env,axTextRange);
}
//
// Usage of accessibilityStringForRangeAttributeForParameter:
// ---
// called by VoiceOver when interacting with text via ctrl-option-shift-downArrow.
// VO needs to know the particular string its currently dealing with so it can
// speak the string
//
- (NSString *)accessibilityStringForRangeAttributeForParameter:(id)parameter
{
#ifdef JAVA_AX_DEBUG_PARMS
if (!([parameter isKindOfClass:[NSValue class]] && strcmp([(NSValue *)parameter objCType], @encode(NSRange)) == 0)) {
JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityBoundsForRangeParameterizedAttribute, parameter);
return nil;
}
#endif
NSRange range = [(NSValue *)parameter rangeValue];
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;");
jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (jstringForRange == NULL) return @"";
NSString* str = JNFJavaToNSString(env, jstringForRange);
(*env)->DeleteLocalRef(env, jstringForRange);
return str;
}
//
// Usage of accessibilityRangeForPositionAttributeForParameter:
// ---
// cmcnote: I'm not sure when this is called / how it's used. Investigate.
// probably could be used in a special text-only accessibilityHitTest to
// find the index of the string under the mouse?
//
- (NSValue *)accessibilityRangeForPositionAttributeForParameter:(id)parameter
{
#ifdef JAVA_AX_DEBUG_PARMS
if (!([parameter isKindOfClass:[NSValue class]] && strcmp([(NSValue *)parameter objCType], @encode(NSPoint)) == 0)) {
JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityRangeForPositionParameterizedAttribute, parameter);
return nil;
}
#endif
NSPoint point = [(NSValue *)parameter pointValue]; // point is in screen coords
point.y = [[[[self view] window] screen] frame].size.height - point.y; // flip into java screen coords (0 is at upper-left corner of screen)
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getCharacterIndexAtPosition, sjc_CAccessibleText, "getCharacterIndexAtPosition", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)I");
jint charIndex = JNFCallStaticIntMethod(env, jm_getCharacterIndexAtPosition, fAccessible, fComponent, point.x, point.y); // AWT_THREADING Safe (AWTRunLoop)
if (charIndex == -1) return nil;
// AccessibleText.getIndexAtPoint returns -1 for an invalid point
NSRange range = NSMakeRange(charIndex, 1); //range's length is 1 - one-character range
return [NSValue valueWithRange:range];
}
//
// Usage of accessibilityRangeForIndexAttributeForParameter:
// ---
// cmcnote: I'm not sure when this is called / how it's used. Investigate.
// AppKit version calls: [string rangeOfComposedCharacterSequenceAtIndex:index]
// We call: CAccessibility.getRangeForIndex, which calls AccessibleText.getAtIndex(AccessibleText.WORD, index)
// to determine the word closest to the given index. Then we find the length/location of this string.
//
- (NSValue *)accessibilityRangeForIndexAttributeForParameter:(id)parameter
{
#ifdef JAVA_AX_DEBUG_PARMS
if (![parameter isKindOfClass:[NSNumber class]]) {
JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityRangeForIndexParameterizedAttribute, parameter);
return nil;
}
#endif
NSUInteger index = [(NSNumber *)parameter unsignedIntegerValue];
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env, axTextRange);
}
/*
* - (NSDictionary *)getActions:(JNIEnv *)env { ... }
*
* In the future, possibly add support: Editable text has AXShowMenu.
* Textfields have AXConfirm.
*
* Note: JLabels (static text) in JLists have a press/click selection action
* which is currently handled in superclass JavaComponentAccessibility.
* If function is added here be sure to use [super getActions:env] for JLabels.
*/
@end

View File

@@ -12,7 +12,7 @@ public class KeyEventProcessing {
@Native
public final static boolean useNationalLayouts = "true".equals(
Util.getProperty(useNationalLayoutsOption,
FontUtilities.isMacOSX && !FontUtilities.isMacOSX_aarch64 ? "true" : "false"));
FontUtilities.isMacOSX ? "true" : "false"));
// Used on windows to emulate latin OEM keys on cyrillic keyboards
public final static String useLatinNonAlphaNumKeycodesOption = "com.sun.awt.useLatinNonAlphaNumKeycodes";

View File

@@ -111,11 +111,12 @@ public class FontStrikeDesc {
*/
public static int getAAHintIntVal(Object aa, Font2D font2D, int ptSize) {
if (FontUtilities.isMacOSX14 &&
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
aa == VALUE_TEXT_ANTIALIAS_ON ||
aa == VALUE_TEXT_ANTIALIAS_GASP))
if (FontUtilities.isMacOSX16 ||
(FontUtilities.isMacOSX14 &&
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
aa == VALUE_TEXT_ANTIALIAS_ON ||
aa == VALUE_TEXT_ANTIALIAS_GASP)))
{
return INTVAL_TEXT_ANTIALIAS_ON;
}
@@ -153,11 +154,12 @@ public class FontStrikeDesc {
FontRenderContext frc) {
Object aa = frc.getAntiAliasingHint();
if (FontUtilities.isMacOSX14 &&
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
aa == VALUE_TEXT_ANTIALIAS_ON ||
aa == VALUE_TEXT_ANTIALIAS_GASP))
if (FontUtilities.isMacOSX16 ||
(FontUtilities.isMacOSX14 &&
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
aa == VALUE_TEXT_ANTIALIAS_ON ||
aa == VALUE_TEXT_ANTIALIAS_GASP)))
{
return INTVAL_TEXT_ANTIALIAS_ON;
}

View File

@@ -50,6 +50,7 @@ public final class FontUtilities {
public static boolean isMacOSX;
public static boolean isMacOSX14;
public static boolean isMacOSX16;
public static boolean isMacOSX_aarch64;
public static boolean useJDKScaler;
@@ -83,9 +84,10 @@ public final class FontUtilities {
isMacOSX = osName.contains("OS X"); // TODO: MacOSX
if (isMacOSX) {
// os.version has values like 10.13.6, 10.14.6
// If it is not positively recognised as 10.13 or less,
// assume it means 10.14 or some later version.
// If it is not positively recognised as 10.13 (10.15) or less,
// assume it means 10.14 (10.16) or some later version.
isMacOSX14 = true;
isMacOSX16 = true;
String version = System.getProperty("os.version", "");
if (version.startsWith("10.")) {
version = version.substring(3);
@@ -96,6 +98,7 @@ public final class FontUtilities {
try {
int v = Integer.parseInt(version);
isMacOSX14 = (v >= 14);
isMacOSX16 = (v >= 16);
} catch (NumberFormatException e) {
}
}

View File

@@ -772,8 +772,9 @@ public final class SunGraphics2D
}
}
}
if (FontUtilities.isMacOSX14 &&
(aahint == SunHints.INTVAL_TEXT_ANTIALIAS_OFF))
if (FontUtilities.isMacOSX16 ||
(FontUtilities.isMacOSX14 &&
aahint == SunHints.INTVAL_TEXT_ANTIALIAS_OFF))
{
aahint = SunHints.INTVAL_TEXT_ANTIALIAS_ON;
}

View File

@@ -456,7 +456,11 @@ public abstract class SurfaceData
} else {
solidTextRenderer = new SolidTextRenderer();
}
lcdTextRenderer = new LCDTextRenderer();
if (FontUtilities.isMacOSX16) {
lcdTextRenderer = aaTextRenderer;
} else {
lcdTextRenderer = new LCDTextRenderer();
}
colorPipe = new AlphaColorPipe();
// colorShape = colorPrimitives;

View File

@@ -695,7 +695,7 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative(
return (jlong) 0;
}
(*env)->GetDoubleArrayRegion(env, matrix, 0, 4, dmat);
ptsz = euclidianDistance(dmat[2], dmat[3]); //i.e. y-size
ptsz = euclidianDistance(dmat[0], dmat[1]); //i.e. x-size
if (ptsz < 1.0) {
//text can not be smaller than 1 point
ptsz = 1.0;

View File

@@ -814,7 +814,7 @@ AwtFileDialog::Show(void *p)
LPTSTR fileBuffer = NULL;
static BOOL useCommonItemDialog = JNU_CallStaticMethodByName(env, NULL,
BOOL useCommonItemDialog = JNU_CallStaticMethodByName(env, NULL,
"sun/awt/windows/WFileDialogPeer", "useCommonItemDialog", "()Z").z == JNI_TRUE;
try {
DASSERT(peer);

View File

@@ -0,0 +1,53 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/*
* @test
* @summary manual test for JBR-3241
* @author Artem.Semenov@jetbrains.com
* @run main/manual AccessibleJComboboxTest
*/
import javax.swing.*;
import java.awt.*;
import java.util.concurrent.CountDownLatch;
public class AccessibleJComboboxTest extends AccessibleComponentTest {
@java.lang.Override
public CountDownLatch createCountDownLatch() {
return new CountDownLatch(1);
}
void createCombobox() {
INSTRUCTIONS = "INSTRUCTIONS:\n"
+ "Check a11y of JCombobox.\n\n"
+ "Turn screen reader on, and Tab to the combobox.\n\n"
+ "If you can hear combobox selected item tab further and press PASS, otherwise press FAIL.";
JPanel frame = new JPanel();
String[] NAMES = {"One", "Two", "Three", "Four", "Five"};
JComboBox<String> combo = new JComboBox<>(NAMES);
JLabel label = new JLabel("This is combobox:");
label.setLabelFor(combo);
frame.setLayout(new FlowLayout());
frame.add(label);
frame.add(combo);
exceptionString = "AccessibleJCombobox test failed!";
super.createUI(frame, "AccessibleJComboboxTest");
}
public static void main(String[] args) throws Exception {
AccessibleJComboboxTest test = new AccessibleJComboboxTest();
countDownLatch = test.createCountDownLatch();
SwingUtilities.invokeLater(test::createCombobox);
countDownLatch.await();
if (!testResult) {
throw new RuntimeException(a11yTest.exceptionString);
}
}
}

View File

@@ -0,0 +1,68 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/*
* @test
* @summary manual test for JBR-3239
* @author Artem.Semenov@jetbrains.com
* @run main/manual AccessibleJScrollPaneTest
*/
import javax.swing.*;
import java.awt.*;
import java.util.concurrent.CountDownLatch;
public class AccessibleJScrollPaneTest extends AccessibleComponentTest {
@java.lang.Override
public CountDownLatch createCountDownLatch() {
return new CountDownLatch(1);
}
void createScrollPane() {
INSTRUCTIONS = "INSTRUCTIONS:\n"
+ "Check a11y of JScrollPane in a simple Window.\n\n"
+ "Turn screen reader on, and tab to the table.\n"
+ "this table has 10 rows and 10 columns, few cells are invisible.\n\n"
+ "On Windows press arrow buttons to move through the table.\n\n"
+ "On MacOS, use up and down arrow buttons to move through the rows, use VoiceOver fast navigation to move through the columns.\n\n"
+ "If you can hear table cells tab further and press PASS, otherwise press FAIL.\n";
final int n = 10;
String[][] data = new String[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
data[i][j] = "Cell " + String.valueOf(i) + ":" + String.valueOf(j);
}
}
String[] columnNames = new String[n];
for (int i = 0; i < n; i++) {
columnNames[i] = "Header " + String.valueOf(i);
}
JTable table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(table.getPreferredScrollableViewportSize().width / 2, table.getRowHeight() * 5));
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
panel.add(scrollPane);
exceptionString = "AccessibleJScrollPane test failed!";
super.createUI(panel, "AccessibleJScrollTest");
}
public static void main(String[] args) throws Exception {
AccessibleJScrollPaneTest test = new AccessibleJScrollPaneTest();
countDownLatch = test.createCountDownLatch();
SwingUtilities.invokeLater(test::createScrollPane);
countDownLatch.await();
if (!testResult) {
throw new RuntimeException(a11yTest.exceptionString);
}
}
}

View File

@@ -0,0 +1,62 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/*
* @test
* @summary manual test for JBR-3240
* @author Artem.Semenov@jetbrains.com
* @run main/manual AccessibleJTabbedPaneTest
*/
import javax.swing.*;
import java.util.concurrent.CountDownLatch;
public class AccessibleJTabbedPaneTest extends AccessibleComponentTest {
@Override
public CountDownLatch createCountDownLatch() {
return new CountDownLatch(1);
}
void createTabPane() {
INSTRUCTIONS = "INSTRUCTIONS:\n"
+ "Check a11y of JTabbedPane in a simple Window.\n\n"
+ "Turn screen reader on, and tab to the JTabbedPane.\n"
+ "Use up and down arrow buttons to move through the tabs.\n\n"
+ "If you can hear selected tab names tab further and press PASS, otherwise press FAIL.\n";
JTabbedPane tabbedPane = new JTabbedPane();
JPanel panel1 = new JPanel();
String[] names = {"One", "Two", "Three", "Four", "Five"};
JList list = new JList(names);
JLabel fieldName = new JLabel("Text field:");
JTextField textField = new JTextField();
fieldName.setLabelFor(textField);
panel1.add(fieldName);
panel1.add(textField);
panel1.add(list);
tabbedPane.addTab("Tab 1", panel1);
JPanel panel2 = new JPanel();
for (int i = 0; i < 5; i++) {
panel2.add(new JCheckBox("CheckBox " + String.valueOf(i + 1)));
}
tabbedPane.addTab("tab 2", panel2);
JPanel panel = new JPanel();
panel.add(tabbedPane);
exceptionString = "AccessibleJTabbedPane test failed!";
createUI(panel, "AccessibleJTabbedPaneTest");
}
public static void main(String[] args) throws Exception {
AccessibleJTabbedPaneTest test = new AccessibleJTabbedPaneTest();
countDownLatch = test.createCountDownLatch();
SwingUtilities.invokeLater(test::createTabPane);
countDownLatch.await();
if (!testResult) {
throw new RuntimeException(a11yTest.exceptionString);
}
}
}