Skip to content

Commit d9263ab

Browse files
author
Martin Fox
committed
8301900: TextArea: Committing text with ENTER in an IME window inserts newline
8088172: Mac: On German keyboard, pressing <+><q> inserts two apostrophes instead of one 8089803: [Mac, TextArea] Japanese IME, caret moves to the next line when pressing Return to select a candidate. Reviewed-by: kcr, angorya
1 parent afa206b commit d9263ab

File tree

3 files changed

+50
-25
lines changed

3 files changed

+50
-25
lines changed

modules/javafx.graphics/src/main/java/com/sun/glass/ui/View.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ public static int getMultiClickMaxY() {
386386

387387
protected abstract void _enableInputMethodEvents(long ptr, boolean enable);
388388
protected void _finishInputMethodComposition(long ptr) {
389-
// Action needed only on Windows.
389+
// Action needed only on some platforms.
390390
}
391391

392392
/*

modules/javafx.graphics/src/main/native-glass/mac/GlassView3D.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050

5151
NSAttributedString *nsAttrBuffer;
5252
BOOL imEnabled;
53-
BOOL shouldProcessKeyEvent;
53+
BOOL handlingKeyEvent;
54+
BOOL didCommitText;
5455
BOOL isHiDPIAware;
5556
}
5657

modules/javafx.graphics/src/main/native-glass/mac/GlassView3D.m

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)