-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
16
-
x86_64
-
os_x
A DESCRIPTION OF THE PROBLEM :
There are a number of assumptions in AWTView.m around input methods and some special case tests to turn on complex input method support only for specific input methods and specific Unicode ranges. This means that Java does not generally work with Keyman (https://keyman.com/mac)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Install Keyman from link above, and a corresponding keyboard (e.g. https://keyman.com/keyboards/khmer_angkor)
2. Open any Java app, e.g. JEditor
3. Select the Keyman keyboard, and attempt to type into a text field. Type xEjmr.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
This should produce: "ខ្មែរ", which is the name of the Khmer language in Khmer.
ACTUAL -
Instead, "xEj្មែr" is produced. You'll note a mix of English and Khmer letters. This arises because single character outputs are not transformed, but multi character outputs are captured; backspaces are mixed. I chose this test case because it exercises the complex transform requirements fairly well and is a good exemplar.
CUSTOMER SUBMITTED WORKAROUND :
The following diff to AWTView.m adds support for Keyman 14.0. I did not feel confident to make more general changes, and noted that there is already specific support for other input methods.
I am currently adding a patch to Keyman to switch it to a "legacy" mode for Java apps. This fix will not work without the patch for Keyman, as AWTView's insertText method currently ignores the replacementRange parameter, which Keyman uses to transform existing text, and that is a much deeper problem to resolve. When Keyman is in legacy mode, it emits a series of backspaces to delete text to the left of the caret, before inserting the replacement text. This is required for complex text transforms such as reordering or recombining, for example as commonly is needed for phonetic input methods for Indic scripts.
---
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m
index 3e80b5a6cf3..2ae1f4f3f12 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m
@@ -263,6 +263,16 @@ - (void) keyDown: (NSEvent *)event {
fProcessingKeystroke = YES;
fKeyEventsNeeded = YES;
+ if([(NSString *)kbdLayout containsString:@"keyman"]) {
+ // Keyman handles all key events; none should be
+ // passed through as default before Keyman processes them
+ fKeyEventsNeeded = NO;
+ }
// Allow TSM to look at the event and potentially send back NSTextInputClient messages.
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
@@ -960,7 +989,9 @@ - (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
if ((utf16Length > 2) ||
((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:codePoint]) ||
- ((codePoint == 0x5c) && ([(NSString *)kbdLayout containsString:@"Kotoeri"]))) {
+ ((codePoint == 0x5c) && ([(NSString *)kbdLayout containsString:@"Kotoeri"])) ||
+ ([(NSString *)kbdLayout containsString:@"keyman"])
+ ) {
aStringIsComplex = YES;
}
FREQUENCY : always
There are a number of assumptions in AWTView.m around input methods and some special case tests to turn on complex input method support only for specific input methods and specific Unicode ranges. This means that Java does not generally work with Keyman (https://keyman.com/mac)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Install Keyman from link above, and a corresponding keyboard (e.g. https://keyman.com/keyboards/khmer_angkor)
2. Open any Java app, e.g. JEditor
3. Select the Keyman keyboard, and attempt to type into a text field. Type xEjmr.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
This should produce: "ខ្មែរ", which is the name of the Khmer language in Khmer.
ACTUAL -
Instead, "xEj្មែr" is produced. You'll note a mix of English and Khmer letters. This arises because single character outputs are not transformed, but multi character outputs are captured; backspaces are mixed. I chose this test case because it exercises the complex transform requirements fairly well and is a good exemplar.
CUSTOMER SUBMITTED WORKAROUND :
The following diff to AWTView.m adds support for Keyman 14.0. I did not feel confident to make more general changes, and noted that there is already specific support for other input methods.
I am currently adding a patch to Keyman to switch it to a "legacy" mode for Java apps. This fix will not work without the patch for Keyman, as AWTView's insertText method currently ignores the replacementRange parameter, which Keyman uses to transform existing text, and that is a much deeper problem to resolve. When Keyman is in legacy mode, it emits a series of backspaces to delete text to the left of the caret, before inserting the replacement text. This is required for complex text transforms such as reordering or recombining, for example as commonly is needed for phonetic input methods for Indic scripts.
---
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m
index 3e80b5a6cf3..2ae1f4f3f12 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m
@@ -263,6 +263,16 @@ - (void) keyDown: (NSEvent *)event {
fProcessingKeystroke = YES;
fKeyEventsNeeded = YES;
+ if([(NSString *)kbdLayout containsString:@"keyman"]) {
+ // Keyman handles all key events; none should be
+ // passed through as default before Keyman processes them
+ fKeyEventsNeeded = NO;
+ }
// Allow TSM to look at the event and potentially send back NSTextInputClient messages.
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
@@ -960,7 +989,9 @@ - (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
if ((utf16Length > 2) ||
((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:codePoint]) ||
- ((codePoint == 0x5c) && ([(NSString *)kbdLayout containsString:@"Kotoeri"]))) {
+ ((codePoint == 0x5c) && ([(NSString *)kbdLayout containsString:@"Kotoeri"])) ||
+ ([(NSString *)kbdLayout containsString:@"keyman"])
+ ) {
aStringIsComplex = YES;
}
FREQUENCY : always
- duplicates
-
JDK-8195675 Call to insertText with single character from custom Input Method ignored
- Resolved