@@ -247,7 +247,8 @@ - (id)initWithFrame:(NSRect)frame withJview:(jobject)jView withJproperties:(jobj
247247 [self addTrackingArea: self ->_trackingArea];
248248 self->nsAttrBuffer = [[NSAttributedString alloc ] initWithString: @" " ];
249249 self->imEnabled = NO ;
250- self->shouldProcessKeyEvent = YES ;
250+ self->handlingKeyEvent = NO ;
251+ self->didCommitText = NO ;
251252 }
252253 return self;
253254}
@@ -380,12 +381,9 @@ - (void)mouseExited:(NSEvent *)theEvent
380381- (void )mouseDown : (NSEvent *)theEvent
381382{
382383 MOUSELOG (" mouseDown" );
383- // First check if system Input Method Engine needs to handle this event
384- NSInputManager *inputManager = [NSInputManager currentInputManager ];
385- if ([inputManager wantsToHandleMouseEvents ]) {
386- if ([inputManager handleMouseEvent: theEvent]) {
387- return ;
388- }
384+ // First check if system Input Context needs to handle this event
385+ if ([self .inputContext handleEvent: theEvent]) {
386+ return ;
389387 }
390388 [self ->_delegate sendJavaMouseEvent: theEvent];
391389}
@@ -476,10 +474,10 @@ - (BOOL)performKeyEquivalent:(NSEvent *)theEvent
476474 // create extra KeyEvents.
477475 //
478476 NSString *chars = [theEvent charactersIgnoringModifiers ];
479- if ([theEvent type ] == NSKeyDown && [chars length ] > 0 )
477+ if ([theEvent type ] == NSEventTypeKeyDown && [chars length ] > 0 )
480478 {
481479 unichar uch = [chars characterAtIndex: 0 ];
482- if ([theEvent modifierFlags ] & NSCommandKeyMask &&
480+ if ([theEvent modifierFlags ] & NSEventModifierFlagCommand &&
483481 (uch == com_sun_glass_events_KeyEvent_VK_PERIOD ||
484482 uch == com_sun_glass_events_KeyEvent_VK_EQUALS))
485483 {
@@ -513,11 +511,25 @@ - (void)keyDown:(NSEvent *)theEvent
513511{
514512 KEYLOG (" keyDown" );
515513
516- if (![[self inputContext ] handleEvent: theEvent] || shouldProcessKeyEvent) {
514+ handlingKeyEvent = YES ;
515+ didCommitText = NO ;
516+ BOOL hadMarkedText = (nsAttrBuffer.length > 0 );
517+ BOOL inputContextHandledEvent = (imEnabled && [self .inputContext handleEvent: theEvent]);
518+ handlingKeyEvent = NO ;
519+
520+ if (didCommitText) {
521+ // Exit composition mode
522+ didCommitText = NO ;
523+ nsAttrBuffer = [nsAttrBuffer initWithString: @" " ];
524+ } else if (hadMarkedText) {
525+ // Either we still have marked text or the keystroke removed it
526+ // (ESC can do that). In either case we don't want to generate a key
527+ // event.
528+ ;
529+ } else if (!inputContextHandledEvent || (nsAttrBuffer.length == 0 )) {
517530 [GlassApplication registerKeyEvent: theEvent];
518531 [self ->_delegate sendJavaKeyEvent: theEvent isDown: YES ];
519532 }
520- shouldProcessKeyEvent = YES ;
521533}
522534
523535- (void )keyUp : (NSEvent *)theEvent
@@ -715,8 +727,15 @@ - (GlassViewDelegate*)delegate
715727- (void )setInputMethodEnabled : (BOOL )enabled
716728{
717729 IMLOG (" setInputMethodEnabled called with arg is %s " , (enabled ? " YES" : " NO" ) );
718- [self unmarkText ];
719- self->imEnabled = enabled;
730+ if (enabled != imEnabled) {
731+ // If enabled is false this has nowhere to go. If enabled is true this
732+ // wasn't intended for the newly focused node.
733+ if (nsAttrBuffer.length ) {
734+ nsAttrBuffer = [nsAttrBuffer initWithString: @" " ];
735+ }
736+ [self .inputContext discardMarkedText ];
737+ imEnabled = enabled;
738+ }
720739}
721740
722741- (void )finishInputMethodComposition
@@ -739,27 +758,34 @@ - (void)commitString:(NSString*)aString
739758- (void )doCommandBySelector : (SEL )aSelector
740759{
741760 IMLOG (" doCommandBySelector called " );
742- // In case the IM was stopped with a mouse and the next typed key
743- // is a special command key (backspace, tab, etc.)
744- self-> shouldProcessKeyEvent = YES ;
761+ // According to Apple an NSResponder will send this up the responder chain
762+ // but a text input client should not. So we ignore this which avoids an
763+ // annoying beep.
745764}
746765
747766- (void ) insertText : (id )aString replacementRange : (NSRange )replacementRange
748767{
749768 IMLOG (" insertText called with string: %s " , [aString UTF8String ]);
750769 if ([self ->nsAttrBuffer length ] > 0 || [aString length ] > 1 ) {
770+ self->didCommitText = YES ;
751771 [self commitString: aString];
752- self->shouldProcessKeyEvent = NO ;
753- } else {
754- self->shouldProcessKeyEvent = YES ;
755772 }
756- self->nsAttrBuffer = [self ->nsAttrBuffer initWithString: @" " ];
773+
774+ // If a user tries to enter an invalid character using a dead key
775+ // combination (like, say, a q with a grave accent) insertText will be
776+ // called twice on the last keystroke, first with the accent and then
777+ // with the letter. We want both inserts to be handled as committed text
778+ // so we defer exiting composition mode until the keystroke is processed.
779+ // We only defer on keystrokes because sometimes insertText is called
780+ // when a mouse event dismisses the IM window.
781+ if (!self->handlingKeyEvent ) {
782+ self->nsAttrBuffer = [self ->nsAttrBuffer initWithString: @" " ];
783+ }
757784}
758785
759786- (void ) setMarkedText : (id )aString selectedRange : (NSRange )selectionRange replacementRange : (NSRange )replacementRange
760787{
761788 if (!self->imEnabled ) {
762- self->shouldProcessKeyEvent = YES ;
763789 return ;
764790 }
765791 BOOL isAttributedString = [aString isKindOfClass: [NSAttributedString class ]];
@@ -769,7 +795,6 @@ - (void) setMarkedText:(id)aString selectedRange:(NSRange)selectionRange replace
769795 [self ->_delegate notifyInputMethod: incomingString attr: 1 length: 0 cursor: (int )[incomingString length ] selectedRange: selectionRange ];
770796 self->nsAttrBuffer = (attrString == nil ? [self ->nsAttrBuffer initWithString: incomingString]
771797 : [self ->nsAttrBuffer initWithAttributedString: attrString]);
772- self->shouldProcessKeyEvent = NO ;
773798}
774799
775800- (void ) unmarkText
@@ -779,7 +804,6 @@ - (void) unmarkText
779804 [self commitString: nsAttrBuffer.string];
780805 nsAttrBuffer = [nsAttrBuffer initWithString: @" " ];
781806 }
782- self->shouldProcessKeyEvent = YES ;
783807}
784808
785809- (BOOL ) hasMarkedText
0 commit comments