From 98a83b362f418bb825ae11b213e7cd87f934593d Mon Sep 17 00:00:00 2001 From: Mario Dorn Date: Fri, 13 Nov 2015 17:19:20 +0100 Subject: [PATCH] Implement NSTextInputClient protocol on OS X This implementation provides support for IME character composition (Fix #456) --- src/cocoa_window.m | 104 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 91 insertions(+), 13 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 15bc48e58..cf583a257 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -127,6 +127,10 @@ static int translateKey(unsigned int key) return _glfw.ns.publicKeys[key]; } +// Defines a constant for empty ranges in NSTextInputClient +// +static const NSRange kEmptyRange = {NSNotFound, 0}; + //------------------------------------------------------------------------ // Delegate for window related notifications @@ -277,10 +281,11 @@ static int translateKey(unsigned int key) // Content view class for the GLFW window //------------------------------------------------------------------------ -@interface GLFWContentView : NSView +@interface GLFWContentView : NSView { _GLFWwindow* window; NSTrackingArea* trackingArea; + NSMutableAttributedString *markedText; } - (id)initWithGlfwWindow:(_GLFWwindow *)initWindow; @@ -310,6 +315,7 @@ static int translateKey(unsigned int key) { window = initWindow; trackingArea = nil; + markedText = [[NSMutableAttributedString alloc] init]; [self updateTrackingAreas]; [self registerForDraggedTypes:[NSArray arrayWithObjects: @@ -482,18 +488,7 @@ static int translateKey(unsigned int key) _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods); - NSString* characters = [event characters]; - NSUInteger i, length = [characters length]; - const int plain = !(mods & GLFW_MOD_SUPER); - - for (i = 0; i < length; i++) - { - const unichar codepoint = [characters characterAtIndex:i]; - if ((codepoint & 0xff00) == 0xf700) - continue; - - _glfwInputChar(window, codepoint, mods, plain); - } + [self interpretKeyEvents:[NSArray arrayWithObject:event]]; } - (void)flagsChanged:(NSEvent *)event @@ -598,6 +593,89 @@ static int translateKey(unsigned int key) [self setNeedsDisplay:YES]; } +- (BOOL)hasMarkedText +{ + return (markedText.length > 0); +} + +- (NSRange)markedRange +{ + return (markedText.length > 0) ? + NSMakeRange(0, markedText.length-1) : + kEmptyRange; +} + +- (NSRange)selectedRange +{ + return kEmptyRange; +} + +- (void)setMarkedText:(id)aString + selectedRange:(NSRange)selectedRange + replacementRange:(NSRange)replacementRange +{ + if( [aString isKindOfClass: [NSAttributedString class]] ) + { + [markedText initWithAttributedString: aString]; + } + else + { + [markedText initWithString: aString]; + } +} + +- (void)unmarkText +{ + [[markedText mutableString] setString:@""]; +} + +- (NSArray*)validAttributesForMarkedText +{ + return [NSArray array]; +} + +- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)aRange + actualRange:(NSRangePointer)actualRange +{ + return nil; +} + +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint +{ + return 0; +} + +- (NSRect)firstRectForCharacterRange:(NSRange)aRange + actualRange:(NSRangePointer)actualRange +{ + return NSMakeRect(0, 0, 0, 0); +} + +- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange +{ + NSEvent* event = [NSApp currentEvent]; + const int mods = translateFlags([event modifierFlags]); + + NSString* characters; + if ([aString isKindOfClass: [NSAttributedString class]]) { + characters = [aString string]; + } else { + characters = (NSString*)aString; + } + + NSUInteger i, length = [characters length]; + const int plain = !(mods & GLFW_MOD_SUPER); + + for (i = 0; i < length; i++) + { + const unichar codepoint = [characters characterAtIndex:i]; + if ((codepoint & 0xff00) == 0xf700) + continue; + + _glfwInputChar(window, codepoint, mods, plain); + } +} + @end