Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(mac): turn on legacy mode for Java apps #3944

Merged
merged 1 commit into from
Nov 25, 2020

Conversation

mcdurdin
Copy link
Member

@mcdurdin mcdurdin commented Nov 24, 2020

Relates to #3935, #174, #458, #3243. (Not marking as fixed because it depends on external changes.)

This switches Java apps into legacy mode. However, Java itself will need patching to support Keyman, as it makes assumptions about input methods, including matching specific input methods by name, before enabling its complex text support.

I think we should consider backporting to 13.0 if the Java fix is accepted in reasonable time.

I have submitted a bug report but submitting a patch to the OpenJDK project looks tiresome and convoluted. It requires a change to a single file, AWTView.m, with the following diff (against JDK 16.0):

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;
     }

References

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8195675

JDK currently has a number of bugs in its IM handling; see:

It's not clear to me exactly which versions of Java currently experience these issues. The fix introduced by 8214578 made things worse, not better, and has an incredibly specific patch for a single IM and single character.

Testing

I have successfully tested this fix with a source build of ELAN (#3243).

export JAVA_HOME=~mcdurdin/Documents/Projects/jdk/build/macosx-x86_64-server-slowdebug/images/jdk
mvn test

I have not yet tested the other apps but it looks hopeful.

Relates to #3935.

This switches Java apps into legacy mode. However, Java itself will need
patching to support Keyman, as it makes assumptions about input methods,
including matching specific input methods by name, before enabling its
complex text support.

I am in process of submitting a bug report and may try and submit a
patch (although the process seems a little convoluted). It requires a
change to a single file, AWTView.m, with the following diff (against
JDK 16.0):

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;
     }
@mcdurdin mcdurdin added this to the P10S20 milestone Nov 24, 2020
@mcdurdin mcdurdin added the fix label Nov 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants