macOS national keyboard support

(cherry picked from commit 83356eb0bb)
(cherry picked from commit c8a36e1804)
This commit is contained in:
Denis Fokin
2016-12-23 17:46:26 +03:00
committed by jbrbot
parent bba923f037
commit 9ad0a4ed00
12 changed files with 329 additions and 14 deletions

View File

@@ -103,7 +103,8 @@ public class CEmbeddedFrame extends EmbeddedFrame {
public void handleKeyEvent(int eventType, int modifierFlags, String characters,
String charsIgnoringMods, boolean isRepeat, short keyCode,
boolean needsKeyTyped) {
responder.handleKeyEvent(eventType, modifierFlags, characters, charsIgnoringMods,
responder.handleKeyEvent(eventType, modifierFlags, characters,
charsIgnoringMods, /*charsIgnoringModifiersAndShift*/ null,
keyCode, needsKeyTyped, isRepeat);
}

View File

@@ -26,6 +26,7 @@
package sun.lwawt.macosx;
import sun.awt.SunToolkit;
import sun.awt.event.KeyEventProcessing;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformEventNotifier;
@@ -34,6 +35,7 @@ import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Locale;
/**
@@ -167,10 +169,26 @@ final class CPlatformResponder {
-roundDelta, -delta, null);
}
private static final String [] cyrillicKeyboardLayouts = new String [] {
"com.apple.keylayout.Russian",
"com.apple.keylayout.RussianWin",
"com.apple.keylayout.Russian-Phonetic",
"com.apple.keylayout.Byelorussian",
"com.apple.keylayout.Ukrainian",
"com.apple.keylayout.UkrainianWin",
"com.apple.keylayout.Bulgarian",
"com.apple.keylayout.Serbian"
};
private static boolean isCyrillicKeyboardLayout() {
return Arrays.stream(cyrillicKeyboardLayouts).anyMatch(l -> l.equals(LWCToolkit.getKeyboardLayoutId()));
}
/**
* Handles key events.
*/
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) :
@@ -182,6 +200,8 @@ final class CPlatformResponder {
boolean postsTyped = false;
boolean spaceKeyTyped = false;
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
char testChar = KeyEvent.CHAR_UNDEFINED;
boolean isDeadChar = (chars!= null && chars.length() == 0);
@@ -204,10 +224,19 @@ final class CPlatformResponder {
}
}
// 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};
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);
@@ -217,7 +246,8 @@ final class CPlatformResponder {
if(isDeadChar){
testChar = (char) out[2];
if(testChar == 0){
jkeyCode = out[0];
if(testChar == 0 && jkeyCode == KeyEvent.VK_UNDEFINED){
return;
}
}
@@ -249,7 +279,6 @@ final class CPlatformResponder {
postsTyped = false;
}
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
long when = System.currentTimeMillis();
if (jeventType == KeyEvent.KEY_PRESSED) {

View File

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

View File

@@ -130,6 +130,10 @@ public final class LWCToolkit extends LWToolkit {
private static native void initIDs();
private static native void initAppkit(ThreadGroup appKitThreadGroup, boolean headless);
private static native void switchKeyboardLayoutNative(String layoutName);
static native String getKeyboardLayoutNativeId();
private static CInputMethodDescriptor sInputMethodDescriptor;
static {
@@ -1039,6 +1043,17 @@ public final class LWCToolkit extends LWToolkit {
!path.endsWith(".");
}
public static void switchKeyboardLayout (String layoutName) {
if (layoutName == null || layoutName.isEmpty()) {
throw new RuntimeException("A valid layout ID is expected. Found: " + layoutName);
}
switchKeyboardLayoutNative(layoutName);
}
public static String getKeyboardLayoutId () {
return getKeyboardLayoutNativeId();
}
@Override
protected PlatformWindow getPlatformWindowUnderMouse() {
return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse();

View File

@@ -38,6 +38,8 @@ final class NSEvent {
static final int SCROLL_PHASE_CONTINUED = 3;
static final int SCROLL_PHASE_MOMENTUM_BEGAN = 4;
static final int SCROLL_PHASE_ENDED = 5;
private boolean hasDeadKey;
private int deadKeyCode;
private int type;
private int modifierFlags;
@@ -57,14 +59,32 @@ final class NSEvent {
private short keyCode;
private String characters;
private String charactersIgnoringModifiers;
private String oldCharacters;
private String oldCharactersIgnoringModifiers;
private String charactersIgnoringModifiersAndShift;
public boolean isHasDeadKey() {
return hasDeadKey;
}
public int getDeadKeyCode() {
return deadKeyCode;
}
// Called from native
NSEvent(int type, int modifierFlags, short keyCode, String characters, String charactersIgnoringModifiers) {
NSEvent(int type, int modifierFlags, short keyCode, String characters, String charactersIgnoringModifiers,
String charactersIgnoringModifiersAndShift, boolean hasDeadKey, int deadKeyCode,
String oldCharacters, String oldCharactersIgnoringModifiers) {
this.type = type;
this.modifierFlags = modifierFlags;
this.keyCode = keyCode;
this.characters = characters;
this.charactersIgnoringModifiers = charactersIgnoringModifiers;
this.charactersIgnoringModifiersAndShift = charactersIgnoringModifiersAndShift;
this.hasDeadKey = hasDeadKey;
this.deadKeyCode = deadKeyCode;
this.oldCharacters = oldCharacters;
this.oldCharactersIgnoringModifiers = oldCharactersIgnoringModifiers;
}
// Called from native
@@ -136,16 +156,26 @@ final class NSEvent {
return charactersIgnoringModifiers;
}
String getCharactersIgnoringModifiersAndShift() {return charactersIgnoringModifiersAndShift;}
String getCharacters() {
return characters;
}
String getOldCharactersIgnoringModifiers() {
return oldCharactersIgnoringModifiers;
}
String getOldCharacters() {
return oldCharacters;
}
@Override
public String toString() {
return "NSEvent[" + getType() + " ," + getModifierFlags() + " ,"
+ getClickCount() + " ," + getButtonNumber() + " ," + getX() + " ,"
+ getY() + " ," + getAbsX() + " ," + getAbsY()+ " ," + getKeyCode() + " ,"
+ getCharacters() + " ," + getCharactersIgnoringModifiers() + "]";
+ getCharacters() + " ," + getCharactersIgnoringModifiers() + " ," + getCharactersIgnoringModifiersAndShift() + "]";
}
/*

View File

@@ -26,6 +26,12 @@
#ifndef __AWTEVENT_H
#define __AWTEVENT_H
#import "LWCToolkit.h"
@interface NSEvent (NSEventExtension)
- (NSString *)charactersIgnoringModifiersAndShift;
@end
jlong UTC(NSEvent *event);
void DeliverJavaKeyEvent(JNIEnv *env, NSEvent *event, jobject peer);
void DeliverJavaMouseEvent(JNIEnv *env, NSEvent *event, jobject peer);

View File

@@ -213,6 +213,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},
@@ -421,13 +422,74 @@ static unichar NsGetDeadKeyChar(unsigned short keyCode)
return 0;
}
static const int UNICODE_OFFSET = 0x01000000;
static BOOL isLatinUnicode(unichar ch) {
// Latin-1 Supplement 0x0080 - 0x00FF
// Latin Extended-A 0x0100 - 0x017F
// Latin Extended-B 0x0180 - 0x024F
return 0x0080 <= ch && ch <= 0x024F;
}
static NSDictionary* getUnicharToVkCodeDictionary() {
static NSDictionary* unicharToVkCodeDictionary = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
unicharToVkCodeDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_BACK_QUOTE], @"`",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_1], @"1",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_2], @"2",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_3], @"3",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_4], @"4",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_5], @"5",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_6], @"6",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_7], @"7",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_8], @"8",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_9], @"9",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_0], @"0",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_EQUALS], @"=",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_MINUS], @"-",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_CLOSE_BRACKET], @"]",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_OPEN_BRACKET], @"[",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_QUOTE], @"\'",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_SEMICOLON], @";",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_COLON], @":",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_BACK_SLASH], @"\\",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_COMMA], @",",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_SLASH], @"/",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_PERIOD], @".",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_ASTERISK], @"*",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_PLUS], @"+",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_COMMA], @",",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_NUMBER_SIGN], @"#",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_DOLLAR], @"$",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_CIRCUMFLEX], @"^",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS], @"(",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS], @")",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_UNDERSCORE], @"_",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_AMPERSAND], @"&",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_QUOTEDBL], @"\"",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_EXCLAMATION_MARK], @"!",
[NSNumber numberWithInt:java_awt_event_KeyEvent_VK_LESS], @"<",
nil
];
// This is ok to retain a singleton object
[unicharToVkCodeDictionary retain];
});
return unicharToVkCodeDictionary;
}
/*
* This is the function that uses the table above to take incoming
* NSEvent keyCodes and translate to the Java virtual key code.
*/
static void
NsCharToJavaVirtualKeyCode(unichar ch, BOOL isDeadChar,
NSUInteger flags, unsigned short key,
NSUInteger flags, unsigned short key, BOOL useNationalLayouts,
jint *keyCode, jint *keyLocation, BOOL *postsTyped,
unichar *deadChar)
{
@@ -494,6 +556,41 @@ return;
}
}
if (useNationalLayouts) {
if (keyTable[key].javaKeyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) {
*postsTyped = keyTable[key].postsTyped;
*keyCode = keyTable[key].javaKeyCode;
*keyLocation = keyTable[key].javaKeyLocation;
return;
}
NSDictionary* unicharToVkCodeDictionary = getUnicharToVkCodeDictionary();
if ([[NSCharacterSet punctuationCharacterSet] characterIsMember:ch] ||
[[NSCharacterSet symbolCharacterSet] characterIsMember:ch])
{
// punctuationCharacterSet and symbolCharacterSet are too big
// to store them all in UnicharToVkCodeDictionary
int tmpKeyCode = [[unicharToVkCodeDictionary objectForKey:[NSString stringWithFormat:@"%C",ch]] intValue];
if (tmpKeyCode != 0) {
*keyCode = tmpKeyCode;
// we cannot find key location from a char, so let's use key code
*postsTyped = YES;
*keyLocation = keyTable[key].javaKeyLocation;
return;
}
}
// Latin-1 suplement & Latin Extended A & B
if (isLatinUnicode(ch)) {
*keyCode = ((int) ch) + UNICODE_OFFSET;
// we cannot find key location from a char, so let's use key code
*postsTyped = YES;
*keyLocation = keyTable[key].javaKeyLocation;
return;
}
}
if (key < size) {
*postsTyped = keyTable[key].postsTyped;
*keyCode = keyTable[key].javaKeyCode;
@@ -688,11 +785,12 @@ JNI_COCOA_ENTER(env);
jint *data = (*env)->GetIntArrayElements(env, inData, &copy);
CHECK_NULL_RETURN(data, postsTyped);
// in = [testChar, testDeadChar, modifierFlags, keyCode]
// in = [testChar, testDeadChar, modifierFlags, keyCode, useNationalLayouts]
jchar testChar = (jchar)data[0];
BOOL isDeadChar = (data[1] != 0);
jint modifierFlags = data[2];
jshort keyCode = (jshort)data[3];
BOOL useNationalLayouts = (data[4] == 1);
jint jkeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
jint jkeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
@@ -700,7 +798,7 @@ JNI_COCOA_ENTER(env);
NsCharToJavaVirtualKeyCode((unichar)testChar, isDeadChar,
(NSUInteger)modifierFlags, (unsigned short)keyCode,
&jkeyCode, &jkeyLocation, &postsTyped,
useNationalLayouts, &jkeyCode, &jkeyLocation, &postsTyped,
(unichar *) &testDeadChar);
// out = [jkeyCode, jkeyLocation, deadChar];

View File

@@ -345,7 +345,7 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
NSString *eventChars = [event charactersIgnoringModifiers];
if ([eventChars length] == 1) {
unichar ch = [eventChars characterAtIndex:0];
if (ch == '=' || ch == '.') {
if (ch == '=' || ch == '.' || ch == /*small cyrillic u*/ 0x044E) {
[[NSApp mainMenu] performKeyEquivalent: event];
return YES;
}
@@ -477,22 +477,82 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
[AWTToolkit eventCountPlusPlus];
JNIEnv *env = [ThreadUtilities getJNIEnv];
TISInputSourceRef sourceRef = TISCopyCurrentKeyboardLayoutInputSource();
CFDataRef keyLayoutPtr = (CFDataRef)TISGetInputSourceProperty(
sourceRef, kTISPropertyUnicodeKeyLayoutData);
CFRelease( sourceRef);
const UCKeyboardLayout *keyboardLayout = (UCKeyboardLayout*)CFDataGetBytePtr(keyLayoutPtr);
UInt32 isDeadKeyPressed = 0;
UInt32 lengthOfBuffer = 8;
UniChar stringWithChars[lengthOfBuffer];
UniCharCount actualLength = 0;
OSStatus status = UCKeyTranslate(
keyboardLayout,
[event keyCode],
kUCKeyActionDown,
0,
LMGetKbdType(),
0,
&isDeadKeyPressed,
lengthOfBuffer,
&actualLength,
stringWithChars);
NSString* charactersIgnoringModifiersAndShiftAsNsString = [NSString stringWithCharacters:stringWithChars length:actualLength];
jstring characters = NULL;
jstring charactersIgnoringModifiers = NULL;
jstring charactersIgnoringModifiersAndShift = NULL;
if ([event type] != NSEventTypeFlagsChanged) {
characters = NSStringToJavaString(env, [event characters]);
charactersIgnoringModifiers = NSStringToJavaString(env, [event charactersIgnoringModifiers]);
charactersIgnoringModifiersAndShift = NSStringToJavaString(env, charactersIgnoringModifiersAndShiftAsNsString);
}
jint javaDeadKeyCode = 0;
if (status == noErr && isDeadKeyPressed != 0) {
status = UCKeyTranslate(
keyboardLayout,
kVK_Space,
kUCKeyActionDown,
0,
LMGetKbdType(),
0,
&isDeadKeyPressed,
lengthOfBuffer,
&actualLength,
stringWithChars);
charactersIgnoringModifiersAndShift = NSStringToJavaString(env, [NSString stringWithCharacters:stringWithChars length:actualLength]);
}
jstring oldCharacters = NULL;
jstring oldCharactersIgnoringModifiers = NULL;
if ([event type] != NSFlagsChanged) {
oldCharacters = NSStringToJavaString(env, [event characters]);
oldCharactersIgnoringModifiers = NSStringToJavaString(env, [event charactersIgnoringModifiers]);
}
DECLARE_CLASS(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
DECLARE_METHOD(jctor_NSEvent, jc_NSEvent, "<init>", "(IISLjava/lang/String;Ljava/lang/String;)V");
DECLARE_METHOD(jctor_NSEvent, jc_NSEvent, "<init>", "(IISLjava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/String;Ljava/lang/String;)V");
jobject jEvent = (*env)->NewObject(env, jc_NSEvent, jctor_NSEvent,
[event type],
[event modifierFlags],
[event keyCode],
characters,
charactersIgnoringModifiers);
charactersIgnoringModifiers,
charactersIgnoringModifiersAndShift,
isDeadKeyPressed,
javaDeadKeyCode,
oldCharacters,
oldCharactersIgnoringModifiers);
CHECK_NULL(jEvent);
DECLARE_CLASS(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");

View File

@@ -29,6 +29,7 @@
#import <assert.h>
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
//#define DEBUG 1

View File

@@ -833,6 +833,46 @@ Java_sun_lwawt_macosx_LWCToolkit_isEmbedded
return isEmbedded ? JNI_TRUE : JNI_FALSE;
}
/*
* Class: sun_lwawt_macosx_LWCToolkit
* Method: getKeyboardLayoutNativeId
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
JNICALL Java_sun_lwawt_macosx_LWCToolkit_getKeyboardLayoutNativeId(JNIEnv *env, jclass cls)
{
__block NSString * layoutId = NULL;
JNI_COCOA_ENTER(env);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
TISInputSourceRef source = TISCopyCurrentKeyboardInputSource();
layoutId = TISGetInputSourceProperty(source, kTISPropertyInputSourceID);
}];
JNI_COCOA_EXIT(env);
return NSStringToJavaString(env, layoutId);
}
/*
* Class: sun_lwawt_macosx_LWCToolkit
* Method: switchKeyboardLayoutNative
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL
JNICALL Java_sun_lwawt_macosx_LWCToolkit_switchKeyboardLayoutNative(JNIEnv *env, jclass cls, jstring jLayoutId)
{
JNI_COCOA_ENTER(env);
__block NSString* layoutId = [JavaStringToNSString(env, jLayoutId) retain];
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
NSArray* sources = CFBridgingRelease(TISCreateInputSourceList((__bridge CFDictionaryRef)@{ (__bridge NSString*)kTISPropertyInputSourceID : layoutId }, FALSE));
TISInputSourceRef source = (__bridge TISInputSourceRef)sources[0];
OSStatus status = TISSelectInputSource(source);
if (status != noErr) {
NSLog(@"error during keyboard layout switch");
}
[layoutId release];
}];
JNI_COCOA_EXIT(env);
}
/*
* Class: sun_awt_PlatformGraphicsInfo
* Method: isInAquaSession

View File

@@ -0,0 +1,22 @@
package sun.awt.event;
import sun.font.FontUtilities;
import java.lang.annotation.Native;
public class KeyEventProcessing {
// This property is used to emulate old behavior
// when user should turn off national keycodes processing
// "com.jetbrains.use.old.keyevent.processing"
public final static String useNationalLayoutsOption = "com.sun.awt.use.national.layouts";
@Native
public final static boolean useNationalLayouts = "true".equals(
Util.getProperty(useNationalLayoutsOption,
FontUtilities.isMacOSX ? "true" : "false"));
// Used on windows to emulate latin OEM keys on cyrillic keyboards
public final static String useLatinNonAlphaNumKeycodesOption = "com.sun.awt.useLatinNonAlphaNumKeycodes";
@Native
public final static boolean useLatinNonAlphaNumKeycodes = "true".equals(
Util.getProperty(useLatinNonAlphaNumKeycodesOption, "false"));
}

View File

@@ -0,0 +1,12 @@
package sun.awt.event;
import java.security.PrivilegedAction;
@SuppressWarnings("removal")
class Util {
public static String getProperty(String option, String dflt) {
return java.security.AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty(option, dflt)
);
}
}