@@ -313,6 +313,12 @@ - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOO
313313
314314 mOldResize = false ;
315315
316+ // CJK 입력 관련 변수 초기화 (한국어, 일본어, 중국어)
317+ mHasMarkedText = FALSE ;
318+ mMarkedTextLength = 0 ;
319+ mMarkedTextAllowed = true ; // 기본값을 true로 설정하여 IME 지원
320+ mSimulatedRightClick = false ;
321+
316322 return self;
317323}
318324
@@ -517,6 +523,23 @@ - (void) keyDown:(NSEvent *)theEvent
517523 {
518524 ch = [str_no_modifiers characterAtIndex: 0 ];
519525 }
526+
527+ // CJK 언어 조합 중인지 확인 (한국어, 일본어, 중국어)
528+ BOOL isComposingCJK = mHasMarkedText ||
529+ (!mMarkedTextAllowed &&
530+ !(mModifiers & (NSControlKeyMask | NSCommandKeyMask )) &&
531+ ![(LLAppDelegate*)[NSApp delegate ] romanScript ] &&
532+ ch > ' ' &&
533+ ch != NSDeleteCharacter &&
534+ (ch < 0xF700 || ch > 0xF8FF ));
535+
536+ // CJK 조합 중이면 키 이벤트를 처리하지 않고 IME에 맡김
537+ if (isComposingCJK && mHasMarkedText )
538+ {
539+ [[self inputContext ] handleEvent: theEvent];
540+ return ;
541+ }
542+
520543 bool acceptsText = mHasMarkedText ? false : callKeyDown (&eventData, keycode, mModifiers , ch);
521544
522545 if (acceptsText &&
@@ -667,8 +690,17 @@ - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replaceme
667690 };
668691
669692 int string_length = [aString length ];
693+
694+ // 빈 문자열이면 marked text 제거
695+ if (string_length == 0 )
696+ {
697+ [self unmarkText ];
698+ return ;
699+ }
700+
670701 unichar text[string_length];
671702 attributedStringInfo segments;
703+
672704 // I used 'respondsToSelector:@selector(string)'
673705 // to judge aString is an attributed string or not.
674706 if ([aString respondsToSelector: @selector (string )])
@@ -684,18 +716,13 @@ - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replaceme
684716 segments.seg_lengths .push_back (string_length);
685717 segments.seg_standouts .push_back (true );
686718 }
719+
687720 setMarkedText (text, selected, replacement, string_length, segments);
688- if (string_length > 0 )
689- {
690- mHasMarkedText = TRUE ;
691- mMarkedTextLength = string_length;
692- }
693- else
694- {
695- // we must clear the marked text when aString is null.
696- [self unmarkText ];
697- }
698- } else {
721+ mHasMarkedText = TRUE ;
722+ mMarkedTextLength = string_length;
723+ }
724+ else
725+ {
699726 if (mHasMarkedText )
700727 {
701728 [self unmarkText ];
@@ -743,10 +770,17 @@ - (void)insertText:(id)insertString
743770
744771- (void )insertText : (id )aString replacementRange : (NSRange )replacementRange
745772{
746- // SL-19801 Special workaround for system emoji picker
747- if ([aString length ] == 2 )
748- {
749- @try
773+ @try
774+ {
775+ // marked text가 있는 경우 먼저 정리
776+ if (mHasMarkedText )
777+ {
778+ resetPreedit ();
779+ mHasMarkedText = FALSE ;
780+ }
781+
782+ // 이모지 처리 (기존 로직 유지)
783+ if ([aString length ] == 2 )
750784 {
751785 uint32_t b0 = [aString characterAtIndex: 0 ];
752786 uint32_t b1 = [aString characterAtIndex: 1 ];
@@ -757,32 +791,23 @@ - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
757791 return ;
758792 }
759793 }
760- @catch (NSException * e)
761- {
762- // One of the characters is an attribute string?
763- NSLog (@" Encountered an unsupported attributed character. Exception: %@ String: %@ " , e.name, aString);
764- return ;
765- }
766- }
767-
768- @try
769- {
770- if (!mHasMarkedText )
794+
795+ // 각 문자를 순차적으로 처리
796+ for (NSInteger i = 0 ; i < [aString length ]; i++)
771797 {
772- for (NSInteger i = 0 ; i < [aString length ]; i++)
798+ unichar character = [aString characterAtIndex: i];
799+
800+ // CJK 문자인지 확인 (한국어, 일본어, 중국어)
801+ if ([self isCJKCharacter: character])
773802 {
774- callUnicodeCallback ([aString characterAtIndex: i], mModifiers );
803+ // CJK 문자는 modifier 없이 전송
804+ callUnicodeCallback (character, 0 );
775805 }
776- } else {
777- resetPreedit ();
778- // We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
779- // But just in case...
780-
781- for (NSInteger i = 0 ; i < [aString length ]; i++)
806+ else
782807 {
783- handleUnicodeCharacter ([aString characterAtIndex: i]);
808+ // 기타 문자들
809+ callUnicodeCallback (character, mModifiers );
784810 }
785- mHasMarkedText = FALSE ;
786811 }
787812 }
788813 @catch (NSException * e)
@@ -831,6 +856,40 @@ - (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex
831856- (void ) allowMarkedTextInput : (bool )allowed
832857{
833858 mMarkedTextAllowed = allowed;
859+
860+ // CJK 입력 모드에서는 강제로 허용
861+ if (![(LLAppDelegate*)[NSApp delegate ] romanScript ])
862+ {
863+ mMarkedTextAllowed = true ;
864+ }
865+ }
866+
867+ // CJK 문자 판별 헬퍼 메서드
868+ - (BOOL )isCJKCharacter : (unichar )character
869+ {
870+ // 한국어: 한글 (가-힐힣)
871+ if (character >= 0xAC00 && character <= 0xD7AF ) return YES ;
872+
873+ // 일본어: 히라가나
874+ if (character >= 0x3040 && character <= 0x309F ) return YES ;
875+
876+ // 일본어: 가타기나
877+ if (character >= 0x30A0 && character <= 0x30FF ) return YES ;
878+
879+ // 일본어: 반각 가타기나
880+ if (character >= 0xFF65 && character <= 0xFF9F ) return YES ;
881+
882+ // 중국어/일본어: CJK 통합 한자
883+ if (character >= 0x4E00 && character <= 0x9FFF ) return YES ;
884+
885+ // 중국어: CJK 확장 A
886+ if (character >= 0x3400 && character <= 0x4DBF ) return YES ;
887+
888+ // 한국어: 한글 자모 (호환용)
889+ if (character >= 0x1100 && character <= 0x11FF ) return YES ; // 한글 자모
890+ if (character >= 0x3130 && character <= 0x318F ) return YES ; // 한글 호환 자모
891+
892+ return NO ;
834893}
835894
836895@end
0 commit comments