mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-09 19:09:38 +01:00
JBR-5953 If hieroglyph typing isn't finalised, focusing another component inserts the composed text there
This commit is contained in:
@@ -62,6 +62,7 @@ public class AquaCaret extends DefaultCaret
|
|||||||
public void deinstall(final JTextComponent c) {
|
public void deinstall(final JTextComponent c) {
|
||||||
c.removePropertyChangeListener(this);
|
c.removePropertyChangeListener(this);
|
||||||
super.deinstall(c);
|
super.deinstall(c);
|
||||||
|
mFocused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ public class CInputMethod extends InputMethodAdapter {
|
|||||||
private volatile Component fAwtFocussedComponent;
|
private volatile Component fAwtFocussedComponent;
|
||||||
private LWComponentPeer<?, ?> fAwtFocussedComponentPeer;
|
private LWComponentPeer<?, ?> fAwtFocussedComponentPeer;
|
||||||
private boolean isActive;
|
private boolean isActive;
|
||||||
private boolean isTemporarilyDeactivated;
|
|
||||||
|
|
||||||
private static Map<TextAttribute, Integer>[] sHighlightStyles;
|
private static Map<TextAttribute, Integer>[] sHighlightStyles;
|
||||||
|
|
||||||
@@ -236,12 +235,10 @@ public class CInputMethod extends InputMethodAdapter {
|
|||||||
*/
|
*/
|
||||||
public void activate() {
|
public void activate() {
|
||||||
isActive = true;
|
isActive = true;
|
||||||
isTemporarilyDeactivated = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deactivate(boolean isTemporary) {
|
public void deactivate(boolean isTemporary) {
|
||||||
isActive = false;
|
isActive = false;
|
||||||
isTemporarilyDeactivated = isTemporary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -269,7 +266,7 @@ public class CInputMethod extends InputMethodAdapter {
|
|||||||
public void removeNotify() {
|
public void removeNotify() {
|
||||||
if (fAwtFocussedComponentPeer != null) {
|
if (fAwtFocussedComponentPeer != null) {
|
||||||
long modelPtr = getNativeViewPtr(fAwtFocussedComponentPeer);
|
long modelPtr = getNativeViewPtr(fAwtFocussedComponentPeer);
|
||||||
nativeEndComposition(modelPtr);
|
nativeEndComposition(modelPtr, fAwtFocussedComponent);
|
||||||
nativeNotifyPeer(modelPtr, null);
|
nativeNotifyPeer(modelPtr, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,10 +281,10 @@ public class CInputMethod extends InputMethodAdapter {
|
|||||||
* to talk to when responding to key events.
|
* to talk to when responding to key events.
|
||||||
*/
|
*/
|
||||||
protected void setAWTFocussedComponent(Component component) {
|
protected void setAWTFocussedComponent(Component component) {
|
||||||
if ((isTemporarilyDeactivated && component == null) || component == fAwtFocussedComponent) {
|
if (component == null || component == fAwtFocussedComponent) {
|
||||||
// Sometimes input happens for the natively unfocused window
|
// Sometimes input happens for the natively unfocused window
|
||||||
// (e.g. in case of system emoji picker),
|
// (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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +352,7 @@ public class CInputMethod extends InputMethodAdapter {
|
|||||||
*/
|
*/
|
||||||
public void endComposition() {
|
public void endComposition() {
|
||||||
if (fAwtFocussedComponentPeer != null)
|
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?
|
* Frequent callbacks from NSTextInput. I think we're supposed to commit it here?
|
||||||
*/
|
*/
|
||||||
private synchronized void unmarkText() {
|
private synchronized void unmarkText(Component component) {
|
||||||
if (fCurrentText == null || fAwtFocussedComponent == null) return;
|
if (component == null) {
|
||||||
|
component = fAwtFocussedComponent;
|
||||||
|
}
|
||||||
|
if (fCurrentText == null || component == null) return;
|
||||||
|
|
||||||
TextHitInfo theCaret = TextHitInfo.afterOffset(fCurrentTextLength);
|
TextHitInfo theCaret = TextHitInfo.afterOffset(fCurrentTextLength);
|
||||||
TextHitInfo visiblePosition = theCaret;
|
TextHitInfo visiblePosition = theCaret;
|
||||||
InputMethodEvent event = new InputMethodEvent(fAwtFocussedComponent,
|
InputMethodEvent event = new InputMethodEvent(component,
|
||||||
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
|
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
|
||||||
fCurrentText.getIterator(),
|
fCurrentText.getIterator(),
|
||||||
fCurrentTextLength,
|
fCurrentTextLength,
|
||||||
theCaret,
|
theCaret,
|
||||||
visiblePosition);
|
visiblePosition);
|
||||||
LWCToolkit.postEvent(LWCToolkit.targetToAppContext(fAwtFocussedComponent), event);
|
LWCToolkit.postEvent(LWCToolkit.targetToAppContext(component), event);
|
||||||
fCurrentText = null;
|
fCurrentText = null;
|
||||||
fCurrentTextAsString = null;
|
fCurrentTextAsString = null;
|
||||||
fCurrentTextLength = 0;
|
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)
|
// Note that if nativePeer isn't something that normally accepts keystrokes (i.e., a CPanel)
|
||||||
// these calls will be ignored.
|
// these calls will be ignored.
|
||||||
private native void nativeNotifyPeer(long nativePeer, CInputMethod imInstance);
|
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);
|
private native void nativeHandleEvent(LWComponentPeer<?, ?> peer, AWTEvent event);
|
||||||
|
|
||||||
// Returns the locale of the active input method.
|
// Returns the locale of the active input method.
|
||||||
|
|||||||
@@ -67,6 +67,6 @@
|
|||||||
|
|
||||||
// Input method-related events
|
// Input method-related events
|
||||||
- (void)setInputMethod:(jobject)inputMethod;
|
- (void)setInputMethod:(jobject)inputMethod;
|
||||||
- (void)abandonInput;
|
- (void)abandonInput:(jobject) component;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ static void debugPrintNSEvent(NSEvent* event, const char* comment) {
|
|||||||
case kVK_End:
|
case kVK_End:
|
||||||
// Abandon input to reset IM and unblock input after
|
// Abandon input to reset IM and unblock input after
|
||||||
// canceling input accented symbols
|
// canceling input accented symbols
|
||||||
[self abandonInput];
|
[self abandonInput:nil];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1157,7 +1157,7 @@ static jclass jc_CInputMethod = NULL;
|
|||||||
// Abandon input to reset IM and unblock input after entering accented
|
// Abandon input to reset IM and unblock input after entering accented
|
||||||
// symbols
|
// symbols
|
||||||
|
|
||||||
[self abandonInput];
|
[self abandonInput:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)keyboardInputSourceChanged:(NSNotification *)notification
|
+ (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
|
#ifdef IM_DEBUG
|
||||||
fprintf(stderr, "AWTView InputMethod Selector Called : [unmarkText]\n");
|
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.
|
// unmarkText cancels any input in progress and commits it to the text field.
|
||||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||||
GET_CIM_CLASS();
|
GET_CIM_CLASS();
|
||||||
DECLARE_METHOD(jm_unmarkText, jc_CInputMethod, "unmarkText", "()V");
|
DECLARE_METHOD(jm_unmarkText, jc_CInputMethod, "unmarkText", "(Ljava/awt/Component;)V");
|
||||||
(*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText);
|
(*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText, component);
|
||||||
CHECK_EXCEPTION();
|
CHECK_EXCEPTION();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1526,14 +1530,14 @@ static jclass jc_CInputMethod = NULL;
|
|||||||
object:nil];
|
object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)abandonInput
|
- (void)abandonInput:(jobject) component
|
||||||
{
|
{
|
||||||
#ifdef IM_DEBUG
|
#ifdef IM_DEBUG
|
||||||
fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n");
|
fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n");
|
||||||
#endif // IM_DEBUG
|
#endif // IM_DEBUG
|
||||||
|
|
||||||
[ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) on:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES];
|
[ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) on:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES];
|
||||||
[self unmarkText];
|
[self unmarkText:component];
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************** END NSTextInputClient Protocol ********************************/
|
/******************************** END NSTextInputClient Protocol ********************************/
|
||||||
|
|||||||
@@ -118,13 +118,6 @@ static void initializeInputMethodController() {
|
|||||||
[view setInputMethod:inputMethod]; // inputMethod is a GlobalRef or null to disable.
|
[view setInputMethod:inputMethod]; // inputMethod is a GlobalRef or null to disable.
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void) _nativeEndComposition:(AWTView *)view {
|
|
||||||
if (view == nil) return;
|
|
||||||
|
|
||||||
[view abandonInput];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -186,16 +179,21 @@ JNI_COCOA_EXIT(env);
|
|||||||
/*
|
/*
|
||||||
* Class: sun_lwawt_macosx_CInputMethod
|
* Class: sun_lwawt_macosx_CInputMethod
|
||||||
* Method: nativeEndComposition
|
* Method: nativeEndComposition
|
||||||
* Signature: (J)V
|
* Signature: (JLjava/awt/Component;)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeEndComposition
|
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);
|
JNI_COCOA_ENTER(env);
|
||||||
AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
|
AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
|
||||||
|
if (!view) return;
|
||||||
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
|
jobject componentRef = (*env)->NewGlobalRef(env, component);
|
||||||
[CInputMethod _nativeEndComposition:view];
|
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
|
||||||
|
[view abandonInput:componentRef];
|
||||||
|
if (componentRef) {
|
||||||
|
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||||
|
(*env)->DeleteGlobalRef(env, componentRef);
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
JNI_COCOA_EXIT(env);
|
JNI_COCOA_EXIT(env);
|
||||||
|
|||||||
Reference in New Issue
Block a user