aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Tsarev <nikita.tsarev@jetbrains.com>2024-05-07 20:41:59 +0200
committerNikita Tsarev <nikita.tsarev@jetbrains.com>2024-05-10 23:32:25 +0200
commit1c9e5f52e76d1ffafd44820b9594e279b9482802 (patch)
treeba2f0b854fac84502dcfff779642ff9c5545fce0
parentf7c47bf3cfac51b088c8d754f8f087ebb005f6dd (diff)
downloadJetBrainsRuntime-upstream-jbr17.tar.gz
JBR-7119: respect replacementRange in IME events on macOSjb17.0.11-b1294upstream-jbr17
-rw-r--r--src/java.desktop/macosx/classes/sun/lwawt/macosx/CInputMethod.java16
-rw-r--r--src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m41
-rw-r--r--test/jdk/jb/sun/awt/macos/InputMethodTest/InputMethodTest.java1
-rw-r--r--test/jdk/jb/sun/awt/macos/InputMethodTest/JapaneseReconvertTest.java53
4 files changed, 83 insertions, 28 deletions
diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CInputMethod.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CInputMethod.java
index 8be6485213b..934cdbe25aa 100644
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CInputMethod.java
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CInputMethod.java
@@ -515,25 +515,23 @@ public class CInputMethod extends InputMethodAdapter {
fCurrentText.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, theHighlight, begin, end);
}
- /* Called from JNI to select the previously typed glyph during press and hold */
- private void selectPreviousGlyph() {
- if (fIMContext == null || fAwtFocussedComponent == null) return; // ???
+ private void selectRange(int selectionStart, int length) {
+ if (fIMContext == null || fAwtFocussedComponent == null) {
+ return;
+ }
+ final int selectionEnd = selectionStart + length;
try {
LWCToolkit.invokeLater(new Runnable() {
public void run() {
- final int offset = fIMContext.getInsertPositionOffset();
- if (offset < 1) return; // ???
-
if (fAwtFocussedComponent instanceof JTextComponent) {
- ((JTextComponent) fAwtFocussedComponent).select(offset - 1, offset);
+ ((JTextComponent) fAwtFocussedComponent).select(selectionStart, selectionEnd);
return;
}
if (fAwtFocussedComponent instanceof TextComponent) {
- ((TextComponent) fAwtFocussedComponent).select(offset - 1, offset);
+ ((TextComponent) fAwtFocussedComponent).select(selectionStart, selectionEnd);
return;
}
- // TODO: Ideally we want to disable press-and-hold in this case
}
}, fAwtFocussedComponent);
} catch (Exception e) {
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 f3a7b17439a..bfe3c59b268 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m
@@ -60,7 +60,6 @@ static unichar lastCtrlCombo;
// Uncomment this line to see fprintfs of each InputMethod API being called on this View
//#define IM_DEBUG TRUE
-//#define EXTRA_DEBUG
//#define LOG_KEY_EVENTS
static BOOL shouldUsePressAndHold() {
@@ -95,7 +94,6 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, i
fEnablePressAndHold = shouldUsePressAndHold();
fInPressAndHold = NO;
- fPAHNeedsToSelect = NO;
mouseIsOver = NO;
[self resetTrackingArea];
@@ -365,6 +363,8 @@ static void debugPrintNSEvent(NSEvent* event, const char* comment) {
fprintf(stderr, "\tmodifierFlags: 0x%08x\n", (unsigned)[event modifierFlags]);
TISInputSourceRef is = TISCopyCurrentKeyboardLayoutInputSource();
fprintf(stderr, "\tTISCopyCurrentKeyboardLayoutInputSource: %s\n", is == nil ? "(nil)" : [(NSString*) TISGetInputSourceProperty(is, kTISPropertyInputSourceID) UTF8String]);
+ fprintf(stderr, "\twillBeHandledByComplexInputMethod: %s\n", [event willBeHandledByComplexInputMethod] ? "true" : "false");
+ CFRelease(is);
}
#endif
@@ -376,6 +376,7 @@ static void debugPrintNSEvent(NSEvent* event, const char* comment) {
fKeyEventsNeeded = YES;
NSString *eventCharacters = [event characters];
+ unsigned mods = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
if (([event modifierFlags] & NSControlKeyMask) && [eventCharacters length] == 1) {
lastCtrlCombo = [eventCharacters characterAtIndex:0];
@@ -395,7 +396,6 @@ static void debugPrintNSEvent(NSEvent* event, const char* comment) {
fProcessingKeystroke = NO;
if (!fInPressAndHold) {
fInPressAndHold = YES;
- fPAHNeedsToSelect = YES;
} else {
// Abandon input to reset IM and unblock input after canceling
// input accented symbols
@@ -1157,7 +1157,9 @@ static jclass jc_CInputMethod = NULL;
- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
{
#ifdef IM_DEBUG
- fprintf(stderr, "AWTView InputMethod Selector Called : [insertText]: %s\n", [aString UTF8String]);
+ fprintf(stderr,
+ "AWTView InputMethod Selector Called : [insertText]: %s, replacementRange: location=%lu, length=%lu\n",
+ [aString UTF8String], replacementRange.location, replacementRange.length);
#endif // IM_DEBUG
NSMutableString * useString = [self parseString:aString];
@@ -1194,12 +1196,12 @@ static jclass jc_CInputMethod = NULL;
JNIEnv *env = [ThreadUtilities getJNIEnv];
GET_CIM_CLASS();
- // We need to select the previous glyph so that it is overwritten.
- if (fPAHNeedsToSelect) {
- DECLARE_METHOD(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
- (*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph);
+
+ if (replacementRange.length > 0) {
+ DECLARE_METHOD(jm_selectRange, jc_CInputMethod, "selectRange", "(II)V");
+ (*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_selectRange, replacementRange.location,
+ replacementRange.length);
CHECK_EXCEPTION();
- fPAHNeedsToSelect = NO;
}
if (usingComplexIM) {
@@ -1216,7 +1218,6 @@ static jclass jc_CInputMethod = NULL;
actualCharacters = [useString copy];
fKeyEventsNeeded = YES;
}
- fPAHNeedsToSelect = NO;
// Abandon input to reset IM and unblock input after entering accented
// symbols
@@ -1255,7 +1256,9 @@ static jclass jc_CInputMethod = NULL;
NSAttributedString *attrString = (isAttributedString ? (NSAttributedString *)aString : nil);
NSString *incomingString = (isAttributedString ? [aString string] : aString);
#ifdef IM_DEBUG
- fprintf(stderr, "AWTView InputMethod Selector Called : [setMarkedText] \"%s\", loc=%lu, length=%lu\n", [incomingString UTF8String], (unsigned long)selectionRange.location, (unsigned long)selectionRange.length);
+ fprintf(stderr, "AWTView InputMethod Selector Called :[setMarkedText] \"%s\","
+ "selectionRange(%lu, %lu), replacementRange(%lu, %lu)\n", [incomingString UTF8String],
+ selectionRange.location, selectionRange.length, replacementRange.location, replacementRange.length);
#endif // IM_DEBUG
JNIEnv *env = [ThreadUtilities getJNIEnv];
GET_CIM_CLASS();
@@ -1263,6 +1266,14 @@ static jclass jc_CInputMethod = NULL;
DECLARE_METHOD(jm_addAttribute, jc_CInputMethod, "addAttribute", "(ZZII)V");
DECLARE_METHOD(jm_dispatchText, jc_CInputMethod, "dispatchText", "(IIZ)V");
+ if (replacementRange.length > 0) {
+ DECLARE_METHOD(jm_selectRange, jc_CInputMethod, "selectRange", "(II)V");
+ (*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_selectRange, replacementRange.location,
+ replacementRange.length);
+ CHECK_EXCEPTION();
+ }
+
+
// NSInputContext already did the analysis of the TSM event and created attributes indicating
// the underlining and color that should be done to the string. We need to look at the underline
// style and color to determine what kind of Java hilighting needs to be done.
@@ -1298,14 +1309,6 @@ static jclass jc_CInputMethod = NULL;
}
}
- DECLARE_METHOD(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
- // We need to select the previous glyph so that it is overwritten.
- if (fPAHNeedsToSelect) {
- (*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph);
- CHECK_EXCEPTION();
- fPAHNeedsToSelect = NO;
- }
-
(*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_dispatchText,
selectionRange.location, selectionRange.length, JNI_FALSE);
CHECK_EXCEPTION();
diff --git a/test/jdk/jb/sun/awt/macos/InputMethodTest/InputMethodTest.java b/test/jdk/jb/sun/awt/macos/InputMethodTest/InputMethodTest.java
index 146fb2e9005..cf5e22d9c9f 100644
--- a/test/jdk/jb/sun/awt/macos/InputMethodTest/InputMethodTest.java
+++ b/test/jdk/jb/sun/awt/macos/InputMethodTest/InputMethodTest.java
@@ -49,6 +49,7 @@ public class InputMethodTest {
CtrlShortcutNewWindowTest (new CtrlShortcutNewWindowTest()),
DeadKeysTest (new DeadKeysTest()),
FocusMoveUncommitedCharactersTest (new FocusMoveUncommitedCharactersTest()),
+ JapaneseReconvertTest(new JapaneseReconvertTest()),
KeyCodesTest (new KeyCodesTest()),
NextAppWinKeyTestDead (new NextAppWinKeyTest(true)),
NextAppWinKeyTestNormal (new NextAppWinKeyTest(false)),
diff --git a/test/jdk/jb/sun/awt/macos/InputMethodTest/JapaneseReconvertTest.java b/test/jdk/jb/sun/awt/macos/InputMethodTest/JapaneseReconvertTest.java
new file mode 100644
index 00000000000..24bb753a2ff
--- /dev/null
+++ b/test/jdk/jb/sun/awt/macos/InputMethodTest/JapaneseReconvertTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2024 JetBrains s.r.o.
+ * 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.
+ *
+ * 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 static java.awt.event.KeyEvent.*;
+
+/**
+ * @test
+ * @summary Regression test for JBR-7119 Converting to Hanja/Kanji on macOS doesn't replace the converted Hangul/Kana symbols
+ * @modules java.desktop/sun.lwawt.macosx
+ * @run main InputMethodTest JapaneseReconvertTest
+ * @requires (jdk.version.major >= 8 & os.family == "mac")
+ */
+
+public class JapaneseReconvertTest implements Runnable {
+ @Override
+ public void run() {
+ InputMethodTest.layout("com.apple.inputmethod.Kotoeri.RomajiTyping.Japanese");
+ InputMethodTest.type(VK_N, 0);
+ InputMethodTest.type(VK_I, 0);
+ InputMethodTest.type(VK_H, 0);
+ InputMethodTest.type(VK_O, 0);
+ InputMethodTest.type(VK_N, 0);
+ InputMethodTest.type(VK_G, 0);
+ InputMethodTest.type(VK_O, 0);
+ InputMethodTest.type(VK_ENTER, 0);
+ InputMethodTest.expectText("日本語");
+
+ InputMethodTest.type(VK_R, CTRL_DOWN_MASK | SHIFT_DOWN_MASK);
+ InputMethodTest.type(VK_ENTER, 0);
+ InputMethodTest.type(VK_ENTER, 0);
+ InputMethodTest.expectText("日本語");
+ }
+}