mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
macOS national keyboard support
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -132,6 +132,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 {
|
||||
@@ -1069,6 +1073,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();
|
||||
|
||||
@@ -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() + "]";
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, ©);
|
||||
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];
|
||||
|
||||
@@ -342,7 +342,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;
|
||||
}
|
||||
@@ -474,22 +474,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");
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#import <assert.h>
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
12
src/java.desktop/share/classes/sun/awt/event/Util.java
Normal file
12
src/java.desktop/share/classes/sun/awt/event/Util.java
Normal 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)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user