From d85a1d0f738db7f0c9b43b6eadc2022abe530dd9 Mon Sep 17 00:00:00 2001 From: nanshiki Date: Sat, 19 Nov 2022 12:45:42 +0900 Subject: [PATCH] Fixed to display IME marked text in SDL2 version on macOS --- src/gui/sdlmain.cpp | 8 ++++- vs/sdl2/src/video/cocoa/SDL_cocoakeyboard.m | 38 +++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index b84ce4467..bec376c61 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -5092,10 +5092,14 @@ void SetIMPosition() { uint8_t height = IS_PC98_ARCH?16:real_readb(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT); uint8_t width = CurMode && DOSV_CheckCJKVideoMode() ? CurMode->cwidth : (height / 2); SDL_Rect rect; + rect.h = 0; #if defined(USE_TTF) if (ttf.inUse) { rect.x = x * ttf.width; rect.y = y * ttf.height + (ttf.height - TTF_FontAscent(ttf.SDL_font)) / 2; +#if defined(MACOSX) + rect.h = ttf.height; +#endif } else { #endif double sx = sdl.clip.w>0&&sdl.draw.width>0?((double)sdl.clip.w/sdl.draw.width):1, sy = sdl.clip.h>0&&sdl.draw.height>0?((double)sdl.clip.h/sdl.draw.height):1; @@ -5104,6 +5108,9 @@ void SetIMPosition() { #if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW /* SDL drawn menus */ rect.y += mainMenu.menuBarHeight; #endif +#if defined(MACOSX) + rect.h = height; +#endif #if defined(USE_TTF) } #endif @@ -5111,7 +5118,6 @@ void SetIMPosition() { rect.y--; #if defined(C_SDL2) rect.w = 0; - rect.h = 0; SDL_SetTextInputRect(&rect); #else SDL_SetIMPosition(rect.x, rect.y); diff --git a/vs/sdl2/src/video/cocoa/SDL_cocoakeyboard.m b/vs/sdl2/src/video/cocoa/SDL_cocoakeyboard.m index da482f006..e3851f99f 100644 --- a/vs/sdl2/src/video/cocoa/SDL_cocoakeyboard.m +++ b/vs/sdl2/src/video/cocoa/SDL_cocoakeyboard.m @@ -34,11 +34,27 @@ /*#define DEBUG_IME NSLog */ #define DEBUG_IME(...) +@interface IMETextView : NSView +@property (nonatomic, copy) NSAttributedString *text; +@end + +@implementation IMETextView +- (void)drawRect:(NSRect)dirtyRect +{ + [super drawRect:dirtyRect]; + CGSize size = [_text size]; + [[NSColor whiteColor] set]; + NSRectFill(dirtyRect); + [_text drawInRect:CGRectMake(0, 0, size.width, size.height)]; +} +@end + @interface SDLTranslatorResponder : NSView { NSString *_markedText; NSRange _markedRange; NSRange _selectedRange; SDL_Rect _inputRect; + IMETextView *_markedLabel; } - (void)doCommandBySelector:(SEL)myselector; - (void)setInputRect:(SDL_Rect *)rect; @@ -68,6 +84,9 @@ } SDL_SendKeyboardText(str); + + [_markedLabel setHidden:YES]; + _markedLabel.text = nil; } - (void)doCommandBySelector:(SEL)myselector @@ -98,6 +117,13 @@ static long end_ticks = 0; - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { if ([aString isKindOfClass:[NSAttributedString class]]) { + [aString addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:_inputRect.h] range:NSMakeRange(0, [aString length])]; + _markedLabel.text = aString; + CGSize size = [aString size]; + [_markedLabel setFrameSize:size]; + [_markedLabel setHidden:NO]; + [_markedLabel setNeedsDisplay:YES]; + aString = [aString string]; } @@ -129,6 +155,8 @@ static long end_ticks = 0; [_markedText release]; _markedText = nil; + [_markedLabel setHidden:YES]; + SDL_SendEditingText("", 0, 0); } @@ -142,8 +170,8 @@ SDL_bool SDL_IM_Composition(int more) { NSWindow *window = [self window]; NSRect contentRect = [window contentRectForFrameRect:[window frame]]; float windowHeight = contentRect.size.height; - NSRect rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y - _inputRect.h, - _inputRect.w, _inputRect.h); + NSRect rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y, + _inputRect.w, 0); if (actualRange) { *actualRange = aRange; @@ -162,6 +190,12 @@ SDL_bool SDL_IM_Composition(int more) { rect = [window convertRectToScreen:rect]; } + if(!_markedLabel) { + _markedLabel = [[IMETextView alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)]; + [[[self window] contentView] addSubview:_markedLabel]; + } + [_markedLabel setFrameOrigin: NSMakePoint(_inputRect.x, windowHeight - _inputRect.y)]; + return rect; }