JBR-5953 If hieroglyph typing isn't finalised, focusing another component inserts the composed text there

This commit is contained in:
Dmitry Batrak
2023-08-18 13:27:47 +03:00
committed by jbrbot
parent ab008670de
commit c4992bc60b
5 changed files with 36 additions and 33 deletions

View File

@@ -62,6 +62,7 @@ public class AquaCaret extends DefaultCaret
public void deinstall(final JTextComponent c) {
c.removePropertyChangeListener(this);
super.deinstall(c);
mFocused = false;
}
@Override

View File

@@ -51,7 +51,6 @@ public class CInputMethod extends InputMethodAdapter {
private volatile Component fAwtFocussedComponent;
private LWComponentPeer<?, ?> fAwtFocussedComponentPeer;
private boolean isActive;
private boolean isTemporarilyDeactivated;
private static Map<TextAttribute, Integer>[] sHighlightStyles;
@@ -236,12 +235,10 @@ public class CInputMethod extends InputMethodAdapter {
*/
public void activate() {
isActive = true;
isTemporarilyDeactivated = false;
}
public void deactivate(boolean isTemporary) {
isActive = false;
isTemporarilyDeactivated = isTemporary;
}
/**
@@ -269,7 +266,7 @@ public class CInputMethod extends InputMethodAdapter {
public void removeNotify() {
if (fAwtFocussedComponentPeer != null) {
long modelPtr = getNativeViewPtr(fAwtFocussedComponentPeer);
nativeEndComposition(modelPtr);
nativeEndComposition(modelPtr, fAwtFocussedComponent);
nativeNotifyPeer(modelPtr, null);
}
@@ -284,10 +281,10 @@ public class CInputMethod extends InputMethodAdapter {
* to talk to when responding to key events.
*/
protected void setAWTFocussedComponent(Component component) {
if ((isTemporarilyDeactivated && component == null) || component == fAwtFocussedComponent) {
if (component == null || component == fAwtFocussedComponent) {
// Sometimes input happens for the natively unfocused window
// (e.g. in case of system emoji picker),
// so we don't reset last focused component on temporary focus lost.
// so we don't reset last focused component on focus lost.
return;
}
@@ -355,7 +352,7 @@ public class CInputMethod extends InputMethodAdapter {
*/
public void endComposition() {
if (fAwtFocussedComponentPeer != null)
nativeEndComposition(getNativeViewPtr(fAwtFocussedComponentPeer));
nativeEndComposition(getNativeViewPtr(fAwtFocussedComponentPeer), fAwtFocussedComponent);
}
/**
@@ -563,18 +560,21 @@ public class CInputMethod extends InputMethodAdapter {
/**
* Frequent callbacks from NSTextInput. I think we're supposed to commit it here?
*/
private synchronized void unmarkText() {
if (fCurrentText == null || fAwtFocussedComponent == null) return;
private synchronized void unmarkText(Component component) {
if (component == null) {
component = fAwtFocussedComponent;
}
if (fCurrentText == null || component == null) return;
TextHitInfo theCaret = TextHitInfo.afterOffset(fCurrentTextLength);
TextHitInfo visiblePosition = theCaret;
InputMethodEvent event = new InputMethodEvent(fAwtFocussedComponent,
InputMethodEvent event = new InputMethodEvent(component,
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
fCurrentText.getIterator(),
fCurrentTextLength,
theCaret,
visiblePosition);
LWCToolkit.postEvent(LWCToolkit.targetToAppContext(fAwtFocussedComponent), event);
LWCToolkit.postEvent(LWCToolkit.targetToAppContext(component), event);
fCurrentText = null;
fCurrentTextAsString = null;
fCurrentTextLength = 0;
@@ -807,7 +807,7 @@ public class CInputMethod extends InputMethodAdapter {
// Note that if nativePeer isn't something that normally accepts keystrokes (i.e., a CPanel)
// these calls will be ignored.
private native void nativeNotifyPeer(long nativePeer, CInputMethod imInstance);
private native void nativeEndComposition(long nativePeer);
private native void nativeEndComposition(long nativePeer, Component component);
private native void nativeHandleEvent(LWComponentPeer<?, ?> peer, AWTEvent event);
// Returns the locale of the active input method.

View File

@@ -67,6 +67,6 @@
// Input method-related events
- (void)setInputMethod:(jobject)inputMethod;
- (void)abandonInput;
- (void)abandonInput:(jobject) component;
@end

View File

@@ -393,7 +393,7 @@ static void debugPrintNSEvent(NSEvent* event, const char* comment) {
case kVK_End:
// Abandon input to reset IM and unblock input after
// canceling input accented symbols
[self abandonInput];
[self abandonInput:nil];
break;
}
}
@@ -1157,7 +1157,7 @@ static jclass jc_CInputMethod = NULL;
// Abandon input to reset IM and unblock input after entering accented
// symbols
[self abandonInput];
[self abandonInput:nil];
}
+ (void)keyboardInputSourceChanged:(NSNotification *)notification
@@ -1251,7 +1251,11 @@ static jclass jc_CInputMethod = NULL;
}
}
- (void) unmarkText
- (void) unmarkText {
[self unmarkText:nil];
}
- (void) unmarkText:(jobject) component
{
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [unmarkText]\n");
@@ -1264,8 +1268,8 @@ static jclass jc_CInputMethod = NULL;
// unmarkText cancels any input in progress and commits it to the text field.
JNIEnv *env = [ThreadUtilities getJNIEnv];
GET_CIM_CLASS();
DECLARE_METHOD(jm_unmarkText, jc_CInputMethod, "unmarkText", "()V");
(*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText);
DECLARE_METHOD(jm_unmarkText, jc_CInputMethod, "unmarkText", "(Ljava/awt/Component;)V");
(*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText, component);
CHECK_EXCEPTION();
}
@@ -1526,14 +1530,14 @@ static jclass jc_CInputMethod = NULL;
object:nil];
}
- (void)abandonInput
- (void)abandonInput:(jobject) component
{
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n");
#endif // IM_DEBUG
[ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) on:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES];
[self unmarkText];
[self unmarkText:component];
}
/******************************** END NSTextInputClient Protocol ********************************/

View File

@@ -118,13 +118,6 @@ static void initializeInputMethodController() {
[view setInputMethod:inputMethod]; // inputMethod is a GlobalRef or null to disable.
}
+ (void) _nativeEndComposition:(AWTView *)view {
if (view == nil) return;
[view abandonInput];
}
@end
/*
@@ -186,16 +179,21 @@ JNI_COCOA_EXIT(env);
/*
* Class: sun_lwawt_macosx_CInputMethod
* Method: nativeEndComposition
* Signature: (J)V
* Signature: (JLjava/awt/Component;)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeEndComposition
(JNIEnv *env, jobject this, jlong nativePeer)
(JNIEnv *env, jobject this, jlong nativePeer, jobject component)
{
JNI_COCOA_ENTER(env);
AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[CInputMethod _nativeEndComposition:view];
AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
if (!view) return;
jobject componentRef = (*env)->NewGlobalRef(env, component);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[view abandonInput:componentRef];
if (componentRef) {
JNIEnv *env = [ThreadUtilities getJNIEnv];
(*env)->DeleteGlobalRef(env, componentRef);
}
}];
JNI_COCOA_EXIT(env);